* [PATCH] x86/CPU/AMD: Fix Zen5 TLB sizes reporting
@ 2026-08-21 2:20 Borislav Petkov
2026-08-21 4:51 ` Borislav Petkov
2026-08-23 20:30 ` kernel test robot
0 siblings, 2 replies; 4+ messages in thread
From: Borislav Petkov @ 2026-08-21 2:20 UTC (permalink / raw)
To: X86; +Cc: LKML, Borislav Petkov (AMD)
From: "Borislav Petkov (AMD)" <bp@alien8.de>
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) <bp@alien8.de>
---
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..4fe158fb8e6e 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;
n = c->extended_cpuid_level;
@@ -875,9 +875,11 @@ void cpu_detect_cache_sizes(struct cpuinfo_x86 *c)
cpuid(0x80000006, &dummy, &ebx, &ecx, &edx);
l2size = ecx >> 16;
+ shift = !!cpu_has(c, X86_FEATURE_L2_TLB_SIZE_X32) * 5;
#ifdef CONFIG_X86_64
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
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] x86/CPU/AMD: Fix Zen5 TLB sizes reporting
2026-08-21 2:20 [PATCH] x86/CPU/AMD: Fix Zen5 TLB sizes reporting Borislav Petkov
@ 2026-08-21 4:51 ` Borislav Petkov
2026-08-23 20:30 ` kernel test robot
1 sibling, 0 replies; 4+ messages in thread
From: Borislav Petkov @ 2026-08-21 4:51 UTC (permalink / raw)
To: Borislav Petkov; +Cc: X86, LKML
On Thu, Aug 20, 2026 at 07:20:31PM -0700, Borislav Petkov wrote:
> 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;
Sashiko says:
| Could this shift operation overflow the target variables?
| The variables tlb_lld_4k and tlb_lli_4k are defined globally as u16.
| The architectural maximum raw value for the CPUID mask is 4095. When
| shifted by 5 for the new X32 encoding, this yields up to 131040, which
| exceeds the 65535 maximum capacity of a u16 variable.
| While current Zen 5 CPUs might report smaller values that fit safely,
| future CPUs returning larger raw values could be truncated.
I say, sure, let's get there first. More than 65K TLB entries - that would be
cheap TLB design when it comes to power... /eyeroll.
I'll gladly touch that bunch of u16s then.
> @@ -875,9 +875,11 @@ void cpu_detect_cache_sizes(struct cpuinfo_x86 *c)
>
> cpuid(0x80000006, &dummy, &ebx, &ecx, &edx);
> l2size = ecx >> 16;
> + shift = !!cpu_has(c, X86_FEATURE_L2_TLB_SIZE_X32) * 5;
>
> #ifdef CONFIG_X86_64
> c->x86_tlbsize += ((ebx >> 16) & 0xfff) + (ebx & 0xfff);
> + c->x86_tlbsize <<= shift;
> #else
Sashiko says:
| Will this trigger a compiler warning on 32-bit builds?
| The shift variable is assigned unconditionally here, but its only usage
| is bounded by the CONFIG_X86_64 block just below it. On targets
| where CONFIG_X86_64 is not set, shift is written to but never read.
Sure, fixed.
Thx.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] x86/CPU/AMD: Fix Zen5 TLB sizes reporting
2026-08-21 2:20 [PATCH] x86/CPU/AMD: Fix Zen5 TLB sizes reporting Borislav Petkov
2026-08-21 4:51 ` Borislav Petkov
@ 2026-08-23 20:30 ` kernel test robot
2026-08-23 20:39 ` Borislav Petkov
1 sibling, 1 reply; 4+ messages in thread
From: kernel test robot @ 2026-08-23 20:30 UTC (permalink / raw)
To: Borislav Petkov, X86; +Cc: oe-kbuild-all, LKML, Borislav Petkov (AMD)
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/202608240450.3JNf2siz-lkp@intel.com/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/202608240450.3JNf2siz-lkp@intel.com/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 <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202608240450.3JNf2siz-lkp@intel.com/
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;
| ^~~~~
vim +/shift +860 arch/x86/kernel/cpu/common.c
857
858 void cpu_detect_cache_sizes(struct cpuinfo_x86 *c)
859 {
> 860 unsigned int n, dummy, ebx, ecx, edx, l2size, shift;
861
862 n = c->extended_cpuid_level;
863
864 if (n >= 0x80000005) {
865 cpuid(0x80000005, &dummy, &ebx, &ecx, &edx);
866 c->x86_cache_size = (ecx>>24) + (edx>>24);
867 #ifdef CONFIG_X86_64
868 /* On K8 L1 TLB is inclusive, so don't count it */
869 c->x86_tlbsize = 0;
870 #endif
871 }
872
873 if (n < 0x80000006) /* Some chips just has a large L1. */
874 return;
875
876 cpuid(0x80000006, &dummy, &ebx, &ecx, &edx);
877 l2size = ecx >> 16;
878 shift = !!cpu_has(c, X86_FEATURE_L2_TLB_SIZE_X32) * 5;
879
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] x86/CPU/AMD: Fix Zen5 TLB sizes reporting
2026-08-23 20:30 ` kernel test robot
@ 2026-08-23 20:39 ` Borislav Petkov
0 siblings, 0 replies; 4+ messages in thread
From: Borislav Petkov @ 2026-08-23 20:39 UTC (permalink / raw)
To: kernel test robot; +Cc: Borislav Petkov, X86, oe-kbuild-all, LKML
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/202608240450.3JNf2siz-lkp@intel.com/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/202608240450.3JNf2siz-lkp@intel.com/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 <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202608240450.3JNf2siz-lkp@intel.com/
>
> 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)" <bp@alien8.de>
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) <bp@alien8.de>
---
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
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-08-23 20:46 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-21 2:20 [PATCH] x86/CPU/AMD: Fix Zen5 TLB sizes reporting Borislav Petkov
2026-08-21 4:51 ` Borislav Petkov
2026-08-23 20:30 ` kernel test robot
2026-08-23 20:39 ` Borislav Petkov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®