From: "Ahmed S. Darwish" <darwi@linutronix.de>
To: Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
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>,
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 v1 23/26] x86/cacheinfo: Use scanned CPUID(0x80000005) and CPUID(0x80000006)
Date: Tue, 6 May 2025 07:04:34 +0200 [thread overview]
Message-ID: <20250506050437.10264-24-darwi@linutronix.de> (raw)
In-Reply-To: <20250506050437.10264-1-darwi@linutronix.de>
For the AMD CPUID(0x4)-emulation logic, use scanned CPUID(0x80000005) and
CPUID(0x80000006) access instead of direct CPUID queries.
Beside centralizing CPUID access, this allows using the auto-generated
<cpuid/leaves.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 = cpudata_cpuid(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 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 e0b130e592dc..5966ca50d601 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 = cpudata_cpuid(c, 0x80000005);
+ const struct leaf_0x80000006_0 *el6 = cpudata_cpuid(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 *)cpudata_cpuid_index(c, 0x8000001d, index);
else
- legacy_amd_cpuid4(index, ®s);
+ legacy_amd_cpuid4(c, index, ®s);
return cpuid4_info_fill_done(id4, ®s);
}
@@ -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 = cpudata_cpuid_nr_entries(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) ?
+ cpudata_cpuid_nr_entries(c, 0x8000001d) :
+ cpudata_cpuid(c, 0x80000006)->l3_assoc ? 4 : 3;
}
void init_hygon_cacheinfo(struct cpuinfo_x86 *c)
--
2.49.0
next prev parent reply other threads:[~2025-05-06 5:05 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-06 5:04 [PATCH v1 00/26] x86: Introduce centralized CPUID model Ahmed S. Darwish
2025-05-06 5:04 ` [PATCH v1 01/26] tools/x86/kcpuid: Update bitfields to x86-cpuid-db v2.4 Ahmed S. Darwish
2025-05-06 8:06 ` [tip: x86/cpu] " tip-bot2 for Ahmed S. Darwish
2025-05-06 5:04 ` [PATCH v1 02/26] x86/cpu: Sanitize CPUID(0x80000000) output Ahmed S. Darwish
2025-05-06 8:15 ` [tip: x86/cpu] " tip-bot2 for Ahmed S. Darwish
2025-05-07 8:50 ` [PATCH v1 02/26] " Andrew Cooper
2025-05-08 20:40 ` H. Peter Anvin
2025-05-08 20:58 ` Andrew Cooper
2025-05-08 22:37 ` H. Peter Anvin
2025-05-09 9:23 ` Ahmed S. Darwish (dev)
2025-05-06 5:04 ` [PATCH v1 03/26] x86/cpuid: Introduce <asm/cpuid/leaves.h> Ahmed S. Darwish
2025-05-06 5:04 ` [PATCH v1 04/26] x86/cpuid: Introduce centralized CPUID data Ahmed S. Darwish
2025-05-14 4:18 ` Sohil Mehta
2025-05-15 21:23 ` Ahmed S. Darwish
2025-05-15 22:12 ` Sohil Mehta
2025-05-06 5:04 ` [PATCH v1 05/26] x86/cpuid: Introduce CPUID scanner Ahmed S. Darwish
2025-05-06 5:04 ` [PATCH v1 06/26] x86/cpuid: Scan CPUID(0x80000000) Ahmed S. Darwish
2025-05-06 5:04 ` [PATCH v1 07/26] x86/cpuid: Introduce debugfs 'x86/scanned_cpuid/[0-ncpus]' Ahmed S. Darwish
2025-05-14 2:56 ` Sohil Mehta
2025-05-15 21:04 ` Ahmed S. Darwish
2025-05-06 5:04 ` [PATCH v1 08/26] x86/cpuid: Introduce external CPUID table accessors Ahmed S. Darwish
2025-05-06 5:04 ` [PATCH v1 09/26] x86/cpu: Use scanned CPUID(0x0) Ahmed S. Darwish
2025-05-06 5:04 ` [PATCH v1 10/26] x86/cpu: Use scanned CPUID(0x80000001) Ahmed S. Darwish
2025-05-06 5:04 ` [PATCH v1 11/26] x86/lib: Add CPUID(0x1) CPU family and model calculation Ahmed S. Darwish
2025-05-06 5:04 ` [PATCH v1 12/26] x86/cpu: Use scanned CPUID(0x1) Ahmed S. Darwish
2025-05-06 8:25 ` Ingo Molnar
2025-05-07 7:36 ` Ahmed S. Darwish
2025-05-06 5:04 ` [PATCH v1 13/26] x86/cpuid: Scan CPUID(0x2) Ahmed S. Darwish
2025-05-06 8:16 ` Ingo Molnar
2025-05-06 8:47 ` Ahmed S. Darwish
2025-05-06 10:39 ` Ingo Molnar
2025-05-06 5:04 ` [PATCH v1 14/26] x86/cpuid: Introduce scanned CPUID(0x2) API Ahmed S. Darwish
2025-05-06 5:04 ` [PATCH v1 15/26] x86/cpu: Use scanned CPUID(0x2) Ahmed S. Darwish
2025-05-06 5:04 ` [PATCH v1 16/26] x86/cacheinfo: " Ahmed S. Darwish
2025-05-06 5:04 ` [PATCH v1 17/26] x86/cpuid: Remove direct CPUID(0x2) query API Ahmed S. Darwish
2025-05-06 8:59 ` Ingo Molnar
2025-05-07 9:15 ` Ahmed S. Darwish
2025-05-06 5:04 ` [PATCH v1 18/26] x86/cpuid: Scan deterministic cache params CPUID leaves Ahmed S. Darwish
2025-05-06 5:04 ` [PATCH v1 19/26] x86/cacheinfo: Use scanned CPUID(0x4) Ahmed S. Darwish
2025-05-06 8:10 ` Ingo Molnar
2025-05-06 8:50 ` Ahmed S. Darwish
2025-05-06 5:04 ` [PATCH v1 20/26] x86/cacheinfo: Use scanned CPUID(0x8000001d) Ahmed S. Darwish
2025-05-06 5:04 ` [PATCH v1 21/26] x86/cpuid: Scan CPUID(0x80000005) and CPUID(0x80000006) Ahmed S. Darwish
2025-05-06 5:04 ` [PATCH v1 22/26] x86/cacheinfo: Use auto-generated data types Ahmed S. Darwish
2025-05-06 5:04 ` Ahmed S. Darwish [this message]
2025-05-06 5:04 ` [PATCH v1 24/26] x86/cpuid: scanner: Add CPUID table rescan support Ahmed S. Darwish
2025-05-06 5:04 ` [PATCH v1 25/26] x86/cpu: Rescan CPUID table after PSN disable Ahmed S. Darwish
2025-05-06 5:04 ` [PATCH v1 26/26] x86/cpu: Rescan CPUID table after unlocking the full CPUID range Ahmed S. Darwish
2025-05-06 8:23 ` [PATCH v1 00/26] x86: Introduce centralized CPUID model Ingo Molnar
2025-05-06 8:48 ` Ahmed S. Darwish
2025-05-06 9:12 ` Ingo Molnar
2025-05-07 8:35 ` Ahmed S. Darwish
2025-05-07 8:45 ` Ahmed S. Darwish
2025-05-07 9:32 ` Ahmed S. Darwish
2025-05-09 9:28 ` Ahmed S. Darwish (dev)
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=20250506050437.10264-24-darwi@linutronix.de \
--to=darwi@linutronix.de \
--cc=andrew.cooper3@citrix.com \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=john.ogness@linutronix.de \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.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®