]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
x86/cpu: Properly parse CPUID leaf 0x2 TLB descriptor 0x63
authorAhmed S. Darwish <darwi@linutronix.de>
Tue, 4 Mar 2025 08:51:14 +0000 (09:51 +0100)
committerIngo Molnar <mingo@kernel.org>
Tue, 4 Mar 2025 08:59:14 +0000 (09:59 +0100)
CPUID leaf 0x2's one-byte TLB descriptors report the number of entries
for specific TLB types, among other properties.

Typically, each emitted descriptor implies the same number of entries
for its respective TLB type(s).  An emitted 0x63 descriptor is an
exception: it implies 4 data TLB entries for 1GB pages and 32 data TLB
entries for 2MB or 4MB pages.

For the TLB descriptors parsing code, the entry count for 1GB pages is
encoded at the intel_tlb_table[] mapping, but the 2MB/4MB entry count is
totally ignored.

Update leaf 0x2's parsing logic 0x2 to account for 32 data TLB entries
for 2MB/4MB pages implied by the 0x63 descriptor.

Fixes: e0ba94f14f74 ("x86/tlb_info: get last level TLB entry number of CPU")
Signed-off-by: Ahmed S. Darwish <darwi@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: stable@kernel.org
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/20250304085152.51092-4-darwi@linutronix.de
arch/x86/kernel/cpu/intel.c

index 2a3716afee6336d32fce9154cac465938e0348eb..134368a3f4b1e50c3d06255e5d07663eacfc3637 100644 (file)
@@ -635,26 +635,37 @@ static unsigned int intel_size_cache(struct cpuinfo_x86 *c, unsigned int size)
 }
 #endif
 
-#define TLB_INST_4K    0x01
-#define TLB_INST_4M    0x02
-#define TLB_INST_2M_4M 0x03
+#define TLB_INST_4K            0x01
+#define TLB_INST_4M            0x02
+#define TLB_INST_2M_4M         0x03
 
-#define TLB_INST_ALL   0x05
-#define TLB_INST_1G    0x06
+#define TLB_INST_ALL           0x05
+#define TLB_INST_1G            0x06
 
-#define TLB_DATA_4K    0x11
-#define TLB_DATA_4M    0x12
-#define TLB_DATA_2M_4M 0x13
-#define TLB_DATA_4K_4M 0x14
+#define TLB_DATA_4K            0x11
+#define TLB_DATA_4M            0x12
+#define TLB_DATA_2M_4M         0x13
+#define TLB_DATA_4K_4M         0x14
 
-#define TLB_DATA_1G    0x16
+#define TLB_DATA_1G            0x16
+#define TLB_DATA_1G_2M_4M      0x17
 
-#define TLB_DATA0_4K   0x21
-#define TLB_DATA0_4M   0x22
-#define TLB_DATA0_2M_4M        0x23
+#define TLB_DATA0_4K           0x21
+#define TLB_DATA0_4M           0x22
+#define TLB_DATA0_2M_4M                0x23
 
-#define STLB_4K                0x41
-#define STLB_4K_2M     0x42
+#define STLB_4K                        0x41
+#define STLB_4K_2M             0x42
+
+/*
+ * All of leaf 0x2's one-byte TLB descriptors implies the same number of
+ * entries for their respective TLB types.  The 0x63 descriptor is an
+ * exception: it implies 4 dTLB entries for 1GB pages 32 dTLB entries
+ * for 2MB or 4MB pages.  Encode descriptor 0x63 dTLB entry count for
+ * 2MB/4MB pages here, as its count for dTLB 1GB pages is already at the
+ * intel_tlb_table[] mapping.
+ */
+#define TLB_0x63_2M_4M_ENTRIES 32
 
 static const struct _tlb_table intel_tlb_table[] = {
        { 0x01, TLB_INST_4K,            32,     " TLB_INST 4 KByte pages, 4-way set associative" },
@@ -676,7 +687,8 @@ static const struct _tlb_table intel_tlb_table[] = {
        { 0x5c, TLB_DATA_4K_4M,         128,    " TLB_DATA 4 KByte and 4 MByte pages" },
        { 0x5d, TLB_DATA_4K_4M,         256,    " TLB_DATA 4 KByte and 4 MByte pages" },
        { 0x61, TLB_INST_4K,            48,     " TLB_INST 4 KByte pages, full associative" },
-       { 0x63, TLB_DATA_1G,            4,      " TLB_DATA 1 GByte pages, 4-way set associative" },
+       { 0x63, TLB_DATA_1G_2M_4M,      4,      " TLB_DATA 1 GByte pages, 4-way set associative"
+                                               " (plus 32 entries TLB_DATA 2 MByte or 4 MByte pages, not encoded here)" },
        { 0x6b, TLB_DATA_4K,            256,    " TLB_DATA 4 KByte pages, 8-way associative" },
        { 0x6c, TLB_DATA_2M_4M,         128,    " TLB_DATA 2 MByte or 4 MByte pages, 8-way associative" },
        { 0x6d, TLB_DATA_1G,            16,     " TLB_DATA 1 GByte pages, fully associative" },
@@ -776,6 +788,12 @@ static void intel_tlb_lookup(const unsigned char desc)
                if (tlb_lld_4m[ENTRIES] < intel_tlb_table[k].entries)
                        tlb_lld_4m[ENTRIES] = intel_tlb_table[k].entries;
                break;
+       case TLB_DATA_1G_2M_4M:
+               if (tlb_lld_2m[ENTRIES] < TLB_0x63_2M_4M_ENTRIES)
+                       tlb_lld_2m[ENTRIES] = TLB_0x63_2M_4M_ENTRIES;
+               if (tlb_lld_4m[ENTRIES] < TLB_0x63_2M_4M_ENTRIES)
+                       tlb_lld_4m[ENTRIES] = TLB_0x63_2M_4M_ENTRIES;
+               fallthrough;
        case TLB_DATA_1G:
                if (tlb_lld_1g[ENTRIES] < intel_tlb_table[k].entries)
                        tlb_lld_1g[ENTRIES] = intel_tlb_table[k].entries;