[PATCH v1 2/2] x86/cacheinfo: Properly parse CPUID(0x80000006) L2/L3 associativity

"Ahmed S. Darwish" <[email protected]>
Newsgroups dev.linux.lists.x86-cpuid,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
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")
Cc: [email protected]
Signed-off-by: Ahmed S. Darwish <[email protected]>
---
 arch/x86/kernel/cpu/cacheinfo.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinfo.c
index 7a95e1ce73f8..038f819da20e 100644
--- a/arch/x86/kernel/cpu/cacheinfo.c
+++ b/arch/x86/kernel/cpu/cacheinfo.c
@@ -208,13 +208,20 @@ union l3_cache {
 	unsigned val;
 };
 
+/*
+ * 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
 
 /* L2/L3 associativity mapping */
 static const unsigned short assocs[] = {
 	[1] = 1,
 	[2] = 2,
+	[3] = 3,
 	[4] = 4,
+	[5] = 6,
 	[6] = 8,
 	[8] = 16,
 	[0xa] = 32,
@@ -267,7 +274,7 @@ amd_cpuid4(int leaf, 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;
 		assoc = assocs[l2.assoc];
 		line_size = l2.line_size;
@@ -276,7 +283,7 @@ amd_cpuid4(int leaf, 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];
 		line_size = l3.line_size;
-- 
2.49.0
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.