mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Ahmed S. Darwish" <darwi@linutronix.de>
To: Borislav Petkov <bp@alien8.de>, Ingo Molnar <mingo@redhat.com>,
	Dave Hansen <dave.hansen@linux.intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>,
	Andrew Cooper <andrew.cooper3@citrix.com>,
	"H. Peter Anvin" <hpa@zytor.com>,
	David Woodhouse <dwmw2@infradead.org>,
	Sean Christopherson <seanjc@google.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Sohil Mehta <sohil.mehta@intel.com>,
	John Ogness <john.ogness@linutronix.de>,
	x86@kernel.org, x86-cpuid@lists.linux.dev,
	LKML <linux-kernel@vger.kernel.org>,
	"Ahmed S. Darwish" <darwi@linutronix.de>
Subject: [PATCH v4 28/34] x86/cacheinfo: Use parsed CPUID(0x80000005) and CPUID(0x80000006)
Date: Fri, 15 Aug 2025 09:02:21 +0200	[thread overview]
Message-ID: <20250815070227.19981-29-darwi@linutronix.de> (raw)
In-Reply-To: <20250815070227.19981-1-darwi@linutronix.de>

For the AMD CPUID(0x4)-emulation logic, use parsed CPUID(0x80000005) and
CPUID(0x80000006) APID access instead of invoking direct CPUID queries.

Beside centralizing CPUID access, this allows using the auto-generated
<cpuid/leaf_types.h> 'struct leaf_0x80000005_0' and 'struct
leaf_0x80000006_0' data types.

Remove the 'union {l1,l2,l3}_cache' definitions as they are no longer
needed.

Note, the expression:

    ci->num_leaves = (cpuid_edx(0x80000006) & 0xf000) ? 4 : 3;

is replaced with:

    ci->num_leaves = cpuid_leaf(c, 0x80000006)->l3_assoc ? 4 : 3;

which is the same logic, since the 'l3_assoc' bitfield is 4 bits wide at
EDX offset 12.  Per AMD manuals, an L3 associativity of zero implies the
absence of an L3 cache on the CPU.

While at it, separate the 'Fallback AMD CPUID(0x4) emulation' comment
from the '@AMD_L2_L3_INVALID_ASSOC' one, since the former acts as a
source code section header.

Signed-off-by: Ahmed S. Darwish <darwi@linutronix.de>
---
 arch/x86/kernel/cpu/cacheinfo.c | 105 ++++++++++++--------------------
 1 file changed, 40 insertions(+), 65 deletions(-)

diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinfo.c
index f0540cba4bd4..de8e7125eedd 100644
--- a/arch/x86/kernel/cpu/cacheinfo.c
+++ b/arch/x86/kernel/cpu/cacheinfo.c
@@ -56,47 +56,17 @@ static const enum cache_type cache_type_map[] = {
 };
 
 /*
- * Fallback AMD CPUID(0x4) emulation
+ * Fallback AMD CPUID(0x4) 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 {
-		unsigned line_size	:8;
-		unsigned lines_per_tag	:8;
-		unsigned assoc		:8;
-		unsigned size_in_kb	:8;
-	};
-	unsigned int val;
-};
-
-union l2_cache {
-	struct {
-		unsigned line_size	:8;
-		unsigned lines_per_tag	:4;
-		unsigned assoc		:4;
-		unsigned size_in_kb	:16;
-	};
-	unsigned int val;
-};
-
-union l3_cache {
-	struct {
-		unsigned line_size	:8;
-		unsigned lines_per_tag	:4;
-		unsigned assoc		:4;
-		unsigned res		:2;
-		unsigned size_encoded	:14;
-	};
-	unsigned int val;
-};
-
 /* L2/L3 associativity mapping */
 static const unsigned short assocs[] = {
 	[1]		= 1,
@@ -117,50 +87,52 @@ static const unsigned short assocs[] = {
 static const unsigned char levels[] = { 1, 1, 2, 3 };
 static const unsigned char types[]  = { 1, 2, 3, 3 };
 
-static void legacy_amd_cpuid4(int index, struct leaf_0x4_0 *regs)
+static void legacy_amd_cpuid4(struct cpuinfo_x86 *c, int index, struct leaf_0x4_0 *regs)
 {
-	unsigned int dummy, line_size, lines_per_tag, assoc, size_in_kb;
-	union l1_cache l1i, l1d, *l1;
-	union l2_cache l2;
-	union l3_cache l3;
+	const struct leaf_0x80000005_0 *el5 = cpuid_leaf(c, 0x80000005);
+	const struct leaf_0x80000006_0 *el6 = cpuid_leaf(c, 0x80000006);
+	const struct cpuid_regs *el5_raw = (const struct cpuid_regs *)el5;
+	unsigned int line_size, lines_per_tag, assoc, size_in_kb;
 
 	*regs = (struct leaf_0x4_0){ };
 
-	cpuid(0x80000005, &dummy, &dummy, &l1d.val, &l1i.val);
-	cpuid(0x80000006, &dummy, &dummy, &l2.val, &l3.val);
-
-	l1 = &l1d;
 	switch (index) {
-	case 1:
-		l1 = &l1i;
-		fallthrough;
 	case 0:
-		if (!l1->val)
+		if (!el5 || !el5_raw->ecx)
 			return;
 
-		assoc		= (l1->assoc == 0xff) ? AMD_CPUID4_FULLY_ASSOCIATIVE : l1->assoc;
-		line_size	= l1->line_size;
-		lines_per_tag	= l1->lines_per_tag;
-		size_in_kb	= l1->size_in_kb;
+		assoc		= el5->l1_dcache_assoc;
+		line_size	= el5->l1_dcache_line_size;
+		lines_per_tag	= el5->l1_dcache_nlines;
+		size_in_kb	= el5->l1_dcache_size_kb;
+		break;
+	case 1:
+		if (!el5 || !el5_raw->edx)
+			return;
+
+		assoc		= el5->l1_icache_assoc;
+		line_size	= el5->l1_icache_line_size;
+		lines_per_tag	= el5->l1_icache_nlines;
+		size_in_kb	= el5->l1_icache_size_kb;
 		break;
 	case 2:
-		if (!l2.assoc || l2.assoc == AMD_L2_L3_INVALID_ASSOC)
+		if (!el6 || !el6->l2_assoc || el6->l2_assoc == AMD_L2_L3_INVALID_ASSOC)
 			return;
 
 		/* Use x86_cache_size as it might have K7 errata fixes */
-		assoc		= assocs[l2.assoc];
-		line_size	= l2.line_size;
-		lines_per_tag	= l2.lines_per_tag;
+		assoc		= assocs[el6->l2_assoc];
+		line_size	= el6->l2_line_size;
+		lines_per_tag	= el6->l2_nlines;
 		size_in_kb	= __this_cpu_read(cpu_info.x86_cache_size);
 		break;
 	case 3:
-		if (!l3.assoc || l3.assoc == AMD_L2_L3_INVALID_ASSOC)
+		if (!el6 || !el6->l3_assoc || el6->l3_assoc == AMD_L2_L3_INVALID_ASSOC)
 			return;
 
-		assoc		= assocs[l3.assoc];
-		line_size	= l3.line_size;
-		lines_per_tag	= l3.lines_per_tag;
-		size_in_kb	= l3.size_encoded * 512;
+		assoc		= assocs[el6->l3_assoc];
+		line_size	= el6->l3_line_size;
+		lines_per_tag	= el6->l3_nlines;
+		size_in_kb	= el6->l3_size_range * 512;
 		if (boot_cpu_has(X86_FEATURE_AMD_DCM)) {
 			size_in_kb	= size_in_kb >> 1;
 			assoc		= assoc >> 1;
@@ -170,6 +142,10 @@ static void legacy_amd_cpuid4(int index, struct leaf_0x4_0 *regs)
 		return;
 	}
 
+	/* For L1d and L1i caches, 0xff is the full associativity marker */
+	if ((index == 0 || index == 1) && assoc == 0xff)
+		assoc = AMD_CPUID4_FULLY_ASSOCIATIVE;
+
 	regs->cache_self_init		= 1;
 	regs->cache_type		= types[index];
 	regs->cache_level		= levels[index];
@@ -207,7 +183,7 @@ static int amd_fill_cpuid4_info(struct cpuinfo_x86 *c, int index, struct _cpuid4
 	if (boot_cpu_has(X86_FEATURE_TOPOEXT) || boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
 		regs = *(struct leaf_0x4_0 *)cpuid_subleaf_index(c, 0x8000001d, index);
 	else
-		legacy_amd_cpuid4(index, &regs);
+		legacy_amd_cpuid4(c, index, &regs);
 
 	return cpuid4_info_fill_done(id4, &regs);
 }
@@ -279,10 +255,9 @@ void init_amd_cacheinfo(struct cpuinfo_x86 *c)
 {
 	struct cpu_cacheinfo *ci = get_cpu_cacheinfo(c->cpu_index);
 
-	if (boot_cpu_has(X86_FEATURE_TOPOEXT))
-		ci->num_leaves = cpuid_subleaf_count(c, 0x8000001d);
-	else if (c->extended_cpuid_level >= 0x80000006)
-		ci->num_leaves = (cpuid_edx(0x80000006) & 0xf000) ? 4 : 3;
+	ci->num_leaves = boot_cpu_has(X86_FEATURE_TOPOEXT) ?
+		cpuid_subleaf_count(c, 0x8000001d) :
+		cpuid_leaf(c, 0x80000006)->l3_assoc ? 4 : 3;
 }
 
 void init_hygon_cacheinfo(struct cpuinfo_x86 *c)
-- 
2.50.1


  parent reply	other threads:[~2025-08-15  7:06 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-15  7:01 [PATCH v4 00/34] x86: Introduce a centralized CPUID data model Ahmed S. Darwish
2025-08-15  7:01 ` [PATCH v4 01/34] x86/cpuid: Remove transitional <asm/cpuid.h> header Ahmed S. Darwish
2025-08-15 10:11   ` [tip: x86/urgent] " tip-bot2 for Ahmed S. Darwish
2025-08-15 15:22   ` tip-bot2 for Ahmed S. Darwish
2025-08-15  7:01 ` [PATCH v4 02/34] ASoC: Intel: avs: Include CPUID header at file scope Ahmed S. Darwish
2025-08-18 14:56   ` Borislav Petkov
2025-08-18 15:14     ` Ahmed S. Darwish
2025-08-15  7:01 ` [PATCH v4 03/34] treewide: Explicitly include the x86 CPUID headers Ahmed S. Darwish
2025-08-15  7:01 ` [PATCH v4 04/34] x86/cpu: <asm/processor.h>: Do not include the CPUID API header Ahmed S. Darwish
2025-08-15  7:01 ` [PATCH v4 05/34] x86/cpuid: Rename cpuid_leaf()/cpuid_subleaf() APIs Ahmed S. Darwish
2025-08-15  7:01 ` [PATCH v4 06/34] x86/cpuid: Introduce <asm/cpuid/leaf_types.h> Ahmed S. Darwish
2025-08-25 14:18   ` Borislav Petkov
2025-08-25 14:56     ` Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 07/34] x86/cpuid: Introduce a centralized CPUID data model Ahmed S. Darwish
2025-08-15 15:34   ` Sean Christopherson
2025-08-18 13:49     ` Ahmed S. Darwish
2025-08-18 18:44       ` Sean Christopherson
2025-08-18 19:54         ` Ahmed S. Darwish
2025-08-18 21:29           ` Sean Christopherson
2025-08-19 13:10             ` Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 08/34] x86/cpuid: Introduce a centralized CPUID parser Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 09/34] x86/cpu: Use parsed CPUID(0x0) Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 10/34] x86/lib: Add CPUID(0x1) CPU family and model calculation Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 11/34] x86/cpu: Use parsed CPUID(0x1) Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 12/34] x86/cpuid: Parse CPUID(0x80000000) Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 13/34] x86/cpu: Use parsed CPUID(0x80000000) Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 14/34] x86/cpuid: Introduce a CPUID leaf x86 vendor table Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 15/34] x86/cpuid: Introduce CPUID parser debugfs interface Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 16/34] x86/cpuid: Parse CPUID(0x2) Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 17/34] x86/cpuid: Warn once on invalid CPUID(0x2) iteration count Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 18/34] x86/cpuid: Introduce parsed CPUID(0x2) API Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 19/34] x86/cpu: Use parsed CPUID(0x2) Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 20/34] x86/cacheinfo: " Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 21/34] x86/cpuid: Remove direct CPUID(0x2) query API Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 22/34] x86/cpuid: Parse 'deterministic cache parameters' CPUID leaves Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 23/34] x86/cacheinfo: Pass a 'struct cpuinfo_x86' refrence to CPUID(0x4) code Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 24/34] x86/cacheinfo: Use parsed CPUID(0x4) Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 25/34] x86/cacheinfo: Use parsed CPUID(0x8000001d) Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 26/34] x86/cpuid: Parse CPUID(0x80000005) and CPUID(0x80000006) Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 27/34] x86/cacheinfo: Use auto-generated data types Ahmed S. Darwish
2025-08-15  7:02 ` Ahmed S. Darwish [this message]
2025-08-15 15:25   ` [PATCH v4 28/34] x86/cacheinfo: Use parsed CPUID(0x80000005) and CPUID(0x80000006) Dave Hansen
2025-08-18 15:38     ` Ahmed S. Darwish
2025-08-18 15:52     ` David Woodhouse
2025-08-18 17:00       ` Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 29/34] x86/amd_nb: Trickle down 'struct cpuinfo_x86' reference Ahmed S. Darwish
2025-08-18  2:54   ` kernel test robot
2025-08-18 14:47     ` Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 30/34] x86/cpuid: Use parsed CPUID(0x80000006) Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 31/34] x86/cpu: Rescan CPUID table after PSN disable Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 32/34] x86/cpu: Rescan CPUID table after unlocking full CPUID range Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 33/34] x86/cpuid: Parse CPUID(0x16) Ahmed S. Darwish
2025-08-15  7:02 ` [PATCH v4 34/34] x86/tsc: Use parsed CPUID(0x16) Ahmed S. Darwish
2025-08-16  9:59 ` [PATCH v4 00/34] x86: Introduce a centralized CPUID data model David Woodhouse
2025-08-18 16:37   ` Ahmed S. Darwish

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250815070227.19981-29-darwi@linutronix.de \
    --to=darwi@linutronix.de \
    --cc=andrew.cooper3@citrix.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=dwmw2@infradead.org \
    --cc=hpa@zytor.com \
    --cc=john.ogness@linutronix.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=seanjc@google.com \
    --cc=sohil.mehta@intel.com \
    --cc=tglx@linutronix.de \
    --cc=x86-cpuid@lists.linux.dev \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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®