diff --git a/tools/packaging/kernel/configs/fragments/x86_64/ptp.conf b/tools/packaging/kernel/configs/fragments/x86_64/ptp.conf new file mode 100644 index 0000000000..bb298860be --- /dev/null +++ b/tools/packaging/kernel/configs/fragments/x86_64/ptp.conf @@ -0,0 +1,6 @@ +# PTP clock support +# +# Needed for keeping the guest time in sync with the host +# provided a ptp client runs in the guest. +CONFIG_PTP_1588_CLOCK=y +CONFIG_PTP_1588_CLOCK_KVM=y diff --git a/tools/packaging/kernel/kata_config_version b/tools/packaging/kernel/kata_config_version index dde92ddc1a..76a8b2b703 100644 --- a/tools/packaging/kernel/kata_config_version +++ b/tools/packaging/kernel/kata_config_version @@ -1 +1 @@ -82 +83 diff --git a/tools/packaging/kernel/patches/5.4.x/0005-ptp-arm64-Enable-ptp_kvm-for-arm64.patch b/tools/packaging/kernel/patches/5.4.x/0005-ptp-arm64-Enable-ptp_kvm-for-arm64.patch deleted file mode 100644 index 36942c5dd1..0000000000 --- a/tools/packaging/kernel/patches/5.4.x/0005-ptp-arm64-Enable-ptp_kvm-for-arm64.patch +++ /dev/null @@ -1,641 +0,0 @@ -From cb55878a1cecb7ef56956a28a9f1b745d0ac522b Mon Sep 17 00:00:00 2001 -From: Jianyong Wu -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 ---- - 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 - #include - #include -+#include - #include - #include - #include -@@ -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 -+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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+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 - #include - #include -+#include - #include - #include - #include --#include --#include - #include - - #include - -+#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 -+#include -+#include -+#include -+#include -+#include -+ -+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 -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 - #include - #include -+#include - #include - #include - -@@ -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 - #include - - /* 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 - #include - #include -+#include - - #include - #include -@@ -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 -