Re: [PATCH] x86/CPU/AMD: Fix Zen5 TLB sizes reporting

Borislav Petkov <[email protected]>
Newsgroups dev.linux.lists.oe-kbuild-all,org.kernel.vger.linux-kernel
Message-ID <20260823203934.GAaotahgOkTBg2eaBT@fat_crate.local>
On Mon, Aug 24, 2026 at 04:30:57AM +0800, kernel test robot wrote:
> Hi Borislav,
> 
> kernel test robot noticed the following build warnings:
> 
> [auto build test WARNING on tip/x86/core]
> [also build test WARNING on tip/master linus/master v7.2 next-20260821]
> [cannot apply to tip/auto-latest]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Borislav-Petkov/x86-CPU-AMD-Fix-Zen5-TLB-sizes-reporting/20260820-192031
> base:   tip/x86/core
> patch link:    https://lore.kernel.org/r/20260821022031.946311-1-bp%40kernel.org
> patch subject: [PATCH] x86/CPU/AMD: Fix Zen5 TLB sizes reporting
> config: i386-allmodconfig (https://download.01.org/0day-ci/archive/20260824/[email protected]/config)
> compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260824/[email protected]/reproduce)
> 
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <[email protected]>
> | Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
> 
> All warnings (new ones prefixed by >>):
> 
>    arch/x86/kernel/cpu/common.c: In function 'cpu_detect_cache_sizes':
> >> arch/x86/kernel/cpu/common.c:860:55: warning: variable 'shift' set but not used [-Wunused-but-set-variable]
>      860 |         unsigned int n, dummy, ebx, ecx, edx, l2size, shift;
>          |                                                       ^~~~~


Yah, AI caught it already, try this:

---
From: "Borislav Petkov (AMD)" <[email protected]>
Date: Thu, 20 Aug 2026 17:02:10 -0700
Subject: [PATCH] x86/CPU/AMD: Fix Zen5 TLB sizes reporting

Starting with Zen5, TLB sizes in CPUID_Fn80000006_E[AB]X are reported
as multiples of 32. There's a CPUID bit which determines that:

  CPUID_Fn80000021_EAX [Extended Feature 2 EAX] (Core::X86::Cpuid::FeatureExt2Eax)
  ...

  14: L2TlbSizeX32. Read-only. Reset: 1. Indicates that L2TLB sizes are encoded as multiples of 32.

Update the places which report that information.

With it, the numbers look correct now:

  -Last level iTLB entries: 4KB 64, 2MB 64, 4MB 32
  -Last level dTLB entries: 4KB 128, 2MB 128, 4MB 64, 1GB 0
  +Last level iTLB entries: 4KB 2048, 2MB 2048, 4MB 1024
  +Last level dTLB entries: 4KB 4096, 2MB 4096, 4MB 2048, 1GB 0

/proc/cpuinfo

  -TLB size        : 192 4K pages
  +TLB size        : 6144 4K pages

Signed-off-by: Borislav Petkov (AMD) <[email protected]>
---
 arch/x86/include/asm/cpufeatures.h |  2 ++
 arch/x86/kernel/cpu/amd.c          | 21 +++++++++++++--------
 arch/x86/kernel/cpu/common.c       |  4 +++-
 3 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 73d5c740202d..46937d15a95a 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -473,6 +473,8 @@
 #define X86_FEATURE_AUTOIBRS		(20*32+ 8) /* Automatic IBRS */
 #define X86_FEATURE_NO_SMM_CTL_MSR	(20*32+ 9) /* SMM_CTL MSR is not present */
 
+#define X86_FEATURE_L2_TLB_SIZE_X32	(20*32+14) /* L2 TLB sizes are encoded as multiples of 32 */
+
 #define X86_FEATURE_GP_ON_USER_CPUID	(20*32+17) /* User CPUID faulting */
 
 #define X86_FEATURE_PREFETCHI		(20*32+20) /* Prefetch Data/Instruction to Cache Level */
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 54e14ed276b5..e5279bc648d3 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -1192,7 +1192,7 @@ static unsigned int amd_size_cache(struct cpuinfo_x86 *c, unsigned int size)
 
 static void cpu_detect_tlb_amd(struct cpuinfo_x86 *c)
 {
-	u32 ebx, eax, ecx, edx;
+	u32 ebx, eax, ecx, edx, shift, tmp;
 	u16 mask = 0xfff;
 
 	if (c->x86 < 0xf)
@@ -1201,10 +1201,12 @@ static void cpu_detect_tlb_amd(struct cpuinfo_x86 *c)
 	if (c->extended_cpuid_level < 0x80000006)
 		return;
 
+	shift = !!cpu_has(c, X86_FEATURE_L2_TLB_SIZE_X32) * 5;
+
 	cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
 
-	tlb_lld_4k = (ebx >> 16) & mask;
-	tlb_lli_4k = ebx & mask;
+	tlb_lld_4k = ((ebx >> 16) & mask) << shift;
+	tlb_lli_4k = (ebx & mask) << shift;
 
 	/*
 	 * K8 doesn't have 2M/4M entries in the L2 TLB so read out the L1 TLB
@@ -1216,16 +1218,18 @@ static void cpu_detect_tlb_amd(struct cpuinfo_x86 *c)
 	}
 
 	/* Handle DTLB 2M and 4M sizes, fall back to L1 if L2 is disabled */
-	if (!((eax >> 16) & mask))
+	tmp = ((eax >> 16) & mask) << shift;
+	if (!tmp)
 		tlb_lld_2m = (cpuid_eax(0x80000005) >> 16) & 0xff;
 	else
-		tlb_lld_2m = (eax >> 16) & mask;
+		tlb_lld_2m = tmp;
 
 	/* a 4M entry uses two 2M entries */
 	tlb_lld_4m = tlb_lld_2m >> 1;
 
 	/* Handle ITLB 2M and 4M sizes, fall back to L1 if L2 is disabled */
-	if (!(eax & mask)) {
+	tmp = (eax & mask) << shift;
+	if (!tmp) {
 		/* Erratum 658 */
 		if (c->x86 == 0x15 && c->x86_model <= 0x1f) {
 			tlb_lli_2m = 1024;
@@ -1233,8 +1237,9 @@ static void cpu_detect_tlb_amd(struct cpuinfo_x86 *c)
 			cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
 			tlb_lli_2m = eax & 0xff;
 		}
-	} else
-		tlb_lli_2m = eax & mask;
+	} else {
+		tlb_lli_2m = tmp;
+	}
 
 	tlb_lli_4m = tlb_lli_2m >> 1;
 
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index c7352827f491..3716a6af13cb 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -857,7 +857,7 @@ static void get_model_name(struct cpuinfo_x86 *c)
 
 void cpu_detect_cache_sizes(struct cpuinfo_x86 *c)
 {
-	unsigned int n, dummy, ebx, ecx, edx, l2size;
+	unsigned int n, dummy, ebx, ecx, edx, l2size, shift __maybe_unused;
 
 	n = c->extended_cpuid_level;
 
@@ -877,7 +877,9 @@ void cpu_detect_cache_sizes(struct cpuinfo_x86 *c)
 	l2size = ecx >> 16;
 
 #ifdef CONFIG_X86_64
+	shift = !!cpu_has(c, X86_FEATURE_L2_TLB_SIZE_X32) * 5;
 	c->x86_tlbsize += ((ebx >> 16) & 0xfff) + (ebx & 0xfff);
+	c->x86_tlbsize <<= shift;
 #else
 	/* do processor-specific cache resizing */
 	if (this_cpu->legacy_cache_size)
-- 
2.53.0

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.