Commit 32c32338 authored by Andreas Herrmann's avatar Andreas Herrmann Committed by Ingo Molnar

x86/amd: Fix L1i and L2 cache sharing information for AMD family 15h processors

For L1 instruction cache and L2 cache the shared CPU information
is wrong. On current AMD family 15h CPUs those caches are shared
between both cores of a compute unit.

This fixes https://bugzilla.kernel.org/show_bug.cgi?id=42607Signed-off-by: default avatarAndreas Herrmann <andreas.herrmann3@amd.com>
Cc: Petkov Borislav <Borislav.Petkov@amd.com>
Cc: Dave Jones <davej@redhat.com>
Cc: <stable@kernel.org>
Link: http://lkml.kernel.org/r/20120208195229.GA17523@alberich.amd.comSigned-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent c1d2f1bc
...@@ -326,8 +326,7 @@ static void __cpuinit amd_calc_l3_indices(struct amd_northbridge *nb) ...@@ -326,8 +326,7 @@ static void __cpuinit amd_calc_l3_indices(struct amd_northbridge *nb)
l3->indices = (max(max3(sc0, sc1, sc2), sc3) << 10) - 1; l3->indices = (max(max3(sc0, sc1, sc2), sc3) << 10) - 1;
} }
static void __cpuinit amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, static void __cpuinit amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, int index)
int index)
{ {
int node; int node;
...@@ -725,14 +724,16 @@ static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info); ...@@ -725,14 +724,16 @@ static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info);
#define CPUID4_INFO_IDX(x, y) (&((per_cpu(ici_cpuid4_info, x))[y])) #define CPUID4_INFO_IDX(x, y) (&((per_cpu(ici_cpuid4_info, x))[y]))
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
static int __cpuinit cache_shared_amd_cpu_map_setup(unsigned int cpu, int index)
{ {
struct _cpuid4_info *this_leaf, *sibling_leaf; struct _cpuid4_info *this_leaf;
unsigned long num_threads_sharing; int ret, i, sibling;
int index_msb, i, sibling;
struct cpuinfo_x86 *c = &cpu_data(cpu); struct cpuinfo_x86 *c = &cpu_data(cpu);
if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) { ret = 0;
if (index == 3) {
ret = 1;
for_each_cpu(i, cpu_llc_shared_mask(cpu)) { for_each_cpu(i, cpu_llc_shared_mask(cpu)) {
if (!per_cpu(ici_cpuid4_info, i)) if (!per_cpu(ici_cpuid4_info, i))
continue; continue;
...@@ -743,8 +744,35 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) ...@@ -743,8 +744,35 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
set_bit(sibling, this_leaf->shared_cpu_map); set_bit(sibling, this_leaf->shared_cpu_map);
} }
} }
} else if ((c->x86 == 0x15) && ((index == 1) || (index == 2))) {
ret = 1;
for_each_cpu(i, cpu_sibling_mask(cpu)) {
if (!per_cpu(ici_cpuid4_info, i))
continue;
this_leaf = CPUID4_INFO_IDX(i, index);
for_each_cpu(sibling, cpu_sibling_mask(cpu)) {
if (!cpu_online(sibling))
continue;
set_bit(sibling, this_leaf->shared_cpu_map);
}
}
}
return ret;
}
static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
{
struct _cpuid4_info *this_leaf, *sibling_leaf;
unsigned long num_threads_sharing;
int index_msb, i;
struct cpuinfo_x86 *c = &cpu_data(cpu);
if (c->x86_vendor == X86_VENDOR_AMD) {
if (cache_shared_amd_cpu_map_setup(cpu, index))
return; return;
} }
this_leaf = CPUID4_INFO_IDX(cpu, index); this_leaf = CPUID4_INFO_IDX(cpu, index);
num_threads_sharing = 1 + this_leaf->base.eax.split.num_threads_sharing; num_threads_sharing = 1 + this_leaf->base.eax.split.num_threads_sharing;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment