15
15
16
16
#include <linux/bitmap.h>
17
17
18
+ #include "kvm_test_harness.h"
18
19
#include "kvm_util.h"
19
20
#include "vmx.h"
20
21
21
- union perf_capabilities {
22
+ static union perf_capabilities {
22
23
struct {
23
24
u64 lbr_format :6 ;
24
25
u64 pebs_trap :1 ;
@@ -32,7 +33,7 @@ union perf_capabilities {
32
33
u64 anythread_deprecated :1 ;
33
34
};
34
35
u64 capabilities ;
35
- };
36
+ } host_cap ;
36
37
37
38
/*
38
39
* The LBR format and most PEBS features are immutable, all other features are
@@ -73,19 +74,19 @@ static void guest_code(uint64_t current_val)
73
74
GUEST_DONE ();
74
75
}
75
76
77
+ KVM_ONE_VCPU_TEST_SUITE (vmx_pmu_caps );
78
+
76
79
/*
77
80
* Verify that guest WRMSRs to PERF_CAPABILITIES #GP regardless of the value
78
81
* written, that the guest always sees the userspace controlled value, and that
79
82
* PERF_CAPABILITIES is immutable after KVM_RUN.
80
83
*/
81
- static void test_guest_wrmsr_perf_capabilities ( union perf_capabilities host_cap )
84
+ KVM_ONE_VCPU_TEST ( vmx_pmu_caps , guest_wrmsr_perf_capabilities , guest_code )
82
85
{
83
- struct kvm_vcpu * vcpu ;
84
- struct kvm_vm * vm = vm_create_with_one_vcpu (& vcpu , guest_code );
85
86
struct ucall uc ;
86
87
int r , i ;
87
88
88
- vm_init_descriptor_tables (vm );
89
+ vm_init_descriptor_tables (vcpu -> vm );
89
90
vcpu_init_descriptor_tables (vcpu );
90
91
91
92
vcpu_set_msr (vcpu , MSR_IA32_PERF_CAPABILITIES , host_cap .capabilities );
@@ -117,31 +118,21 @@ static void test_guest_wrmsr_perf_capabilities(union perf_capabilities host_cap)
117
118
TEST_ASSERT (!r , "Post-KVM_RUN write '0x%llx'didn't fail" ,
118
119
host_cap .capabilities ^ BIT_ULL (i ));
119
120
}
120
-
121
- kvm_vm_free (vm );
122
121
}
123
122
124
123
/*
125
124
* Verify KVM allows writing PERF_CAPABILITIES with all KVM-supported features
126
125
* enabled, as well as '0' (to disable all features).
127
126
*/
128
- static void test_basic_perf_capabilities ( union perf_capabilities host_cap )
127
+ KVM_ONE_VCPU_TEST ( vmx_pmu_caps , basic_perf_capabilities , guest_code )
129
128
{
130
- struct kvm_vcpu * vcpu ;
131
- struct kvm_vm * vm = vm_create_with_one_vcpu (& vcpu , NULL );
132
-
133
129
vcpu_set_msr (vcpu , MSR_IA32_PERF_CAPABILITIES , 0 );
134
130
vcpu_set_msr (vcpu , MSR_IA32_PERF_CAPABILITIES , host_cap .capabilities );
135
-
136
- kvm_vm_free (vm );
137
131
}
138
132
139
- static void test_fungible_perf_capabilities ( union perf_capabilities host_cap )
133
+ KVM_ONE_VCPU_TEST ( vmx_pmu_caps , fungible_perf_capabilities , guest_code )
140
134
{
141
135
const uint64_t fungible_caps = host_cap .capabilities & ~immutable_caps .capabilities ;
142
-
143
- struct kvm_vcpu * vcpu ;
144
- struct kvm_vm * vm = vm_create_with_one_vcpu (& vcpu , NULL );
145
136
int bit ;
146
137
147
138
for_each_set_bit (bit , & fungible_caps , 64 ) {
@@ -150,8 +141,6 @@ static void test_fungible_perf_capabilities(union perf_capabilities host_cap)
150
141
host_cap .capabilities & ~BIT_ULL (bit ));
151
142
}
152
143
vcpu_set_msr (vcpu , MSR_IA32_PERF_CAPABILITIES , host_cap .capabilities );
153
-
154
- kvm_vm_free (vm );
155
144
}
156
145
157
146
/*
@@ -160,14 +149,11 @@ static void test_fungible_perf_capabilities(union perf_capabilities host_cap)
160
149
* separately as they are multi-bit values, e.g. toggling or setting a single
161
150
* bit can generate a false positive without dedicated safeguards.
162
151
*/
163
- static void test_immutable_perf_capabilities ( union perf_capabilities host_cap )
152
+ KVM_ONE_VCPU_TEST ( vmx_pmu_caps , immutable_perf_capabilities , guest_code )
164
153
{
165
154
const uint64_t reserved_caps = (~host_cap .capabilities |
166
155
immutable_caps .capabilities ) &
167
156
~format_caps .capabilities ;
168
-
169
- struct kvm_vcpu * vcpu ;
170
- struct kvm_vm * vm = vm_create_with_one_vcpu (& vcpu , NULL );
171
157
union perf_capabilities val = host_cap ;
172
158
int r , bit ;
173
159
@@ -201,8 +187,6 @@ static void test_immutable_perf_capabilities(union perf_capabilities host_cap)
201
187
TEST_ASSERT (!r , "Bad PEBS FMT = 0x%x didn't fail, host = 0x%x" ,
202
188
val .pebs_format , host_cap .pebs_format );
203
189
}
204
-
205
- kvm_vm_free (vm );
206
190
}
207
191
208
192
/*
@@ -211,32 +195,24 @@ static void test_immutable_perf_capabilities(union perf_capabilities host_cap)
211
195
* LBR_TOS as those bits are writable across all uarch implementations (arch
212
196
* LBRs will need to poke a different MSR).
213
197
*/
214
- static void test_lbr_perf_capabilities ( union perf_capabilities host_cap )
198
+ KVM_ONE_VCPU_TEST ( vmx_pmu_caps , lbr_perf_capabilities , guest_code )
215
199
{
216
- struct kvm_vcpu * vcpu ;
217
- struct kvm_vm * vm ;
218
200
int r ;
219
201
220
202
if (!host_cap .lbr_format )
221
203
return ;
222
204
223
- vm = vm_create_with_one_vcpu (& vcpu , NULL );
224
-
225
205
vcpu_set_msr (vcpu , MSR_IA32_PERF_CAPABILITIES , host_cap .capabilities );
226
206
vcpu_set_msr (vcpu , MSR_LBR_TOS , 7 );
227
207
228
208
vcpu_clear_cpuid_entry (vcpu , X86_PROPERTY_PMU_VERSION .function );
229
209
230
210
r = _vcpu_set_msr (vcpu , MSR_LBR_TOS , 7 );
231
211
TEST_ASSERT (!r , "Writing LBR_TOS should fail after disabling vPMU" );
232
-
233
- kvm_vm_free (vm );
234
212
}
235
213
236
214
int main (int argc , char * argv [])
237
215
{
238
- union perf_capabilities host_cap ;
239
-
240
216
TEST_REQUIRE (get_kvm_param_bool ("enable_pmu" ));
241
217
TEST_REQUIRE (kvm_cpu_has (X86_FEATURE_PDCM ));
242
218
@@ -248,9 +224,5 @@ int main(int argc, char *argv[])
248
224
TEST_ASSERT (host_cap .full_width_write ,
249
225
"Full-width writes should always be supported" );
250
226
251
- test_basic_perf_capabilities (host_cap );
252
- test_fungible_perf_capabilities (host_cap );
253
- test_immutable_perf_capabilities (host_cap );
254
- test_guest_wrmsr_perf_capabilities (host_cap );
255
- test_lbr_perf_capabilities (host_cap );
227
+ return test_harness_run (argc , argv );
256
228
}
0 commit comments