Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/testing/selftests/kvm/arm64/vcpu_width_config.c
38237 views
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 @init0, and then
19
* add another vCPU, and run KVM_ARM_VCPU_INIT with @init1.
20
*/
21
static int add_init_2vcpus(struct kvm_vcpu_init *init0,
22
struct kvm_vcpu_init *init1)
23
{
24
struct kvm_vcpu *vcpu0, *vcpu1;
25
struct kvm_vm *vm;
26
int ret;
27
28
vm = vm_create_barebones();
29
30
vcpu0 = __vm_vcpu_add(vm, 0);
31
ret = __vcpu_ioctl(vcpu0, KVM_ARM_VCPU_INIT, init0);
32
if (ret)
33
goto free_exit;
34
35
vcpu1 = __vm_vcpu_add(vm, 1);
36
ret = __vcpu_ioctl(vcpu1, KVM_ARM_VCPU_INIT, init1);
37
38
free_exit:
39
kvm_vm_free(vm);
40
return ret;
41
}
42
43
/*
44
* Add two vCPUs, then run KVM_ARM_VCPU_INIT for one vCPU with @init0,
45
* and run KVM_ARM_VCPU_INIT for another vCPU with @init1.
46
*/
47
static int add_2vcpus_init_2vcpus(struct kvm_vcpu_init *init0,
48
struct kvm_vcpu_init *init1)
49
{
50
struct kvm_vcpu *vcpu0, *vcpu1;
51
struct kvm_vm *vm;
52
int ret;
53
54
vm = vm_create_barebones();
55
56
vcpu0 = __vm_vcpu_add(vm, 0);
57
vcpu1 = __vm_vcpu_add(vm, 1);
58
59
ret = __vcpu_ioctl(vcpu0, KVM_ARM_VCPU_INIT, init0);
60
if (ret)
61
goto free_exit;
62
63
ret = __vcpu_ioctl(vcpu1, KVM_ARM_VCPU_INIT, init1);
64
65
free_exit:
66
kvm_vm_free(vm);
67
return ret;
68
}
69
70
/*
71
* Tests that two 64bit vCPUs can be configured, two 32bit vCPUs can be
72
* configured, and two mixed-width vCPUs cannot be configured.
73
* Each of those three cases, configure vCPUs in two different orders.
74
* The one is running KVM_CREATE_VCPU for 2 vCPUs, and then running
75
* KVM_ARM_VCPU_INIT for them.
76
* The other is running KVM_CREATE_VCPU and KVM_ARM_VCPU_INIT for a vCPU,
77
* and then run those commands for another vCPU.
78
*/
79
int main(void)
80
{
81
struct kvm_vcpu_init init0, init1;
82
struct kvm_vm *vm;
83
int ret;
84
85
TEST_REQUIRE(kvm_has_cap(KVM_CAP_ARM_EL1_32BIT));
86
87
/* Get the preferred target type and copy that to init1 for later use */
88
vm = vm_create_barebones();
89
vm_ioctl(vm, KVM_ARM_PREFERRED_TARGET, &init0);
90
kvm_vm_free(vm);
91
init1 = init0;
92
93
/* Test with 64bit vCPUs */
94
ret = add_init_2vcpus(&init0, &init0);
95
TEST_ASSERT(ret == 0,
96
"Configuring 64bit EL1 vCPUs failed unexpectedly");
97
ret = add_2vcpus_init_2vcpus(&init0, &init0);
98
TEST_ASSERT(ret == 0,
99
"Configuring 64bit EL1 vCPUs failed unexpectedly");
100
101
/* Test with 32bit vCPUs */
102
init0.features[0] = (1 << KVM_ARM_VCPU_EL1_32BIT);
103
ret = add_init_2vcpus(&init0, &init0);
104
TEST_ASSERT(ret == 0,
105
"Configuring 32bit EL1 vCPUs failed unexpectedly");
106
ret = add_2vcpus_init_2vcpus(&init0, &init0);
107
TEST_ASSERT(ret == 0,
108
"Configuring 32bit EL1 vCPUs failed unexpectedly");
109
110
/* Test with mixed-width vCPUs */
111
init0.features[0] = 0;
112
init1.features[0] = (1 << KVM_ARM_VCPU_EL1_32BIT);
113
ret = add_init_2vcpus(&init0, &init1);
114
TEST_ASSERT(ret != 0,
115
"Configuring mixed-width vCPUs worked unexpectedly");
116
ret = add_2vcpus_init_2vcpus(&init0, &init1);
117
TEST_ASSERT(ret != 0,
118
"Configuring mixed-width vCPUs worked unexpectedly");
119
120
return 0;
121
}
122
123