perf/x86/intel: Make anythread filter support conditional
authorStephane Eranian <eranian@google.com>
Wed, 28 Oct 2020 19:42:47 +0000 (12:42 -0700)
committerPeter Zijlstra <peterz@infradead.org>
Mon, 9 Nov 2020 17:12:36 +0000 (18:12 +0100)
Starting with Arch Perfmon v5, the anythread filter on generic counters may be
deprecated. The current kernel was exporting the any filter without checking.
On Icelake, it means you could do cpu/event=0x3c,any/ even though the filter
does not exist. This patch corrects the problem by relying on the CPUID 0xa leaf
function to determine if anythread is supported or not as described in the
Intel SDM Vol3b 18.2.5.1 AnyThread Deprecation section.

Signed-off-by: Stephane Eranian <eranian@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20201028194247.3160610-1-eranian@google.com
arch/x86/events/intel/core.c
arch/x86/events/perf_event.h
arch/x86/include/asm/perf_event.h
arch/x86/kvm/cpuid.c

index c37387c8212a21f021da999eae065d51f56a743d..af457f8cb29ddabda6bc5d15f717355f2d1c7bd0 100644 (file)
@@ -4987,6 +4987,12 @@ __init int intel_pmu_init(void)
 
        x86_add_quirk(intel_arch_events_quirk); /* Install first, so it runs last */
 
+       if (version >= 5) {
+               x86_pmu.intel_cap.anythread_deprecated = edx.split.anythread_deprecated;
+               if (x86_pmu.intel_cap.anythread_deprecated)
+                       pr_cont(" AnyThread deprecated, ");
+       }
+
        /*
         * Install the hw-cache-events table:
         */
@@ -5512,6 +5518,10 @@ __init int intel_pmu_init(void)
        x86_pmu.intel_ctrl |=
                ((1LL << x86_pmu.num_counters_fixed)-1) << INTEL_PMC_IDX_FIXED;
 
+       /* AnyThread may be deprecated on arch perfmon v5 or later */
+       if (x86_pmu.intel_cap.anythread_deprecated)
+               x86_pmu.format_attrs = intel_arch_formats_attr;
+
        if (x86_pmu.event_constraints) {
                /*
                 * event on fixed counter2 (REF_CYCLES) only works on this
index 1d1fe46552bac923b645dce9b1d28301f232cfab..6a8edfe59b09c94605b412aab5e2e01db346ded7 100644 (file)
@@ -585,6 +585,7 @@ union perf_capabilities {
                u64     pebs_baseline:1;
                u64     perf_metrics:1;
                u64     pebs_output_pt_available:1;
+               u64     anythread_deprecated:1;
        };
        u64     capabilities;
 };
index 6960cd6d1f2319e9245a027e290b6c9e53ef5e79..b9a7fd0a27e2d541fdcd63c004918080f8fe499e 100644 (file)
@@ -137,7 +137,9 @@ union cpuid10_edx {
        struct {
                unsigned int num_counters_fixed:5;
                unsigned int bit_width_fixed:8;
-               unsigned int reserved:19;
+               unsigned int reserved1:2;
+               unsigned int anythread_deprecated:1;
+               unsigned int reserved2:16;
        } split;
        unsigned int full;
 };
index 06a278b3701d127b7f7096f23091f69891467362..0752dec66e293790e876bf6dbbf20de8eb0b9621 100644 (file)
@@ -672,7 +672,9 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
 
                edx.split.num_counters_fixed = min(cap.num_counters_fixed, MAX_FIXED_COUNTERS);
                edx.split.bit_width_fixed = cap.bit_width_fixed;
-               edx.split.reserved = 0;
+               edx.split.anythread_deprecated = 1;
+               edx.split.reserved1 = 0;
+               edx.split.reserved2 = 0;
 
                entry->eax = eax.full;
                entry->ebx = cap.events_mask;