Hi Steven,
Sorry, I really make mistake here, I really mean no r1 value.diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index db6dce3d0e23..366b0646c360 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -3,6 +3,7 @@
#include <linux/arm-smccc.h>
#include <linux/kvm_host.h>
+#include <linux/clocksource_ids.h>
#include <asm/kvm_emulate.h>
@@ -11,6 +12,10 @@
int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
{
+#ifdef CONFIG_ARM64_KVM_PTP_HOST
+ struct system_time_snapshot systime_snapshot;
+ u64 cycles = 0;
+#endif
u32 func_id = smccc_get_function(vcpu);
u32 val[4] = {SMCCC_RET_NOT_SUPPORTED};
u32 feature;
@@ -70,7 +75,52 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
break;
case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID:
val[0] = BIT(ARM_SMCCC_KVM_FUNC_FEATURES);
+
+#ifdef CONFIG_ARM64_KVM_PTP_HOST
+ val[0] |= BIT(ARM_SMCCC_KVM_FUNC_KVM_PTP); #endif
+ break;
+
+#ifdef CONFIG_ARM64_KVM_PTP_HOST
+ /*
+ * This serves virtual kvm_ptp.
+ * Four 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_VENDOR_HYP_KVM_PTP_FUNC_ID:
+ /*
+ * system time and counter value must captured in the same
+ * time to keep consistency and precision.
+ */
+ ktime_get_snapshot(&systime_snapshot);
+ if (systime_snapshot.cs_id != CSID_ARM_ARCH_COUNTER)
+ break;
+ val[0] = upper_32_bits(systime_snapshot.real);
+ val[1] = lower_32_bits(systime_snapshot.real);
+ /*
+ * which of virtual counter or physical counter being
+ * asked for is decided by the first argument of smccc
+ * call. If no first argument or invalid argument, zero
+ * counter value will return;
+ */
It's not actually possible to have "no first argument" - there's no argument
count, so whatever is in the register during the call with be passed. I'd also
caution that "first argument" is ambigious: r0 could be the 'first' but is also the
function number, here you mean r1.
There's also a subtle cast to 32 bits here (feature is u32), which might beYeah, it's better to add a note, but I think it's better add it at the first time calling smccc_get_arg1.
worth a comment before someone 'optimises' by removing the 'feature'
variable.
WDYT?
Finally I'm not sure if zero counter value is best - would it not be possible for
this to be a valid counter value?
We have two different ways to call this service in ptp_kvm guest, one needs counter cycle, the other
not. So I think it's vain to return a valid counter cycle back if the ptp_kvm does not needs it.
Ok,
+ feature = smccc_get_arg1(vcpu);
+ switch (feature) {
+ case ARM_PTP_VIRT_COUNTER:
+ cycles = systime_snapshot.cycles -
+ vcpu_vtimer(vcpu)->cntvoff;
Please indent the continuation line so that it's obvious.
Yeah, I think so, it's better to define these parameters ID as single number and not related to
+ break;\
+ case ARM_PTP_PHY_COUNTER:
+ cycles = systime_snapshot.cycles;
+ break;
+ }
+ val[2] = upper_32_bits(cycles);
+ val[3] = lower_32_bits(cycles);
break;
+#endif
+
default:
return kvm_psci_call(vcpu);
}
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 86ff30131e7b..e593ec515f82 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -98,6 +98,9 @@
/* KVM "vendor specific" services */
#define ARM_SMCCC_KVM_FUNC_FEATURES 0
+#define ARM_SMCCC_KVM_FUNC_KVM_PTP 1
+#define ARM_SMCCC_KVM_FUNC_KVM_PTP_PHY 2
+#define ARM_SMCCC_KVM_FUNC_KVM_PTP_VIRT 3
#define ARM_SMCCC_KVM_FUNC_FEATURES_2 127
#define ARM_SMCCC_KVM_NUM_FUNCS 128
@@ -107,6 +110,33 @@
ARM_SMCCC_OWNER_VENDOR_HYP,
ARM_SMCCC_KVM_FUNC_FEATURES)\
+/*
+ * kvm_ptp is a feature used for time sync between vm and host.
+ * kvm_ptp module in guest kernel will get service from host using
+ * this hypercall ID.
+ */
+#define ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,\
+ ARM_SMCCC_SMC_32,\
+ ARM_SMCCC_OWNER_VENDOR_HYP,\
+ ARM_SMCCC_KVM_FUNC_KVM_PTP)\
+
+/*
+ * kvm_ptp may get counter cycle from host and should ask for which
+of
+ * physical counter or virtual counter by using ARM_PTP_PHY_COUNTER
+and
+ * ARM_PTP_VIRT_COUNTER explicitly.
+ */
+#define ARM_PTP_PHY_COUNTER
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,\
+ ARM_SMCCC_SMC_32,\
+ ARM_SMCCC_OWNER_VENDOR_HYP,\
+ ARM_SMCCC_KVM_FUNC_KVM_PTP_PHY)\
+
+#define ARM_PTP_VIRT_COUNTER
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,\
+ ARM_SMCCC_SMC_32,\
+ ARM_SMCCC_OWNER_VENDOR_HYP,\
+ ARM_SMCCC_KVM_FUNC_KVM_PTP_VIRT)
These two are not SMCCC calls themselves (just parameters to an SMCCC),
so they really shouldn't be defined using ARM_SMCCC_CALL_VAL (it's just
confusing and unnecessary). Can we not just pick small integers (e.g. 0 and 1)
for these?
SMCCC. What about keep these 2 macros and define it directly as a number in include/linux/arm-smccc.h.
We also need some documentation of these SMCCC calls somewhere whichGood point, a documentation is needed to explain these new SMCCC funcs.
would make this sort of review easier. For instance for paravirtualised stolen
time there is Documentation/virt/kvm/arm/pvtime.rst (which also links to
the published document from Arm).
Do you think we should do that in this patch serial? Does it beyond the scope of this patch set?