History

Merge branch kvm-arm64/hcall-selection into kvmarm-master/next

* kvm-arm64/hcall-selection: : . : Introduce a new set of virtual sysregs for userspace to : select the hypercalls it wants to see exposed to the guest. : : Patches courtesy of Raghavendra and Oliver. : . KVM: arm64: Fix hypercall bitmap writeback when vcpus have already run KVM: arm64: Hide KVM_REG_ARM_*_BMAP_BIT_COUNT from userspace Documentation: Fix index.rst after psci.rst renaming selftests: KVM: aarch64: Add the bitmap firmware registers to get-reg-list selftests: KVM: aarch64: Introduce hypercall ABI test selftests: KVM: Create helper for making SMCCC calls selftests: KVM: Rename psci_cpu_on_test to psci_test tools: Import ARM SMCCC definitions Docs: KVM: Add doc for the bitmap firmware registers Docs: KVM: Rename psci.rst to hypercalls.rst KVM: arm64: Add vendor hypervisor firmware register KVM: arm64: Add standard hypervisor firmware register KVM: arm64: Setup a framework for hypercall bitmap firmware registers KVM: arm64: Factor out firmware register handling from psci.c

Marc Zyngier committed 4 years ago

Commit 0586e282 parents d25f30f 528ada221 files · +1146 −303Browse files

Unified · Split

21 files
  1. Documentation/virt/kvm/api.rst +18 −0
  2. Documentation/virt/kvm/arm/hypercalls.rst +138 −0
  3. Documentation/virt/kvm/arm/index.rst +1 −1
  4. Documentation/virt/kvm/arm/psci.rst +0 −77
  5. arch/arm64/include/asm/kvm_host.h +16 −0
  6. arch/arm64/include/uapi/asm/kvm.h +34 −0
  7. arch/arm64/kvm/arm.c +1 −0
  8. arch/arm64/kvm/guest.c +7 −3
  9. arch/arm64/kvm/hypercalls.c +324 −3
  10. arch/arm64/kvm/psci.c +0 −183
  11. include/kvm/arm_hypercalls.h +8 −0
  12. include/kvm/arm_psci.h +0 −7
  13. tools/include/linux/arm-smccc.h +193 −0
  14. tools/testing/selftests/kvm/.gitignore +2 −1
  15. tools/testing/selftests/kvm/Makefile +2 −1
  16. tools/testing/selftests/kvm/aarch64/get-reg-list.c +8 −0
  17. tools/testing/selftests/kvm/aarch64/hypercalls.c +336 −0
  18. tools/testing/selftests/kvm/aarch64/psci_test.c +8 −17
  19. tools/testing/selftests/kvm/include/aarch64/processor.h +22 −0
  20. tools/testing/selftests/kvm/lib/aarch64/processor.c +25 −0
  21. tools/testing/selftests/kvm/steal_time.c +3 −10
Documentation/virt/kvm/api.rst+18−0
@@ -2601,6 +2601,24 @@ EINVAL. · 2600 unmodified lines
26012601 After the vcpu's SVE configuration is finalized, further attempts to
26022602 write this register will fail with EPERM.
26032603
2604+arm64 bitmap feature firmware pseudo-registers have the following bit pattern::
2605+
2606+ 0x6030 0000 0016 <regno:16>
2607+
2608+The bitmap feature firmware registers exposes the hypercall services that
2609+are available for userspace to configure. The set bits corresponds to the
2610+services that are available for the guests to access. By default, KVM
2611+sets all the supported bits during VM initialization. The userspace can
2612+discover the available services via KVM_GET_ONE_REG, and write back the
2613+bitmap corresponding to the features that it wishes guests to see via
2614+KVM_SET_ONE_REG.
2615+
2616+Note: These registers are immutable once any of the vCPUs of the VM has
2617+run at least once. A KVM_SET_ONE_REG in such a scenario will return
2618+a -EBUSY to userspace.
2619+
2620+(See Documentation/virt/kvm/arm/hypercalls.rst for more details.)
2621+
26042622
26052623 MIPS registers are mapped using the lower 32 bits. The upper 16 of that is
26062624 the register group type:
Documentation/virt/kvm/arm/hypercalls.rst+138−0
@@ -0,0 +1,138 @@
1+.. SPDX-License-Identifier: GPL-2.0
2+
3+=======================
4+ARM Hypercall Interface
5+=======================
6+
7+KVM handles the hypercall services as requested by the guests. New hypercall
8+services are regularly made available by the ARM specification or by KVM (as
9+vendor services) if they make sense from a virtualization point of view.
10+
11+This means that a guest booted on two different versions of KVM can observe
12+two different "firmware" revisions. This could cause issues if a given guest
13+is tied to a particular version of a hypercall service, or if a migration
14+causes a different version to be exposed out of the blue to an unsuspecting
15+guest.
16+
17+In order to remedy this situation, KVM exposes a set of "firmware
18+pseudo-registers" that can be manipulated using the GET/SET_ONE_REG
19+interface. These registers can be saved/restored by userspace, and set
20+to a convenient value as required.
21+
22+The following registers are defined:
23+
24+* KVM_REG_ARM_PSCI_VERSION:
25+
26+ KVM implements the PSCI (Power State Coordination Interface)
27+ specification in order to provide services such as CPU on/off, reset
28+ and power-off to the guest.
29+
30+ - Only valid if the vcpu has the KVM_ARM_VCPU_PSCI_0_2 feature set
31+ (and thus has already been initialized)
32+ - Returns the current PSCI version on GET_ONE_REG (defaulting to the
33+ highest PSCI version implemented by KVM and compatible with v0.2)
34+ - Allows any PSCI version implemented by KVM and compatible with
35+ v0.2 to be set with SET_ONE_REG
36+ - Affects the whole VM (even if the register view is per-vcpu)
37+
38+* KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
39+ Holds the state of the firmware support to mitigate CVE-2017-5715, as
40+ offered by KVM to the guest via a HVC call. The workaround is described
41+ under SMCCC_ARCH_WORKAROUND_1 in [1].
42+
43+ Accepted values are:
44+
45+ KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL:
46+ KVM does not offer
47+ firmware support for the workaround. The mitigation status for the
48+ guest is unknown.
49+ KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_AVAIL:
50+ The workaround HVC call is
51+ available to the guest and required for the mitigation.
52+ KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_REQUIRED:
53+ The workaround HVC call
54+ is available to the guest, but it is not needed on this VCPU.
55+
56+* KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
57+ Holds the state of the firmware support to mitigate CVE-2018-3639, as
58+ offered by KVM to the guest via a HVC call. The workaround is described
59+ under SMCCC_ARCH_WORKAROUND_2 in [1]_.
60+
61+ Accepted values are:
62+
63+ KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL:
64+ A workaround is not
65+ available. KVM does not offer firmware support for the workaround.
66+ KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_UNKNOWN:
67+ The workaround state is
68+ unknown. KVM does not offer firmware support for the workaround.
69+ KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL:
70+ The workaround is available,
71+ and can be disabled by a vCPU. If
72+ KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED is set, it is active for
73+ this vCPU.
74+ KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED:
75+ The workaround is always active on this vCPU or it is not needed.
76+
77+
78+Bitmap Feature Firmware Registers
79+---------------------------------
80+
81+Contrary to the above registers, the following registers exposes the
82+hypercall services in the form of a feature-bitmap to the userspace. This
83+bitmap is translated to the services that are available to the guest.
84+There is a register defined per service call owner and can be accessed via
85+GET/SET_ONE_REG interface.
86+
87+By default, these registers are set with the upper limit of the features
88+that are supported. This way userspace can discover all the usable
89+hypercall services via GET_ONE_REG. The user-space can write-back the
90+desired bitmap back via SET_ONE_REG. The features for the registers that
91+are untouched, probably because userspace isn't aware of them, will be
92+exposed as is to the guest.
93+
94+Note that KVM will not allow the userspace to configure the registers
95+anymore once any of the vCPUs has run at least once. Instead, it will
96+return a -EBUSY.
97+
98+The pseudo-firmware bitmap register are as follows:
99+
100+* KVM_REG_ARM_STD_BMAP:
101+ Controls the bitmap of the ARM Standard Secure Service Calls.
102+
103+ The following bits are accepted:
104+
105+ Bit-0: KVM_REG_ARM_STD_BIT_TRNG_V1_0:
106+ The bit represents the services offered under v1.0 of ARM True Random
107+ Number Generator (TRNG) specification, ARM DEN0098.
108+
109+* KVM_REG_ARM_STD_HYP_BMAP:
110+ Controls the bitmap of the ARM Standard Hypervisor Service Calls.
111+
112+ The following bits are accepted:
113+
114+ Bit-0: KVM_REG_ARM_STD_HYP_BIT_PV_TIME:
115+ The bit represents the Paravirtualized Time service as represented by
116+ ARM DEN0057A.
117+
118+* KVM_REG_ARM_VENDOR_HYP_BMAP:
119+ Controls the bitmap of the Vendor specific Hypervisor Service Calls.
120+
121+ The following bits are accepted:
122+
123+ Bit-0: KVM_REG_ARM_VENDOR_HYP_BIT_FUNC_FEAT
124+ The bit represents the ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID
125+ and ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID function-ids.
126+
127+ Bit-1: KVM_REG_ARM_VENDOR_HYP_BIT_PTP:
128+ The bit represents the Precision Time Protocol KVM service.
129+
130+Errors:
131+
132+ ======= =============================================================
133+ -ENOENT Unknown register accessed.
134+ -EBUSY Attempt a 'write' to the register after the VM has started.
135+ -EINVAL Invalid bitmap written to the register.
136+ ======= =============================================================
137+
138+.. [1] https://developer.arm.com/-/media/developer/pdf/ARM_DEN_0070A_Firmware_interfaces_for_mitigating_CVE-2017-5715.pdf
Documentation/virt/kvm/arm/index.rst+1−1
@@ -8,6 +8,6 @@ ARM · 7 unmodified lines
88 :maxdepth: 2
99
1010 hyp-abi
11− psci
11+ hypercalls
1212 pvtime
1313 ptp_kvm
Documentation/virt/kvm/arm/psci.rst+0−77
@@ -1,77 +0,0 @@
1−.. SPDX-License-Identifier: GPL-2.0
2−
3−=========================================
4−Power State Coordination Interface (PSCI)
5−=========================================
6−
7−KVM implements the PSCI (Power State Coordination Interface)
8−specification in order to provide services such as CPU on/off, reset
9−and power-off to the guest.
10−
11−The PSCI specification is regularly updated to provide new features,
12−and KVM implements these updates if they make sense from a virtualization
13−point of view.
14−
15−This means that a guest booted on two different versions of KVM can
16−observe two different "firmware" revisions. This could cause issues if
17−a given guest is tied to a particular PSCI revision (unlikely), or if
18−a migration causes a different PSCI version to be exposed out of the
19−blue to an unsuspecting guest.
20−
21−In order to remedy this situation, KVM exposes a set of "firmware
22−pseudo-registers" that can be manipulated using the GET/SET_ONE_REG
23−interface. These registers can be saved/restored by userspace, and set
24−to a convenient value if required.
25−
26−The following register is defined:
27−
28−* KVM_REG_ARM_PSCI_VERSION:
29−
30− - Only valid if the vcpu has the KVM_ARM_VCPU_PSCI_0_2 feature set
31− (and thus has already been initialized)
32− - Returns the current PSCI version on GET_ONE_REG (defaulting to the
33− highest PSCI version implemented by KVM and compatible with v0.2)
34− - Allows any PSCI version implemented by KVM and compatible with
35− v0.2 to be set with SET_ONE_REG
36− - Affects the whole VM (even if the register view is per-vcpu)
37−
38−* KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
39− Holds the state of the firmware support to mitigate CVE-2017-5715, as
40− offered by KVM to the guest via a HVC call. The workaround is described
41− under SMCCC_ARCH_WORKAROUND_1 in [1].
42−
43− Accepted values are:
44−
45− KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL:
46− KVM does not offer
47− firmware support for the workaround. The mitigation status for the
48− guest is unknown.
49− KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_AVAIL:
50− The workaround HVC call is
51− available to the guest and required for the mitigation.
52− KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_REQUIRED:
53− The workaround HVC call
54− is available to the guest, but it is not needed on this VCPU.
55−
56−* KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
57− Holds the state of the firmware support to mitigate CVE-2018-3639, as
58− offered by KVM to the guest via a HVC call. The workaround is described
59− under SMCCC_ARCH_WORKAROUND_2 in [1]_.
60−
61− Accepted values are:
62−
63− KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL:
64− A workaround is not
65− available. KVM does not offer firmware support for the workaround.
66− KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_UNKNOWN:
67− The workaround state is
68− unknown. KVM does not offer firmware support for the workaround.
69− KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL:
70− The workaround is available,
71− and can be disabled by a vCPU. If
72− KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED is set, it is active for
73− this vCPU.
74− KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED:
75− The workaround is always active on this vCPU or it is not needed.
76−
77−.. [1] https://developer.arm.com/-/media/developer/pdf/ARM_DEN_0070A_Firmware_interfaces_for_mitigating_CVE-2017-5715.pdf
arch/arm64/include/asm/kvm_host.h+16−0
@@ -101,6 +101,19 @@ struct kvm_s2_mmu { · 100 unmodified lines
101101 struct kvm_arch_memory_slot {
102102 };
103103
104+/**
105+ * struct kvm_smccc_features: Descriptor of the hypercall services exposed to the guests
106+ *
107+ * @std_bmap: Bitmap of standard secure service calls
108+ * @std_hyp_bmap: Bitmap of standard hypervisor service calls
109+ * @vendor_hyp_bmap: Bitmap of vendor specific hypervisor service calls
110+ */
111+struct kvm_smccc_features {
112+ unsigned long std_bmap;
113+ unsigned long std_hyp_bmap;
114+ unsigned long vendor_hyp_bmap;
115+};
116+
104117 struct kvm_arch {
105118 struct kvm_s2_mmu mmu;
106119
@@ -150,6 +163,9 @@ struct kvm_arch { · 43 unmodified lines
150163
151164 u8 pfr0_csv2;
152165 u8 pfr0_csv3;
166+
167+ /* Hypercall features firmware registers' descriptor */
168+ struct kvm_smccc_features smccc_feat;
153169 };
154170
155171 struct kvm_vcpu_fault_info {
arch/arm64/include/uapi/asm/kvm.h+34−0
@@ -332,6 +332,40 @@ struct kvm_arm_copy_mte_tags { · 331 unmodified lines
332332 #define KVM_ARM64_SVE_VLS_WORDS \
333333 ((KVM_ARM64_SVE_VQ_MAX - KVM_ARM64_SVE_VQ_MIN) / 64 + 1)
334334
335+/* Bitmap feature firmware registers */
336+#define KVM_REG_ARM_FW_FEAT_BMAP (0x0016 << KVM_REG_ARM_COPROC_SHIFT)
337+#define KVM_REG_ARM_FW_FEAT_BMAP_REG(r) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
338+ KVM_REG_ARM_FW_FEAT_BMAP | \
339+ ((r) & 0xffff))
340+
341+#define KVM_REG_ARM_STD_BMAP KVM_REG_ARM_FW_FEAT_BMAP_REG(0)
342+
343+enum {
344+ KVM_REG_ARM_STD_BIT_TRNG_V1_0 = 0,
345+#ifdef __KERNEL__
346+ KVM_REG_ARM_STD_BMAP_BIT_COUNT,
347+#endif
348+};
349+
350+#define KVM_REG_ARM_STD_HYP_BMAP KVM_REG_ARM_FW_FEAT_BMAP_REG(1)
351+
352+enum {
353+ KVM_REG_ARM_STD_HYP_BIT_PV_TIME = 0,
354+#ifdef __KERNEL__
355+ KVM_REG_ARM_STD_HYP_BMAP_BIT_COUNT,
356+#endif
357+};
358+
359+#define KVM_REG_ARM_VENDOR_HYP_BMAP KVM_REG_ARM_FW_FEAT_BMAP_REG(2)
360+
361+enum {
362+ KVM_REG_ARM_VENDOR_HYP_BIT_FUNC_FEAT = 0,
363+ KVM_REG_ARM_VENDOR_HYP_BIT_PTP = 1,
364+#ifdef __KERNEL__
365+ KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_COUNT,
366+#endif
367+};
368+
335369 /* Device Control API: ARM VGIC */
336370 #define KVM_DEV_ARM_VGIC_GRP_ADDR 0
337371 #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1
arch/arm64/kvm/arm.c+1−0
@@ -156,6 +156,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) · 155 unmodified lines
156156 kvm->arch.max_vcpus = kvm_arm_default_max_vcpus();
157157
158158 set_default_spectre(kvm);
159+ kvm_arm_init_hypercalls(kvm);
159160
160161 return ret;
161162 out_free_stage2_pgd:
arch/arm64/kvm/guest.c+7−3
@@ -18,7 +18,7 @@ · 17 unmodified lines
1818 #include <linux/string.h>
1919 #include <linux/vmalloc.h>
2020 #include <linux/fs.h>
21−#include <kvm/arm_psci.h>
21+#include <kvm/arm_hypercalls.h>
2222 #include <asm/cputype.h>
2323 #include <linux/uaccess.h>
2424 #include <asm/fpsimd.h>
@@ -756,7 +756,9 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) · 731 unmodified lines
756756
757757 switch (reg->id & KVM_REG_ARM_COPROC_MASK) {
758758 case KVM_REG_ARM_CORE: return get_core_reg(vcpu, reg);
759− case KVM_REG_ARM_FW: return kvm_arm_get_fw_reg(vcpu, reg);
759+ case KVM_REG_ARM_FW:
760+ case KVM_REG_ARM_FW_FEAT_BMAP:
761+ return kvm_arm_get_fw_reg(vcpu, reg);
760762 case KVM_REG_ARM64_SVE: return get_sve_reg(vcpu, reg);
761763 }
762764
@@ -774,7 +776,9 @@ int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) · 11 unmodified lines
774776
775777 switch (reg->id & KVM_REG_ARM_COPROC_MASK) {
776778 case KVM_REG_ARM_CORE: return set_core_reg(vcpu, reg);
777− case KVM_REG_ARM_FW: return kvm_arm_set_fw_reg(vcpu, reg);
779+ case KVM_REG_ARM_FW:
780+ case KVM_REG_ARM_FW_FEAT_BMAP:
781+ return kvm_arm_set_fw_reg(vcpu, reg);
778782 case KVM_REG_ARM64_SVE: return set_sve_reg(vcpu, reg);
779783 }
780784
arch/arm64/kvm/hypercalls.c+324−3
@@ -9,6 +9,13 @@ · 8 unmodified lines
99 #include <kvm/arm_hypercalls.h>
1010 #include <kvm/arm_psci.h>
1111
12+#define KVM_ARM_SMCCC_STD_FEATURES \
13+ GENMASK(KVM_REG_ARM_STD_BMAP_BIT_COUNT - 1, 0)
14+#define KVM_ARM_SMCCC_STD_HYP_FEATURES \
15+ GENMASK(KVM_REG_ARM_STD_HYP_BMAP_BIT_COUNT - 1, 0)
16+#define KVM_ARM_SMCCC_VENDOR_HYP_FEATURES \
17+ GENMASK(KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_COUNT - 1, 0)
18+
1219 static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val)
1320 {
1421 struct system_time_snapshot systime_snapshot;
@@ -58,13 +65,73 @@ static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val) · 43 unmodified lines
5865 val[3] = lower_32_bits(cycles);
5966 }
6067
68+static bool kvm_hvc_call_default_allowed(u32 func_id)
69+{
70+ switch (func_id) {
71+ /*
72+ * List of function-ids that are not gated with the bitmapped
73+ * feature firmware registers, and are to be allowed for
74+ * servicing the call by default.
75+ */
76+ case ARM_SMCCC_VERSION_FUNC_ID:
77+ case ARM_SMCCC_ARCH_FEATURES_FUNC_ID:
78+ return true;
79+ default:
80+ /* PSCI 0.2 and up is in the 0:0x1f range */
81+ if (ARM_SMCCC_OWNER_NUM(func_id) == ARM_SMCCC_OWNER_STANDARD &&
82+ ARM_SMCCC_FUNC_NUM(func_id) <= 0x1f)
83+ return true;
84+
85+ /*
86+ * KVM's PSCI 0.1 doesn't comply with SMCCC, and has
87+ * its own function-id base and range
88+ */
89+ if (func_id >= KVM_PSCI_FN(0) && func_id <= KVM_PSCI_FN(3))
90+ return true;
91+
92+ return false;
93+ }
94+}
95+
96+static bool kvm_hvc_call_allowed(struct kvm_vcpu *vcpu, u32 func_id)
97+{
98+ struct kvm_smccc_features *smccc_feat = &vcpu->kvm->arch.smccc_feat;
99+
100+ switch (func_id) {
101+ case ARM_SMCCC_TRNG_VERSION:
102+ case ARM_SMCCC_TRNG_FEATURES:
103+ case ARM_SMCCC_TRNG_GET_UUID:
104+ case ARM_SMCCC_TRNG_RND32:
105+ case ARM_SMCCC_TRNG_RND64:
106+ return test_bit(KVM_REG_ARM_STD_BIT_TRNG_V1_0,
107+ &smccc_feat->std_bmap);
108+ case ARM_SMCCC_HV_PV_TIME_FEATURES:
109+ case ARM_SMCCC_HV_PV_TIME_ST:
110+ return test_bit(KVM_REG_ARM_STD_HYP_BIT_PV_TIME,
111+ &smccc_feat->std_hyp_bmap);
112+ case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID:
113+ case ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID:
114+ return test_bit(KVM_REG_ARM_VENDOR_HYP_BIT_FUNC_FEAT,
115+ &smccc_feat->vendor_hyp_bmap);
116+ case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID:
117+ return test_bit(KVM_REG_ARM_VENDOR_HYP_BIT_PTP,
118+ &smccc_feat->vendor_hyp_bmap);
119+ default:
120+ return kvm_hvc_call_default_allowed(func_id);
121+ }
122+}
123+
61124 int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
62125 {
126+ struct kvm_smccc_features *smccc_feat = &vcpu->kvm->arch.smccc_feat;
63127 u32 func_id = smccc_get_function(vcpu);
64128 u64 val[4] = {SMCCC_RET_NOT_SUPPORTED};
65129 u32 feature;
66130 gpa_t gpa;
67131
132+ if (!kvm_hvc_call_allowed(vcpu, func_id))
133+ goto out;
134+
68135 switch (func_id) {
69136 case ARM_SMCCC_VERSION_FUNC_ID:
70137 val[0] = ARM_SMCCC_VERSION_1_1;
@@ -120,7 +187,9 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) · 49 unmodified lines
120187 }
121188 break;
122189 case ARM_SMCCC_HV_PV_TIME_FEATURES:
123− val[0] = SMCCC_RET_SUCCESS;
190+ if (test_bit(KVM_REG_ARM_STD_HYP_BIT_PV_TIME,
191+ &smccc_feat->std_hyp_bmap))
192+ val[0] = SMCCC_RET_SUCCESS;
124193 break;
125194 }
126195 break;
@@ -139,8 +208,7 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) · 12 unmodified lines
139208 val[3] = ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3;
140209 break;
141210 case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID:
142− val[0] = BIT(ARM_SMCCC_KVM_FUNC_FEATURES);
143− val[0] |= BIT(ARM_SMCCC_KVM_FUNC_PTP);
211+ val[0] = smccc_feat->vendor_hyp_bmap;
144212 break;
145213 case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID:
146214 kvm_ptp_get_time(vcpu, val);
@@ -155,6 +223,259 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) · 8 unmodified lines
155223 return kvm_psci_call(vcpu);
156224 }
157225
226+out:
158227 smccc_set_retval(vcpu, val[0], val[1], val[2], val[3]);
159228 return 1;
160229 }
230+
231+static const u64 kvm_arm_fw_reg_ids[] = {
232+ KVM_REG_ARM_PSCI_VERSION,
233+ KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1,
234+ KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2,
235+ KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3,
236+ KVM_REG_ARM_STD_BMAP,
237+ KVM_REG_ARM_STD_HYP_BMAP,
238+ KVM_REG_ARM_VENDOR_HYP_BMAP,
239+};
240+
241+void kvm_arm_init_hypercalls(struct kvm *kvm)
242+{
243+ struct kvm_smccc_features *smccc_feat = &kvm->arch.smccc_feat;
244+
245+ smccc_feat->std_bmap = KVM_ARM_SMCCC_STD_FEATURES;
246+ smccc_feat->std_hyp_bmap = KVM_ARM_SMCCC_STD_HYP_FEATURES;
247+ smccc_feat->vendor_hyp_bmap = KVM_ARM_SMCCC_VENDOR_HYP_FEATURES;
248+}
249+
250+int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
251+{
252+ return ARRAY_SIZE(kvm_arm_fw_reg_ids);
253+}
254+
255+int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
256+{
257+ int i;
258+
259+ for (i = 0; i < ARRAY_SIZE(kvm_arm_fw_reg_ids); i++) {
260+ if (put_user(kvm_arm_fw_reg_ids[i], uindices++))
261+ return -EFAULT;
262+ }
263+
264+ return 0;
265+}
266+
267+#define KVM_REG_FEATURE_LEVEL_MASK GENMASK(3, 0)
268+
269+/*
270+ * Convert the workaround level into an easy-to-compare number, where higher
271+ * values mean better protection.
272+ */
273+static int get_kernel_wa_level(u64 regid)
274+{
275+ switch (regid) {
276+ case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
277+ switch (arm64_get_spectre_v2_state()) {
278+ case SPECTRE_VULNERABLE:
279+ return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL;
280+ case SPECTRE_MITIGATED:
281+ return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_AVAIL;
282+ case SPECTRE_UNAFFECTED:
283+ return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_REQUIRED;
284+ }
285+ return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL;
286+ case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
287+ switch (arm64_get_spectre_v4_state()) {
288+ case SPECTRE_MITIGATED:
289+ /*
290+ * As for the hypercall discovery, we pretend we
291+ * don't have any FW mitigation if SSBS is there at
292+ * all times.
293+ */
294+ if (cpus_have_final_cap(ARM64_SSBS))
295+ return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
296+ fallthrough;
297+ case SPECTRE_UNAFFECTED:
298+ return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED;
299+ case SPECTRE_VULNERABLE:
300+ return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
301+ }
302+ break;
303+ case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:
304+ switch (arm64_get_spectre_bhb_state()) {
305+ case SPECTRE_VULNERABLE:
306+ return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL;
307+ case SPECTRE_MITIGATED:
308+ return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_AVAIL;
309+ case SPECTRE_UNAFFECTED:
310+ return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_REQUIRED;
311+ }
312+ return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL;
313+ }
314+
315+ return -EINVAL;
316+}
317+
318+int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
319+{
320+ struct kvm_smccc_features *smccc_feat = &vcpu->kvm->arch.smccc_feat;
321+ void __user *uaddr = (void __user *)(long)reg->addr;
322+ u64 val;
323+
324+ switch (reg->id) {
325+ case KVM_REG_ARM_PSCI_VERSION:
326+ val = kvm_psci_version(vcpu);
327+ break;
328+ case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
329+ case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
330+ case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:
331+ val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK;
332+ break;
333+ case KVM_REG_ARM_STD_BMAP:
334+ val = READ_ONCE(smccc_feat->std_bmap);
335+ break;
336+ case KVM_REG_ARM_STD_HYP_BMAP:
337+ val = READ_ONCE(smccc_feat->std_hyp_bmap);
338+ break;
339+ case KVM_REG_ARM_VENDOR_HYP_BMAP:
340+ val = READ_ONCE(smccc_feat->vendor_hyp_bmap);
341+ break;
342+ default:
343+ return -ENOENT;
344+ }
345+
346+ if (copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)))
347+ return -EFAULT;
348+
349+ return 0;
350+}
351+
352+static int kvm_arm_set_fw_reg_bmap(struct kvm_vcpu *vcpu, u64 reg_id, u64 val)
353+{
354+ int ret = 0;
355+ struct kvm *kvm = vcpu->kvm;
356+ struct kvm_smccc_features *smccc_feat = &kvm->arch.smccc_feat;
357+ unsigned long *fw_reg_bmap, fw_reg_features;
358+
359+ switch (reg_id) {
360+ case KVM_REG_ARM_STD_BMAP:
361+ fw_reg_bmap = &smccc_feat->std_bmap;
362+ fw_reg_features = KVM_ARM_SMCCC_STD_FEATURES;
363+ break;
364+ case KVM_REG_ARM_STD_HYP_BMAP:
365+ fw_reg_bmap = &smccc_feat->std_hyp_bmap;
366+ fw_reg_features = KVM_ARM_SMCCC_STD_HYP_FEATURES;
367+ break;
368+ case KVM_REG_ARM_VENDOR_HYP_BMAP:
369+ fw_reg_bmap = &smccc_feat->vendor_hyp_bmap;
370+ fw_reg_features = KVM_ARM_SMCCC_VENDOR_HYP_FEATURES;
371+ break;
372+ default:
373+ return -ENOENT;
374+ }
375+
376+ /* Check for unsupported bit */
377+ if (val & ~fw_reg_features)
378+ return -EINVAL;
379+
380+ mutex_lock(&kvm->lock);
381+
382+ if (test_bit(KVM_ARCH_FLAG_HAS_RAN_ONCE, &kvm->arch.flags) &&
383+ val != *fw_reg_bmap) {
384+ ret = -EBUSY;
385+ goto out;
386+ }
387+
388+ WRITE_ONCE(*fw_reg_bmap, val);
389+out:
390+ mutex_unlock(&kvm->lock);
391+ return ret;
392+}
393+
394+int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
395+{
396+ void __user *uaddr = (void __user *)(long)reg->addr;
397+ u64 val;
398+ int wa_level;
399+
400+ if (copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id)))
401+ return -EFAULT;
402+
403+ switch (reg->id) {
404+ case KVM_REG_ARM_PSCI_VERSION:
405+ {
406+ bool wants_02;
407+
408+ wants_02 = test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features);
409+
410+ switch (val) {
411+ case KVM_ARM_PSCI_0_1:
412+ if (wants_02)
413+ return -EINVAL;
414+ vcpu->kvm->arch.psci_version = val;
415+ return 0;
416+ case KVM_ARM_PSCI_0_2:
417+ case KVM_ARM_PSCI_1_0:
418+ case KVM_ARM_PSCI_1_1:
419+ if (!wants_02)
420+ return -EINVAL;
421+ vcpu->kvm->arch.psci_version = val;
422+ return 0;
423+ }
424+ break;
425+ }
426+
427+ case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
428+ case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:
429+ if (val & ~KVM_REG_FEATURE_LEVEL_MASK)
430+ return -EINVAL;
431+
432+ if (get_kernel_wa_level(reg->id) < val)
433+ return -EINVAL;
434+
435+ return 0;
436+
437+ case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
438+ if (val & ~(KVM_REG_FEATURE_LEVEL_MASK |
439+ KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED))
440+ return -EINVAL;
441+
442+ /* The enabled bit must not be set unless the level is AVAIL. */
443+ if ((val & KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED) &&
444+ (val & KVM_REG_FEATURE_LEVEL_MASK) != KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL)
445+ return -EINVAL;
446+
447+ /*
448+ * Map all the possible incoming states to the only two we
449+ * really want to deal with.
450+ */
451+ switch (val & KVM_REG_FEATURE_LEVEL_MASK) {
452+ case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL:
453+ case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_UNKNOWN:
454+ wa_level = KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
455+ break;
456+ case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL:
457+ case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED:
458+ wa_level = KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED;
459+ break;
460+ default:
461+ return -EINVAL;
462+ }
463+
464+ /*
465+ * We can deal with NOT_AVAIL on NOT_REQUIRED, but not the
466+ * other way around.
467+ */
468+ if (get_kernel_wa_level(reg->id) < wa_level)
469+ return -EINVAL;
470+
471+ return 0;
472+ case KVM_REG_ARM_STD_BMAP:
473+ case KVM_REG_ARM_STD_HYP_BMAP:
474+ case KVM_REG_ARM_VENDOR_HYP_BMAP:
475+ return kvm_arm_set_fw_reg_bmap(vcpu, reg->id, val);
476+ default:
477+ return -ENOENT;
478+ }
479+
480+ return -EINVAL;
481+}
arch/arm64/kvm/psci.c+0−183
@@ -437,186 +437,3 @@ int kvm_psci_call(struct kvm_vcpu *vcpu) · 436 unmodified lines
437437 return -EINVAL;
438438 }
439439 }
440−
441−int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
442−{
443− return 4; /* PSCI version and three workaround registers */
444−}
445−
446−int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
447−{
448− if (put_user(KVM_REG_ARM_PSCI_VERSION, uindices++))
449− return -EFAULT;
450−
451− if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1, uindices++))
452− return -EFAULT;
453−
454− if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2, uindices++))
455− return -EFAULT;
456−
457− if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3, uindices++))
458− return -EFAULT;
459−
460− return 0;
461−}
462−
463−#define KVM_REG_FEATURE_LEVEL_WIDTH 4
464−#define KVM_REG_FEATURE_LEVEL_MASK (BIT(KVM_REG_FEATURE_LEVEL_WIDTH) - 1)
465−
466−/*
467− * Convert the workaround level into an easy-to-compare number, where higher
468− * values mean better protection.
469− */
470−static int get_kernel_wa_level(u64 regid)
471−{
472− switch (regid) {
473− case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
474− switch (arm64_get_spectre_v2_state()) {
475− case SPECTRE_VULNERABLE:
476− return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL;
477− case SPECTRE_MITIGATED:
478− return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_AVAIL;
479− case SPECTRE_UNAFFECTED:
480− return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_REQUIRED;
481− }
482− return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL;
483− case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
484− switch (arm64_get_spectre_v4_state()) {
485− case SPECTRE_MITIGATED:
486− /*
487− * As for the hypercall discovery, we pretend we
488− * don't have any FW mitigation if SSBS is there at
489− * all times.
490− */
491− if (cpus_have_final_cap(ARM64_SSBS))
492− return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
493− fallthrough;
494− case SPECTRE_UNAFFECTED:
495− return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED;
496− case SPECTRE_VULNERABLE:
497− return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
498− }
499− break;
500− case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:
501− switch (arm64_get_spectre_bhb_state()) {
502− case SPECTRE_VULNERABLE:
503− return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL;
504− case SPECTRE_MITIGATED:
505− return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_AVAIL;
506− case SPECTRE_UNAFFECTED:
507− return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_REQUIRED;
508− }
509− return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL;
510− }
511−
512− return -EINVAL;
513−}
514−
515−int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
516−{
517− void __user *uaddr = (void __user *)(long)reg->addr;
518− u64 val;
519−
520− switch (reg->id) {
521− case KVM_REG_ARM_PSCI_VERSION:
522− val = kvm_psci_version(vcpu);
523− break;
524− case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
525− case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
526− case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:
527− val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK;
528− break;
529− default:
530− return -ENOENT;
531− }
532−
533− if (copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)))
534− return -EFAULT;
535−
536− return 0;
537−}
538−
539−int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
540−{
541− void __user *uaddr = (void __user *)(long)reg->addr;
542− u64 val;
543− int wa_level;
544−
545− if (copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id)))
546− return -EFAULT;
547−
548− switch (reg->id) {
549− case KVM_REG_ARM_PSCI_VERSION:
550− {
551− bool wants_02;
552−
553− wants_02 = test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features);
554−
555− switch (val) {
556− case KVM_ARM_PSCI_0_1:
557− if (wants_02)
558− return -EINVAL;
559− vcpu->kvm->arch.psci_version = val;
560− return 0;
561− case KVM_ARM_PSCI_0_2:
562− case KVM_ARM_PSCI_1_0:
563− case KVM_ARM_PSCI_1_1:
564− if (!wants_02)
565− return -EINVAL;
566− vcpu->kvm->arch.psci_version = val;
567− return 0;
568− }
569− break;
570− }
571−
572− case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
573− case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:
574− if (val & ~KVM_REG_FEATURE_LEVEL_MASK)
575− return -EINVAL;
576−
577− if (get_kernel_wa_level(reg->id) < val)
578− return -EINVAL;
579−
580− return 0;
581−
582− case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
583− if (val & ~(KVM_REG_FEATURE_LEVEL_MASK |
584− KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED))
585− return -EINVAL;
586−
587− /* The enabled bit must not be set unless the level is AVAIL. */
588− if ((val & KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED) &&
589− (val & KVM_REG_FEATURE_LEVEL_MASK) != KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL)
590− return -EINVAL;
591−
592− /*
593− * Map all the possible incoming states to the only two we
594− * really want to deal with.
595− */
596− switch (val & KVM_REG_FEATURE_LEVEL_MASK) {
597− case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL:
598− case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_UNKNOWN:
599− wa_level = KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
600− break;
601− case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL:
602− case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED:
603− wa_level = KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED;
604− break;
605− default:
606− return -EINVAL;
607− }
608−
609− /*
610− * We can deal with NOT_AVAIL on NOT_REQUIRED, but not the
611− * other way around.
612− */
613− if (get_kernel_wa_level(reg->id) < wa_level)
614− return -EINVAL;
615−
616− return 0;
617− default:
618− return -ENOENT;
619− }
620−
621− return -EINVAL;
622−}
include/kvm/arm_hypercalls.h+8−0
@@ -40,4 +40,12 @@ static inline void smccc_set_retval(struct kvm_vcpu *vcpu, · 39 unmodified lines
4040 vcpu_set_reg(vcpu, 3, a3);
4141 }
4242
43+struct kvm_one_reg;
44+
45+void kvm_arm_init_hypercalls(struct kvm *kvm);
46+int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu);
47+int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices);
48+int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
49+int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
50+
4351 #endif
include/kvm/arm_psci.h+0−7
@@ -39,11 +39,4 @@ static inline int kvm_psci_version(struct kvm_vcpu *vcpu) · 38 unmodified lines
3939
4040 int kvm_psci_call(struct kvm_vcpu *vcpu);
4141
42−struct kvm_one_reg;
43−
44−int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu);
45−int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices);
46−int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
47−int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
48−
4942 #endif /* __KVM_ARM_PSCI_H__ */
tools/include/linux/arm-smccc.h+193−0
@@ -0,0 +1,193 @@
1+/* SPDX-License-Identifier: GPL-2.0-only */
2+/*
3+ * Copyright (c) 2015, Linaro Limited
4+ */
5+#ifndef __LINUX_ARM_SMCCC_H
6+#define __LINUX_ARM_SMCCC_H
7+
8+#include <linux/const.h>
9+
10+/*
11+ * This file provides common defines for ARM SMC Calling Convention as
12+ * specified in
13+ * https://developer.arm.com/docs/den0028/latest
14+ *
15+ * This code is up-to-date with version DEN 0028 C
16+ */
17+
18+#define ARM_SMCCC_STD_CALL _AC(0,U)
19+#define ARM_SMCCC_FAST_CALL _AC(1,U)
20+#define ARM_SMCCC_TYPE_SHIFT 31
21+
22+#define ARM_SMCCC_SMC_32 0
23+#define ARM_SMCCC_SMC_64 1
24+#define ARM_SMCCC_CALL_CONV_SHIFT 30
25+
26+#define ARM_SMCCC_OWNER_MASK 0x3F
27+#define ARM_SMCCC_OWNER_SHIFT 24
28+
29+#define ARM_SMCCC_FUNC_MASK 0xFFFF
30+
31+#define ARM_SMCCC_IS_FAST_CALL(smc_val) \
32+ ((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT))
33+#define ARM_SMCCC_IS_64(smc_val) \
34+ ((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT))
35+#define ARM_SMCCC_FUNC_NUM(smc_val) ((smc_val) & ARM_SMCCC_FUNC_MASK)
36+#define ARM_SMCCC_OWNER_NUM(smc_val) \
37+ (((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK)
38+
39+#define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
40+ (((type) << ARM_SMCCC_TYPE_SHIFT) | \
41+ ((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
42+ (((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
43+ ((func_num) & ARM_SMCCC_FUNC_MASK))
44+
45+#define ARM_SMCCC_OWNER_ARCH 0
46+#define ARM_SMCCC_OWNER_CPU 1
47+#define ARM_SMCCC_OWNER_SIP 2
48+#define ARM_SMCCC_OWNER_OEM 3
49+#define ARM_SMCCC_OWNER_STANDARD 4
50+#define ARM_SMCCC_OWNER_STANDARD_HYP 5
51+#define ARM_SMCCC_OWNER_VENDOR_HYP 6
52+#define ARM_SMCCC_OWNER_TRUSTED_APP 48
53+#define ARM_SMCCC_OWNER_TRUSTED_APP_END 49
54+#define ARM_SMCCC_OWNER_TRUSTED_OS 50
55+#define ARM_SMCCC_OWNER_TRUSTED_OS_END 63
56+
57+#define ARM_SMCCC_FUNC_QUERY_CALL_UID 0xff01
58+
59+#define ARM_SMCCC_QUIRK_NONE 0
60+#define ARM_SMCCC_QUIRK_QCOM_A6 1 /* Save/restore register a6 */
61+
62+#define ARM_SMCCC_VERSION_1_0 0x10000
63+#define ARM_SMCCC_VERSION_1_1 0x10001
64+#define ARM_SMCCC_VERSION_1_2 0x10002
65+#define ARM_SMCCC_VERSION_1_3 0x10003
66+
67+#define ARM_SMCCC_1_3_SVE_HINT 0x10000
68+
69+#define ARM_SMCCC_VERSION_FUNC_ID \
70+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
71+ ARM_SMCCC_SMC_32, \
72+ 0, 0)
73+
74+#define ARM_SMCCC_ARCH_FEATURES_FUNC_ID \
75+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
76+ ARM_SMCCC_SMC_32, \
77+ 0, 1)
78+
79+#define ARM_SMCCC_ARCH_SOC_ID \
80+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
81+ ARM_SMCCC_SMC_32, \
82+ 0, 2)
83+
84+#define ARM_SMCCC_ARCH_WORKAROUND_1 \
85+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
86+ ARM_SMCCC_SMC_32, \
87+ 0, 0x8000)
88+
89+#define ARM_SMCCC_ARCH_WORKAROUND_2 \
90+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
91+ ARM_SMCCC_SMC_32, \
92+ 0, 0x7fff)
93+
94+#define ARM_SMCCC_ARCH_WORKAROUND_3 \
95+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
96+ ARM_SMCCC_SMC_32, \
97+ 0, 0x3fff)
98+
99+#define ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID \
100+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
101+ ARM_SMCCC_SMC_32, \
102+ ARM_SMCCC_OWNER_VENDOR_HYP, \
103+ ARM_SMCCC_FUNC_QUERY_CALL_UID)
104+
105+/* KVM UID value: 28b46fb6-2ec5-11e9-a9ca-4b564d003a74 */
106+#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0 0xb66fb428U
107+#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1 0xe911c52eU
108+#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2 0x564bcaa9U
109+#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3 0x743a004dU
110+
111+/* KVM "vendor specific" services */
112+#define ARM_SMCCC_KVM_FUNC_FEATURES 0
113+#define ARM_SMCCC_KVM_FUNC_PTP 1
114+#define ARM_SMCCC_KVM_FUNC_FEATURES_2 127
115+#define ARM_SMCCC_KVM_NUM_FUNCS 128
116+
117+#define ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID \
118+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
119+ ARM_SMCCC_SMC_32, \
120+ ARM_SMCCC_OWNER_VENDOR_HYP, \
121+ ARM_SMCCC_KVM_FUNC_FEATURES)
122+
123+#define SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED 1
124+
125+/*
126+ * ptp_kvm is a feature used for time sync between vm and host.
127+ * ptp_kvm module in guest kernel will get service from host using
128+ * this hypercall ID.
129+ */
130+#define ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID \
131+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
132+ ARM_SMCCC_SMC_32, \
133+ ARM_SMCCC_OWNER_VENDOR_HYP, \
134+ ARM_SMCCC_KVM_FUNC_PTP)
135+
136+/* ptp_kvm counter type ID */
137+#define KVM_PTP_VIRT_COUNTER 0
138+#define KVM_PTP_PHYS_COUNTER 1
139+
140+/* Paravirtualised time calls (defined by ARM DEN0057A) */
141+#define ARM_SMCCC_HV_PV_TIME_FEATURES \
142+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
143+ ARM_SMCCC_SMC_64, \
144+ ARM_SMCCC_OWNER_STANDARD_HYP, \
145+ 0x20)
146+
147+#define ARM_SMCCC_HV_PV_TIME_ST \
148+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
149+ ARM_SMCCC_SMC_64, \
150+ ARM_SMCCC_OWNER_STANDARD_HYP, \
151+ 0x21)
152+
153+/* TRNG entropy source calls (defined by ARM DEN0098) */
154+#define ARM_SMCCC_TRNG_VERSION \
155+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
156+ ARM_SMCCC_SMC_32, \
157+ ARM_SMCCC_OWNER_STANDARD, \
158+ 0x50)
159+
160+#define ARM_SMCCC_TRNG_FEATURES \
161+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
162+ ARM_SMCCC_SMC_32, \
163+ ARM_SMCCC_OWNER_STANDARD, \
164+ 0x51)
165+
166+#define ARM_SMCCC_TRNG_GET_UUID \
167+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
168+ ARM_SMCCC_SMC_32, \
169+ ARM_SMCCC_OWNER_STANDARD, \
170+ 0x52)
171+
172+#define ARM_SMCCC_TRNG_RND32 \
173+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
174+ ARM_SMCCC_SMC_32, \
175+ ARM_SMCCC_OWNER_STANDARD, \
176+ 0x53)
177+
178+#define ARM_SMCCC_TRNG_RND64 \
179+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
180+ ARM_SMCCC_SMC_64, \
181+ ARM_SMCCC_OWNER_STANDARD, \
182+ 0x53)
183+
184+/*
185+ * Return codes defined in ARM DEN 0070A
186+ * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028 C
187+ */
188+#define SMCCC_RET_SUCCESS 0
189+#define SMCCC_RET_NOT_SUPPORTED -1
190+#define SMCCC_RET_NOT_REQUIRED -2
191+#define SMCCC_RET_INVALID_PARAMETER -3
192+
193+#endif /*__LINUX_ARM_SMCCC_H*/
tools/testing/selftests/kvm/.gitignore+2−1
@@ -2,7 +2,8 @@ · 1 unmodified line
22 /aarch64/arch_timer
33 /aarch64/debug-exceptions
44 /aarch64/get-reg-list
5−/aarch64/psci_cpu_on_test
5+/aarch64/hypercalls
6+/aarch64/psci_test
67 /aarch64/vcpu_width_config
78 /aarch64/vgic_init
89 /aarch64/vgic_irq
tools/testing/selftests/kvm/Makefile+2−1
@@ -105,7 +105,8 @@ TEST_GEN_PROGS_x86_64 += system_counter_offset_test · 104 unmodified lines
105105 TEST_GEN_PROGS_aarch64 += aarch64/arch_timer
106106 TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
107107 TEST_GEN_PROGS_aarch64 += aarch64/get-reg-list
108−TEST_GEN_PROGS_aarch64 += aarch64/psci_cpu_on_test
108+TEST_GEN_PROGS_aarch64 += aarch64/hypercalls
109+TEST_GEN_PROGS_aarch64 += aarch64/psci_test
109110 TEST_GEN_PROGS_aarch64 += aarch64/vcpu_width_config
110111 TEST_GEN_PROGS_aarch64 += aarch64/vgic_init
111112 TEST_GEN_PROGS_aarch64 += aarch64/vgic_irq
tools/testing/selftests/kvm/aarch64/get-reg-list.c+8−0
@@ -294,6 +294,11 @@ static void print_reg(struct vcpu_config *c, __u64 id) · 293 unmodified lines
294294 "%s: Unexpected bits set in FW reg id: 0x%llx", config_name(c), id);
295295 printf("\tKVM_REG_ARM_FW_REG(%lld),\n", id & 0xffff);
296296 break;
297+ case KVM_REG_ARM_FW_FEAT_BMAP:
298+ TEST_ASSERT(id == KVM_REG_ARM_FW_FEAT_BMAP_REG(id & 0xffff),
299+ "%s: Unexpected bits set in the bitmap feature FW reg id: 0x%llx", config_name(c), id);
300+ printf("\tKVM_REG_ARM_FW_FEAT_BMAP_REG(%lld),\n", id & 0xffff);
301+ break;
297302 case KVM_REG_ARM64_SVE:
298303 if (has_cap(c, KVM_CAP_ARM_SVE))
299304 printf("\t%s,\n", sve_id_to_str(c, id));
@@ -692,6 +697,9 @@ static __u64 base_regs[] = { · 392 unmodified lines
692697 KVM_REG_ARM_FW_REG(1), /* KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1 */
693698 KVM_REG_ARM_FW_REG(2), /* KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2 */
694699 KVM_REG_ARM_FW_REG(3), /* KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3 */
700+ KVM_REG_ARM_FW_FEAT_BMAP_REG(0), /* KVM_REG_ARM_STD_BMAP */
701+ KVM_REG_ARM_FW_FEAT_BMAP_REG(1), /* KVM_REG_ARM_STD_HYP_BMAP */
702+ KVM_REG_ARM_FW_FEAT_BMAP_REG(2), /* KVM_REG_ARM_VENDOR_HYP_BMAP */
695703 ARM64_SYS_REG(3, 3, 14, 3, 1), /* CNTV_CTL_EL0 */
696704 ARM64_SYS_REG(3, 3, 14, 3, 2), /* CNTV_CVAL_EL0 */
697705 ARM64_SYS_REG(3, 3, 14, 0, 2),
tools/testing/selftests/kvm/aarch64/hypercalls.c+336−0
@@ -0,0 +1,336 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+
3+/* hypercalls: Check the ARM64's psuedo-firmware bitmap register interface.
4+ *
5+ * The test validates the basic hypercall functionalities that are exposed
6+ * via the psuedo-firmware bitmap register. This includes the registers'
7+ * read/write behavior before and after the VM has started, and if the
8+ * hypercalls are properly masked or unmasked to the guest when disabled or
9+ * enabled from the KVM userspace, respectively.
10+ */
11+
12+#include <errno.h>
13+#include <linux/arm-smccc.h>
14+#include <asm/kvm.h>
15+#include <kvm_util.h>
16+
17+#include "processor.h"
18+
19+#define FW_REG_ULIMIT_VAL(max_feat_bit) (GENMASK(max_feat_bit, 0))
20+
21+/* Last valid bits of the bitmapped firmware registers */
22+#define KVM_REG_ARM_STD_BMAP_BIT_MAX 0
23+#define KVM_REG_ARM_STD_HYP_BMAP_BIT_MAX 0
24+#define KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_MAX 1
25+
26+struct kvm_fw_reg_info {
27+ uint64_t reg; /* Register definition */
28+ uint64_t max_feat_bit; /* Bit that represents the upper limit of the feature-map */
29+};
30+
31+#define FW_REG_INFO(r) \
32+ { \
33+ .reg = r, \
34+ .max_feat_bit = r##_BIT_MAX, \
35+ }
36+
37+static const struct kvm_fw_reg_info fw_reg_info[] = {
38+ FW_REG_INFO(KVM_REG_ARM_STD_BMAP),
39+ FW_REG_INFO(KVM_REG_ARM_STD_HYP_BMAP),
40+ FW_REG_INFO(KVM_REG_ARM_VENDOR_HYP_BMAP),
41+};
42+
43+enum test_stage {
44+ TEST_STAGE_REG_IFACE,
45+ TEST_STAGE_HVC_IFACE_FEAT_DISABLED,
46+ TEST_STAGE_HVC_IFACE_FEAT_ENABLED,
47+ TEST_STAGE_HVC_IFACE_FALSE_INFO,
48+ TEST_STAGE_END,
49+};
50+
51+static int stage = TEST_STAGE_REG_IFACE;
52+
53+struct test_hvc_info {
54+ uint32_t func_id;
55+ uint64_t arg1;
56+};
57+
58+#define TEST_HVC_INFO(f, a1) \
59+ { \
60+ .func_id = f, \
61+ .arg1 = a1, \
62+ }
63+
64+static const struct test_hvc_info hvc_info[] = {
65+ /* KVM_REG_ARM_STD_BMAP */
66+ TEST_HVC_INFO(ARM_SMCCC_TRNG_VERSION, 0),
67+ TEST_HVC_INFO(ARM_SMCCC_TRNG_FEATURES, ARM_SMCCC_TRNG_RND64),
68+ TEST_HVC_INFO(ARM_SMCCC_TRNG_GET_UUID, 0),
69+ TEST_HVC_INFO(ARM_SMCCC_TRNG_RND32, 0),
70+ TEST_HVC_INFO(ARM_SMCCC_TRNG_RND64, 0),
71+
72+ /* KVM_REG_ARM_STD_HYP_BMAP */
73+ TEST_HVC_INFO(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, ARM_SMCCC_HV_PV_TIME_FEATURES),
74+ TEST_HVC_INFO(ARM_SMCCC_HV_PV_TIME_FEATURES, ARM_SMCCC_HV_PV_TIME_ST),
75+ TEST_HVC_INFO(ARM_SMCCC_HV_PV_TIME_ST, 0),
76+
77+ /* KVM_REG_ARM_VENDOR_HYP_BMAP */
78+ TEST_HVC_INFO(ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID,
79+ ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID),
80+ TEST_HVC_INFO(ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID, 0),
81+ TEST_HVC_INFO(ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID, KVM_PTP_VIRT_COUNTER),
82+};
83+
84+/* Feed false hypercall info to test the KVM behavior */
85+static const struct test_hvc_info false_hvc_info[] = {
86+ /* Feature support check against a different family of hypercalls */
87+ TEST_HVC_INFO(ARM_SMCCC_TRNG_FEATURES, ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID),
88+ TEST_HVC_INFO(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, ARM_SMCCC_TRNG_RND64),
89+ TEST_HVC_INFO(ARM_SMCCC_HV_PV_TIME_FEATURES, ARM_SMCCC_TRNG_RND64),
90+};
91+
92+static void guest_test_hvc(const struct test_hvc_info *hc_info)
93+{
94+ unsigned int i;
95+ struct arm_smccc_res res;
96+ unsigned int hvc_info_arr_sz;
97+
98+ hvc_info_arr_sz =
99+ hc_info == hvc_info ? ARRAY_SIZE(hvc_info) : ARRAY_SIZE(false_hvc_info);
100+
101+ for (i = 0; i < hvc_info_arr_sz; i++, hc_info++) {
102+ memset(&res, 0, sizeof(res));
103+ smccc_hvc(hc_info->func_id, hc_info->arg1, 0, 0, 0, 0, 0, 0, &res);
104+
105+ switch (stage) {
106+ case TEST_STAGE_HVC_IFACE_FEAT_DISABLED:
107+ case TEST_STAGE_HVC_IFACE_FALSE_INFO:
108+ GUEST_ASSERT_3(res.a0 == SMCCC_RET_NOT_SUPPORTED,
109+ res.a0, hc_info->func_id, hc_info->arg1);
110+ break;
111+ case TEST_STAGE_HVC_IFACE_FEAT_ENABLED:
112+ GUEST_ASSERT_3(res.a0 != SMCCC_RET_NOT_SUPPORTED,
113+ res.a0, hc_info->func_id, hc_info->arg1);
114+ break;
115+ default:
116+ GUEST_ASSERT_1(0, stage);
117+ }
118+ }
119+}
120+
121+static void guest_code(void)
122+{
123+ while (stage != TEST_STAGE_END) {
124+ switch (stage) {
125+ case TEST_STAGE_REG_IFACE:
126+ break;
127+ case TEST_STAGE_HVC_IFACE_FEAT_DISABLED:
128+ case TEST_STAGE_HVC_IFACE_FEAT_ENABLED:
129+ guest_test_hvc(hvc_info);
130+ break;
131+ case TEST_STAGE_HVC_IFACE_FALSE_INFO:
132+ guest_test_hvc(false_hvc_info);
133+ break;
134+ default:
135+ GUEST_ASSERT_1(0, stage);
136+ }
137+
138+ GUEST_SYNC(stage);
139+ }
140+
141+ GUEST_DONE();
142+}
143+
144+static int set_fw_reg(struct kvm_vm *vm, uint64_t id, uint64_t val)
145+{
146+ struct kvm_one_reg reg = {
147+ .id = id,
148+ .addr = (uint64_t)&val,
149+ };
150+
151+ return _vcpu_ioctl(vm, 0, KVM_SET_ONE_REG, &reg);
152+}
153+
154+static void get_fw_reg(struct kvm_vm *vm, uint64_t id, uint64_t *addr)
155+{
156+ struct kvm_one_reg reg = {
157+ .id = id,
158+ .addr = (uint64_t)addr,
159+ };
160+
161+ vcpu_ioctl(vm, 0, KVM_GET_ONE_REG, &reg);
162+}
163+
164+struct st_time {
165+ uint32_t rev;
166+ uint32_t attr;
167+ uint64_t st_time;
168+};
169+
170+#define STEAL_TIME_SIZE ((sizeof(struct st_time) + 63) & ~63)
171+#define ST_GPA_BASE (1 << 30)
172+
173+static void steal_time_init(struct kvm_vm *vm)
174+{
175+ uint64_t st_ipa = (ulong)ST_GPA_BASE;
176+ unsigned int gpages;
177+ struct kvm_device_attr dev = {
178+ .group = KVM_ARM_VCPU_PVTIME_CTRL,
179+ .attr = KVM_ARM_VCPU_PVTIME_IPA,
180+ .addr = (uint64_t)&st_ipa,
181+ };
182+
183+ gpages = vm_calc_num_guest_pages(VM_MODE_DEFAULT, STEAL_TIME_SIZE);
184+ vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, ST_GPA_BASE, 1, gpages, 0);
185+
186+ vcpu_ioctl(vm, 0, KVM_SET_DEVICE_ATTR, &dev);
187+}
188+
189+static void test_fw_regs_before_vm_start(struct kvm_vm *vm)
190+{
191+ uint64_t val;
192+ unsigned int i;
193+ int ret;
194+
195+ for (i = 0; i < ARRAY_SIZE(fw_reg_info); i++) {
196+ const struct kvm_fw_reg_info *reg_info = &fw_reg_info[i];
197+
198+ /* First 'read' should be an upper limit of the features supported */
199+ get_fw_reg(vm, reg_info->reg, &val);
200+ TEST_ASSERT(val == FW_REG_ULIMIT_VAL(reg_info->max_feat_bit),
201+ "Expected all the features to be set for reg: 0x%lx; expected: 0x%lx; read: 0x%lx\n",
202+ reg_info->reg, FW_REG_ULIMIT_VAL(reg_info->max_feat_bit), val);
203+
204+ /* Test a 'write' by disabling all the features of the register map */
205+ ret = set_fw_reg(vm, reg_info->reg, 0);
206+ TEST_ASSERT(ret == 0,
207+ "Failed to clear all the features of reg: 0x%lx; ret: %d\n",
208+ reg_info->reg, errno);
209+
210+ get_fw_reg(vm, reg_info->reg, &val);
211+ TEST_ASSERT(val == 0,
212+ "Expected all the features to be cleared for reg: 0x%lx\n", reg_info->reg);
213+
214+ /*
215+ * Test enabling a feature that's not supported.
216+ * Avoid this check if all the bits are occupied.
217+ */
218+ if (reg_info->max_feat_bit < 63) {
219+ ret = set_fw_reg(vm, reg_info->reg, BIT(reg_info->max_feat_bit + 1));
220+ TEST_ASSERT(ret != 0 && errno == EINVAL,
221+ "Unexpected behavior or return value (%d) while setting an unsupported feature for reg: 0x%lx\n",
222+ errno, reg_info->reg);
223+ }
224+ }
225+}
226+
227+static void test_fw_regs_after_vm_start(struct kvm_vm *vm)
228+{
229+ uint64_t val;
230+ unsigned int i;
231+ int ret;
232+
233+ for (i = 0; i < ARRAY_SIZE(fw_reg_info); i++) {
234+ const struct kvm_fw_reg_info *reg_info = &fw_reg_info[i];
235+
236+ /*
237+ * Before starting the VM, the test clears all the bits.
238+ * Check if that's still the case.
239+ */
240+ get_fw_reg(vm, reg_info->reg, &val);
241+ TEST_ASSERT(val == 0,
242+ "Expected all the features to be cleared for reg: 0x%lx\n",
243+ reg_info->reg);
244+
245+ /*
246+ * Since the VM has run at least once, KVM shouldn't allow modification of
247+ * the registers and should return EBUSY. Set the registers and check for
248+ * the expected errno.
249+ */
250+ ret = set_fw_reg(vm, reg_info->reg, FW_REG_ULIMIT_VAL(reg_info->max_feat_bit));
251+ TEST_ASSERT(ret != 0 && errno == EBUSY,
252+ "Unexpected behavior or return value (%d) while setting a feature while VM is running for reg: 0x%lx\n",
253+ errno, reg_info->reg);
254+ }
255+}
256+
257+static struct kvm_vm *test_vm_create(void)
258+{
259+ struct kvm_vm *vm;
260+
261+ vm = vm_create_default(0, 0, guest_code);
262+
263+ ucall_init(vm, NULL);
264+ steal_time_init(vm);
265+
266+ return vm;
267+}
268+
269+static struct kvm_vm *test_guest_stage(struct kvm_vm *vm)
270+{
271+ struct kvm_vm *ret_vm = vm;
272+
273+ pr_debug("Stage: %d\n", stage);
274+
275+ switch (stage) {
276+ case TEST_STAGE_REG_IFACE:
277+ test_fw_regs_after_vm_start(vm);
278+ break;
279+ case TEST_STAGE_HVC_IFACE_FEAT_DISABLED:
280+ /* Start a new VM so that all the features are now enabled by default */
281+ kvm_vm_free(vm);
282+ ret_vm = test_vm_create();
283+ break;
284+ case TEST_STAGE_HVC_IFACE_FEAT_ENABLED:
285+ case TEST_STAGE_HVC_IFACE_FALSE_INFO:
286+ break;
287+ default:
288+ TEST_FAIL("Unknown test stage: %d\n", stage);
289+ }
290+
291+ stage++;
292+ sync_global_to_guest(vm, stage);
293+
294+ return ret_vm;
295+}
296+
297+static void test_run(void)
298+{
299+ struct kvm_vm *vm;
300+ struct ucall uc;
301+ bool guest_done = false;
302+
303+ vm = test_vm_create();
304+
305+ test_fw_regs_before_vm_start(vm);
306+
307+ while (!guest_done) {
308+ vcpu_run(vm, 0);
309+
310+ switch (get_ucall(vm, 0, &uc)) {
311+ case UCALL_SYNC:
312+ vm = test_guest_stage(vm);
313+ break;
314+ case UCALL_DONE:
315+ guest_done = true;
316+ break;
317+ case UCALL_ABORT:
318+ TEST_FAIL("%s at %s:%ld\n\tvalues: 0x%lx, 0x%lx; 0x%lx, stage: %u",
319+ (const char *)uc.args[0], __FILE__, uc.args[1],
320+ uc.args[2], uc.args[3], uc.args[4], stage);
321+ break;
322+ default:
323+ TEST_FAIL("Unexpected guest exit\n");
324+ }
325+ }
326+
327+ kvm_vm_free(vm);
328+}
329+
330+int main(void)
331+{
332+ setbuf(stdout, NULL);
333+
334+ test_run();
335+ return 0;
336+}
tools/testing/selftests/kvm/aarch64/psci_test.crenamed from tools/testing/selftests/kvm/aarch64/psci_cpu_on_test.c+8−17
@@ -26,32 +26,23 @@ · 25 unmodified lines
2626 static uint64_t psci_cpu_on(uint64_t target_cpu, uint64_t entry_addr,
2727 uint64_t context_id)
2828 {
29− register uint64_t x0 asm("x0") = PSCI_0_2_FN64_CPU_ON;
30− register uint64_t x1 asm("x1") = target_cpu;
31− register uint64_t x2 asm("x2") = entry_addr;
32− register uint64_t x3 asm("x3") = context_id;
29+ struct arm_smccc_res res;
3330
34− asm("hvc #0"
35− : "=r"(x0)
36− : "r"(x0), "r"(x1), "r"(x2), "r"(x3)
37− : "memory");
31+ smccc_hvc(PSCI_0_2_FN64_CPU_ON, target_cpu, entry_addr, context_id,
32+ 0, 0, 0, 0, &res);
3833
39− return x0;
34+ return res.a0;
4035 }
4136
4237 static uint64_t psci_affinity_info(uint64_t target_affinity,
4338 uint64_t lowest_affinity_level)
4439 {
45− register uint64_t x0 asm("x0") = PSCI_0_2_FN64_AFFINITY_INFO;
46− register uint64_t x1 asm("x1") = target_affinity;
47− register uint64_t x2 asm("x2") = lowest_affinity_level;
40+ struct arm_smccc_res res;
4841
49− asm("hvc #0"
50− : "=r"(x0)
51− : "r"(x0), "r"(x1), "r"(x2)
52− : "memory");
42+ smccc_hvc(PSCI_0_2_FN64_AFFINITY_INFO, target_affinity, lowest_affinity_level,
43+ 0, 0, 0, 0, 0, &res);
5344
54− return x0;
45+ return res.a0;
5546 }
5647
5748 static void guest_main(uint64_t target_cpu)
tools/testing/selftests/kvm/include/aarch64/processor.h+22−0
@@ -185,4 +185,26 @@ static inline void local_irq_disable(void) · 184 unmodified lines
185185 asm volatile("msr daifset, #3" : : : "memory");
186186 }
187187
188+/**
189+ * struct arm_smccc_res - Result from SMC/HVC call
190+ * @a0-a3 result values from registers 0 to 3
191+ */
192+struct arm_smccc_res {
193+ unsigned long a0;
194+ unsigned long a1;
195+ unsigned long a2;
196+ unsigned long a3;
197+};
198+
199+/**
200+ * smccc_hvc - Invoke a SMCCC function using the hvc conduit
201+ * @function_id: the SMCCC function to be called
202+ * @arg0-arg6: SMCCC function arguments, corresponding to registers x1-x7
203+ * @res: pointer to write the return values from registers x0-x3
204+ *
205+ */
206+void smccc_hvc(uint32_t function_id, uint64_t arg0, uint64_t arg1,
207+ uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5,
208+ uint64_t arg6, struct arm_smccc_res *res);
209+
188210 #endif /* SELFTEST_KVM_PROCESSOR_H */
tools/testing/selftests/kvm/lib/aarch64/processor.c+25−0
@@ -500,3 +500,28 @@ void __attribute__((constructor)) init_guest_modes(void) · 499 unmodified lines
500500 {
501501 guest_modes_append_default();
502502 }
503+
504+void smccc_hvc(uint32_t function_id, uint64_t arg0, uint64_t arg1,
505+ uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5,
506+ uint64_t arg6, struct arm_smccc_res *res)
507+{
508+ asm volatile("mov w0, %w[function_id]\n"
509+ "mov x1, %[arg0]\n"
510+ "mov x2, %[arg1]\n"
511+ "mov x3, %[arg2]\n"
512+ "mov x4, %[arg3]\n"
513+ "mov x5, %[arg4]\n"
514+ "mov x6, %[arg5]\n"
515+ "mov x7, %[arg6]\n"
516+ "hvc #0\n"
517+ "mov %[res0], x0\n"
518+ "mov %[res1], x1\n"
519+ "mov %[res2], x2\n"
520+ "mov %[res3], x3\n"
521+ : [res0] "=r"(res->a0), [res1] "=r"(res->a1),
522+ [res2] "=r"(res->a2), [res3] "=r"(res->a3)
523+ : [function_id] "r"(function_id), [arg0] "r"(arg0),
524+ [arg1] "r"(arg1), [arg2] "r"(arg2), [arg3] "r"(arg3),
525+ [arg4] "r"(arg4), [arg5] "r"(arg5), [arg6] "r"(arg6)
526+ : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7");
527+}
tools/testing/selftests/kvm/steal_time.c+3−10
@@ -118,17 +118,10 @@ struct st_time { · 117 unmodified lines
118118
119119 static int64_t smccc(uint32_t func, uint64_t arg)
120120 {
121− unsigned long ret;
121+ struct arm_smccc_res res;
122122
123− asm volatile(
124− "mov w0, %w1\n"
125− "mov x1, %2\n"
126− "hvc #0\n"
127− "mov %0, x0\n"
128− : "=r" (ret) : "r" (func), "r" (arg) :
129− "x0", "x1", "x2", "x3");
130−
131− return ret;
123+ smccc_hvc(func, arg, 0, 0, 0, 0, 0, 0, &res);
124+ return res.a0;
132125 }
133126
134127 static void check_status(struct st_time *st)