mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-28 19:54:35 +00:00
kernel: Remove arm patches for ptp
These patches are causing compilation issues while building on x86. Remove these while we fix the issue. Signed-off-by: Archana Shinde <archana.m.shinde@intel.com>
This commit is contained in:
parent
82efd2f267
commit
b474828052
@ -1,641 +0,0 @@
|
||||
From cb55878a1cecb7ef56956a28a9f1b745d0ac522b Mon Sep 17 00:00:00 2001
|
||||
From: Jianyong Wu <jianyong.wu@arm.com>
|
||||
Date: Wed, 1 Apr 2020 15:39:44 +0800
|
||||
Subject: [PATCH 3/3] ptp: arm64: Enable ptp_kvm for arm64.
|
||||
|
||||
Currently in arm64 virtualization environment, there is no mechanism to
|
||||
keep time sync between guest and host. Time in guest will drift compared
|
||||
with host after boot up as they may both use third party time sources
|
||||
to correct their time respectively. The time deviation will be in order
|
||||
of milliseconds but some scenarios ask for higher time precision, like
|
||||
in cloud envirenment, we want all the VMs running in the host aquire the
|
||||
same level accuracy from host clock.
|
||||
|
||||
Use of kvm ptp clock, which choose the host clock source clock as a
|
||||
reference clock to sync time clock between guest and host has been adopted
|
||||
by x86 which makes the time sync order from milliseconds to nanoseconds.
|
||||
|
||||
This patch enables kvm ptp on arm64.
|
||||
|
||||
Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
|
||||
---
|
||||
drivers/clocksource/arm_arch_timer.c | 24 ++++++
|
||||
drivers/firmware/psci/psci.c | 1 +
|
||||
drivers/ptp/Kconfig | 2 +-
|
||||
drivers/ptp/Makefile | 1 +
|
||||
drivers/ptp/ptp_kvm.h | 11 +++
|
||||
drivers/ptp/ptp_kvm_arm64.c | 51 ++++++++++++
|
||||
drivers/ptp/{ptp_kvm.c => ptp_kvm_common.c} | 78 +++++-------------
|
||||
drivers/ptp/ptp_kvm_x86.c | 87 +++++++++++++++++++++
|
||||
include/linux/arm-smccc.h | 8 ++
|
||||
include/linux/clocksource.h | 6 ++
|
||||
include/linux/clocksource_ids.h | 13 +++
|
||||
include/linux/timekeeping.h | 12 +--
|
||||
include/uapi/linux/kvm.h | 1 +
|
||||
kernel/time/clocksource.c | 3 +
|
||||
kernel/time/timekeeping.c | 1 +
|
||||
virt/kvm/arm/arm.c | 1 +
|
||||
virt/kvm/arm/psci.c | 23 ++++++
|
||||
17 files changed, 258 insertions(+), 65 deletions(-)
|
||||
create mode 100644 drivers/ptp/ptp_kvm.h
|
||||
create mode 100644 drivers/ptp/ptp_kvm_arm64.c
|
||||
rename drivers/ptp/{ptp_kvm.c => ptp_kvm_common.c} (63%)
|
||||
create mode 100644 drivers/ptp/ptp_kvm_x86.c
|
||||
create mode 100644 include/linux/clocksource_ids.h
|
||||
|
||||
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
|
||||
index 9a5464c625b4..0c723df39b55 100644
|
||||
--- a/drivers/clocksource/arm_arch_timer.c
|
||||
+++ b/drivers/clocksource/arm_arch_timer.c
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <linux/cpu_pm.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/clocksource.h>
|
||||
+#include <linux/clocksource_ids.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_address.h>
|
||||
@@ -187,6 +188,7 @@ static u64 arch_counter_read_cc(const struct cyclecounter *cc)
|
||||
|
||||
static struct clocksource clocksource_counter = {
|
||||
.name = "arch_sys_counter",
|
||||
+ .id = CSID_ARM_ARCH_COUNTER,
|
||||
.rating = 400,
|
||||
.read = arch_counter_read,
|
||||
.mask = CLOCKSOURCE_MASK(56),
|
||||
@@ -1623,3 +1625,25 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table)
|
||||
}
|
||||
TIMER_ACPI_DECLARE(arch_timer, ACPI_SIG_GTDT, arch_timer_acpi_init);
|
||||
#endif
|
||||
+
|
||||
+#if IS_ENABLED(CONFIG_PTP_1588_CLOCK_KVM)
|
||||
+#include <linux/arm-smccc.h>
|
||||
+int kvm_arch_ptp_get_crosststamp(unsigned long *cycle, struct timespec64 *ts,
|
||||
+ struct clocksource **cs)
|
||||
+{
|
||||
+ struct arm_smccc_res hvc_res;
|
||||
+ ktime_t ktime_overall;
|
||||
+
|
||||
+ arm_smccc_1_1_invoke(ARM_SMCCC_HYP_KVM_PTP_FUNC_ID, &hvc_res);
|
||||
+ if ((long)(hvc_res.a0) < 0)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ ktime_overall = hvc_res.a0 << 32 | hvc_res.a1;
|
||||
+ *ts = ktime_to_timespec64(ktime_overall);
|
||||
+ *cycle = hvc_res.a2 << 32 | hvc_res.a3;
|
||||
+ *cs = &clocksource_counter;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(kvm_arch_ptp_get_crosststamp);
|
||||
+#endif
|
||||
diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
|
||||
index eb797081d159..87a7dc18b175 100644
|
||||
--- a/drivers/firmware/psci/psci.c
|
||||
+++ b/drivers/firmware/psci/psci.c
|
||||
@@ -71,6 +71,7 @@ enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void)
|
||||
return SMCCC_CONDUIT_NONE;
|
||||
}
|
||||
}
|
||||
+EXPORT_SYMBOL(arm_smccc_1_1_get_conduit);
|
||||
|
||||
typedef unsigned long (psci_fn)(unsigned long, unsigned long,
|
||||
unsigned long, unsigned long);
|
||||
diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig
|
||||
index 0517272a268e..6f3688e7e440 100644
|
||||
--- a/drivers/ptp/Kconfig
|
||||
+++ b/drivers/ptp/Kconfig
|
||||
@@ -110,7 +110,7 @@ config PTP_1588_CLOCK_PCH
|
||||
config PTP_1588_CLOCK_KVM
|
||||
tristate "KVM virtual PTP clock"
|
||||
depends on PTP_1588_CLOCK
|
||||
- depends on KVM_GUEST && X86
|
||||
+ depends on KVM_GUEST && X86 || ARM64 && ARM_ARCH_TIMER
|
||||
default y
|
||||
help
|
||||
This driver adds support for using kvm infrastructure as a PTP
|
||||
diff --git a/drivers/ptp/Makefile b/drivers/ptp/Makefile
|
||||
index 677d1d178a3e..3b7554f56ad9 100644
|
||||
--- a/drivers/ptp/Makefile
|
||||
+++ b/drivers/ptp/Makefile
|
||||
@@ -4,6 +4,7 @@
|
||||
#
|
||||
|
||||
ptp-y := ptp_clock.o ptp_chardev.o ptp_sysfs.o
|
||||
+ptp_kvm-y := ptp_kvm_$(ARCH).o ptp_kvm_common.o
|
||||
obj-$(CONFIG_PTP_1588_CLOCK) += ptp.o
|
||||
obj-$(CONFIG_PTP_1588_CLOCK_DTE) += ptp_dte.o
|
||||
obj-$(CONFIG_PTP_1588_CLOCK_IXP46X) += ptp_ixp46x.o
|
||||
diff --git a/drivers/ptp/ptp_kvm.h b/drivers/ptp/ptp_kvm.h
|
||||
new file mode 100644
|
||||
index 000000000000..4bf1802bbeb8
|
||||
--- /dev/null
|
||||
+++ b/drivers/ptp/ptp_kvm.h
|
||||
@@ -0,0 +1,11 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
+/*
|
||||
+ * Virtual PTP 1588 clock for use with KVM guests
|
||||
+ *
|
||||
+ * Copyright (C) 2017 Red Hat Inc.
|
||||
+ */
|
||||
+
|
||||
+int kvm_arch_ptp_init(void);
|
||||
+int kvm_arch_ptp_get_clock(struct timespec64 *ts);
|
||||
+int kvm_arch_ptp_get_crosststamp(unsigned long *cycle,
|
||||
+ struct timespec64 *tspec, void *cs);
|
||||
diff --git a/drivers/ptp/ptp_kvm_arm64.c b/drivers/ptp/ptp_kvm_arm64.c
|
||||
new file mode 100644
|
||||
index 000000000000..446f2444d285
|
||||
--- /dev/null
|
||||
+++ b/drivers/ptp/ptp_kvm_arm64.c
|
||||
@@ -0,0 +1,51 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * Virtual PTP 1588 clock for use with KVM guests
|
||||
+ * Copyright (C) 2019 ARM Ltd.
|
||||
+ * All Rights Reserved
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <asm/hypervisor.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/psci.h>
|
||||
+#include <linux/arm-smccc.h>
|
||||
+#include <linux/timecounter.h>
|
||||
+#include <linux/sched/clock.h>
|
||||
+#include <asm/arch_timer.h>
|
||||
+
|
||||
+int kvm_arch_ptp_init(void)
|
||||
+{
|
||||
+ struct arm_smccc_res hvc_res;
|
||||
+
|
||||
+ arm_smccc_1_1_invoke(ARM_SMCCC_HYP_KVM_PTP_FUNC_ID, &hvc_res);
|
||||
+ if ((long)(hvc_res.a0) < 0)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int kvm_arch_ptp_get_clock_generic(struct timespec64 *ts,
|
||||
+ struct arm_smccc_res *hvc_res)
|
||||
+{
|
||||
+ ktime_t ktime_overall;
|
||||
+
|
||||
+ arm_smccc_1_1_invoke(ARM_SMCCC_HYP_KVM_PTP_FUNC_ID, hvc_res);
|
||||
+ if ((long)(hvc_res->a0) < 0)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ ktime_overall = hvc_res->a0 << 32 | hvc_res->a1;
|
||||
+ *ts = ktime_to_timespec64(ktime_overall);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int kvm_arch_ptp_get_clock(struct timespec64 *ts)
|
||||
+{
|
||||
+ struct arm_smccc_res hvc_res;
|
||||
+
|
||||
+ kvm_arch_ptp_get_clock_generic(ts, &hvc_res);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/drivers/ptp/ptp_kvm.c b/drivers/ptp/ptp_kvm_common.c
|
||||
similarity index 63%
|
||||
rename from drivers/ptp/ptp_kvm.c
|
||||
rename to drivers/ptp/ptp_kvm_common.c
|
||||
index fc7d0b77e118..60442f70d3fc 100644
|
||||
--- a/drivers/ptp/ptp_kvm.c
|
||||
+++ b/drivers/ptp/ptp_kvm_common.c
|
||||
@@ -8,15 +8,16 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
+#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <uapi/linux/kvm_para.h>
|
||||
#include <asm/kvm_para.h>
|
||||
-#include <asm/pvclock.h>
|
||||
-#include <asm/kvmclock.h>
|
||||
#include <uapi/asm/kvm_para.h>
|
||||
|
||||
#include <linux/ptp_clock_kernel.h>
|
||||
|
||||
+#include "ptp_kvm.h"
|
||||
+
|
||||
struct kvm_ptp_clock {
|
||||
struct ptp_clock *ptp_clock;
|
||||
struct ptp_clock_info caps;
|
||||
@@ -24,56 +25,29 @@ struct kvm_ptp_clock {
|
||||
|
||||
DEFINE_SPINLOCK(kvm_ptp_lock);
|
||||
|
||||
-static struct pvclock_vsyscall_time_info *hv_clock;
|
||||
-
|
||||
-static struct kvm_clock_pairing clock_pair;
|
||||
-static phys_addr_t clock_pair_gpa;
|
||||
-
|
||||
static int ptp_kvm_get_time_fn(ktime_t *device_time,
|
||||
struct system_counterval_t *system_counter,
|
||||
void *ctx)
|
||||
{
|
||||
- unsigned long ret;
|
||||
+ unsigned long ret, cycle;
|
||||
struct timespec64 tspec;
|
||||
- unsigned version;
|
||||
- int cpu;
|
||||
- struct pvclock_vcpu_time_info *src;
|
||||
+ struct clocksource *cs;
|
||||
|
||||
spin_lock(&kvm_ptp_lock);
|
||||
|
||||
preempt_disable_notrace();
|
||||
- cpu = smp_processor_id();
|
||||
- src = &hv_clock[cpu].pvti;
|
||||
-
|
||||
- do {
|
||||
- /*
|
||||
- * We are using a TSC value read in the hosts
|
||||
- * kvm_hc_clock_pairing handling.
|
||||
- * So any changes to tsc_to_system_mul
|
||||
- * and tsc_shift or any other pvclock
|
||||
- * data invalidate that measurement.
|
||||
- */
|
||||
- version = pvclock_read_begin(src);
|
||||
-
|
||||
- ret = kvm_hypercall2(KVM_HC_CLOCK_PAIRING,
|
||||
- clock_pair_gpa,
|
||||
- KVM_CLOCK_PAIRING_WALLCLOCK);
|
||||
- if (ret != 0) {
|
||||
- pr_err_ratelimited("clock pairing hypercall ret %lu\n", ret);
|
||||
- spin_unlock(&kvm_ptp_lock);
|
||||
- preempt_enable_notrace();
|
||||
- return -EOPNOTSUPP;
|
||||
- }
|
||||
-
|
||||
- tspec.tv_sec = clock_pair.sec;
|
||||
- tspec.tv_nsec = clock_pair.nsec;
|
||||
- ret = __pvclock_read_cycles(src, clock_pair.tsc);
|
||||
- } while (pvclock_read_retry(src, version));
|
||||
+ ret = kvm_arch_ptp_get_crosststamp(&cycle, &tspec, &cs);
|
||||
+ if (ret != 0) {
|
||||
+ pr_err_ratelimited("clock pairing hypercall ret %lu\n", ret);
|
||||
+ spin_unlock(&kvm_ptp_lock);
|
||||
+ preempt_enable_notrace();
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
|
||||
preempt_enable_notrace();
|
||||
|
||||
- system_counter->cycles = ret;
|
||||
- system_counter->cs = &kvm_clock;
|
||||
+ system_counter->cycles = cycle;
|
||||
+ system_counter->cs = cs;
|
||||
|
||||
*device_time = timespec64_to_ktime(tspec);
|
||||
|
||||
@@ -116,17 +90,13 @@ static int ptp_kvm_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
|
||||
|
||||
spin_lock(&kvm_ptp_lock);
|
||||
|
||||
- ret = kvm_hypercall2(KVM_HC_CLOCK_PAIRING,
|
||||
- clock_pair_gpa,
|
||||
- KVM_CLOCK_PAIRING_WALLCLOCK);
|
||||
+ ret = kvm_arch_ptp_get_clock(&tspec);
|
||||
if (ret != 0) {
|
||||
pr_err_ratelimited("clock offset hypercall ret %lu\n", ret);
|
||||
spin_unlock(&kvm_ptp_lock);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
- tspec.tv_sec = clock_pair.sec;
|
||||
- tspec.tv_nsec = clock_pair.nsec;
|
||||
spin_unlock(&kvm_ptp_lock);
|
||||
|
||||
memcpy(ts, &tspec, sizeof(struct timespec64));
|
||||
@@ -166,21 +136,11 @@ static void __exit ptp_kvm_exit(void)
|
||||
|
||||
static int __init ptp_kvm_init(void)
|
||||
{
|
||||
- long ret;
|
||||
-
|
||||
- if (!kvm_para_available())
|
||||
- return -ENODEV;
|
||||
+ int ret;
|
||||
|
||||
- clock_pair_gpa = slow_virt_to_phys(&clock_pair);
|
||||
- hv_clock = pvclock_get_pvti_cpu0_va();
|
||||
-
|
||||
- if (!hv_clock)
|
||||
- return -ENODEV;
|
||||
-
|
||||
- ret = kvm_hypercall2(KVM_HC_CLOCK_PAIRING, clock_pair_gpa,
|
||||
- KVM_CLOCK_PAIRING_WALLCLOCK);
|
||||
- if (ret == -KVM_ENOSYS || ret == -KVM_EOPNOTSUPP)
|
||||
- return -ENODEV;
|
||||
+ ret = kvm_arch_ptp_init();
|
||||
+ if (ret)
|
||||
+ return -EOPNOTSUPP;
|
||||
|
||||
kvm_ptp_clock.caps = ptp_kvm_caps;
|
||||
|
||||
diff --git a/drivers/ptp/ptp_kvm_x86.c b/drivers/ptp/ptp_kvm_x86.c
|
||||
new file mode 100644
|
||||
index 000000000000..6c891d7299c6
|
||||
--- /dev/null
|
||||
+++ b/drivers/ptp/ptp_kvm_x86.c
|
||||
@@ -0,0 +1,87 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+/*
|
||||
+ * Virtual PTP 1588 clock for use with KVM guests
|
||||
+ *
|
||||
+ * Copyright (C) 2017 Red Hat Inc.
|
||||
+ */
|
||||
+
|
||||
+#include <asm/pvclock.h>
|
||||
+#include <asm/kvmclock.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <uapi/asm/kvm_para.h>
|
||||
+#include <uapi/linux/kvm_para.h>
|
||||
+#include <linux/ptp_clock_kernel.h>
|
||||
+
|
||||
+phys_addr_t clock_pair_gpa;
|
||||
+struct kvm_clock_pairing clock_pair;
|
||||
+struct pvclock_vsyscall_time_info *hv_clock;
|
||||
+
|
||||
+int kvm_arch_ptp_init(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!kvm_para_available())
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ clock_pair_gpa = slow_virt_to_phys(&clock_pair);
|
||||
+ hv_clock = pvclock_get_pvti_cpu0_va();
|
||||
+ if (!hv_clock)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ ret = kvm_hypercall2(KVM_HC_CLOCK_PAIRING, clock_pair_gpa,
|
||||
+ KVM_CLOCK_PAIRING_WALLCLOCK);
|
||||
+ if (ret == -KVM_ENOSYS || ret == -KVM_EOPNOTSUPP)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int kvm_arch_ptp_get_clock(struct timespec64 *ts)
|
||||
+{
|
||||
+ long ret;
|
||||
+
|
||||
+ ret = kvm_hypercall2(KVM_HC_CLOCK_PAIRING,
|
||||
+ clock_pair_gpa,
|
||||
+ KVM_CLOCK_PAIRING_WALLCLOCK);
|
||||
+ if (ret != 0)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ ts->tv_sec = clock_pair.sec;
|
||||
+ ts->tv_nsec = clock_pair.nsec;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int kvm_arch_ptp_get_crosststamp(unsigned long *cycle, struct timespec64 *tspec,
|
||||
+ struct clocksource **cs)
|
||||
+{
|
||||
+ unsigned long ret;
|
||||
+ unsigned int version;
|
||||
+ int cpu;
|
||||
+ struct pvclock_vcpu_time_info *src;
|
||||
+
|
||||
+ cpu = smp_processor_id();
|
||||
+ src = &hv_clock[cpu].pvti;
|
||||
+
|
||||
+ do {
|
||||
+ /*
|
||||
+ * We are using a TSC value read in the hosts
|
||||
+ * kvm_hc_clock_pairing handling.
|
||||
+ * So any changes to tsc_to_system_mul
|
||||
+ * and tsc_shift or any other pvclock
|
||||
+ * data invalidate that measurement.
|
||||
+ */
|
||||
+ version = pvclock_read_begin(src);
|
||||
+
|
||||
+ ret = kvm_hypercall2(KVM_HC_CLOCK_PAIRING,
|
||||
+ clock_pair_gpa,
|
||||
+ KVM_CLOCK_PAIRING_WALLCLOCK);
|
||||
+ tspec->tv_sec = clock_pair.sec;
|
||||
+ tspec->tv_nsec = clock_pair.nsec;
|
||||
+ *cycle = __pvclock_read_cycles(src, clock_pair.tsc);
|
||||
+ } while (pvclock_read_retry(src, version));
|
||||
+
|
||||
+ *cs = &kvm_clock;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
|
||||
index e6d4cb4f61f1..32a46d564934 100644
|
||||
--- a/include/linux/arm-smccc.h
|
||||
+++ b/include/linux/arm-smccc.h
|
||||
@@ -45,6 +45,7 @@
|
||||
#define ARM_SMCCC_OWNER_SIP 2
|
||||
#define ARM_SMCCC_OWNER_OEM 3
|
||||
#define ARM_SMCCC_OWNER_STANDARD 4
|
||||
+#define ARM_SMCCC_OWNER_STANDARD_HYP 5
|
||||
#define ARM_SMCCC_OWNER_TRUSTED_APP 48
|
||||
#define ARM_SMCCC_OWNER_TRUSTED_APP_END 49
|
||||
#define ARM_SMCCC_OWNER_TRUSTED_OS 50
|
||||
@@ -76,6 +77,13 @@
|
||||
ARM_SMCCC_SMC_32, \
|
||||
0, 0x7fff)
|
||||
|
||||
+/* PTP KVM call requests clock time from guest OS to host */
|
||||
+#define ARM_SMCCC_HYP_KVM_PTP_FUNC_ID \
|
||||
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
|
||||
+ ARM_SMCCC_SMC_32, \
|
||||
+ ARM_SMCCC_OWNER_STANDARD_HYP, \
|
||||
+ 0)
|
||||
+
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/linkage.h>
|
||||
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
|
||||
index b21db536fd52..96e85b6f9ca0 100644
|
||||
--- a/include/linux/clocksource.h
|
||||
+++ b/include/linux/clocksource.h
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <linux/timer.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/of.h>
|
||||
+#include <linux/clocksource_ids.h>
|
||||
#include <asm/div64.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
@@ -49,6 +50,10 @@ struct module;
|
||||
* 400-499: Perfect
|
||||
* The ideal clocksource. A must-use where
|
||||
* available.
|
||||
+ * @id: Defaults to CSID_GENERIC. The id value is captured
|
||||
+ * in certain snapshot functions to allow callers to
|
||||
+ * validate the clocksource from which the snapshot was
|
||||
+ * taken.
|
||||
* @read: returns a cycle value, passes clocksource as argument
|
||||
* @enable: optional function to enable the clocksource
|
||||
* @disable: optional function to disable the clocksource
|
||||
@@ -91,6 +96,7 @@ struct clocksource {
|
||||
const char *name;
|
||||
struct list_head list;
|
||||
int rating;
|
||||
+ enum clocksource_ids id;
|
||||
int (*enable)(struct clocksource *cs);
|
||||
void (*disable)(struct clocksource *cs);
|
||||
unsigned long flags;
|
||||
diff --git a/include/linux/clocksource_ids.h b/include/linux/clocksource_ids.h
|
||||
new file mode 100644
|
||||
index 000000000000..93bec8426c44
|
||||
--- /dev/null
|
||||
+++ b/include/linux/clocksource_ids.h
|
||||
@@ -0,0 +1,13 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+#ifndef _LINUX_CLOCKSOURCE_IDS_H
|
||||
+#define _LINUX_CLOCKSOURCE_IDS_H
|
||||
+
|
||||
+/* Enum to give clocksources a unique identifier */
|
||||
+enum clocksource_ids {
|
||||
+ CSID_GENERIC = 0,
|
||||
+ CSID_ARM_ARCH_COUNTER,
|
||||
+ CSID_MAX,
|
||||
+};
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
|
||||
index b27e2ffa96c1..4ecc32ad3879 100644
|
||||
--- a/include/linux/timekeeping.h
|
||||
+++ b/include/linux/timekeeping.h
|
||||
@@ -2,6 +2,7 @@
|
||||
#ifndef _LINUX_TIMEKEEPING_H
|
||||
#define _LINUX_TIMEKEEPING_H
|
||||
|
||||
+#include <linux/clocksource_ids.h>
|
||||
#include <linux/errno.h>
|
||||
|
||||
/* Included from linux/ktime.h */
|
||||
@@ -232,11 +233,12 @@ extern void timekeeping_inject_sleeptime64(const struct timespec64 *delta);
|
||||
* @cs_was_changed_seq: The sequence number of clocksource change events
|
||||
*/
|
||||
struct system_time_snapshot {
|
||||
- u64 cycles;
|
||||
- ktime_t real;
|
||||
- ktime_t raw;
|
||||
- unsigned int clock_was_set_seq;
|
||||
- u8 cs_was_changed_seq;
|
||||
+ u64 cycles;
|
||||
+ ktime_t real;
|
||||
+ ktime_t raw;
|
||||
+ enum clocksource_ids cs_id;
|
||||
+ unsigned int clock_was_set_seq;
|
||||
+ u8 cs_was_changed_seq;
|
||||
};
|
||||
|
||||
/*
|
||||
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
|
||||
index 52641d8ca9e8..16008ebe5474 100644
|
||||
--- a/include/uapi/linux/kvm.h
|
||||
+++ b/include/uapi/linux/kvm.h
|
||||
@@ -1000,6 +1000,7 @@ struct kvm_ppc_resize_hpt {
|
||||
#define KVM_CAP_PMU_EVENT_FILTER 173
|
||||
#define KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 174
|
||||
#define KVM_CAP_HYPERV_DIRECT_TLBFLUSH 175
|
||||
+#define KVM_CAP_ARM_KVM_PTP 176
|
||||
|
||||
#ifdef KVM_CAP_IRQ_ROUTING
|
||||
|
||||
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
|
||||
index fff5f64981c6..5fe2d61172b1 100644
|
||||
--- a/kernel/time/clocksource.c
|
||||
+++ b/kernel/time/clocksource.c
|
||||
@@ -921,6 +921,9 @@ int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq)
|
||||
|
||||
clocksource_arch_init(cs);
|
||||
|
||||
+ if (WARN_ON_ONCE((unsigned int)cs->id >= CSID_MAX))
|
||||
+ cs->id = CSID_GENERIC;
|
||||
+
|
||||
/* Initialize mult/shift and max_idle_ns */
|
||||
__clocksource_update_freq_scale(cs, scale, freq);
|
||||
|
||||
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
|
||||
index ca69290bee2a..a8b378338b9e 100644
|
||||
--- a/kernel/time/timekeeping.c
|
||||
+++ b/kernel/time/timekeeping.c
|
||||
@@ -979,6 +979,7 @@ void ktime_get_snapshot(struct system_time_snapshot *systime_snapshot)
|
||||
do {
|
||||
seq = read_seqcount_begin(&tk_core.seq);
|
||||
now = tk_clock_read(&tk->tkr_mono);
|
||||
+ systime_snapshot->cs_id = tk->tkr_mono.clock->id;
|
||||
systime_snapshot->cs_was_changed_seq = tk->cs_was_changed_seq;
|
||||
systime_snapshot->clock_was_set_seq = tk->clock_was_set_seq;
|
||||
base_real = ktime_add(tk->tkr_mono.base,
|
||||
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
|
||||
index 86c6aa1cb58e..ee159ce9ca39 100644
|
||||
--- a/virt/kvm/arm/arm.c
|
||||
+++ b/virt/kvm/arm/arm.c
|
||||
@@ -197,6 +197,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
|
||||
case KVM_CAP_IMMEDIATE_EXIT:
|
||||
case KVM_CAP_VCPU_EVENTS:
|
||||
case KVM_CAP_ARM_IRQ_LINE_LAYOUT_2:
|
||||
+ case KVM_CAP_ARM_KVM_PTP:
|
||||
r = 1;
|
||||
break;
|
||||
case KVM_CAP_ARM_SET_DEVICE_ADDR:
|
||||
diff --git a/virt/kvm/arm/psci.c b/virt/kvm/arm/psci.c
|
||||
index 87927f7e1ee7..6e689f9952fb 100644
|
||||
--- a/virt/kvm/arm/psci.c
|
||||
+++ b/virt/kvm/arm/psci.c
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <linux/kvm_host.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/wait.h>
|
||||
+#include <linux/clocksource_ids.h>
|
||||
|
||||
#include <asm/cputype.h>
|
||||
#include <asm/kvm_emulate.h>
|
||||
@@ -389,6 +390,9 @@ static int kvm_psci_call(struct kvm_vcpu *vcpu)
|
||||
|
||||
int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
+ struct system_time_snapshot systime_snapshot;
|
||||
+ long arg[4];
|
||||
+ u64 cycles;
|
||||
u32 func_id = smccc_get_function(vcpu);
|
||||
u32 val = SMCCC_RET_NOT_SUPPORTED;
|
||||
u32 feature;
|
||||
@@ -428,6 +432,25 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
+ /*
|
||||
+ * This will used for virtual ptp kvm clock. three values will be
|
||||
+ * passed back.
|
||||
+ * reg0 stores high 32-bit host ktime;
|
||||
+ * reg1 stores low 32-bit host ktime;
|
||||
+ * reg2 stores high 32-bit difference of host cycles and cntvoff;
|
||||
+ * reg3 stores low 32-bit difference of host cycles and cntvoff.
|
||||
+ */
|
||||
+ case ARM_SMCCC_HYP_KVM_PTP_FUNC_ID:
|
||||
+ ktime_get_snapshot(&systime_snapshot);
|
||||
+ if (systime_snapshot.cs_id != CSID_ARM_ARCH_COUNTER)
|
||||
+ break;
|
||||
+ arg[0] = systime_snapshot.real >> 32;
|
||||
+ arg[1] = systime_snapshot.real << 32 >> 32;
|
||||
+ cycles = systime_snapshot.cycles - vcpu_vtimer(vcpu)->cntvoff;
|
||||
+ arg[2] = cycles >> 32;
|
||||
+ arg[3] = cycles << 32 >> 32;
|
||||
+ smccc_set_retval(vcpu, arg[0], arg[1], arg[2], arg[3]);
|
||||
+ return 1;
|
||||
default:
|
||||
return kvm_psci_call(vcpu);
|
||||
}
|
||||
--
|
||||
2.17.1
|
||||
|
Loading…
Reference in New Issue
Block a user