summaryrefslogtreecommitdiffstats
path: root/tools/testing
diff options
context:
space:
mode:
authorSean Christopherson <seanjc@google.com>2023-03-10 16:46:12 -0800
committerSean Christopherson <seanjc@google.com>2023-04-06 14:58:44 -0700
commita2a34d148e75c242fd059e8c7ab31e88396013b6 (patch)
treedb60fd66fc70a5245d519d999d22614c5cb29e4c /tools/testing
parent37f4e79c43e5750e75b3de8726b4c21bae6ab7aa (diff)
downloadlinux-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.c30
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);
}