Hi Steven,
Yeah, _PHY_ is not the same meaning with _PTP_FUNC_ID, so I think it should be a different name.index db6dce3d0e23..c964122f8dae 100644
--- a/virt/kvm/arm/hypercalls.c
+++ b/virt/kvm/arm/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;
+#endif
u32 func_id = smccc_get_function(vcpu);
u32 val[4] = {SMCCC_RET_NOT_SUPPORTED};
u32 feature;
@@ -70,7 +75,49 @@ 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.
+ */
+ feature = smccc_get_arg1(vcpu);
+ switch (feature) {
+ case ARM_SMCCC_VENDOR_HYP_KVM_PTP_PHY_FUNC_ID:
+ cycles = systime_snapshot.cycles;
+ break;
+ default:
There's something a bit odd here.
ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID and
ARM_SMCCC_VENDOR_HYP_KVM_PTP_PHY_FUNC_ID look like they should
be names of separate (top-level) functions, but actually the _PHY_ one is a
parameter for the first. If the intention is to have a parameter then it would
be better to pick a better name for the _PHY_ define and not define it using
ARM_SMCCC_CALL_VAL.
What about ARM_SMCCC_VENDOR_HYP_KVM_PTP_PHY_COUNTER?
Second the use of "default:" means that there's no possibility to later extendI think we can add more clocks by adding more cases, this "default" means we can use no first arg to determine the default clock.
this interface for more clocks if needed in the future.
Alternatively you could indeed implement as two top-level functions andI think "switch (feature)" maybe better as this _PHY_ is not like a function id. Just like:
change this to a...
switch (func_id)
... along with multiple case labels as the functions would obviously be mostly
the same.
Also a minor style issue - you might want to consider splitting this into it's
own function.
"
case ARM_SMCCC_ARCH_FEATURES_FUNC_ID:
feature = smccc_get_arg1(vcpu);
switch (feature) {
case ARM_SMCCC_ARCH_WORKAROUND_1:
...
"
Finally I do think it would be useful to add some documentation of the newYeah, more doc needed here.
SMC calls. It would be easier to review the interface based on that
documentation rather than trying to reverse-engineer the interface from the
code.