[kvm-unit-tests 4/6] x86: pmu: PERF_GLOBAL_INUSE MSR verification for vPMU v4

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

 



Arch PMU v4 introduces a new MSR, IA32_PERF_GLOBAL_INUSE. It provides
as "InUse" bit for each GP counter and fixed counter in processor.
Additionally PMI InUse[bit 63] indicates if the PMI mechanisam has
been configured.

This commit add the test case for this MSR, when a counter is started,
its index bit must be set in this MSR, when a counter is stopped through
writing 0 into counter's control MSR, its index bit must be cleared in
this MSR.

Signed-off-by: Xiong Zhang <xiong.y.zhang@xxxxxxxxx>
---
 lib/x86/msr.h |  4 ++++
 x86/pmu.c     | 14 ++++++++++++--
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/lib/x86/msr.h b/lib/x86/msr.h
index 63b8539..3bffe80 100644
--- a/lib/x86/msr.h
+++ b/lib/x86/msr.h
@@ -430,6 +430,10 @@
 #define MSR_CORE_PERF_GLOBAL_CTRL	0x0000038f
 #define MSR_CORE_PERF_GLOBAL_OVF_CTRL	0x00000390
 #define MSR_CORE_PERF_GLOBAL_STATUS_SET	0x00000391
+#define MSR_CORE_PERF_GLOBAL_INUSE      0x00000392
+
+/* PERF_GLOBAL_INUSE bits */
+#define MSR_CORE_PERF_GLOBAL_INUSE_PMI_BIT       63
 
 /* PERF_GLOBAL_OVF_CTRL bits */
 #define MSR_CORE_PERF_GLOBAL_OVF_CTRL_LBR_FREEZE  (1ULL << 58)
diff --git a/x86/pmu.c b/x86/pmu.c
index a171e9e..0ec0062 100644
--- a/x86/pmu.c
+++ b/x86/pmu.c
@@ -155,6 +155,15 @@ static void __start_event(pmu_counter_t *evt, uint64_t count)
 	    ctrl = (ctrl & ~(0xf << shift)) | (usrospmi << shift);
 	    wrmsr(MSR_CORE_PERF_FIXED_CTR_CTRL, ctrl);
     }
+    if (pmu.version >= 4) {
+	    u64 inuse = rdmsr(MSR_CORE_PERF_GLOBAL_INUSE);
+	    int idx = event_to_global_idx(evt);
+
+	    report(inuse & BIT_ULL(idx), "start counter_idx: %d", idx);
+	    if (evt->config & EVNTSEL_INT)
+		    report(inuse & BIT_ULL(MSR_CORE_PERF_GLOBAL_INUSE_PMI_BIT),
+			   "INT, start counter_idx: %d", idx);
+    }
     global_enable(evt);
     apic_write(APIC_LVTPC, PMI_VECTOR);
 }
@@ -168,14 +177,15 @@ static void stop_event(pmu_counter_t *evt)
 {
 	global_disable(evt);
 	if (is_gp(evt)) {
-		wrmsr(MSR_GP_EVENT_SELECTx(event_to_global_idx(evt)),
-		      evt->config & ~EVNTSEL_EN);
+		wrmsr(MSR_GP_EVENT_SELECTx(event_to_global_idx(evt)), 0);
 	} else {
 		uint32_t ctrl = rdmsr(MSR_CORE_PERF_FIXED_CTR_CTRL);
 		int shift = (evt->ctr - MSR_CORE_PERF_FIXED_CTR0) * 4;
 		wrmsr(MSR_CORE_PERF_FIXED_CTR_CTRL, ctrl & ~(0xf << shift));
 	}
 	evt->count = rdmsr(evt->ctr);
+	if (pmu.version >= 4)
+		report((rdmsr(MSR_CORE_PERF_GLOBAL_INUSE) & BIT_ULL(evt->idx)) == 0, "stop counter idx: %d", evt->idx);
 }
 
 static noinline void measure_many(pmu_counter_t *evt, int count)
-- 
2.34.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