Mask the set of available architectural events based on the bit vector length to avoid marking reserved/undefined events as available. Per the SDM: EAX Bits 31-24: Length of EBX bit vector to enumerate architectural performance monitoring events. Architectural event x is supported if EBX[x]=0 && EAX[31:24]>x. Suggested-by: Dapeng Mi <dapeng1.mi@xxxxxxxxxxxxxxx> Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx> --- lib/x86/pmu.c | 3 ++- x86/pmu.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/x86/pmu.c b/lib/x86/pmu.c index d37c874c..92707698 100644 --- a/lib/x86/pmu.c +++ b/lib/x86/pmu.c @@ -21,7 +21,8 @@ void pmu_init(void) pmu.arch_event_mask_length = (cpuid_10.a >> 24) & 0xff; /* CPUID.0xA.EBX bit is '1' if an arch event is NOT available. */ - pmu.arch_event_available = ~cpuid_10.b; + pmu.arch_event_available = ~cpuid_10.b & + (BIT(pmu.arch_event_mask_length) - 1); if (this_cpu_has(X86_FEATURE_PDCM)) pmu.perf_cap = rdmsr(MSR_IA32_PERF_CAPABILITIES); diff --git a/x86/pmu.c b/x86/pmu.c index e79122ed..3987311c 100644 --- a/x86/pmu.c +++ b/x86/pmu.c @@ -993,6 +993,7 @@ int main(int ac, char **av) printf("GP counters: %d\n", pmu.nr_gp_counters); printf("GP counter width: %d\n", pmu.gp_counter_width); printf("Event Mask length: %d\n", pmu.arch_event_mask_length); + printf("Arch Events (mask): 0x%x\n", pmu.arch_event_available); printf("Fixed counters: %d\n", pmu.nr_fixed_counters); printf("Fixed counter width: %d\n", pmu.fixed_counter_width); -- 2.50.0.rc0.642.g800a2b2222-goog