1515
1616#include <linux/bitmap.h>
1717
18+ #include "kvm_test_harness.h"
1819#include "kvm_util.h"
1920#include "vmx.h"
2021
21- union perf_capabilities {
22+ static union perf_capabilities {
2223 struct {
2324 u64 lbr_format :6 ;
2425 u64 pebs_trap :1 ;
@@ -32,7 +33,7 @@ union perf_capabilities {
3233 u64 anythread_deprecated :1 ;
3334 };
3435 u64 capabilities ;
35- };
36+ } host_cap ;
3637
3738/*
3839 * 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)
7374 GUEST_DONE ();
7475}
7576
77+ KVM_ONE_VCPU_TEST_SUITE (vmx_pmu_caps );
78+
7679/*
7780 * Verify that guest WRMSRs to PERF_CAPABILITIES #GP regardless of the value
7881 * written, that the guest always sees the userspace controlled value, and that
7982 * PERF_CAPABILITIES is immutable after KVM_RUN.
8083 */
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 )
8285{
83- struct kvm_vcpu * vcpu ;
84- struct kvm_vm * vm = vm_create_with_one_vcpu (& vcpu , guest_code );
8586 struct ucall uc ;
8687 int r , i ;
8788
88- vm_init_descriptor_tables (vm );
89+ vm_init_descriptor_tables (vcpu -> vm );
8990 vcpu_init_descriptor_tables (vcpu );
9091
9192 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)
117118 TEST_ASSERT (!r , "Post-KVM_RUN write '0x%llx'didn't fail" ,
118119 host_cap .capabilities ^ BIT_ULL (i ));
119120 }
120-
121- kvm_vm_free (vm );
122121}
123122
124123/*
125124 * Verify KVM allows writing PERF_CAPABILITIES with all KVM-supported features
126125 * enabled, as well as '0' (to disable all features).
127126 */
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 )
129128{
130- struct kvm_vcpu * vcpu ;
131- struct kvm_vm * vm = vm_create_with_one_vcpu (& vcpu , NULL );
132-
133129 vcpu_set_msr (vcpu , MSR_IA32_PERF_CAPABILITIES , 0 );
134130 vcpu_set_msr (vcpu , MSR_IA32_PERF_CAPABILITIES , host_cap .capabilities );
135-
136- kvm_vm_free (vm );
137131}
138132
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 )
140134{
141135 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 );
145136 int bit ;
146137
147138 for_each_set_bit (bit , & fungible_caps , 64 ) {
@@ -150,8 +141,6 @@ static void test_fungible_perf_capabilities(union perf_capabilities host_cap)
150141 host_cap .capabilities & ~BIT_ULL (bit ));
151142 }
152143 vcpu_set_msr (vcpu , MSR_IA32_PERF_CAPABILITIES , host_cap .capabilities );
153-
154- kvm_vm_free (vm );
155144}
156145
157146/*
@@ -160,14 +149,11 @@ static void test_fungible_perf_capabilities(union perf_capabilities host_cap)
160149 * separately as they are multi-bit values, e.g. toggling or setting a single
161150 * bit can generate a false positive without dedicated safeguards.
162151 */
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 )
164153{
165154 const uint64_t reserved_caps = (~host_cap .capabilities |
166155 immutable_caps .capabilities ) &
167156 ~format_caps .capabilities ;
168-
169- struct kvm_vcpu * vcpu ;
170- struct kvm_vm * vm = vm_create_with_one_vcpu (& vcpu , NULL );
171157 union perf_capabilities val = host_cap ;
172158 int r , bit ;
173159
@@ -201,8 +187,6 @@ static void test_immutable_perf_capabilities(union perf_capabilities host_cap)
201187 TEST_ASSERT (!r , "Bad PEBS FMT = 0x%x didn't fail, host = 0x%x" ,
202188 val .pebs_format , host_cap .pebs_format );
203189 }
204-
205- kvm_vm_free (vm );
206190}
207191
208192/*
@@ -211,32 +195,24 @@ static void test_immutable_perf_capabilities(union perf_capabilities host_cap)
211195 * LBR_TOS as those bits are writable across all uarch implementations (arch
212196 * LBRs will need to poke a different MSR).
213197 */
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 )
215199{
216- struct kvm_vcpu * vcpu ;
217- struct kvm_vm * vm ;
218200 int r ;
219201
220202 if (!host_cap .lbr_format )
221203 return ;
222204
223- vm = vm_create_with_one_vcpu (& vcpu , NULL );
224-
225205 vcpu_set_msr (vcpu , MSR_IA32_PERF_CAPABILITIES , host_cap .capabilities );
226206 vcpu_set_msr (vcpu , MSR_LBR_TOS , 7 );
227207
228208 vcpu_clear_cpuid_entry (vcpu , X86_PROPERTY_PMU_VERSION .function );
229209
230210 r = _vcpu_set_msr (vcpu , MSR_LBR_TOS , 7 );
231211 TEST_ASSERT (!r , "Writing LBR_TOS should fail after disabling vPMU" );
232-
233- kvm_vm_free (vm );
234212}
235213
236214int main (int argc , char * argv [])
237215{
238- union perf_capabilities host_cap ;
239-
240216 TEST_REQUIRE (get_kvm_param_bool ("enable_pmu" ));
241217 TEST_REQUIRE (kvm_cpu_has (X86_FEATURE_PDCM ));
242218
@@ -248,9 +224,5 @@ int main(int argc, char *argv[])
248224 TEST_ASSERT (host_cap .full_width_write ,
249225 "Full-width writes should always be supported" );
250226
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 );
256228}
0 commit comments