1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Test for VMX-pmu perf capability msr 4 * 5 * Copyright (C) 2021 Intel Corporation 6 * 7 * Test to check the effect of various CPUID settings on 8 * MSR_IA32_PERF_CAPABILITIES MSR, and check that what 9 * we write with KVM_SET_MSR is _not_ modified by the guest 10 * and check it can be retrieved with KVM_GET_MSR, also test 11 * the invalid LBR formats are rejected. 12 */ 13 14 #define _GNU_SOURCE /* for program_invocation_short_name */ 15 #include <sys/ioctl.h> 16 17 #include "kvm_util.h" 18 #include "vmx.h" 19 20 #define PMU_CAP_FW_WRITES (1ULL << 13) 21 #define PMU_CAP_LBR_FMT 0x3f 22 23 union perf_capabilities { 24 struct { 25 u64 lbr_format:6; 26 u64 pebs_trap:1; 27 u64 pebs_arch_reg:1; 28 u64 pebs_format:4; 29 u64 smm_freeze:1; 30 u64 full_width_write:1; 31 u64 pebs_baseline:1; 32 u64 perf_metrics:1; 33 u64 pebs_output_pt_available:1; 34 u64 anythread_deprecated:1; 35 }; 36 u64 capabilities; 37 }; 38 39 static void guest_code(void) 40 { 41 wrmsr(MSR_IA32_PERF_CAPABILITIES, PMU_CAP_LBR_FMT); 42 } 43 44 int main(int argc, char *argv[]) 45 { 46 struct kvm_vm *vm; 47 struct kvm_vcpu *vcpu; 48 int ret; 49 union perf_capabilities host_cap; 50 uint64_t val; 51 52 host_cap.capabilities = kvm_get_feature_msr(MSR_IA32_PERF_CAPABILITIES); 53 host_cap.capabilities &= (PMU_CAP_FW_WRITES | PMU_CAP_LBR_FMT); 54 55 /* Create VM */ 56 vm = vm_create_with_one_vcpu(&vcpu, guest_code); 57 58 TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_PDCM)); 59 60 TEST_REQUIRE(kvm_cpu_has_p(X86_PROPERTY_PMU_VERSION)); 61 TEST_REQUIRE(kvm_cpu_property(X86_PROPERTY_PMU_VERSION) > 0); 62 63 /* testcase 1, set capabilities when we have PDCM bit */ 64 vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, PMU_CAP_FW_WRITES); 65 66 /* check capabilities can be retrieved with KVM_GET_MSR */ 67 ASSERT_EQ(vcpu_get_msr(vcpu, MSR_IA32_PERF_CAPABILITIES), PMU_CAP_FW_WRITES); 68 69 /* check whatever we write with KVM_SET_MSR is _not_ modified */ 70 vcpu_run(vcpu); 71 ASSERT_EQ(vcpu_get_msr(vcpu, MSR_IA32_PERF_CAPABILITIES), PMU_CAP_FW_WRITES); 72 73 /* testcase 2, check valid LBR formats are accepted */ 74 vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, 0); 75 ASSERT_EQ(vcpu_get_msr(vcpu, MSR_IA32_PERF_CAPABILITIES), 0); 76 77 vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, host_cap.lbr_format); 78 ASSERT_EQ(vcpu_get_msr(vcpu, MSR_IA32_PERF_CAPABILITIES), (u64)host_cap.lbr_format); 79 80 /* 81 * Testcase 3, check that an "invalid" LBR format is rejected. Only an 82 * exact match of the host's format (and 0/disabled) is allowed. 83 */ 84 for (val = 1; val <= PMU_CAP_LBR_FMT; val++) { 85 if (val == (host_cap.capabilities & PMU_CAP_LBR_FMT)) 86 continue; 87 88 ret = _vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, val); 89 TEST_ASSERT(!ret, "Bad LBR FMT = 0x%lx didn't fail", val); 90 } 91 92 printf("Completed perf capability tests.\n"); 93 kvm_vm_free(vm); 94 } 95