Skip to content

Commit baa36da

Browse files
committed
KVM: selftests: Expand negative testing of guest writes to PERF_CAPABILITIES
Test that the guest can't write 0 to PERF_CAPABILITIES, can't write the current value, and can't toggle _any_ bits. There is no reason to special case the LBR format. Link: https://lore.kernel.org/r/20230311004618.920745-17-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent a2a34d1 commit baa36da

1 file changed

Lines changed: 54 additions & 7 deletions

File tree

tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,59 @@ static const union perf_capabilities format_caps = {
5454
.pebs_format = -1,
5555
};
5656

57-
static void guest_code(void)
57+
static void guest_code(uint64_t current_val)
5858
{
59-
wrmsr(MSR_IA32_PERF_CAPABILITIES, PMU_CAP_LBR_FMT);
59+
uint8_t vector;
60+
int i;
61+
62+
vector = wrmsr_safe(MSR_IA32_PERF_CAPABILITIES, current_val);
63+
GUEST_ASSERT_2(vector == GP_VECTOR, current_val, vector);
64+
65+
vector = wrmsr_safe(MSR_IA32_PERF_CAPABILITIES, 0);
66+
GUEST_ASSERT_2(vector == GP_VECTOR, 0, vector);
67+
68+
for (i = 0; i < 64; i++) {
69+
vector = wrmsr_safe(MSR_IA32_PERF_CAPABILITIES,
70+
current_val ^ BIT_ULL(i));
71+
GUEST_ASSERT_2(vector == GP_VECTOR,
72+
current_val ^ BIT_ULL(i), vector);
73+
}
74+
75+
GUEST_DONE();
76+
}
77+
78+
/*
79+
* Verify that guest WRMSRs to PERF_CAPABILITIES #GP regardless of the value
80+
* written, that the guest always sees the userspace controlled value, and that
81+
* PERF_CAPABILITIES is immutable after KVM_RUN.
82+
*/
83+
static void test_guest_wrmsr_perf_capabilities(union perf_capabilities host_cap)
84+
{
85+
struct kvm_vcpu *vcpu;
86+
struct kvm_vm *vm = vm_create_with_one_vcpu(&vcpu, guest_code);
87+
struct ucall uc;
88+
89+
vm_init_descriptor_tables(vm);
90+
vcpu_init_descriptor_tables(vcpu);
91+
92+
vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, host_cap.capabilities);
93+
94+
vcpu_args_set(vcpu, 1, host_cap.capabilities);
95+
vcpu_run(vcpu);
96+
97+
switch (get_ucall(vcpu, &uc)) {
98+
case UCALL_ABORT:
99+
REPORT_GUEST_ASSERT_2(uc, "val = 0x%lx, vector = %lu");
100+
break;
101+
case UCALL_DONE:
102+
break;
103+
default:
104+
TEST_FAIL("Unexpected ucall: %lu", uc.cmd);
105+
}
106+
107+
ASSERT_EQ(vcpu_get_msr(vcpu, MSR_IA32_PERF_CAPABILITIES), host_cap.capabilities);
108+
109+
kvm_vm_free(vm);
60110
}
61111

62112
/*
@@ -79,7 +129,7 @@ static void test_fungible_perf_capabilities(union perf_capabilities host_cap)
79129
const uint64_t fungible_caps = host_cap.capabilities & ~immutable_caps.capabilities;
80130

81131
struct kvm_vcpu *vcpu;
82-
struct kvm_vm *vm = vm_create_with_one_vcpu(&vcpu, guest_code);
132+
struct kvm_vm *vm = vm_create_with_one_vcpu(&vcpu, NULL);
83133
int bit;
84134

85135
for_each_set_bit(bit, &fungible_caps, 64) {
@@ -89,10 +139,6 @@ static void test_fungible_perf_capabilities(union perf_capabilities host_cap)
89139
}
90140
vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, host_cap.capabilities);
91141

92-
/* check whatever we write with KVM_SET_MSR is _not_ modified */
93-
vcpu_run(vcpu);
94-
ASSERT_EQ(vcpu_get_msr(vcpu, MSR_IA32_PERF_CAPABILITIES), host_cap.capabilities);
95-
96142
kvm_vm_free(vm);
97143
}
98144

@@ -153,6 +199,7 @@ int main(int argc, char *argv[])
153199
test_basic_perf_capabilities(host_cap);
154200
test_fungible_perf_capabilities(host_cap);
155201
test_immutable_perf_capabilities(host_cap);
202+
test_guest_wrmsr_perf_capabilities(host_cap);
156203

157204
printf("Completed perf capability tests.\n");
158205
}

0 commit comments

Comments
 (0)