Commit f6bdaab7 authored by Ahmed S. Darwish's avatar Ahmed S. Darwish Committed by Ingo Molnar
Browse files

x86/cpu: Properly parse CPUID leaf 0x2 TLB descriptor 0x63



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: e0ba94f1 ("x86/tlb_info: get last level TLB entry number of CPU")
Signed-off-by: default avatarAhmed S. Darwish <darwi@linutronix.de>
Signed-off-by: default avatarIngo 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
parent 18811482
Loading
Loading
Loading
Loading
+34 −16
Original line number Diff line number Diff line
@@ -648,6 +648,7 @@ static unsigned int intel_size_cache(struct cpuinfo_x86 *c, unsigned int size)
#define TLB_DATA_4K_4M		0x14

#define TLB_DATA_1G		0x16
#define TLB_DATA_1G_2M_4M	0x17

#define TLB_DATA0_4K		0x21
#define TLB_DATA0_4M		0x22
@@ -656,6 +657,16 @@ static unsigned int intel_size_cache(struct cpuinfo_x86 *c, unsigned int size)
#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" },
	{ 0x02, TLB_INST_4M,		2,	" TLB_INST 4 MByte pages, full 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;