Skip to content

Commit a2a34d1

Browse files
committed
KVM: selftests: Test all immutable non-format bits in PERF_CAPABILITIES
Add negative testing of all immutable bits in PERF_CAPABILITIES, i.e. single bits that are reserved-0 or are effectively reserved-1 by KVM. Omit LBR and PEBS format bits from the test as it's easier to test them manually than it is to add safeguards to the comment path, e.g. toggling a single bit can yield a format of '0', which is legal as a "disable" value. Link: https://lore.kernel.org/r/20230311004618.920745-16-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 37f4e79 commit a2a34d1

1 file changed

Lines changed: 27 additions & 3 deletions

File tree

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

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ static const union perf_capabilities immutable_caps = {
4949
.pebs_baseline = 1,
5050
};
5151

52+
static const union perf_capabilities format_caps = {
53+
.lbr_format = -1,
54+
.pebs_format = -1,
55+
};
56+
5257
static void guest_code(void)
5358
{
5459
wrmsr(MSR_IA32_PERF_CAPABILITIES, PMU_CAP_LBR_FMT);
@@ -91,12 +96,30 @@ static void test_fungible_perf_capabilities(union perf_capabilities host_cap)
9196
kvm_vm_free(vm);
9297
}
9398

99+
/*
100+
* Verify KVM rejects attempts to set unsupported and/or immutable features in
101+
* PERF_CAPABILITIES. Note, LBR format and PEBS format need to be validated
102+
* separately as they are multi-bit values, e.g. toggling or setting a single
103+
* bit can generate a false positive without dedicated safeguards.
104+
*/
94105
static void test_immutable_perf_capabilities(union perf_capabilities host_cap)
95106
{
107+
const uint64_t reserved_caps = (~host_cap.capabilities |
108+
immutable_caps.capabilities) &
109+
~format_caps.capabilities;
110+
96111
struct kvm_vcpu *vcpu;
97112
struct kvm_vm *vm = vm_create_with_one_vcpu(&vcpu, NULL);
98113
uint64_t val;
99-
int ret;
114+
int r, bit;
115+
116+
for_each_set_bit(bit, &reserved_caps, 64) {
117+
r = _vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES,
118+
host_cap.capabilities ^ BIT_ULL(bit));
119+
TEST_ASSERT(!r, "%s immutable feature 0x%llx (bit %d) didn't fail",
120+
host_cap.capabilities & BIT_ULL(bit) ? "Setting" : "Clearing",
121+
BIT_ULL(bit), bit);
122+
}
100123

101124
/*
102125
* KVM only supports the host's native LBR format, as well as '0' (to
@@ -106,9 +129,10 @@ static void test_immutable_perf_capabilities(union perf_capabilities host_cap)
106129
if (val == (host_cap.capabilities & PMU_CAP_LBR_FMT))
107130
continue;
108131

109-
ret = _vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, val);
110-
TEST_ASSERT(!ret, "Bad LBR FMT = 0x%lx didn't fail", val);
132+
r = _vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, val);
133+
TEST_ASSERT(!r, "Bad LBR FMT = 0x%lx didn't fail", val);
111134
}
135+
112136
kvm_vm_free(vm);
113137
}
114138

0 commit comments

Comments
 (0)