Commit 016281880439a8665ecf37514865742da58131d4
Exists in
master
and in
4 other branches
Merge branch 'x86-cpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-cpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86, cpu: Fix detection of Celeron Covington stepping A1 and B0 Documentation, ABI: Update L3 cache index disable text x86, AMD, cacheinfo: Fix L3 cache index disable checks x86, AMD, cacheinfo: Fix fallout caused by max3 conversion x86, cpu: Change NOP selection for certain Intel CPUs x86, cpu: Clean up and unify the NOP selection infrastructure x86, percpu: Use ASM_NOP4 instead of hardcoding P6_NOP4 x86, cpu: Move AMD Elan Kconfig under "Processor family" Fix up trivial conflicts in alternative handling (commit dc326fca2b64 "x86, cpu: Clean up and unify the NOP selection infrastructure" removed some hacky 5-byte instruction stuff, while commit d430d3d7e646 "jump label: Introduce static_branch() interface" renamed HAVE_JUMP_LABEL to CONFIG_JUMP_LABEL in the code that went away)
Showing 15 changed files Side-by-side Diff
- Documentation/ABI/testing/sysfs-devices-system-cpu
- arch/x86/Kconfig
- arch/x86/Kconfig.cpu
- arch/x86/Makefile_32.cpu
- arch/x86/include/asm/alternative.h
- arch/x86/include/asm/module.h
- arch/x86/include/asm/nops.h
- arch/x86/include/asm/percpu.h
- arch/x86/kernel/alternative.c
- arch/x86/kernel/cpu/intel.c
- arch/x86/kernel/cpu/intel_cacheinfo.c
- arch/x86/kernel/ftrace.c
- arch/x86/kernel/jump_label.c
- arch/x86/kernel/setup.c
- drivers/cpufreq/Kconfig.x86
Documentation/ABI/testing/sysfs-devices-system-cpu
... | ... | @@ -183,22 +183,22 @@ |
183 | 183 | to learn how to control the knobs. |
184 | 184 | |
185 | 185 | |
186 | -What: /sys/devices/system/cpu/cpu*/cache/index*/cache_disable_X | |
187 | -Date: August 2008 | |
186 | +What: /sys/devices/system/cpu/cpu*/cache/index3/cache_disable_{0,1} | |
187 | +Date: August 2008 | |
188 | 188 | KernelVersion: 2.6.27 |
189 | -Contact: mark.langsdorf@amd.com | |
190 | -Description: These files exist in every cpu's cache index directories. | |
191 | - There are currently 2 cache_disable_# files in each | |
192 | - directory. Reading from these files on a supported | |
193 | - processor will return that cache disable index value | |
194 | - for that processor and node. Writing to one of these | |
195 | - files will cause the specificed cache index to be disabled. | |
189 | +Contact: discuss@x86-64.org | |
190 | +Description: Disable L3 cache indices | |
196 | 191 | |
197 | - Currently, only AMD Family 10h Processors support cache index | |
198 | - disable, and only for their L3 caches. See the BIOS and | |
199 | - Kernel Developer's Guide at | |
200 | - http://support.amd.com/us/Embedded_TechDocs/31116-Public-GH-BKDG_3-28_5-28-09.pdf | |
201 | - for formatting information and other details on the | |
202 | - cache index disable. | |
203 | -Users: joachim.deguara@amd.com | |
192 | + These files exist in every CPU's cache/index3 directory. Each | |
193 | + cache_disable_{0,1} file corresponds to one disable slot which | |
194 | + can be used to disable a cache index. Reading from these files | |
195 | + on a processor with this functionality will return the currently | |
196 | + disabled index for that node. There is one L3 structure per | |
197 | + node, or per internal node on MCM machines. Writing a valid | |
198 | + index to one of these files will cause the specificed cache | |
199 | + index to be disabled. | |
200 | + | |
201 | + All AMD processors with L3 caches provide this functionality. | |
202 | + For details, see BKDGs at | |
203 | + http://developer.amd.com/documentation/guides/Pages/default.aspx |
arch/x86/Kconfig
... | ... | @@ -365,17 +365,6 @@ |
365 | 365 | # Following is an alphabetically sorted list of 32 bit extended platforms |
366 | 366 | # Please maintain the alphabetic order if and when there are additions |
367 | 367 | |
368 | -config X86_ELAN | |
369 | - bool "AMD Elan" | |
370 | - depends on X86_32 | |
371 | - depends on X86_EXTENDED_PLATFORM | |
372 | - ---help--- | |
373 | - Select this for an AMD Elan processor. | |
374 | - | |
375 | - Do not use this option for K6/Athlon/Opteron processors! | |
376 | - | |
377 | - If unsure, choose "PC-compatible" instead. | |
378 | - | |
379 | 368 | config X86_INTEL_CE |
380 | 369 | bool "CE4100 TV platform" |
381 | 370 | depends on PCI |
arch/x86/Kconfig.cpu
1 | 1 | # Put here option for CPU selection and depending optimization |
2 | -if !X86_ELAN | |
3 | - | |
4 | 2 | choice |
5 | 3 | prompt "Processor family" |
6 | 4 | default M686 if X86_32 |
... | ... | @@ -203,6 +201,14 @@ |
203 | 201 | stores for this CPU, which can increase performance of some |
204 | 202 | operations. |
205 | 203 | |
204 | +config MELAN | |
205 | + bool "AMD Elan" | |
206 | + depends on X86_32 | |
207 | + ---help--- | |
208 | + Select this for an AMD Elan processor. | |
209 | + | |
210 | + Do not use this option for K6/Athlon/Opteron processors! | |
211 | + | |
206 | 212 | config MGEODEGX1 |
207 | 213 | bool "GeodeGX1" |
208 | 214 | depends on X86_32 |
... | ... | @@ -292,8 +298,6 @@ |
292 | 298 | This is really intended for distributors who need more |
293 | 299 | generic optimizations. |
294 | 300 | |
295 | -endif | |
296 | - | |
297 | 301 | # |
298 | 302 | # Define implied options from the CPU selection here |
299 | 303 | config X86_INTERNODE_CACHE_SHIFT |
... | ... | @@ -312,7 +316,7 @@ |
312 | 316 | int |
313 | 317 | default "7" if MPENTIUM4 || MPSC |
314 | 318 | default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU |
315 | - default "4" if X86_ELAN || M486 || M386 || MGEODEGX1 | |
319 | + default "4" if MELAN || M486 || M386 || MGEODEGX1 | |
316 | 320 | default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX |
317 | 321 | |
318 | 322 | config X86_XADD |
... | ... | @@ -358,7 +362,7 @@ |
358 | 362 | |
359 | 363 | config X86_ALIGNMENT_16 |
360 | 364 | def_bool y |
361 | - depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 | |
365 | + depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 | |
362 | 366 | |
363 | 367 | config X86_INTEL_USERCOPY |
364 | 368 | def_bool y |
arch/x86/Makefile_32.cpu
arch/x86/include/asm/alternative.h
... | ... | @@ -190,13 +190,5 @@ |
190 | 190 | extern void *text_poke_smp(void *addr, const void *opcode, size_t len); |
191 | 191 | extern void text_poke_smp_batch(struct text_poke_param *params, int n); |
192 | 192 | |
193 | -#if defined(CONFIG_DYNAMIC_FTRACE) || defined(CONFIG_JUMP_LABEL) | |
194 | -#define IDEAL_NOP_SIZE_5 5 | |
195 | -extern unsigned char ideal_nop5[IDEAL_NOP_SIZE_5]; | |
196 | -extern void arch_init_ideal_nop5(void); | |
197 | -#else | |
198 | -static inline void arch_init_ideal_nop5(void) {} | |
199 | -#endif | |
200 | - | |
201 | 193 | #endif /* _ASM_X86_ALTERNATIVE_H */ |
arch/x86/include/asm/module.h
... | ... | @@ -35,7 +35,7 @@ |
35 | 35 | #define MODULE_PROC_FAMILY "K7 " |
36 | 36 | #elif defined CONFIG_MK8 |
37 | 37 | #define MODULE_PROC_FAMILY "K8 " |
38 | -#elif defined CONFIG_X86_ELAN | |
38 | +#elif defined CONFIG_MELAN | |
39 | 39 | #define MODULE_PROC_FAMILY "ELAN " |
40 | 40 | #elif defined CONFIG_MCRUSOE |
41 | 41 | #define MODULE_PROC_FAMILY "CRUSOE " |
arch/x86/include/asm/nops.h
1 | 1 | #ifndef _ASM_X86_NOPS_H |
2 | 2 | #define _ASM_X86_NOPS_H |
3 | 3 | |
4 | -/* Define nops for use with alternative() */ | |
4 | +/* | |
5 | + * Define nops for use with alternative() and for tracing. | |
6 | + * | |
7 | + * *_NOP5_ATOMIC must be a single instruction. | |
8 | + */ | |
5 | 9 | |
10 | +#define NOP_DS_PREFIX 0x3e | |
11 | + | |
6 | 12 | /* generic versions from gas |
7 | 13 | 1: nop |
8 | 14 | the following instructions are NOT nops in 64-bit mode, |
... | ... | @@ -13,14 +19,15 @@ |
13 | 19 | 6: leal 0x00000000(%esi),%esi |
14 | 20 | 7: leal 0x00000000(,%esi,1),%esi |
15 | 21 | */ |
16 | -#define GENERIC_NOP1 ".byte 0x90\n" | |
17 | -#define GENERIC_NOP2 ".byte 0x89,0xf6\n" | |
18 | -#define GENERIC_NOP3 ".byte 0x8d,0x76,0x00\n" | |
19 | -#define GENERIC_NOP4 ".byte 0x8d,0x74,0x26,0x00\n" | |
20 | -#define GENERIC_NOP5 GENERIC_NOP1 GENERIC_NOP4 | |
21 | -#define GENERIC_NOP6 ".byte 0x8d,0xb6,0x00,0x00,0x00,0x00\n" | |
22 | -#define GENERIC_NOP7 ".byte 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00\n" | |
23 | -#define GENERIC_NOP8 GENERIC_NOP1 GENERIC_NOP7 | |
22 | +#define GENERIC_NOP1 0x90 | |
23 | +#define GENERIC_NOP2 0x89,0xf6 | |
24 | +#define GENERIC_NOP3 0x8d,0x76,0x00 | |
25 | +#define GENERIC_NOP4 0x8d,0x74,0x26,0x00 | |
26 | +#define GENERIC_NOP5 GENERIC_NOP1,GENERIC_NOP4 | |
27 | +#define GENERIC_NOP6 0x8d,0xb6,0x00,0x00,0x00,0x00 | |
28 | +#define GENERIC_NOP7 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00 | |
29 | +#define GENERIC_NOP8 GENERIC_NOP1,GENERIC_NOP7 | |
30 | +#define GENERIC_NOP5_ATOMIC NOP_DS_PREFIX,GENERIC_NOP4 | |
24 | 31 | |
25 | 32 | /* Opteron 64bit nops |
26 | 33 | 1: nop |
... | ... | @@ -29,13 +36,14 @@ |
29 | 36 | 4: osp osp osp nop |
30 | 37 | */ |
31 | 38 | #define K8_NOP1 GENERIC_NOP1 |
32 | -#define K8_NOP2 ".byte 0x66,0x90\n" | |
33 | -#define K8_NOP3 ".byte 0x66,0x66,0x90\n" | |
34 | -#define K8_NOP4 ".byte 0x66,0x66,0x66,0x90\n" | |
35 | -#define K8_NOP5 K8_NOP3 K8_NOP2 | |
36 | -#define K8_NOP6 K8_NOP3 K8_NOP3 | |
37 | -#define K8_NOP7 K8_NOP4 K8_NOP3 | |
38 | -#define K8_NOP8 K8_NOP4 K8_NOP4 | |
39 | +#define K8_NOP2 0x66,K8_NOP1 | |
40 | +#define K8_NOP3 0x66,K8_NOP2 | |
41 | +#define K8_NOP4 0x66,K8_NOP3 | |
42 | +#define K8_NOP5 K8_NOP3,K8_NOP2 | |
43 | +#define K8_NOP6 K8_NOP3,K8_NOP3 | |
44 | +#define K8_NOP7 K8_NOP4,K8_NOP3 | |
45 | +#define K8_NOP8 K8_NOP4,K8_NOP4 | |
46 | +#define K8_NOP5_ATOMIC 0x66,K8_NOP4 | |
39 | 47 | |
40 | 48 | /* K7 nops |
41 | 49 | uses eax dependencies (arbitrary choice) |
... | ... | @@ -47,13 +55,14 @@ |
47 | 55 | 7: leal 0x00000000(,%eax,1),%eax |
48 | 56 | */ |
49 | 57 | #define K7_NOP1 GENERIC_NOP1 |
50 | -#define K7_NOP2 ".byte 0x8b,0xc0\n" | |
51 | -#define K7_NOP3 ".byte 0x8d,0x04,0x20\n" | |
52 | -#define K7_NOP4 ".byte 0x8d,0x44,0x20,0x00\n" | |
53 | -#define K7_NOP5 K7_NOP4 ASM_NOP1 | |
54 | -#define K7_NOP6 ".byte 0x8d,0x80,0,0,0,0\n" | |
55 | -#define K7_NOP7 ".byte 0x8D,0x04,0x05,0,0,0,0\n" | |
56 | -#define K7_NOP8 K7_NOP7 ASM_NOP1 | |
58 | +#define K7_NOP2 0x8b,0xc0 | |
59 | +#define K7_NOP3 0x8d,0x04,0x20 | |
60 | +#define K7_NOP4 0x8d,0x44,0x20,0x00 | |
61 | +#define K7_NOP5 K7_NOP4,K7_NOP1 | |
62 | +#define K7_NOP6 0x8d,0x80,0,0,0,0 | |
63 | +#define K7_NOP7 0x8D,0x04,0x05,0,0,0,0 | |
64 | +#define K7_NOP8 K7_NOP7,K7_NOP1 | |
65 | +#define K7_NOP5_ATOMIC NOP_DS_PREFIX,K7_NOP4 | |
57 | 66 | |
58 | 67 | /* P6 nops |
59 | 68 | uses eax dependencies (Intel-recommended choice) |
60 | 69 | |
61 | 70 | |
62 | 71 | |
63 | 72 | |
64 | 73 | |
65 | 74 | |
... | ... | @@ -69,53 +78,66 @@ |
69 | 78 | There is kernel code that depends on this. |
70 | 79 | */ |
71 | 80 | #define P6_NOP1 GENERIC_NOP1 |
72 | -#define P6_NOP2 ".byte 0x66,0x90\n" | |
73 | -#define P6_NOP3 ".byte 0x0f,0x1f,0x00\n" | |
74 | -#define P6_NOP4 ".byte 0x0f,0x1f,0x40,0\n" | |
75 | -#define P6_NOP5 ".byte 0x0f,0x1f,0x44,0x00,0\n" | |
76 | -#define P6_NOP6 ".byte 0x66,0x0f,0x1f,0x44,0x00,0\n" | |
77 | -#define P6_NOP7 ".byte 0x0f,0x1f,0x80,0,0,0,0\n" | |
78 | -#define P6_NOP8 ".byte 0x0f,0x1f,0x84,0x00,0,0,0,0\n" | |
81 | +#define P6_NOP2 0x66,0x90 | |
82 | +#define P6_NOP3 0x0f,0x1f,0x00 | |
83 | +#define P6_NOP4 0x0f,0x1f,0x40,0 | |
84 | +#define P6_NOP5 0x0f,0x1f,0x44,0x00,0 | |
85 | +#define P6_NOP6 0x66,0x0f,0x1f,0x44,0x00,0 | |
86 | +#define P6_NOP7 0x0f,0x1f,0x80,0,0,0,0 | |
87 | +#define P6_NOP8 0x0f,0x1f,0x84,0x00,0,0,0,0 | |
88 | +#define P6_NOP5_ATOMIC P6_NOP5 | |
79 | 89 | |
90 | +#define _ASM_MK_NOP(x) ".byte " __stringify(x) "\n" | |
91 | + | |
80 | 92 | #if defined(CONFIG_MK7) |
81 | -#define ASM_NOP1 K7_NOP1 | |
82 | -#define ASM_NOP2 K7_NOP2 | |
83 | -#define ASM_NOP3 K7_NOP3 | |
84 | -#define ASM_NOP4 K7_NOP4 | |
85 | -#define ASM_NOP5 K7_NOP5 | |
86 | -#define ASM_NOP6 K7_NOP6 | |
87 | -#define ASM_NOP7 K7_NOP7 | |
88 | -#define ASM_NOP8 K7_NOP8 | |
93 | +#define ASM_NOP1 _ASM_MK_NOP(K7_NOP1) | |
94 | +#define ASM_NOP2 _ASM_MK_NOP(K7_NOP2) | |
95 | +#define ASM_NOP3 _ASM_MK_NOP(K7_NOP3) | |
96 | +#define ASM_NOP4 _ASM_MK_NOP(K7_NOP4) | |
97 | +#define ASM_NOP5 _ASM_MK_NOP(K7_NOP5) | |
98 | +#define ASM_NOP6 _ASM_MK_NOP(K7_NOP6) | |
99 | +#define ASM_NOP7 _ASM_MK_NOP(K7_NOP7) | |
100 | +#define ASM_NOP8 _ASM_MK_NOP(K7_NOP8) | |
101 | +#define ASM_NOP5_ATOMIC _ASM_MK_NOP(K7_NOP5_ATOMIC) | |
89 | 102 | #elif defined(CONFIG_X86_P6_NOP) |
90 | -#define ASM_NOP1 P6_NOP1 | |
91 | -#define ASM_NOP2 P6_NOP2 | |
92 | -#define ASM_NOP3 P6_NOP3 | |
93 | -#define ASM_NOP4 P6_NOP4 | |
94 | -#define ASM_NOP5 P6_NOP5 | |
95 | -#define ASM_NOP6 P6_NOP6 | |
96 | -#define ASM_NOP7 P6_NOP7 | |
97 | -#define ASM_NOP8 P6_NOP8 | |
103 | +#define ASM_NOP1 _ASM_MK_NOP(P6_NOP1) | |
104 | +#define ASM_NOP2 _ASM_MK_NOP(P6_NOP2) | |
105 | +#define ASM_NOP3 _ASM_MK_NOP(P6_NOP3) | |
106 | +#define ASM_NOP4 _ASM_MK_NOP(P6_NOP4) | |
107 | +#define ASM_NOP5 _ASM_MK_NOP(P6_NOP5) | |
108 | +#define ASM_NOP6 _ASM_MK_NOP(P6_NOP6) | |
109 | +#define ASM_NOP7 _ASM_MK_NOP(P6_NOP7) | |
110 | +#define ASM_NOP8 _ASM_MK_NOP(P6_NOP8) | |
111 | +#define ASM_NOP5_ATOMIC _ASM_MK_NOP(P6_NOP5_ATOMIC) | |
98 | 112 | #elif defined(CONFIG_X86_64) |
99 | -#define ASM_NOP1 K8_NOP1 | |
100 | -#define ASM_NOP2 K8_NOP2 | |
101 | -#define ASM_NOP3 K8_NOP3 | |
102 | -#define ASM_NOP4 K8_NOP4 | |
103 | -#define ASM_NOP5 K8_NOP5 | |
104 | -#define ASM_NOP6 K8_NOP6 | |
105 | -#define ASM_NOP7 K8_NOP7 | |
106 | -#define ASM_NOP8 K8_NOP8 | |
113 | +#define ASM_NOP1 _ASM_MK_NOP(K8_NOP1) | |
114 | +#define ASM_NOP2 _ASM_MK_NOP(K8_NOP2) | |
115 | +#define ASM_NOP3 _ASM_MK_NOP(K8_NOP3) | |
116 | +#define ASM_NOP4 _ASM_MK_NOP(K8_NOP4) | |
117 | +#define ASM_NOP5 _ASM_MK_NOP(K8_NOP5) | |
118 | +#define ASM_NOP6 _ASM_MK_NOP(K8_NOP6) | |
119 | +#define ASM_NOP7 _ASM_MK_NOP(K8_NOP7) | |
120 | +#define ASM_NOP8 _ASM_MK_NOP(K8_NOP8) | |
121 | +#define ASM_NOP5_ATOMIC _ASM_MK_NOP(K8_NOP5_ATOMIC) | |
107 | 122 | #else |
108 | -#define ASM_NOP1 GENERIC_NOP1 | |
109 | -#define ASM_NOP2 GENERIC_NOP2 | |
110 | -#define ASM_NOP3 GENERIC_NOP3 | |
111 | -#define ASM_NOP4 GENERIC_NOP4 | |
112 | -#define ASM_NOP5 GENERIC_NOP5 | |
113 | -#define ASM_NOP6 GENERIC_NOP6 | |
114 | -#define ASM_NOP7 GENERIC_NOP7 | |
115 | -#define ASM_NOP8 GENERIC_NOP8 | |
123 | +#define ASM_NOP1 _ASM_MK_NOP(GENERIC_NOP1) | |
124 | +#define ASM_NOP2 _ASM_MK_NOP(GENERIC_NOP2) | |
125 | +#define ASM_NOP3 _ASM_MK_NOP(GENERIC_NOP3) | |
126 | +#define ASM_NOP4 _ASM_MK_NOP(GENERIC_NOP4) | |
127 | +#define ASM_NOP5 _ASM_MK_NOP(GENERIC_NOP5) | |
128 | +#define ASM_NOP6 _ASM_MK_NOP(GENERIC_NOP6) | |
129 | +#define ASM_NOP7 _ASM_MK_NOP(GENERIC_NOP7) | |
130 | +#define ASM_NOP8 _ASM_MK_NOP(GENERIC_NOP8) | |
131 | +#define ASM_NOP5_ATOMIC _ASM_MK_NOP(GENERIC_NOP5_ATOMIC) | |
116 | 132 | #endif |
117 | 133 | |
118 | 134 | #define ASM_NOP_MAX 8 |
135 | +#define NOP_ATOMIC5 (ASM_NOP_MAX+1) /* Entry for the 5-byte atomic NOP */ | |
136 | + | |
137 | +#ifndef __ASSEMBLY__ | |
138 | +extern const unsigned char * const *ideal_nops; | |
139 | +extern void arch_init_ideal_nops(void); | |
140 | +#endif | |
119 | 141 | |
120 | 142 | #endif /* _ASM_X86_NOPS_H */ |
arch/x86/include/asm/percpu.h
... | ... | @@ -517,7 +517,7 @@ |
517 | 517 | typeof(o2) __o2 = o2; \ |
518 | 518 | typeof(o2) __n2 = n2; \ |
519 | 519 | typeof(o2) __dummy; \ |
520 | - alternative_io("call this_cpu_cmpxchg16b_emu\n\t" P6_NOP4, \ | |
520 | + alternative_io("call this_cpu_cmpxchg16b_emu\n\t" ASM_NOP4, \ | |
521 | 521 | "cmpxchg16b " __percpu_prefix "(%%rsi)\n\tsetz %0\n\t", \ |
522 | 522 | X86_FEATURE_CX16, \ |
523 | 523 | ASM_OUTPUT2("=a"(__ret), "=d"(__dummy)), \ |
arch/x86/kernel/alternative.c
... | ... | @@ -67,17 +67,30 @@ |
67 | 67 | #define DPRINTK(fmt, args...) if (debug_alternative) \ |
68 | 68 | printk(KERN_DEBUG fmt, args) |
69 | 69 | |
70 | +/* | |
71 | + * Each GENERIC_NOPX is of X bytes, and defined as an array of bytes | |
72 | + * that correspond to that nop. Getting from one nop to the next, we | |
73 | + * add to the array the offset that is equal to the sum of all sizes of | |
74 | + * nops preceding the one we are after. | |
75 | + * | |
76 | + * Note: The GENERIC_NOP5_ATOMIC is at the end, as it breaks the | |
77 | + * nice symmetry of sizes of the previous nops. | |
78 | + */ | |
70 | 79 | #if defined(GENERIC_NOP1) && !defined(CONFIG_X86_64) |
71 | -/* Use inline assembly to define this because the nops are defined | |
72 | - as inline assembly strings in the include files and we cannot | |
73 | - get them easily into strings. */ | |
74 | -asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nintelnops: " | |
75 | - GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6 | |
76 | - GENERIC_NOP7 GENERIC_NOP8 | |
77 | - "\t.previous"); | |
78 | -extern const unsigned char intelnops[]; | |
79 | -static const unsigned char *const __initconst_or_module | |
80 | -intel_nops[ASM_NOP_MAX+1] = { | |
80 | +static const unsigned char intelnops[] = | |
81 | +{ | |
82 | + GENERIC_NOP1, | |
83 | + GENERIC_NOP2, | |
84 | + GENERIC_NOP3, | |
85 | + GENERIC_NOP4, | |
86 | + GENERIC_NOP5, | |
87 | + GENERIC_NOP6, | |
88 | + GENERIC_NOP7, | |
89 | + GENERIC_NOP8, | |
90 | + GENERIC_NOP5_ATOMIC | |
91 | +}; | |
92 | +static const unsigned char * const intel_nops[ASM_NOP_MAX+2] = | |
93 | +{ | |
81 | 94 | NULL, |
82 | 95 | intelnops, |
83 | 96 | intelnops + 1, |
84 | 97 | |
... | ... | @@ -87,17 +100,25 @@ |
87 | 100 | intelnops + 1 + 2 + 3 + 4 + 5, |
88 | 101 | intelnops + 1 + 2 + 3 + 4 + 5 + 6, |
89 | 102 | intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7, |
103 | + intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8, | |
90 | 104 | }; |
91 | 105 | #endif |
92 | 106 | |
93 | 107 | #ifdef K8_NOP1 |
94 | -asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nk8nops: " | |
95 | - K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6 | |
96 | - K8_NOP7 K8_NOP8 | |
97 | - "\t.previous"); | |
98 | -extern const unsigned char k8nops[]; | |
99 | -static const unsigned char *const __initconst_or_module | |
100 | -k8_nops[ASM_NOP_MAX+1] = { | |
108 | +static const unsigned char k8nops[] = | |
109 | +{ | |
110 | + K8_NOP1, | |
111 | + K8_NOP2, | |
112 | + K8_NOP3, | |
113 | + K8_NOP4, | |
114 | + K8_NOP5, | |
115 | + K8_NOP6, | |
116 | + K8_NOP7, | |
117 | + K8_NOP8, | |
118 | + K8_NOP5_ATOMIC | |
119 | +}; | |
120 | +static const unsigned char * const k8_nops[ASM_NOP_MAX+2] = | |
121 | +{ | |
101 | 122 | NULL, |
102 | 123 | k8nops, |
103 | 124 | k8nops + 1, |
104 | 125 | |
... | ... | @@ -107,17 +128,25 @@ |
107 | 128 | k8nops + 1 + 2 + 3 + 4 + 5, |
108 | 129 | k8nops + 1 + 2 + 3 + 4 + 5 + 6, |
109 | 130 | k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, |
131 | + k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8, | |
110 | 132 | }; |
111 | 133 | #endif |
112 | 134 | |
113 | 135 | #if defined(K7_NOP1) && !defined(CONFIG_X86_64) |
114 | -asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nk7nops: " | |
115 | - K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6 | |
116 | - K7_NOP7 K7_NOP8 | |
117 | - "\t.previous"); | |
118 | -extern const unsigned char k7nops[]; | |
119 | -static const unsigned char *const __initconst_or_module | |
120 | -k7_nops[ASM_NOP_MAX+1] = { | |
136 | +static const unsigned char k7nops[] = | |
137 | +{ | |
138 | + K7_NOP1, | |
139 | + K7_NOP2, | |
140 | + K7_NOP3, | |
141 | + K7_NOP4, | |
142 | + K7_NOP5, | |
143 | + K7_NOP6, | |
144 | + K7_NOP7, | |
145 | + K7_NOP8, | |
146 | + K7_NOP5_ATOMIC | |
147 | +}; | |
148 | +static const unsigned char * const k7_nops[ASM_NOP_MAX+2] = | |
149 | +{ | |
121 | 150 | NULL, |
122 | 151 | k7nops, |
123 | 152 | k7nops + 1, |
124 | 153 | |
... | ... | @@ -127,17 +156,25 @@ |
127 | 156 | k7nops + 1 + 2 + 3 + 4 + 5, |
128 | 157 | k7nops + 1 + 2 + 3 + 4 + 5 + 6, |
129 | 158 | k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, |
159 | + k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8, | |
130 | 160 | }; |
131 | 161 | #endif |
132 | 162 | |
133 | 163 | #ifdef P6_NOP1 |
134 | -asm("\t" __stringify(__INITRODATA_OR_MODULE) "\np6nops: " | |
135 | - P6_NOP1 P6_NOP2 P6_NOP3 P6_NOP4 P6_NOP5 P6_NOP6 | |
136 | - P6_NOP7 P6_NOP8 | |
137 | - "\t.previous"); | |
138 | -extern const unsigned char p6nops[]; | |
139 | -static const unsigned char *const __initconst_or_module | |
140 | -p6_nops[ASM_NOP_MAX+1] = { | |
164 | +static const unsigned char __initconst_or_module p6nops[] = | |
165 | +{ | |
166 | + P6_NOP1, | |
167 | + P6_NOP2, | |
168 | + P6_NOP3, | |
169 | + P6_NOP4, | |
170 | + P6_NOP5, | |
171 | + P6_NOP6, | |
172 | + P6_NOP7, | |
173 | + P6_NOP8, | |
174 | + P6_NOP5_ATOMIC | |
175 | +}; | |
176 | +static const unsigned char * const p6_nops[ASM_NOP_MAX+2] = | |
177 | +{ | |
141 | 178 | NULL, |
142 | 179 | p6nops, |
143 | 180 | p6nops + 1, |
144 | 181 | |
145 | 182 | |
146 | 183 | |
147 | 184 | |
148 | 185 | |
149 | 186 | |
150 | 187 | |
151 | 188 | |
... | ... | @@ -147,47 +184,65 @@ |
147 | 184 | p6nops + 1 + 2 + 3 + 4 + 5, |
148 | 185 | p6nops + 1 + 2 + 3 + 4 + 5 + 6, |
149 | 186 | p6nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, |
187 | + p6nops + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8, | |
150 | 188 | }; |
151 | 189 | #endif |
152 | 190 | |
191 | +/* Initialize these to a safe default */ | |
153 | 192 | #ifdef CONFIG_X86_64 |
193 | +const unsigned char * const *ideal_nops = p6_nops; | |
194 | +#else | |
195 | +const unsigned char * const *ideal_nops = intel_nops; | |
196 | +#endif | |
154 | 197 | |
155 | -extern char __vsyscall_0; | |
156 | -static const unsigned char *const *__init_or_module find_nop_table(void) | |
198 | +void __init arch_init_ideal_nops(void) | |
157 | 199 | { |
158 | - if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && | |
159 | - boot_cpu_has(X86_FEATURE_NOPL)) | |
160 | - return p6_nops; | |
161 | - else | |
162 | - return k8_nops; | |
163 | -} | |
200 | + switch (boot_cpu_data.x86_vendor) { | |
201 | + case X86_VENDOR_INTEL: | |
202 | + /* | |
203 | + * Due to a decoder implementation quirk, some | |
204 | + * specific Intel CPUs actually perform better with | |
205 | + * the "k8_nops" than with the SDM-recommended NOPs. | |
206 | + */ | |
207 | + if (boot_cpu_data.x86 == 6 && | |
208 | + boot_cpu_data.x86_model >= 0x0f && | |
209 | + boot_cpu_data.x86_model != 0x1c && | |
210 | + boot_cpu_data.x86_model != 0x26 && | |
211 | + boot_cpu_data.x86_model != 0x27 && | |
212 | + boot_cpu_data.x86_model < 0x30) { | |
213 | + ideal_nops = k8_nops; | |
214 | + } else if (boot_cpu_has(X86_FEATURE_NOPL)) { | |
215 | + ideal_nops = p6_nops; | |
216 | + } else { | |
217 | +#ifdef CONFIG_X86_64 | |
218 | + ideal_nops = k8_nops; | |
219 | +#else | |
220 | + ideal_nops = intel_nops; | |
221 | +#endif | |
222 | + } | |
164 | 223 | |
165 | -#else /* CONFIG_X86_64 */ | |
166 | - | |
167 | -static const unsigned char *const *__init_or_module find_nop_table(void) | |
168 | -{ | |
169 | - if (boot_cpu_has(X86_FEATURE_K8)) | |
170 | - return k8_nops; | |
171 | - else if (boot_cpu_has(X86_FEATURE_K7)) | |
172 | - return k7_nops; | |
173 | - else if (boot_cpu_has(X86_FEATURE_NOPL)) | |
174 | - return p6_nops; | |
175 | - else | |
176 | - return intel_nops; | |
224 | + default: | |
225 | +#ifdef CONFIG_X86_64 | |
226 | + ideal_nops = k8_nops; | |
227 | +#else | |
228 | + if (boot_cpu_has(X86_FEATURE_K8)) | |
229 | + ideal_nops = k8_nops; | |
230 | + else if (boot_cpu_has(X86_FEATURE_K7)) | |
231 | + ideal_nops = k7_nops; | |
232 | + else | |
233 | + ideal_nops = intel_nops; | |
234 | +#endif | |
235 | + } | |
177 | 236 | } |
178 | 237 | |
179 | -#endif /* CONFIG_X86_64 */ | |
180 | - | |
181 | 238 | /* Use this to add nops to a buffer, then text_poke the whole buffer. */ |
182 | 239 | static void __init_or_module add_nops(void *insns, unsigned int len) |
183 | 240 | { |
184 | - const unsigned char *const *noptable = find_nop_table(); | |
185 | - | |
186 | 241 | while (len > 0) { |
187 | 242 | unsigned int noplen = len; |
188 | 243 | if (noplen > ASM_NOP_MAX) |
189 | 244 | noplen = ASM_NOP_MAX; |
190 | - memcpy(insns, noptable[noplen], noplen); | |
245 | + memcpy(insns, ideal_nops[noplen], noplen); | |
191 | 246 | insns += noplen; |
192 | 247 | len -= noplen; |
193 | 248 | } |
... | ... | @@ -195,6 +250,7 @@ |
195 | 250 | |
196 | 251 | extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; |
197 | 252 | extern s32 __smp_locks[], __smp_locks_end[]; |
253 | +extern char __vsyscall_0; | |
198 | 254 | void *text_poke_early(void *addr, const void *opcode, size_t len); |
199 | 255 | |
200 | 256 | /* Replace instructions with better alternatives for this CPU type. |
... | ... | @@ -687,30 +743,4 @@ |
687 | 743 | wrote_text = 0; |
688 | 744 | __stop_machine(stop_machine_text_poke, (void *)&tpp, NULL); |
689 | 745 | } |
690 | - | |
691 | -#if defined(CONFIG_DYNAMIC_FTRACE) || defined(CONFIG_JUMP_LABEL) | |
692 | - | |
693 | -#ifdef CONFIG_X86_64 | |
694 | -unsigned char ideal_nop5[5] = { 0x66, 0x66, 0x66, 0x66, 0x90 }; | |
695 | -#else | |
696 | -unsigned char ideal_nop5[5] = { 0x3e, 0x8d, 0x74, 0x26, 0x00 }; | |
697 | -#endif | |
698 | - | |
699 | -void __init arch_init_ideal_nop5(void) | |
700 | -{ | |
701 | - /* | |
702 | - * There is no good nop for all x86 archs. This selection | |
703 | - * algorithm should be unified with the one in find_nop_table(), | |
704 | - * but this should be good enough for now. | |
705 | - * | |
706 | - * For cases other than the ones below, use the safe (as in | |
707 | - * always functional) defaults above. | |
708 | - */ | |
709 | -#ifdef CONFIG_X86_64 | |
710 | - /* Don't use these on 32 bits due to broken virtualizers */ | |
711 | - if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) | |
712 | - memcpy(ideal_nop5, p6_nops[5], 5); | |
713 | -#endif | |
714 | -} | |
715 | -#endif |
arch/x86/kernel/cpu/intel.c
... | ... | @@ -411,12 +411,10 @@ |
411 | 411 | |
412 | 412 | switch (c->x86_model) { |
413 | 413 | case 5: |
414 | - if (c->x86_mask == 0) { | |
415 | - if (l2 == 0) | |
416 | - p = "Celeron (Covington)"; | |
417 | - else if (l2 == 256) | |
418 | - p = "Mobile Pentium II (Dixon)"; | |
419 | - } | |
414 | + if (l2 == 0) | |
415 | + p = "Celeron (Covington)"; | |
416 | + else if (l2 == 256) | |
417 | + p = "Mobile Pentium II (Dixon)"; | |
420 | 418 | break; |
421 | 419 | |
422 | 420 | case 6: |
arch/x86/kernel/cpu/intel_cacheinfo.c
... | ... | @@ -327,7 +327,6 @@ |
327 | 327 | l3->subcaches[2] = sc2 = !(val & BIT(8)) + !(val & BIT(9)); |
328 | 328 | l3->subcaches[3] = sc3 = !(val & BIT(12)) + !(val & BIT(13)); |
329 | 329 | |
330 | - l3->indices = (max(max(max(sc0, sc1), sc2), sc3) << 10) - 1; | |
331 | 330 | l3->indices = (max(max3(sc0, sc1, sc2), sc3) << 10) - 1; |
332 | 331 | } |
333 | 332 | |
334 | 333 | |
335 | 334 | |
... | ... | @@ -454,27 +453,16 @@ |
454 | 453 | { |
455 | 454 | int ret = 0; |
456 | 455 | |
457 | -#define SUBCACHE_MASK (3UL << 20) | |
458 | -#define SUBCACHE_INDEX 0xfff | |
459 | - | |
460 | - /* | |
461 | - * check whether this slot is already used or | |
462 | - * the index is already disabled | |
463 | - */ | |
456 | + /* check if @slot is already used or the index is already disabled */ | |
464 | 457 | ret = amd_get_l3_disable_slot(l3, slot); |
465 | 458 | if (ret >= 0) |
466 | 459 | return -EINVAL; |
467 | 460 | |
468 | - /* | |
469 | - * check whether the other slot has disabled the | |
470 | - * same index already | |
471 | - */ | |
472 | - if (index == amd_get_l3_disable_slot(l3, !slot)) | |
461 | + if (index > l3->indices) | |
473 | 462 | return -EINVAL; |
474 | 463 | |
475 | - /* do not allow writes outside of allowed bits */ | |
476 | - if ((index & ~(SUBCACHE_MASK | SUBCACHE_INDEX)) || | |
477 | - ((index & SUBCACHE_INDEX) > l3->indices)) | |
464 | + /* check whether the other slot has disabled the same index already */ | |
465 | + if (index == amd_get_l3_disable_slot(l3, !slot)) | |
478 | 466 | return -EINVAL; |
479 | 467 | |
480 | 468 | amd_l3_disable_index(l3, cpu, slot, index); |
arch/x86/kernel/ftrace.c
arch/x86/kernel/jump_label.c
... | ... | @@ -34,7 +34,7 @@ |
34 | 34 | code.offset = entry->target - |
35 | 35 | (entry->code + JUMP_LABEL_NOP_SIZE); |
36 | 36 | } else |
37 | - memcpy(&code, ideal_nop5, JUMP_LABEL_NOP_SIZE); | |
37 | + memcpy(&code, ideal_nops[NOP_ATOMIC5], JUMP_LABEL_NOP_SIZE); | |
38 | 38 | get_online_cpus(); |
39 | 39 | mutex_lock(&text_mutex); |
40 | 40 | text_poke_smp((void *)entry->code, &code, JUMP_LABEL_NOP_SIZE); |
... | ... | @@ -44,7 +44,8 @@ |
44 | 44 | |
45 | 45 | void arch_jump_label_text_poke_early(jump_label_t addr) |
46 | 46 | { |
47 | - text_poke_early((void *)addr, ideal_nop5, JUMP_LABEL_NOP_SIZE); | |
47 | + text_poke_early((void *)addr, ideal_nops[NOP_ATOMIC5], | |
48 | + JUMP_LABEL_NOP_SIZE); | |
48 | 49 | } |
49 | 50 | |
50 | 51 | #endif |
arch/x86/kernel/setup.c
... | ... | @@ -691,8 +691,6 @@ |
691 | 691 | |
692 | 692 | void __init setup_arch(char **cmdline_p) |
693 | 693 | { |
694 | - unsigned long flags; | |
695 | - | |
696 | 694 | #ifdef CONFIG_X86_32 |
697 | 695 | memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); |
698 | 696 | visws_early_detect(); |
... | ... | @@ -1041,9 +1039,7 @@ |
1041 | 1039 | |
1042 | 1040 | mcheck_init(); |
1043 | 1041 | |
1044 | - local_irq_save(flags); | |
1045 | - arch_init_ideal_nop5(); | |
1046 | - local_irq_restore(flags); | |
1042 | + arch_init_ideal_nops(); | |
1047 | 1043 | } |
1048 | 1044 | |
1049 | 1045 | #ifdef CONFIG_X86_32 |
drivers/cpufreq/Kconfig.x86
... | ... | @@ -35,7 +35,7 @@ |
35 | 35 | config ELAN_CPUFREQ |
36 | 36 | tristate "AMD Elan SC400 and SC410" |
37 | 37 | select CPU_FREQ_TABLE |
38 | - depends on X86_ELAN | |
38 | + depends on MELAN | |
39 | 39 | ---help--- |
40 | 40 | This adds the CPUFreq driver for AMD Elan SC400 and SC410 |
41 | 41 | processors. |
... | ... | @@ -51,7 +51,7 @@ |
51 | 51 | config SC520_CPUFREQ |
52 | 52 | tristate "AMD Elan SC520" |
53 | 53 | select CPU_FREQ_TABLE |
54 | - depends on X86_ELAN | |
54 | + depends on MELAN | |
55 | 55 | ---help--- |
56 | 56 | This adds the CPUFreq driver for AMD Elan SC520 processor. |
57 | 57 |