For AMD cacheinfo, use parsed CPUID(0x80000006) instead of issuing a direct
CPUID query.
Beside the CPUID parser centralization benefits, this allows using the
auto-generated x86-cpuid-db data types, and their C99 bitfields, instead of
doing ugly bitwise operations on CPUID output.
For enumerating L3 cache availability, check if CPUID(0x80000006).EDX
l3_assoc output is not zero. Per AMD manuals, an L3 associativity of zero
implies the absence of a CPU L3 cache.
Since cpuid_amd_hygon_has_l3_cache() is now using the CPUID parser APIs,
move its definition under the section: "Convenience leaf-specific functions
(using parsed CPUID)."
Signed-off-by: Ahmed S. Darwish <darwi@linutronix.de>
---
arch/x86/include/asm/cpuid/api.h | 20 +++++++++++---------
arch/x86/kernel/amd_nb.c | 3 ++-
arch/x86/kernel/cpu/cacheinfo.c | 6 +++---
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/arch/x86/include/asm/cpuid/api.h b/arch/x86/include/asm/cpuid/api.h
index f4bdfe3c9325..611ee8596115 100644
--- a/arch/x86/include/asm/cpuid/api.h
+++ b/arch/x86/include/asm/cpuid/api.h
@@ -212,15 +212,6 @@ static inline u32 cpuid_base_hypervisor(const char *sig, u32 leaves)
return 0;
}
-/*
- * CPUID(0x80000006) parsing:
- */
-
-static inline bool cpuid_amd_hygon_has_l3_cache(void)
-{
- return cpuid_edx(0x80000006);
-}
-
/*
* 'struct cpuid_leaves' accessors (without sanity checks):
*
@@ -502,6 +493,17 @@ static inline bool cpuid_amd_hygon_has_l3_cache(void)
_ptr < &((const union leaf_0x2_regs *)(_regs))->desc[16] && (_desc = &cpuid_0x2_table[*_ptr]);\
_ptr++)
+/*
+ * CPUID(0x80000006)
+ */
+
+static inline bool cpuid_amd_hygon_has_l3_cache(struct cpuinfo_x86 *c)
+{
+ const struct leaf_0x80000006_0 *el6 = cpuid_leaf(c, 0x80000006);
+
+ return el6 && el6->l3_assoc;
+}
+
/*
* CPUID parser exported APIs:
*/
diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c
index 5d364540673d..06ebbd564945 100644
--- a/arch/x86/kernel/amd_nb.c
+++ b/arch/x86/kernel/amd_nb.c
@@ -16,6 +16,7 @@
#include <asm/amd/nb.h>
#include <asm/cpuid/api.h>
+#include <asm/processor.h>
static u32 *flush_words;
@@ -93,7 +94,7 @@ static int amd_cache_northbridges(void)
if (amd_gart_present())
amd_northbridges.flags |= AMD_NB_GART;
- if (!cpuid_amd_hygon_has_l3_cache())
+ if (!cpuid_amd_hygon_has_l3_cache(&boot_cpu_data))
return 0;
/*
diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinfo.c
index 7dab0d7152cc..3e40bcca1c3b 100644
--- a/arch/x86/kernel/cpu/cacheinfo.c
+++ b/arch/x86/kernel/cpu/cacheinfo.c
@@ -235,7 +235,7 @@ static unsigned int get_cache_id(u32 apicid, const struct _cpuid4_info *id4)
void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, u16 die_id)
{
- if (!cpuid_amd_hygon_has_l3_cache())
+ if (!cpuid_amd_hygon_has_l3_cache(c))
return;
if (c->x86 < 0x17) {
@@ -262,7 +262,7 @@ void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, u16 die_id)
void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c)
{
- if (!cpuid_amd_hygon_has_l3_cache())
+ if (!cpuid_amd_hygon_has_l3_cache(c))
return;
/*
@@ -280,7 +280,7 @@ void init_amd_cacheinfo(struct cpuinfo_x86 *c)
if (boot_cpu_has(X86_FEATURE_TOPOEXT))
ci->num_leaves = cpuid_subleaf_count(c, 0x8000001d);
else if (el6)
- ci->num_leaves = (el6->l3_assoc) ? 4 : 3;
+ ci->num_leaves = cpuid_amd_hygon_has_l3_cache(c) ? 4 : 3;
}
void init_hygon_cacheinfo(struct cpuinfo_x86 *c)
--
2.53.0