[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250905121515.192792-27-darwi@linutronix.de>
Date: Fri, 5 Sep 2025 14:15:06 +0200
From: "Ahmed S. Darwish" <darwi@...utronix.de>
To: Borislav Petkov <bp@...en8.de>,
Ingo Molnar <mingo@...hat.com>,
Dave Hansen <dave.hansen@...ux.intel.com>
Cc: Thomas Gleixner <tglx@...utronix.de>,
Andrew Cooper <andrew.cooper3@...rix.com>,
Sean Christopherson <seanjc@...gle.com>,
David Woodhouse <dwmw2@...radead.org>,
"H. Peter Anvin" <hpa@...or.com>,
Peter Zijlstra <peterz@...radead.org>,
Sohil Mehta <sohil.mehta@...el.com>,
John Ogness <john.ogness@...utronix.de>,
x86@...nel.org,
x86-cpuid@...ts.linux.dev,
LKML <linux-kernel@...r.kernel.org>,
"Ahmed S. Darwish" <darwi@...utronix.de>
Subject: [PATCH v5 26/35] x86/cacheinfo: Use parsed CPUID(0x4)
For the Intel cacheinfo code, use parsed CPUID(0x4) access instead of a
direct CPUID query.
Use the parsed CPUID API:
cpuid_subleaf_count(c, 0x4)
to determine the number of CPUID(0x4) cache subleaves instead of calling
find_num_cache_leaves(), which uses direct CPUID(0x4) queries.
Since find_num_cache_leaves() is no longer needed for Intel code paths,
make it AMD-specific:
- Rename it to amd_find_num_cache_leaves()
- Remove its Intel CPUID(0x4) logic
Adjust the AMD code paths accordingly.
At intel_cacheinfo_0x4(), remove the max CPUID level check since
cpuid_subleaf_count(c, 0x4) will safely return zero if CPUID(0x4) is not
supported by the CPU.
Signed-off-by: Ahmed S. Darwish <darwi@...utronix.de>
---
arch/x86/kernel/cpu/cacheinfo.c | 40 ++++++++++++++-------------------
1 file changed, 17 insertions(+), 23 deletions(-)
diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinfo.c
index f6b093dd8416..76fa3a01a34b 100644
--- a/arch/x86/kernel/cpu/cacheinfo.c
+++ b/arch/x86/kernel/cpu/cacheinfo.c
@@ -252,16 +252,17 @@ static int amd_fill_cpuid4_info(int index, struct _cpuid4_info *id4)
return cpuid4_info_fill_done(id4, eax, ebx, ecx);
}
-static int intel_fill_cpuid4_info(struct cpuinfo_x86 *unused, int index, struct _cpuid4_info *id4)
+static int intel_fill_cpuid4_info(struct cpuinfo_x86 *c, int index, struct _cpuid4_info *id4)
{
- union _cpuid4_leaf_eax eax;
- union _cpuid4_leaf_ebx ebx;
- union _cpuid4_leaf_ecx ecx;
- u32 ignored;
+ const struct cpuid_regs *regs = cpuid_subleaf_n_raw(c, 0x4, index);
- cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &ignored);
+ if (!regs)
+ return -EIO;
- return cpuid4_info_fill_done(id4, eax, ebx, ecx);
+ return cpuid4_info_fill_done(id4,
+ (union _cpuid4_leaf_eax)(regs->eax),
+ (union _cpuid4_leaf_ebx)(regs->ebx),
+ (union _cpuid4_leaf_ecx)(regs->ecx));
}
static int fill_cpuid4_info(struct cpuinfo_x86 *c, int index, struct _cpuid4_info *id4)
@@ -273,17 +274,16 @@ static int fill_cpuid4_info(struct cpuinfo_x86 *c, int index, struct _cpuid4_inf
intel_fill_cpuid4_info(c, index, id4);
}
-static int find_num_cache_leaves(struct cpuinfo_x86 *c)
+static int amd_find_num_cache_leaves(struct cpuinfo_x86 *c)
{
- unsigned int eax, ebx, ecx, edx, op;
union _cpuid4_leaf_eax cache_eax;
+ unsigned int eax, ebx, ecx, edx;
int i = -1;
- /* Do a CPUID(op) loop to calculate num_cache_leaves */
- op = (c->x86_vendor == X86_VENDOR_AMD || c->x86_vendor == X86_VENDOR_HYGON) ? 0x8000001d : 4;
+ /* Do a CPUID(0x8000001d) loop to calculate num_cache_leaves */
do {
++i;
- cpuid_count(op, i, &eax, &ebx, &ecx, &edx);
+ cpuid_count(0x8000001d, i, &eax, &ebx, &ecx, &edx);
cache_eax.full = eax;
} while (cache_eax.split.type != CTYPE_NULL);
return i;
@@ -328,7 +328,7 @@ void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, u16 die_id)
* Newer families: LLC ID is calculated from the number
* of threads sharing the L3 cache.
*/
- u32 llc_index = find_num_cache_leaves(c) - 1;
+ u32 llc_index = amd_find_num_cache_leaves(c) - 1;
struct _cpuid4_info id4 = {};
if (!amd_fill_cpuid4_info(llc_index, &id4))
@@ -353,7 +353,7 @@ 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 = find_num_cache_leaves(c);
+ ci->num_leaves = amd_find_num_cache_leaves(c);
else if (c->extended_cpuid_level >= 0x80000006)
ci->num_leaves = (cpuid_edx(0x80000006) & 0xf000) ? 4 : 3;
}
@@ -362,7 +362,7 @@ void init_hygon_cacheinfo(struct cpuinfo_x86 *c)
{
struct cpu_cacheinfo *ci = get_cpu_cacheinfo(c->cpu_index);
- ci->num_leaves = find_num_cache_leaves(c);
+ ci->num_leaves = amd_find_num_cache_leaves(c);
}
static void intel_cacheinfo_done(struct cpuinfo_x86 *c, unsigned int l3,
@@ -426,15 +426,9 @@ static bool intel_cacheinfo_0x4(struct cpuinfo_x86 *c)
unsigned int l2_id = BAD_APICID, l3_id = BAD_APICID;
unsigned int l1d = 0, l1i = 0, l2 = 0, l3 = 0;
- if (c->cpuid_level < 4)
- return false;
-
- /*
- * There should be at least one leaf. A non-zero value means
- * that the number of leaves has been previously initialized.
- */
+ /* Non-zero means that it has been previously initialized */
if (!ci->num_leaves)
- ci->num_leaves = find_num_cache_leaves(c);
+ ci->num_leaves = cpuid_subleaf_count(c, 0x4);
if (!ci->num_leaves)
return false;
--
2.50.1
Powered by blists - more mailing lists