Commit 6c963c42 authored by Ahmed S. Darwish's avatar Ahmed S. Darwish Committed by Ingo Molnar
Browse files

x86/cacheinfo: Introduce cpuid_amd_hygon_has_l3_cache()



Multiple code paths at cacheinfo.c and amd_nb.c check for AMD/Hygon CPUs
L3 cache presensce by directly checking leaf 0x80000006 EDX output.

Extract that logic into its own function.  While at it, rework the
AMD/Hygon LLC topology ID caclculation comments for clarity.

Signed-off-by: default avatarAhmed S. Darwish <darwi@linutronix.de>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/20250324133324.23458-29-darwi@linutronix.de
parent eeeebc4f
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -207,4 +207,13 @@ static inline u32 hypervisor_cpuid_base(const char *sig, u32 leaves)
	return 0;
}

/*
 * CPUID(0x80000006) parsing helpers
 */

static inline bool cpuid_amd_hygon_has_l3_cache(void)
{
	return cpuid_edx(0x80000006);
}

#endif /* _ASM_X86_CPUID_API_H */
+3 −4
Original line number Diff line number Diff line
@@ -13,7 +13,9 @@
#include <linux/export.h>
#include <linux/spinlock.h>
#include <linux/pci_ids.h>

#include <asm/amd_nb.h>
#include <asm/cpuid.h>

static u32 *flush_words;

@@ -91,10 +93,7 @@ static int amd_cache_northbridges(void)
	if (amd_gart_present())
		amd_northbridges.flags |= AMD_NB_GART;

	/*
	 * Check for L3 cache presence.
	 */
	if (!cpuid_edx(0x80000006))
	if (!cpuid_amd_hygon_has_l3_cache())
		return 0;

	/*
+14 −18
Original line number Diff line number Diff line
@@ -281,29 +281,29 @@ static int find_num_cache_leaves(struct cpuinfo_x86 *c)
	return i;
}

void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, u16 die_id)
{
/*
	 * We may have multiple LLCs if L3 caches exist, so check if we
	 * have an L3 cache by looking at the L3 cache CPUID leaf.
 * AMD/Hygon CPUs may have multiple LLCs if L3 caches exist.
 */
	if (!cpuid_edx(0x80000006))

void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, u16 die_id)
{
	if (!cpuid_amd_hygon_has_l3_cache())
		return;

	if (c->x86 < 0x17) {
		/* LLC is at the node level. */
		/* Pre-Zen: LLC is at the node level */
		c->topo.llc_id = die_id;
	} else if (c->x86 == 0x17 && c->x86_model <= 0x1F) {
		/*
		 * LLC is at the core complex level.
		 * Core complex ID is ApicId[3] for these processors.
		 * Family 17h up to 1F models: LLC is at the core
		 * complex level.  Core complex ID is ApicId[3].
		 */
		c->topo.llc_id = c->topo.apicid >> 3;
	} else {
		/*
		 * LLC ID is calculated from the number of threads sharing the
		 * cache.
		 * */
		 * Newer families: LLC ID is calculated from the number
		 * of threads sharing the L3 cache.
		 */
		u32 eax, ebx, ecx, edx, num_sharing_cache = 0;
		u32 llc_index = find_num_cache_leaves(c) - 1;

@@ -321,16 +321,12 @@ void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, u16 die_id)

void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c)
{
	/*
	 * We may have multiple LLCs if L3 caches exist, so check if we
	 * have an L3 cache by looking at the L3 cache CPUID leaf.
	 */
	if (!cpuid_edx(0x80000006))
	if (!cpuid_amd_hygon_has_l3_cache())
		return;

	/*
	 * LLC is at the core complex level.
	 * Core complex ID is ApicId[3] for these processors.
	 * Hygons are similar to AMD Family 17h up to 1F models: LLC is
	 * at the core complex level.  Core complex ID is ApicId[3].
	 */
	c->topo.llc_id = c->topo.apicid >> 3;
}