[tip: x86/cpu] x86/cacheinfo: Properly parse CPUID(0x80000006) L2/L3 associativity

"tip-bot2 for Ahmed S. Darwish" <[email protected]>
Newsgroups dev.linux.lists.x86-cpuid,org.kernel.vger.linux-kernel
Message-ID <174422761319.31282.4153060826522358872.tip-bot2@tip-bot2>
The following commit has been merged into the x86/cpu branch of tip:

Commit-ID:     d02c83d75f9f76dda046edbd9f39b911427677c9
Gitweb:        https://git.kernel.org/tip/d02c83d75f9f76dda046edbd9f39b911427677c9
Author:        Ahmed S. Darwish <[email protected]>
AuthorDate:    Wed, 09 Apr 2025 14:22:31 +02:00
Committer:     Ingo Molnar <[email protected]>
CommitterDate: Wed, 09 Apr 2025 20:47:05 +02:00

x86/cacheinfo: Properly parse CPUID(0x80000006) L2/L3 associativity

Complete the AMD CPUID(4) emulation logic, which uses CPUID(0x80000006)
for L2/L3 cache info and an assocs[] associativity mapping array, by
adding entries for 3-way caches and 6-way caches.

Properly handle the case where CPUID(0x80000006) returns an L2/L3
associativity of 9.  This is not real associativity, but a marker to
indicate that the respective L2/L3 cache information should be retrieved
from CPUID(0x8000001d) instead.  If such a marker is encountered, return
early from legacy_amd_cpuid4(), thus effectively emulating an "invalid
index" CPUID(4) response with a cache type of zero.

When checking if CPUID(0x80000006) L2/L3 cache info output is valid, and
given the associtivity marker 9 above, do not just check if the whole
ECX/EDX register is zero.  Rather, check if the associativity is zero or
9.  An associativity of zero implies no L2/L3 cache, which make it the
more correct check anyway vs. a zero check of the whole output register.

Fixes: a326e948c538 ("x86, cacheinfo: Fixup L3 cache information for AMD multi-node processors")
Signed-off-by: Ahmed S. Darwish <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
Cc: Andrew Cooper <[email protected]>
Cc: "H. Peter Anvin" <[email protected]>
Cc: John Ogness <[email protected]>
Cc: [email protected]
Link: https://lore.kernel.org/r/[email protected]
---
 arch/x86/kernel/cpu/cacheinfo.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinfo.c
index f4817cd..52727f8 100644
--- a/arch/x86/kernel/cpu/cacheinfo.c
+++ b/arch/x86/kernel/cpu/cacheinfo.c
@@ -89,9 +89,13 @@ static const enum cache_type cache_type_map[] = {
 /*
  * Fallback AMD CPUID(4) emulation
  * AMD CPUs with TOPOEXT can just use CPUID(0x8000001d)
+ *
+ * @AMD_L2_L3_INVALID_ASSOC: cache info for the respective L2/L3 cache should
+ * be determined from CPUID(0x8000001d) instead of CPUID(0x80000006).
  */
 
 #define AMD_CPUID4_FULLY_ASSOCIATIVE	0xffff
+#define AMD_L2_L3_INVALID_ASSOC		0x9
 
 union l1_cache {
 	struct {
@@ -128,7 +132,9 @@ union l3_cache {
 static const unsigned short assocs[] = {
 	[1]		= 1,
 	[2]		= 2,
+	[3]		= 3,
 	[4]		= 4,
+	[5]		= 6,
 	[6]		= 8,
 	[8]		= 16,
 	[0xa]		= 32,
@@ -172,7 +178,7 @@ static void legacy_amd_cpuid4(int index, union _cpuid4_leaf_eax *eax,
 		size_in_kb	= l1->size_in_kb;
 		break;
 	case 2:
-		if (!l2.val)
+		if (!l2.assoc || l2.assoc == AMD_L2_L3_INVALID_ASSOC)
 			return;
 
 		/* Use x86_cache_size as it might have K7 errata fixes */
@@ -182,7 +188,7 @@ static void legacy_amd_cpuid4(int index, union _cpuid4_leaf_eax *eax,
 		size_in_kb	= __this_cpu_read(cpu_info.x86_cache_size);
 		break;
 	case 3:
-		if (!l3.val)
+		if (!l3.assoc || l3.assoc == AMD_L2_L3_INVALID_ASSOC)
 			return;
 
 		assoc		= assocs[l3.assoc];
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.