[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200522083724.38182-11-jianyong.wu@arm.com>
Date: Fri, 22 May 2020 16:37:23 +0800
From: Jianyong Wu <jianyong.wu@....com>
To: netdev@...r.kernel.org, yangbo.lu@....com, john.stultz@...aro.org,
tglx@...utronix.de, pbonzini@...hat.com,
sean.j.christopherson@...el.com, maz@...nel.org,
richardcochran@...il.com, Mark.Rutland@....com, will@...nel.org,
suzuki.poulose@....com, steven.price@....com
Cc: linux-kernel@...r.kernel.org, linux-arm-kernel@...ts.infradead.org,
kvmarm@...ts.cs.columbia.edu, kvm@...r.kernel.org,
Steve.Capper@....com, Kaly.Xin@....com, justin.he@....com,
Wei.Chen@....com, jianyong.wu@....com, nd@....com
Subject: [RFC PATCH v12 10/11] arm64: add mechanism to let user choose which counter to return
In general, vm inside will use virtual counter compered with host use
phyical counter. But in some special scenarios, like nested
virtualization, phyical counter maybe used by vm. A interface added in
ptp_kvm driver to offer a mechanism to let user choose which counter
should be return from host.
To use this feature, you should call PTP_EXTTS_REQUEST(2) ioctl with flag
set bit PTP_KVM_ARM_PHY_COUNTER in its argument then call
PTP_SYS_OFFSET_PRECISE(2) ioctl to get the cross timestamp and phyical
counter will return. If the bit not set or no call for PTP_EXTTS_REQUEST2,
virtual counter will return by default.
Signed-off-by: Jianyong Wu <jianyong.wu@....com>
Suggested-by: Marc Zyngier <maz@...nel.org>
---
drivers/clocksource/arm_arch_timer.c | 13 ++++++++++++-
drivers/ptp/ptp_chardev.c | 25 +++++++++++++++++++++++++
drivers/ptp/ptp_kvm_common.c | 7 ++++---
include/uapi/linux/ptp_clock.h | 4 +++-
4 files changed, 44 insertions(+), 5 deletions(-)
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 06959b901b0d..75a3bb118201 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -1650,7 +1650,18 @@ int kvm_arch_ptp_get_crosststamp(unsigned long *cycle, struct timespec64 *ts,
struct arm_smccc_res hvc_res;
ktime_t ktime_overall;
- arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID, &hvc_res);
+ /*
+ * an argument will be passed by a0 to determine weather virtual
+ * counter or phyical counter should be passed back.
+ */
+ if (ctx && *ctx)
+ arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID,
+ ARM_SMCCC_VENDOR_HYP_KVM_PTP_PHY_FUNC_ID,
+ &hvc_res);
+ else
+ arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID,
+ &hvc_res);
+
if ((int)(hvc_res.a0) < 0)
return -EOPNOTSUPP;
diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
index fef72f29f3c8..8b0a7b328bcd 100644
--- a/drivers/ptp/ptp_chardev.c
+++ b/drivers/ptp/ptp_chardev.c
@@ -123,6 +123,9 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
struct timespec64 ts;
int enable, err = 0;
+#ifdef CONFIG_ARM64
+ static long flag;
+#endif
switch (cmd) {
case PTP_CLOCK_GETCAPS:
@@ -149,6 +152,24 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
err = -EFAULT;
break;
}
+
+#ifdef CONFIG_ARM64
+ /*
+ * Just using this ioctl to tell kvm ptp driver to get PHC
+ * with physical counter, so if bit PTP_KVM_ARM_PHY_COUNTER
+ * is set then just exit directly.
+ * In most cases, we just need virtual counter from host and
+ * there is limited scenario using this to get physical counter
+ * in guest.
+ * Be careful to use this as there is no way to set it back
+ * unless you reinstall the module.
+ * This is only for arm64.
+ */
+ if (req.extts.flags & PTP_KVM_ARM_PHY_COUNTER) {
+ flag = 1;
+ break;
+ }
+#endif
if (cmd == PTP_EXTTS_REQUEST2) {
/* Tell the drivers to check the flags carefully. */
req.extts.flags |= PTP_STRICT_FLAGS;
@@ -235,7 +256,11 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
err = -EOPNOTSUPP;
break;
}
+#ifdef CONFIG_ARM64
+ err = ptp->info->getcrosststamp(ptp->info, &xtstamp, &flag);
+#else
err = ptp->info->getcrosststamp(ptp->info, &xtstamp, NULL);
+#endif
if (err)
break;
diff --git a/drivers/ptp/ptp_kvm_common.c b/drivers/ptp/ptp_kvm_common.c
index 4fdd8ab11a28..39367e230176 100644
--- a/drivers/ptp/ptp_kvm_common.c
+++ b/drivers/ptp/ptp_kvm_common.c
@@ -36,7 +36,7 @@ static int ptp_kvm_get_time_fn(ktime_t *device_time,
spin_lock(&kvm_ptp_lock);
preempt_disable_notrace();
- ret = kvm_arch_ptp_get_crosststamp(&cycle, &tspec, &cs);
+ ret = kvm_arch_ptp_get_crosststamp(&cycle, &tspec, &cs, ctx);
if (ret != 0) {
pr_err_ratelimited("clock pairing hypercall ret %lu\n", ret);
spin_unlock(&kvm_ptp_lock);
@@ -57,9 +57,10 @@ static int ptp_kvm_get_time_fn(ktime_t *device_time,
}
static int ptp_kvm_getcrosststamp(struct ptp_clock_info *ptp,
- struct system_device_crosststamp *xtstamp)
+ struct system_device_crosststamp *xtstamp,
+ long *flag)
{
- return get_device_system_crosststamp(ptp_kvm_get_time_fn, NULL,
+ return get_device_system_crosststamp(ptp_kvm_get_time_fn, flag,
NULL, xtstamp);
}
diff --git a/include/uapi/linux/ptp_clock.h b/include/uapi/linux/ptp_clock.h
index 9dc9d0079e98..71e388a82244 100644
--- a/include/uapi/linux/ptp_clock.h
+++ b/include/uapi/linux/ptp_clock.h
@@ -32,6 +32,7 @@
#define PTP_RISING_EDGE (1<<1)
#define PTP_FALLING_EDGE (1<<2)
#define PTP_STRICT_FLAGS (1<<3)
+#define PTP_KVM_ARM_PHY_COUNTER (1<<4)
#define PTP_EXTTS_EDGES (PTP_RISING_EDGE | PTP_FALLING_EDGE)
/*
@@ -40,7 +41,8 @@
#define PTP_EXTTS_VALID_FLAGS (PTP_ENABLE_FEATURE | \
PTP_RISING_EDGE | \
PTP_FALLING_EDGE | \
- PTP_STRICT_FLAGS)
+ PTP_STRICT_FLAGS | \
+ PTP_KVM_ARM_PHY_COUNTER)
/*
* flag fields valid for the original PTP_EXTTS_REQUEST ioctl.
--
2.17.1
Powered by blists - more mailing lists