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