Skip to content

Commit 9677be0

Browse files
ricardonbp3tk0v
authored andcommitted
x86/cacheinfo: Delete global num_cache_leaves
Linux remembers cpu_cachinfo::num_leaves per CPU, but x86 initializes all CPUs from the same global "num_cache_leaves". This is erroneous on systems such as Meteor Lake, where each CPU has a distinct num_leaves value. Delete the global "num_cache_leaves" and initialize num_leaves on each CPU. init_cache_level() no longer needs to set num_leaves. Also, it never had to set num_levels as it is unnecessary in x86. Keep checking for zero cache leaves. Such condition indicates a bug. [ bp: Cleanup. ] Signed-off-by: Ricardo Neri <[email protected]> Signed-off-by: Borislav Petkov (AMD) <[email protected]> Cc: [email protected] # 6.3+ Link: https://lore.kernel.org/r/[email protected]
1 parent b3fce42 commit 9677be0

File tree

1 file changed

+21
-22
lines changed

1 file changed

+21
-22
lines changed

arch/x86/kernel/cpu/cacheinfo.c

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,6 @@ struct _cpuid4_info_regs {
178178
struct amd_northbridge *nb;
179179
};
180180

181-
static unsigned short num_cache_leaves;
182-
183181
/* AMD doesn't have CPUID4. Emulate it here to report the same
184182
information to the user. This makes some assumptions about the machine:
185183
L2 not shared, no SMT etc. that is currently true on AMD CPUs.
@@ -717,20 +715,23 @@ void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c)
717715

718716
void init_amd_cacheinfo(struct cpuinfo_x86 *c)
719717
{
718+
struct cpu_cacheinfo *ci = get_cpu_cacheinfo(c->cpu_index);
720719

721720
if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
722-
num_cache_leaves = find_num_cache_leaves(c);
721+
ci->num_leaves = find_num_cache_leaves(c);
723722
} else if (c->extended_cpuid_level >= 0x80000006) {
724723
if (cpuid_edx(0x80000006) & 0xf000)
725-
num_cache_leaves = 4;
724+
ci->num_leaves = 4;
726725
else
727-
num_cache_leaves = 3;
726+
ci->num_leaves = 3;
728727
}
729728
}
730729

731730
void init_hygon_cacheinfo(struct cpuinfo_x86 *c)
732731
{
733-
num_cache_leaves = find_num_cache_leaves(c);
732+
struct cpu_cacheinfo *ci = get_cpu_cacheinfo(c->cpu_index);
733+
734+
ci->num_leaves = find_num_cache_leaves(c);
734735
}
735736

736737
void init_intel_cacheinfo(struct cpuinfo_x86 *c)
@@ -740,21 +741,21 @@ void init_intel_cacheinfo(struct cpuinfo_x86 *c)
740741
unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
741742
unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
742743
unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
744+
struct cpu_cacheinfo *ci = get_cpu_cacheinfo(c->cpu_index);
743745

744746
if (c->cpuid_level > 3) {
745-
static int is_initialized;
746-
747-
if (is_initialized == 0) {
748-
/* Init num_cache_leaves from boot CPU */
749-
num_cache_leaves = find_num_cache_leaves(c);
750-
is_initialized++;
751-
}
747+
/*
748+
* There should be at least one leaf. A non-zero value means
749+
* that the number of leaves has been initialized.
750+
*/
751+
if (!ci->num_leaves)
752+
ci->num_leaves = find_num_cache_leaves(c);
752753

753754
/*
754755
* Whenever possible use cpuid(4), deterministic cache
755756
* parameters cpuid leaf to find the cache details
756757
*/
757-
for (i = 0; i < num_cache_leaves; i++) {
758+
for (i = 0; i < ci->num_leaves; i++) {
758759
struct _cpuid4_info_regs this_leaf = {};
759760
int retval;
760761

@@ -790,14 +791,14 @@ void init_intel_cacheinfo(struct cpuinfo_x86 *c)
790791
* Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for
791792
* trace cache
792793
*/
793-
if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
794+
if ((!ci->num_leaves || c->x86 == 15) && c->cpuid_level > 1) {
794795
/* supports eax=2 call */
795796
int j, n;
796797
unsigned int regs[4];
797798
unsigned char *dp = (unsigned char *)regs;
798799
int only_trace = 0;
799800

800-
if (num_cache_leaves != 0 && c->x86 == 15)
801+
if (ci->num_leaves && c->x86 == 15)
801802
only_trace = 1;
802803

803804
/* Number of times to iterate */
@@ -991,14 +992,12 @@ static void ci_leaf_init(struct cacheinfo *this_leaf,
991992

992993
int init_cache_level(unsigned int cpu)
993994
{
994-
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
995+
struct cpu_cacheinfo *ci = get_cpu_cacheinfo(cpu);
995996

996-
if (!num_cache_leaves)
997+
/* There should be at least one leaf. */
998+
if (!ci->num_leaves)
997999
return -ENOENT;
998-
if (!this_cpu_ci)
999-
return -EINVAL;
1000-
this_cpu_ci->num_levels = 3;
1001-
this_cpu_ci->num_leaves = num_cache_leaves;
1000+
10021001
return 0;
10031002
}
10041003

0 commit comments

Comments
 (0)