From: Paolo Bonzini Date: Mon, 11 Mar 2024 14:41:09 +0000 (-0400) Subject: Merge tag 'kvm-x86-pmu-6.9' of https://github.com/kvm-x86/linux into HEAD X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=e9025cdd8c5c17e97949423856aced1d6f31c62f;p=linux.git Merge tag 'kvm-x86-pmu-6.9' of https://github.com/kvm-x86/linux into HEAD KVM x86 PMU changes for 6.9: - Fix several bugs where KVM speciously prevents the guest from utilizing fixed counters and architectural event encodings based on whether or not guest CPUID reports support for the _architectural_ encoding. - Fix a variety of bugs in KVM's emulation of RDPMC, e.g. for "fast" reads, priority of VMX interception vs #GP, PMC types in architectural PMUs, etc. - Add a selftest to verify KVM correctly emulates RDMPC, counter availability, and a variety of other PMC-related behaviors that depend on guest CPUID, i.e. are difficult to validate via KVM-Unit-Tests. - Zero out PMU metadata on AMD if the virtual PMU is disabled to avoid wasting cycles, e.g. when checking if a PMC event needs to be synthesized when skipping an instruction. - Optimize triggering of emulated events, e.g. for "count instructions" events when skipping an instruction, which yields a ~10% performance improvement in VM-Exit microbenchmarks when a vPMU is exposed to the guest. - Tighten the check for "PMI in guest" to reduce false positives if an NMI arrives in the host while KVM is handling an IRQ VM-Exit. --- e9025cdd8c5c17e97949423856aced1d6f31c62f diff --cc tools/testing/selftests/kvm/Makefile index b0f13fafa1552,ce58098d80fda..19f5710bb4568 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@@ -36,8 -36,8 +36,9 @@@ LIBKVM_x86_64 += lib/x86_64/apic. LIBKVM_x86_64 += lib/x86_64/handlers.S LIBKVM_x86_64 += lib/x86_64/hyperv.c LIBKVM_x86_64 += lib/x86_64/memstress.c + LIBKVM_x86_64 += lib/x86_64/pmu.c LIBKVM_x86_64 += lib/x86_64/processor.c +LIBKVM_x86_64 += lib/x86_64/sev.c LIBKVM_x86_64 += lib/x86_64/svm.c LIBKVM_x86_64 += lib/x86_64/ucall.c LIBKVM_x86_64 += lib/x86_64/vmx.c diff --cc tools/testing/selftests/kvm/include/x86_64/processor.h index d2534a4a077b7,abac816f6594c..3bd03b088dda6 --- a/tools/testing/selftests/kvm/include/x86_64/processor.h +++ b/tools/testing/selftests/kvm/include/x86_64/processor.h @@@ -23,12 -23,9 +23,15 @@@ extern bool host_cpu_is_intel; extern bool host_cpu_is_amd; +enum vm_guest_x86_subtype { + VM_SUBTYPE_NONE = 0, + VM_SUBTYPE_SEV, + VM_SUBTYPE_SEV_ES, +}; + + /* Forced emulation prefix, used to invoke the emulator unconditionally. */ + #define KVM_FEP "ud2; .byte 'k', 'v', 'm';" + #define NMI_VECTOR 0x02 #define X86_EFLAGS_FIXED (1u << 1) diff --cc tools/testing/selftests/kvm/x86_64/userspace_msr_exit_test.c index 9591a5fd54d7c,ab3a8c4f0b864..f4f61a2d2464c --- a/tools/testing/selftests/kvm/x86_64/userspace_msr_exit_test.c +++ b/tools/testing/selftests/kvm/x86_64/userspace_msr_exit_test.c @@@ -528,13 -511,16 +512,16 @@@ static void run_guest_then_process_ucal process_ucall_done(vcpu); } -static void test_msr_filter_allow(void) +KVM_ONE_VCPU_TEST_SUITE(user_msr); + +KVM_ONE_VCPU_TEST(user_msr, msr_filter_allow, guest_code_filter_allow) { - struct kvm_vcpu *vcpu; - struct kvm_vm *vm; + struct kvm_vm *vm = vcpu->vm; + uint64_t cmd; int rc; - vm = vm_create_with_one_vcpu(&vcpu, guest_code_filter_allow); + sync_global_to_guest(vm, fep_available); + rc = kvm_check_cap(KVM_CAP_X86_USER_SPACE_MSR); TEST_ASSERT(rc, "KVM_CAP_X86_USER_SPACE_MSR is available"); vm_enable_cap(vm, KVM_CAP_X86_USER_SPACE_MSR, KVM_MSR_EXIT_REASON_FILTER); @@@ -583,8 -569,11 +570,9 @@@ /* Confirm the guest completed without issues. */ run_guest_then_process_ucall_done(vcpu); } else { + TEST_ASSERT_EQ(cmd, UCALL_DONE); printf("To run the instruction emulated tests set the module parameter 'kvm.force_emulation_prefix=1'\n"); } - - kvm_vm_free(vm); } static int handle_ucall(struct kvm_vcpu *vcpu) @@@ -786,5 -791,15 +774,7 @@@ KVM_ONE_VCPU_TEST(user_msr, user_exit_m int main(int argc, char *argv[]) { + fep_available = kvm_is_forced_emulation_enabled(); + - test_msr_filter_allow(); - - test_msr_filter_deny(); - - test_msr_permission_bitmap(); - - test_user_exit_msr_flags(); - - return 0; + return test_harness_run(argc, argv); } diff --cc tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c index 876442fadada8,8ded194c5a6d2..ea0cb3cae0f75 --- a/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c @@@ -213,7 -235,9 +213,7 @@@ KVM_ONE_VCPU_TEST(vmx_pmu_caps, lbr_per int main(int argc, char *argv[]) { - TEST_REQUIRE(get_kvm_param_bool("enable_pmu")); - union perf_capabilities host_cap; - + TEST_REQUIRE(kvm_is_pmu_enabled()); TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_PDCM)); TEST_REQUIRE(kvm_cpu_has_p(X86_PROPERTY_PMU_VERSION));