]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/suse-2.6.27.39/patches.arch/x2APIC_PATCH_40_of_41_bbb65d2d365efe9951290e61678dcf81ec60add4
Add a patch to fix Intel E100 wake-on-lan problems.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.arch / x2APIC_PATCH_40_of_41_bbb65d2d365efe9951290e61678dcf81ec60add4
1 From: Suresh Siddha <suresh.b.siddha@intel.com>
2 Subject: x86: use cpuid vector 0xb when available for detecting cpu topology
3 References: fate #303948 and fate #303984
4 Patch-Mainline: queued for .28
5 Commit-ID: bbb65d2d365efe9951290e61678dcf81ec60add4
6
7 Signed-off-by: Thomas Renninger <trenn@suse.de>
8
9 cpuid leaf 0xb provides extended topology enumeration. This interface provides
10 the 32-bit x2APIC id of the logical processor and it also provides a new
11 mechanism to detect SMT and core siblings (which provides increased
12 addressability).
13
14 Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
15 Signed-off-by: Ingo Molnar <mingo@elte.hu>
16
17 ---
18 arch/x86/kernel/cpu/addon_cpuid_features.c | 86 +++++++++++++++++++++++++++++
19 arch/x86/kernel/cpu/common_64.c | 3 +
20 arch/x86/kernel/cpu/intel.c | 11 +++
21 arch/x86/kernel/cpu/intel_64.c | 5 +
22 include/asm-x86/cpufeature.h | 2
23 include/asm-x86/processor.h | 1
24 6 files changed, 105 insertions(+), 3 deletions(-)
25
26 --- a/arch/x86/kernel/cpu/addon_cpuid_features.c
27 +++ b/arch/x86/kernel/cpu/addon_cpuid_features.c
28 @@ -7,6 +7,8 @@
29 #include <asm/pat.h>
30 #include <asm/processor.h>
31
32 +#include <mach_apic.h>
33 +
34 struct cpuid_bit {
35 u16 feature;
36 u8 reg;
37 @@ -48,6 +50,90 @@ void __cpuinit init_scattered_cpuid_feat
38 }
39 }
40
41 +/* leaf 0xb SMT level */
42 +#define SMT_LEVEL 0
43 +
44 +/* leaf 0xb sub-leaf types */
45 +#define INVALID_TYPE 0
46 +#define SMT_TYPE 1
47 +#define CORE_TYPE 2
48 +
49 +#define LEAFB_SUBTYPE(ecx) (((ecx) >> 8) & 0xff)
50 +#define BITS_SHIFT_NEXT_LEVEL(eax) ((eax) & 0x1f)
51 +#define LEVEL_MAX_SIBLINGS(ebx) ((ebx) & 0xffff)
52 +
53 +/*
54 + * Check for extended topology enumeration cpuid leaf 0xb and if it
55 + * exists, use it for populating initial_apicid and cpu topology
56 + * detection.
57 + */
58 +void __cpuinit detect_extended_topology(struct cpuinfo_x86 *c)
59 +{
60 + unsigned int eax, ebx, ecx, edx, sub_index;
61 + unsigned int ht_mask_width, core_plus_mask_width;
62 + unsigned int core_select_mask, core_level_siblings;
63 +
64 + if (c->cpuid_level < 0xb)
65 + return;
66 +
67 + cpuid_count(0xb, SMT_LEVEL, &eax, &ebx, &ecx, &edx);
68 +
69 + /*
70 + * check if the cpuid leaf 0xb is actually implemented.
71 + */
72 + if (ebx == 0 || (LEAFB_SUBTYPE(ecx) != SMT_TYPE))
73 + return;
74 +
75 + set_cpu_cap(c, X86_FEATURE_XTOPOLOGY);
76 +
77 + /*
78 + * initial apic id, which also represents 32-bit extended x2apic id.
79 + */
80 + c->initial_apicid = edx;
81 +
82 + /*
83 + * Populate HT related information from sub-leaf level 0.
84 + */
85 + core_level_siblings = smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx);
86 + core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
87 +
88 + sub_index = 1;
89 + do {
90 + cpuid_count(0xb, sub_index, &eax, &ebx, &ecx, &edx);
91 +
92 + /*
93 + * Check for the Core type in the implemented sub leaves.
94 + */
95 + if (LEAFB_SUBTYPE(ecx) == CORE_TYPE) {
96 + core_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
97 + core_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
98 + break;
99 + }
100 +
101 + sub_index++;
102 + } while (LEAFB_SUBTYPE(ecx) != INVALID_TYPE);
103 +
104 + core_select_mask = (~(-1 << core_plus_mask_width)) >> ht_mask_width;
105 +
106 +#ifdef CONFIG_X86_32
107 + c->cpu_core_id = phys_pkg_id(c->initial_apicid, ht_mask_width)
108 + & core_select_mask;
109 + c->phys_proc_id = phys_pkg_id(c->initial_apicid, core_plus_mask_width);
110 +#else
111 + c->cpu_core_id = phys_pkg_id(ht_mask_width) & core_select_mask;
112 + c->phys_proc_id = phys_pkg_id(core_plus_mask_width);
113 +#endif
114 + c->x86_max_cores = (core_level_siblings / smp_num_siblings);
115 +
116 +
117 + printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
118 + c->phys_proc_id);
119 + if (c->x86_max_cores > 1)
120 + printk(KERN_INFO "CPU: Processor Core ID: %d\n",
121 + c->cpu_core_id);
122 + return;
123 +}
124 +
125 #ifdef CONFIG_X86_PAT
126 void __cpuinit validate_pat_support(struct cpuinfo_x86 *c)
127 {
128 --- a/arch/x86/kernel/cpu/common_64.c
129 +++ b/arch/x86/kernel/cpu/common_64.c
130 @@ -128,6 +128,9 @@ void __cpuinit detect_ht(struct cpuinfo_
131 u32 eax, ebx, ecx, edx;
132 int index_msb, core_bits;
133
134 + if (cpu_has(c, X86_FEATURE_XTOPOLOGY))
135 + return;
136 +
137 cpuid(1, &eax, &ebx, &ecx, &edx);
138
139
140 --- a/arch/x86/kernel/cpu/intel_64.c
141 +++ b/arch/x86/kernel/cpu/intel_64.c
142 @@ -93,7 +93,10 @@ static void __cpuinit init_intel(struct
143 if (c->x86 == 6)
144 set_cpu_cap(c, X86_FEATURE_REP_GOOD);
145 set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
146 - c->x86_max_cores = intel_num_cpu_cores(c);
147 +
148 + detect_extended_topology(c);
149 + if (!cpu_has(c, X86_FEATURE_XTOPOLOGY))
150 + c->x86_max_cores = intel_num_cpu_cores(c);
151
152 srat_detect_node();
153 }
154 --- a/arch/x86/kernel/cpu/intel.c
155 +++ b/arch/x86/kernel/cpu/intel.c
156 @@ -196,9 +196,16 @@ static void __cpuinit init_intel(struct
157 if (p)
158 strcpy(c->x86_model_id, p);
159
160 - c->x86_max_cores = num_cpu_cores(c);
161 + detect_extended_topology(c);
162
163 - detect_ht(c);
164 + if (!cpu_has(c, X86_FEATURE_XTOPOLOGY)) {
165 + /*
166 + * let's use the legacy cpuid vector 0x1 and 0x4 for topology
167 + * detection.
168 + */
169 + c->x86_max_cores = num_cpu_cores(c);
170 + detect_ht(c);
171 + }
172
173 /* Work around errata */
174 Intel_errata_workarounds(c);
175 --- a/include/asm-x86/cpufeature.h
176 +++ b/include/asm-x86/cpufeature.h
177 @@ -82,6 +82,8 @@
178 #define X86_FEATURE_11AP (3*32+19) /* Bad local APIC aka 11AP */
179 #define X86_FEATURE_NOPL (3*32+20) /* The NOPL (0F 1F) instructions */
180 #define X86_FEATURE_AMDC1E (3*32+21) /* AMD C1E detected */
181 +#define X86_FEATURE_XTOPOLOGY (3*32+22) /* cpu topology enum extensions */
182 +
183
184 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
185 #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */
186 --- a/include/asm-x86/processor.h
187 +++ b/include/asm-x86/processor.h
188 @@ -161,6 +161,7 @@ extern void init_scattered_cpuid_feature
189 extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
190 extern unsigned short num_cache_leaves;
191
192 +extern void detect_extended_topology(struct cpuinfo_x86 *c);
193 #if defined(CONFIG_X86_HT) || defined(CONFIG_X86_64)
194 extern void detect_ht(struct cpuinfo_x86 *c);
195 #else