]>
Commit | Line | Data |
---|---|---|
162e698d GKH |
1 | From 32c3233885eb10ac9cb9410f2f8cd64b8df2b2a1 Mon Sep 17 00:00:00 2001 |
2 | From: Andreas Herrmann <andreas.herrmann3@amd.com> | |
3 | Date: Wed, 8 Feb 2012 20:52:29 +0100 | |
4 | Subject: x86/amd: Fix L1i and L2 cache sharing information for AMD family 15h processors | |
5 | ||
6 | From: Andreas Herrmann <andreas.herrmann3@amd.com> | |
7 | ||
8 | commit 32c3233885eb10ac9cb9410f2f8cd64b8df2b2a1 upstream. | |
9 | ||
10 | For L1 instruction cache and L2 cache the shared CPU information | |
11 | is wrong. On current AMD family 15h CPUs those caches are shared | |
12 | between both cores of a compute unit. | |
13 | ||
14 | This fixes https://bugzilla.kernel.org/show_bug.cgi?id=42607 | |
15 | ||
16 | Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com> | |
17 | Cc: Petkov Borislav <Borislav.Petkov@amd.com> | |
18 | Cc: Dave Jones <davej@redhat.com> | |
19 | Link: http://lkml.kernel.org/r/20120208195229.GA17523@alberich.amd.com | |
20 | Signed-off-by: Ingo Molnar <mingo@elte.hu> | |
21 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
22 | ||
23 | --- | |
24 | arch/x86/kernel/cpu/intel_cacheinfo.c | 44 +++++++++++++++++++++++++++------- | |
25 | 1 file changed, 36 insertions(+), 8 deletions(-) | |
26 | ||
27 | --- a/arch/x86/kernel/cpu/intel_cacheinfo.c | |
28 | +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c | |
29 | @@ -330,8 +330,7 @@ static void __cpuinit amd_calc_l3_indice | |
30 | l3->indices = (max(max3(sc0, sc1, sc2), sc3) << 10) - 1; | |
31 | } | |
32 | ||
33 | -static void __cpuinit amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, | |
34 | - int index) | |
35 | +static void __cpuinit amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, int index) | |
36 | { | |
37 | static struct amd_l3_cache *__cpuinitdata l3_caches; | |
38 | int node; | |
39 | @@ -748,14 +747,16 @@ static DEFINE_PER_CPU(struct _cpuid4_inf | |
40 | #define CPUID4_INFO_IDX(x, y) (&((per_cpu(ici_cpuid4_info, x))[y])) | |
41 | ||
42 | #ifdef CONFIG_SMP | |
43 | -static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) | |
44 | + | |
45 | +static int __cpuinit cache_shared_amd_cpu_map_setup(unsigned int cpu, int index) | |
46 | { | |
47 | - struct _cpuid4_info *this_leaf, *sibling_leaf; | |
48 | - unsigned long num_threads_sharing; | |
49 | - int index_msb, i, sibling; | |
50 | + struct _cpuid4_info *this_leaf; | |
51 | + int ret, i, sibling; | |
52 | struct cpuinfo_x86 *c = &cpu_data(cpu); | |
53 | ||
54 | - if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) { | |
55 | + ret = 0; | |
56 | + if (index == 3) { | |
57 | + ret = 1; | |
58 | for_each_cpu(i, cpu_llc_shared_mask(cpu)) { | |
59 | if (!per_cpu(ici_cpuid4_info, i)) | |
60 | continue; | |
61 | @@ -766,8 +767,35 @@ static void __cpuinit cache_shared_cpu_m | |
62 | set_bit(sibling, this_leaf->shared_cpu_map); | |
63 | } | |
64 | } | |
65 | - return; | |
66 | + } else if ((c->x86 == 0x15) && ((index == 1) || (index == 2))) { | |
67 | + ret = 1; | |
68 | + for_each_cpu(i, cpu_sibling_mask(cpu)) { | |
69 | + if (!per_cpu(ici_cpuid4_info, i)) | |
70 | + continue; | |
71 | + this_leaf = CPUID4_INFO_IDX(i, index); | |
72 | + for_each_cpu(sibling, cpu_sibling_mask(cpu)) { | |
73 | + if (!cpu_online(sibling)) | |
74 | + continue; | |
75 | + set_bit(sibling, this_leaf->shared_cpu_map); | |
76 | + } | |
77 | + } | |
78 | } | |
79 | + | |
80 | + return ret; | |
81 | +} | |
82 | + | |
83 | +static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) | |
84 | +{ | |
85 | + struct _cpuid4_info *this_leaf, *sibling_leaf; | |
86 | + unsigned long num_threads_sharing; | |
87 | + int index_msb, i; | |
88 | + struct cpuinfo_x86 *c = &cpu_data(cpu); | |
89 | + | |
90 | + if (c->x86_vendor == X86_VENDOR_AMD) { | |
91 | + if (cache_shared_amd_cpu_map_setup(cpu, index)) | |
92 | + return; | |
93 | + } | |
94 | + | |
95 | this_leaf = CPUID4_INFO_IDX(cpu, index); | |
96 | num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing; | |
97 |