Skip to content

Commit 2f5d27e

Browse files
reijiw-kvmMarc Zyngier
authored andcommitted
KVM: arm64: selftests: Introduce vcpu_width_config
Introduce a test for aarch64 that ensures non-mixed-width vCPUs (all 64bit vCPUs or all 32bit vcPUs) can be configured, and mixed-width vCPUs cannot be configured. Reviewed-by: Andrew Jones <[email protected]> Signed-off-by: Reiji Watanabe <[email protected]> Reviewed-by: Oliver Upton <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 26bf74b commit 2f5d27e

File tree

3 files changed

+124
-0
lines changed

3 files changed

+124
-0
lines changed

tools/testing/selftests/kvm/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
/aarch64/debug-exceptions
44
/aarch64/get-reg-list
55
/aarch64/psci_cpu_on_test
6+
/aarch64/vcpu_width_config
67
/aarch64/vgic_init
78
/aarch64/vgic_irq
89
/s390x/memop

tools/testing/selftests/kvm/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ TEST_GEN_PROGS_aarch64 += aarch64/arch_timer
106106
TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
107107
TEST_GEN_PROGS_aarch64 += aarch64/get-reg-list
108108
TEST_GEN_PROGS_aarch64 += aarch64/psci_cpu_on_test
109+
TEST_GEN_PROGS_aarch64 += aarch64/vcpu_width_config
109110
TEST_GEN_PROGS_aarch64 += aarch64/vgic_init
110111
TEST_GEN_PROGS_aarch64 += aarch64/vgic_irq
111112
TEST_GEN_PROGS_aarch64 += demand_paging_test
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* vcpu_width_config - Test KVM_ARM_VCPU_INIT() with KVM_ARM_VCPU_EL1_32BIT.
4+
*
5+
* Copyright (c) 2022 Google LLC.
6+
*
7+
* This is a test that ensures that non-mixed-width vCPUs (all 64bit vCPUs
8+
* or all 32bit vcPUs) can be configured and mixed-width vCPUs cannot be
9+
* configured.
10+
*/
11+
12+
#include "kvm_util.h"
13+
#include "processor.h"
14+
#include "test_util.h"
15+
16+
17+
/*
18+
* Add a vCPU, run KVM_ARM_VCPU_INIT with @init1, and then
19+
* add another vCPU, and run KVM_ARM_VCPU_INIT with @init2.
20+
*/
21+
static int add_init_2vcpus(struct kvm_vcpu_init *init1,
22+
struct kvm_vcpu_init *init2)
23+
{
24+
struct kvm_vm *vm;
25+
int ret;
26+
27+
vm = vm_create(VM_MODE_DEFAULT, DEFAULT_GUEST_PHY_PAGES, O_RDWR);
28+
29+
vm_vcpu_add(vm, 0);
30+
ret = _vcpu_ioctl(vm, 0, KVM_ARM_VCPU_INIT, init1);
31+
if (ret)
32+
goto free_exit;
33+
34+
vm_vcpu_add(vm, 1);
35+
ret = _vcpu_ioctl(vm, 1, KVM_ARM_VCPU_INIT, init2);
36+
37+
free_exit:
38+
kvm_vm_free(vm);
39+
return ret;
40+
}
41+
42+
/*
43+
* Add two vCPUs, then run KVM_ARM_VCPU_INIT for one vCPU with @init1,
44+
* and run KVM_ARM_VCPU_INIT for another vCPU with @init2.
45+
*/
46+
static int add_2vcpus_init_2vcpus(struct kvm_vcpu_init *init1,
47+
struct kvm_vcpu_init *init2)
48+
{
49+
struct kvm_vm *vm;
50+
int ret;
51+
52+
vm = vm_create(VM_MODE_DEFAULT, DEFAULT_GUEST_PHY_PAGES, O_RDWR);
53+
54+
vm_vcpu_add(vm, 0);
55+
vm_vcpu_add(vm, 1);
56+
57+
ret = _vcpu_ioctl(vm, 0, KVM_ARM_VCPU_INIT, init1);
58+
if (ret)
59+
goto free_exit;
60+
61+
ret = _vcpu_ioctl(vm, 1, KVM_ARM_VCPU_INIT, init2);
62+
63+
free_exit:
64+
kvm_vm_free(vm);
65+
return ret;
66+
}
67+
68+
/*
69+
* Tests that two 64bit vCPUs can be configured, two 32bit vCPUs can be
70+
* configured, and two mixed-width vCPUs cannot be configured.
71+
* Each of those three cases, configure vCPUs in two different orders.
72+
* The one is running KVM_CREATE_VCPU for 2 vCPUs, and then running
73+
* KVM_ARM_VCPU_INIT for them.
74+
* The other is running KVM_CREATE_VCPU and KVM_ARM_VCPU_INIT for a vCPU,
75+
* and then run those commands for another vCPU.
76+
*/
77+
int main(void)
78+
{
79+
struct kvm_vcpu_init init1, init2;
80+
struct kvm_vm *vm;
81+
int ret;
82+
83+
if (!kvm_check_cap(KVM_CAP_ARM_EL1_32BIT)) {
84+
print_skip("KVM_CAP_ARM_EL1_32BIT is not supported");
85+
exit(KSFT_SKIP);
86+
}
87+
88+
/* Get the preferred target type and copy that to init2 for later use */
89+
vm = vm_create(VM_MODE_DEFAULT, DEFAULT_GUEST_PHY_PAGES, O_RDWR);
90+
vm_ioctl(vm, KVM_ARM_PREFERRED_TARGET, &init1);
91+
kvm_vm_free(vm);
92+
init2 = init1;
93+
94+
/* Test with 64bit vCPUs */
95+
ret = add_init_2vcpus(&init1, &init1);
96+
TEST_ASSERT(ret == 0,
97+
"Configuring 64bit EL1 vCPUs failed unexpectedly");
98+
ret = add_2vcpus_init_2vcpus(&init1, &init1);
99+
TEST_ASSERT(ret == 0,
100+
"Configuring 64bit EL1 vCPUs failed unexpectedly");
101+
102+
/* Test with 32bit vCPUs */
103+
init1.features[0] = (1 << KVM_ARM_VCPU_EL1_32BIT);
104+
ret = add_init_2vcpus(&init1, &init1);
105+
TEST_ASSERT(ret == 0,
106+
"Configuring 32bit EL1 vCPUs failed unexpectedly");
107+
ret = add_2vcpus_init_2vcpus(&init1, &init1);
108+
TEST_ASSERT(ret == 0,
109+
"Configuring 32bit EL1 vCPUs failed unexpectedly");
110+
111+
/* Test with mixed-width vCPUs */
112+
init1.features[0] = 0;
113+
init2.features[0] = (1 << KVM_ARM_VCPU_EL1_32BIT);
114+
ret = add_init_2vcpus(&init1, &init2);
115+
TEST_ASSERT(ret != 0,
116+
"Configuring mixed-width vCPUs worked unexpectedly");
117+
ret = add_2vcpus_init_2vcpus(&init1, &init2);
118+
TEST_ASSERT(ret != 0,
119+
"Configuring mixed-width vCPUs worked unexpectedly");
120+
121+
return 0;
122+
}

0 commit comments

Comments
 (0)