diff options
author | Sean Christopherson <seanjc@google.com> | 2023-03-10 16:46:12 -0800 |
---|---|---|
committer | Sean Christopherson <seanjc@google.com> | 2023-04-06 14:58:44 -0700 |
commit | a2a34d148e75c242fd059e8c7ab31e88396013b6 (patch) | |
tree | db60fd66fc70a5245d519d999d22614c5cb29e4c /tools/testing | |
parent | 37f4e79c43e5750e75b3de8726b4c21bae6ab7aa (diff) | |
download | linux-a2a34d148e75c242fd059e8c7ab31e88396013b6.tar.gz linux-a2a34d148e75c242fd059e8c7ab31e88396013b6.tar.bz2 linux-a2a34d148e75c242fd059e8c7ab31e88396013b6.zip |
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>
Diffstat (limited to 'tools/testing')
-rw-r--r-- | tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c b/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c index 2647282ff380..d91bf44a2e39 100644 --- a/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c @@ -49,6 +49,11 @@ static const union perf_capabilities immutable_caps = { .pebs_baseline = 1, }; +static const union perf_capabilities format_caps = { + .lbr_format = -1, + .pebs_format = -1, +}; + static void guest_code(void) { wrmsr(MSR_IA32_PERF_CAPABILITIES, PMU_CAP_LBR_FMT); @@ -91,12 +96,30 @@ static void test_fungible_perf_capabilities(union perf_capabilities host_cap) kvm_vm_free(vm); } +/* + * Verify KVM rejects attempts to set unsupported and/or immutable features in + * PERF_CAPABILITIES. Note, LBR format and PEBS format need to be validated + * separately as they are multi-bit values, e.g. toggling or setting a single + * bit can generate a false positive without dedicated safeguards. + */ static void test_immutable_perf_capabilities(union perf_capabilities host_cap) { + const uint64_t reserved_caps = (~host_cap.capabilities | + immutable_caps.capabilities) & + ~format_caps.capabilities; + struct kvm_vcpu *vcpu; struct kvm_vm *vm = vm_create_with_one_vcpu(&vcpu, NULL); uint64_t val; - int ret; + int r, bit; + + for_each_set_bit(bit, &reserved_caps, 64) { + r = _vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, + host_cap.capabilities ^ BIT_ULL(bit)); + TEST_ASSERT(!r, "%s immutable feature 0x%llx (bit %d) didn't fail", + host_cap.capabilities & BIT_ULL(bit) ? "Setting" : "Clearing", + BIT_ULL(bit), bit); + } /* * 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) if (val == (host_cap.capabilities & PMU_CAP_LBR_FMT)) continue; - ret = _vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, val); - TEST_ASSERT(!ret, "Bad LBR FMT = 0x%lx didn't fail", val); + r = _vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, val); + TEST_ASSERT(!r, "Bad LBR FMT = 0x%lx didn't fail", val); } + kvm_vm_free(vm); } |