]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
perf/x86/intel: Fix ARCH_PERFMON_NUM_COUNTER_LEAF
authorKan Liang <kan.liang@linux.intel.com>
Wed, 29 Jan 2025 15:48:19 +0000 (07:48 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 27 Feb 2025 12:10:53 +0000 (04:10 -0800)
commit 47a973fd75639fe80d59f9e1860113bb2a0b112b upstream.

The EAX of the CPUID Leaf 023H enumerates the mask of valid sub-leaves.
To tell the availability of the sub-leaf 1 (enumerate the counter mask),
perf should check the bit 1 (0x2) of EAS, rather than bit 0 (0x1).

The error is not user-visible on bare metal. Because the sub-leaf 0 and
the sub-leaf 1 are always available. However, it may bring issues in a
virtualization environment when a VMM only enumerates the sub-leaf 0.

Introduce the cpuid35_e?x to replace the macros, which makes the
implementation style consistent.

Fixes: eb467aaac21e ("perf/x86/intel: Support Architectural PerfMon Extension leaf")
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: stable@vger.kernel.org
Link: https://lkml.kernel.org/r/20250129154820.3755948-3-kan.liang@linux.intel.com
[ The patch is not exactly the same as the upstream patch. Because in the 6.6
  stable kernel, the umask2/eq enumeration is not supported. The number of
  counters is used rather than the counter mask. But the change is
  straightforward, which utilizes the structured union to replace the macros
  when parsing the CPUID enumeration. It also fixed a wrong macros. ]
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/events/intel/core.c
arch/x86/include/asm/perf_event.h

index df286789c94f188169797c50e0f5c0ef798f1c80..61ac094e26bd78a741327f9e08e65d14fb49c917 100644 (file)
@@ -4643,16 +4643,19 @@ static void intel_pmu_check_num_counters(int *num_counters,
 
 static void update_pmu_cap(struct x86_hybrid_pmu *pmu)
 {
-       unsigned int sub_bitmaps = cpuid_eax(ARCH_PERFMON_EXT_LEAF);
-       unsigned int eax, ebx, ecx, edx;
+       unsigned int cntr, fixed_cntr, ecx, edx;
+       union cpuid35_eax eax;
+       union cpuid35_ebx ebx;
 
-       if (sub_bitmaps & ARCH_PERFMON_NUM_COUNTER_LEAF_BIT) {
+       cpuid(ARCH_PERFMON_EXT_LEAF, &eax.full, &ebx.full, &ecx, &edx);
+
+       if (eax.split.cntr_subleaf) {
                cpuid_count(ARCH_PERFMON_EXT_LEAF, ARCH_PERFMON_NUM_COUNTER_LEAF,
-                           &eax, &ebx, &ecx, &edx);
-               pmu->num_counters = fls(eax);
-               pmu->num_counters_fixed = fls(ebx);
+                           &cntr, &fixed_cntr, &ecx, &edx);
+               pmu->num_counters = fls(cntr);
+               pmu->num_counters_fixed = fls(fixed_cntr);
                intel_pmu_check_num_counters(&pmu->num_counters, &pmu->num_counters_fixed,
-                                            &pmu->intel_ctrl, ebx);
+                                            &pmu->intel_ctrl, fixed_cntr);
        }
 }
 
index 85a9fd5a3ec33176ff3e2dd96aae915136f47864..384e8a7db4827be48c0db95377ec077b70e47bc6 100644 (file)
@@ -177,9 +177,33 @@ union cpuid10_edx {
  * detection/enumeration details:
  */
 #define ARCH_PERFMON_EXT_LEAF                  0x00000023
-#define ARCH_PERFMON_NUM_COUNTER_LEAF_BIT      0x1
 #define ARCH_PERFMON_NUM_COUNTER_LEAF          0x1
 
+union cpuid35_eax {
+       struct {
+               unsigned int    leaf0:1;
+               /* Counters Sub-Leaf */
+               unsigned int    cntr_subleaf:1;
+               /* Auto Counter Reload Sub-Leaf */
+               unsigned int    acr_subleaf:1;
+               /* Events Sub-Leaf */
+               unsigned int    events_subleaf:1;
+               unsigned int    reserved:28;
+       } split;
+       unsigned int            full;
+};
+
+union cpuid35_ebx {
+       struct {
+               /* UnitMask2 Supported */
+               unsigned int    umask2:1;
+               /* EQ-bit Supported */
+               unsigned int    eq:1;
+               unsigned int    reserved:30;
+       } split;
+       unsigned int            full;
+};
+
 /*
  * Intel Architectural LBR CPUID detection/enumeration details:
  */