KVM: arm64: Implement PV_TIME_FEATURES call
authorSteven Price <steven.price@arm.com>
Mon, 21 Oct 2019 15:28:16 +0000 (16:28 +0100)
committerMarc Zyngier <maz@kernel.org>
Mon, 21 Oct 2019 18:20:27 +0000 (19:20 +0100)
This provides a mechanism for querying which paravirtualized time
features are available in this hypervisor.

Also add the header file which defines the ABI for the paravirtualized
time features we're about to add.

Signed-off-by: Steven Price <steven.price@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm/include/asm/kvm_host.h
arch/arm64/include/asm/kvm_host.h
arch/arm64/include/asm/pvclock-abi.h [new file with mode: 0644]
arch/arm64/kvm/Makefile
include/linux/arm-smccc.h
virt/kvm/arm/hypercalls.c
virt/kvm/arm/pvtime.c [new file with mode: 0644]

index 8a37c8e89777fcb48944e7ec2dc7dd842cd7502e..5a0c3569ebde563f1a5d7b7c6908e04b4536b7a4 100644 (file)
@@ -7,6 +7,7 @@
 #ifndef __ARM_KVM_HOST_H__
 #define __ARM_KVM_HOST_H__
 
+#include <linux/arm-smccc.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/kvm_types.h>
@@ -323,6 +324,11 @@ static inline int kvm_arch_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 int kvm_perf_init(void);
 int kvm_perf_teardown(void);
 
+static inline long kvm_hypercall_pv_features(struct kvm_vcpu *vcpu)
+{
+       return SMCCC_RET_NOT_SUPPORTED;
+}
+
 void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
 
 struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
index f656169db8c33bb3fa1ecac3f7fac872922c98b7..93b46d9526d0e8b1ffaf7aeee14cd1fb23e27b6b 100644 (file)
@@ -478,6 +478,8 @@ void handle_exit_early(struct kvm_vcpu *vcpu, struct kvm_run *run,
 int kvm_perf_init(void);
 int kvm_perf_teardown(void);
 
+long kvm_hypercall_pv_features(struct kvm_vcpu *vcpu);
+
 void kvm_set_sei_esr(struct kvm_vcpu *vcpu, u64 syndrome);
 
 struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
diff --git a/arch/arm64/include/asm/pvclock-abi.h b/arch/arm64/include/asm/pvclock-abi.h
new file mode 100644 (file)
index 0000000..c4f1c0a
--- /dev/null
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2019 Arm Ltd. */
+
+#ifndef __ASM_PVCLOCK_ABI_H
+#define __ASM_PVCLOCK_ABI_H
+
+/* The below structure is defined in ARM DEN0057A */
+
+struct pvclock_vcpu_stolen_time {
+       __le32 revision;
+       __le32 attributes;
+       __le64 stolen_time;
+       /* Structure must be 64 byte aligned, pad to that size */
+       u8 padding[48];
+} __packed;
+
+#endif
index 73dce4d47d473dfbcf4399089d677f27a803d3ba..5ffbdc39e780e798b38c6da40cd6b864b7cb9b33 100644 (file)
@@ -14,6 +14,7 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/e
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arm.o $(KVM)/arm/mmu.o $(KVM)/arm/mmio.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/psci.o $(KVM)/arm/perf.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hypercalls.o
+kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/pvtime.o
 
 kvm-$(CONFIG_KVM_ARM_HOST) += inject_fault.o regmap.o va_layout.o
 kvm-$(CONFIG_KVM_ARM_HOST) += hyp.o hyp-init.o handle_exit.o
index df01a857903491f22199a2b6cff891e09234fb0d..92e0046ce7a7cec860d79e372d5ca8fdeca5e3bb 100644 (file)
@@ -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
@@ -318,5 +319,18 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
 #define SMCCC_RET_NOT_SUPPORTED                        -1
 #define SMCCC_RET_NOT_REQUIRED                 -2
 
+/* Paravirtualised time calls (defined by ARM DEN0057A) */
+#define ARM_SMCCC_HV_PV_TIME_FEATURES                          \
+       ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,                 \
+                          ARM_SMCCC_SMC_64,                    \
+                          ARM_SMCCC_OWNER_STANDARD_HYP,        \
+                          0x20)
+
+#define ARM_SMCCC_HV_PV_TIME_ST                                        \
+       ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,                 \
+                          ARM_SMCCC_SMC_64,                    \
+                          ARM_SMCCC_OWNER_STANDARD_HYP,        \
+                          0x21)
+
 #endif /*__ASSEMBLY__*/
 #endif /*__LINUX_ARM_SMCCC_H*/
index f875241bd030ae64f2f0074cb0b9ea2d44059a2c..97ea8b133e77a21d21b03354c9ecd4ae75fb5754 100644 (file)
@@ -12,7 +12,7 @@
 int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
 {
        u32 func_id = smccc_get_function(vcpu);
-       u32 val = SMCCC_RET_NOT_SUPPORTED;
+       long val = SMCCC_RET_NOT_SUPPORTED;
        u32 feature;
 
        switch (func_id) {
@@ -48,8 +48,14 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
                                break;
                        }
                        break;
+               case ARM_SMCCC_HV_PV_TIME_FEATURES:
+                       val = SMCCC_RET_SUCCESS;
+                       break;
                }
                break;
+       case ARM_SMCCC_HV_PV_TIME_FEATURES:
+               val = kvm_hypercall_pv_features(vcpu);
+               break;
        default:
                return kvm_psci_call(vcpu);
        }
diff --git a/virt/kvm/arm/pvtime.c b/virt/kvm/arm/pvtime.c
new file mode 100644 (file)
index 0000000..9fc69fc
--- /dev/null
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2019 Arm Ltd.
+
+#include <linux/arm-smccc.h>
+
+#include <kvm/arm_hypercalls.h>
+
+long kvm_hypercall_pv_features(struct kvm_vcpu *vcpu)
+{
+       u32 feature = smccc_get_arg1(vcpu);
+       long val = SMCCC_RET_NOT_SUPPORTED;
+
+       switch (feature) {
+       case ARM_SMCCC_HV_PV_TIME_FEATURES:
+               val = SMCCC_RET_SUCCESS;
+               break;
+       }
+
+       return val;
+}