[PATCH 3/3] KVM: selftests: Test writing PERF_CAPABILITIES after KVM_RUN is rejected

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Like Xu <likexu@xxxxxxxxxxx>

KVM should also disallow changing the feature MSR PERF_CAPABILITIES after
KVM_RUN to prevent unexpected behavior. Implement run_vcpu() in a separate
thread approach and opportunistically rearrange test cases.

Signed-off-by: Like Xu <likexu@xxxxxxxxxxx>
---
 .../selftests/kvm/x86_64/vmx_pmu_caps_test.c  | 49 +++++++++++++------
 1 file changed, 34 insertions(+), 15 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 928c10e520c7..0ee00fec8c2c 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
@@ -13,13 +13,13 @@
 
 #define _GNU_SOURCE /* for program_invocation_short_name */
 #include <sys/ioctl.h>
+#include <pthread.h>
 
 #include "kvm_util.h"
 #include "vmx.h"
 
 #define PMU_CAP_FW_WRITES	(1ULL << 13)
 #define PMU_CAP_LBR_FMT		0x3f
-
 union cpuid10_eax {
 	struct {
 		unsigned int version_id:8;
@@ -46,17 +46,28 @@ union perf_capabilities {
 	u64	capabilities;
 };
 
+static struct kvm_vm *vm;
+static struct kvm_vcpu *vcpu;
+
 static void guest_code(void)
 {
 	wrmsr(MSR_IA32_PERF_CAPABILITIES, PMU_CAP_LBR_FMT);
 }
 
+static void *run_vcpu(void *ignore)
+{
+	vcpu_run(vcpu);
+
+	TEST_ASSERT(!_vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, 0),
+		    "Update PERF_CAPABILITIES after VCPU_RUN didn't fail.");
+
+	return NULL;
+}
+
 int main(int argc, char *argv[])
 {
+	pthread_t cpu_thread;
 	const struct kvm_cpuid_entry2 *entry_a_0;
-	struct kvm_vm *vm;
-	struct kvm_vcpu *vcpu;
-	int ret;
 	union cpuid10_eax eax;
 	union perf_capabilities host_cap;
 	uint64_t val;
@@ -65,7 +76,8 @@ int main(int argc, char *argv[])
 	host_cap.capabilities &= (PMU_CAP_FW_WRITES | PMU_CAP_LBR_FMT);
 
 	/* Create VM */
-	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
+	vm = vm_create(1);
+	vcpu = vm_vcpu_add(vm, 1, guest_code);
 
 	TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_PDCM));
 
@@ -77,33 +89,40 @@ int main(int argc, char *argv[])
 
 	/* testcase 1, set capabilities when we have PDCM bit */
 	vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, PMU_CAP_FW_WRITES);
-
-	/* check capabilities can be retrieved with KVM_GET_MSR */
 	ASSERT_EQ(vcpu_get_msr(vcpu, MSR_IA32_PERF_CAPABILITIES), PMU_CAP_FW_WRITES);
 
-	/* check whatever we write with KVM_SET_MSR is _not_ modified */
-	vcpu_run(vcpu);
-	ASSERT_EQ(vcpu_get_msr(vcpu, MSR_IA32_PERF_CAPABILITIES), PMU_CAP_FW_WRITES);
-
-	/* testcase 2, check valid LBR formats are accepted */
+	/* testcase 2, check value zero (which disables all features) is accepted */
 	vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, 0);
 	ASSERT_EQ(vcpu_get_msr(vcpu, MSR_IA32_PERF_CAPABILITIES), 0);
 
+	/* testcase 3, check valid LBR formats are accepted */
 	vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, host_cap.lbr_format);
 	ASSERT_EQ(vcpu_get_msr(vcpu, MSR_IA32_PERF_CAPABILITIES), (u64)host_cap.lbr_format);
 
 	/*
-	 * Testcase 3, check that an "invalid" LBR format is rejected.  Only an
+	 * Testcase 4, check that an "invalid" LBR format is rejected.  Only an
 	 * exact match of the host's format (and 0/disabled) is allowed.
 	 */
 	for (val = 1; val <= PMU_CAP_LBR_FMT; val++) {
 		if (val == host_cap.lbr_format)
 			continue;
 
-		ret = _vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, val);
-		TEST_ASSERT(!ret, "Bad LBR FMT = 0x%lx didn't fail", val);
+		TEST_ASSERT(!_vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, val),
+			    "Bad LBR FMT = 0x%lx didn't fail", val);
 	}
 
+	/* Testcase 5, check whatever use space writes is _not_ modified after VCPU_RUN */
+	vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, host_cap.capabilities);
+
+	pthread_create(&cpu_thread, NULL, run_vcpu, NULL);
+	pthread_join(cpu_thread, NULL);
+
+	TEST_ASSERT(!_vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, 0),
+		    "Update PERF_CAPABILITIES after VCPU_RUN didn't fail.");
+
+	ASSERT_EQ(vcpu_get_msr(vcpu, MSR_IA32_PERF_CAPABILITIES), host_cap.capabilities);
+
 	printf("Completed perf capability tests.\n");
 	kvm_vm_free(vm);
+	return 0;
 }
-- 
2.37.1




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux