// SPDX-License-Identifier: GPL-2.0 /* * Test for VMX-pmu perf capability msr * * Copyright (C) 2021 Intel Corporation * * Test to check the effect of various CPUID settings on * MSR_IA32_PERF_CAPABILITIES MSR, and check that what * we write with KVM_SET_MSR is _not_ modified by the guest * and check it can be retrieved with KVM_GET_MSR, also test * the invalid LBR formats are rejected.
*/ #include <sys/ioctl.h>
/* * The LBR format and most PEBS features are immutable, all other features are * fungible (if supported by the host and KVM).
*/ staticconstunion perf_capabilities immutable_caps = {
.lbr_format = -1,
.pebs_trap = 1,
.pebs_arch_reg = 1,
.pebs_format = -1,
.pebs_baseline = 1,
};
for (i = 0; i < 64; i++)
guest_test_perf_capabilities_gp(current_val ^ BIT_ULL(i));
GUEST_DONE();
}
KVM_ONE_VCPU_TEST_SUITE(vmx_pmu_caps);
/* * Verify that guest WRMSRs to PERF_CAPABILITIES #GP regardless of the value * written, that the guest always sees the userspace controlled value, and that * PERF_CAPABILITIES is immutable after KVM_RUN.
*/
KVM_ONE_VCPU_TEST(vmx_pmu_caps, guest_wrmsr_perf_capabilities, guest_code)
{ struct ucall uc; int r, i;
for (i = 0; i < 64; i++) {
r = _vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES,
host_cap.capabilities ^ BIT_ULL(i));
TEST_ASSERT(!r, "Post-KVM_RUN write '0x%llx'didn't fail",
host_cap.capabilities ^ BIT_ULL(i));
}
}
/* * Verify KVM allows writing PERF_CAPABILITIES with all KVM-supported features * enabled, as well as '0' (to disable all features).
*/
KVM_ONE_VCPU_TEST(vmx_pmu_caps, basic_perf_capabilities, guest_code)
{
vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, 0);
vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, host_cap.capabilities);
}
/* * 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.
*/
KVM_ONE_VCPU_TEST(vmx_pmu_caps, immutable_perf_capabilities, guest_code)
{ const uint64_t reserved_caps = (~host_cap.capabilities |
immutable_caps.capabilities) &
~format_caps.capabilities; union perf_capabilities val = host_cap; int r, bit;
/* * KVM only supports the host's native LBR format, as well as '0' (to * disable LBR support). Verify KVM rejects all other LBR formats.
*/ for (val.lbr_format = 1; val.lbr_format; val.lbr_format++) { if (val.lbr_format == host_cap.lbr_format) continue;
/* Ditto for the PEBS format. */ for (val.pebs_format = 1; val.pebs_format; val.pebs_format++) { if (val.pebs_format == host_cap.pebs_format) continue;
/* * Test that LBR MSRs are writable when LBRs are enabled, and then verify that * disabling the vPMU via CPUID also disables LBR support. Set bits 2:0 of * LBR_TOS as those bits are writable across all uarch implementations (arch * LBRs will need to poke a different MSR).
*/
KVM_ONE_VCPU_TEST(vmx_pmu_caps, lbr_perf_capabilities, guest_code)
{ int r;
for (i = 0; i < 64; i++) {
r = _vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, BIT_ULL(i));
TEST_ASSERT(!r, "Setting PERF_CAPABILITIES bit %d (= 0x%llx) should fail without PDCM",
i, BIT_ULL(i));
}
}
int main(int argc, char *argv[])
{
TEST_REQUIRE(kvm_is_pmu_enabled());
TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_PDCM));
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.