Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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)

+242 -222
+16 -16
Documentation/ABI/testing/sysfs-devices-system-cpu
··· 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
-11
arch/x86/Kconfig
··· 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
+10 -6
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 ··· 201 203 stores for this CPU, which can increase performance of some 202 204 operations. 203 205 206 + config MELAN 207 + bool "AMD Elan" 208 + depends on X86_32 209 + ---help--- 210 + Select this for an AMD Elan processor. 211 + 212 + Do not use this option for K6/Athlon/Opteron processors! 213 + 204 214 config MGEODEGX1 205 215 bool "GeodeGX1" 206 216 depends on X86_32 ··· 298 292 This is really intended for distributors who need more 299 293 generic optimizations. 300 294 301 - endif 302 - 303 295 # 304 296 # Define implied options from the CPU selection here 305 297 config X86_INTERNODE_CACHE_SHIFT ··· 316 312 int 317 313 default "7" if MPENTIUM4 || MPSC 318 314 default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU 319 - default "4" if X86_ELAN || M486 || M386 || MGEODEGX1 315 + default "4" if MELAN || M486 || M386 || MGEODEGX1 320 316 default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX 321 317 322 318 config X86_XADD ··· 362 358 363 359 config X86_ALIGNMENT_16 364 360 def_bool y 365 - depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 361 + depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 366 362 367 363 config X86_INTEL_USERCOPY 368 364 def_bool y
+1 -1
arch/x86/Makefile_32.cpu
··· 37 37 $(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic)) 38 38 39 39 # AMD Elan support 40 - cflags-$(CONFIG_X86_ELAN) += -march=i486 40 + cflags-$(CONFIG_MELAN) += -march=i486 41 41 42 42 # Geode GX1 support 43 43 cflags-$(CONFIG_MGEODEGX1) += -march=pentium-mmx
-8
arch/x86/include/asm/alternative.h
··· 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 */
+1 -1
arch/x86/include/asm/module.h
··· 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 "
+84 -62
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 + */ 9 + 10 + #define NOP_DS_PREFIX 0x3e 5 11 6 12 /* generic versions from gas 7 13 1: nop ··· 19 13 6: leal 0x00000000(%esi),%esi 20 14 7: leal 0x00000000(,%esi,1),%esi 21 15 */ 22 - #define GENERIC_NOP1 ".byte 0x90\n" 23 - #define GENERIC_NOP2 ".byte 0x89,0xf6\n" 24 - #define GENERIC_NOP3 ".byte 0x8d,0x76,0x00\n" 25 - #define GENERIC_NOP4 ".byte 0x8d,0x74,0x26,0x00\n" 26 - #define GENERIC_NOP5 GENERIC_NOP1 GENERIC_NOP4 27 - #define GENERIC_NOP6 ".byte 0x8d,0xb6,0x00,0x00,0x00,0x00\n" 28 - #define GENERIC_NOP7 ".byte 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00\n" 29 - #define GENERIC_NOP8 GENERIC_NOP1 GENERIC_NOP7 16 + #define GENERIC_NOP1 0x90 17 + #define GENERIC_NOP2 0x89,0xf6 18 + #define GENERIC_NOP3 0x8d,0x76,0x00 19 + #define GENERIC_NOP4 0x8d,0x74,0x26,0x00 20 + #define GENERIC_NOP5 GENERIC_NOP1,GENERIC_NOP4 21 + #define GENERIC_NOP6 0x8d,0xb6,0x00,0x00,0x00,0x00 22 + #define GENERIC_NOP7 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00 23 + #define GENERIC_NOP8 GENERIC_NOP1,GENERIC_NOP7 24 + #define GENERIC_NOP5_ATOMIC NOP_DS_PREFIX,GENERIC_NOP4 30 25 31 26 /* Opteron 64bit nops 32 27 1: nop ··· 36 29 4: osp osp osp nop 37 30 */ 38 31 #define K8_NOP1 GENERIC_NOP1 39 - #define K8_NOP2 ".byte 0x66,0x90\n" 40 - #define K8_NOP3 ".byte 0x66,0x66,0x90\n" 41 - #define K8_NOP4 ".byte 0x66,0x66,0x66,0x90\n" 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 32 + #define K8_NOP2 0x66,K8_NOP1 33 + #define K8_NOP3 0x66,K8_NOP2 34 + #define K8_NOP4 0x66,K8_NOP3 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_NOP5_ATOMIC 0x66,K8_NOP4 46 40 47 41 /* K7 nops 48 42 uses eax dependencies (arbitrary choice) ··· 55 47 7: leal 0x00000000(,%eax,1),%eax 56 48 */ 57 49 #define K7_NOP1 GENERIC_NOP1 58 - #define K7_NOP2 ".byte 0x8b,0xc0\n" 59 - #define K7_NOP3 ".byte 0x8d,0x04,0x20\n" 60 - #define K7_NOP4 ".byte 0x8d,0x44,0x20,0x00\n" 61 - #define K7_NOP5 K7_NOP4 ASM_NOP1 62 - #define K7_NOP6 ".byte 0x8d,0x80,0,0,0,0\n" 63 - #define K7_NOP7 ".byte 0x8D,0x04,0x05,0,0,0,0\n" 64 - #define K7_NOP8 K7_NOP7 ASM_NOP1 50 + #define K7_NOP2 0x8b,0xc0 51 + #define K7_NOP3 0x8d,0x04,0x20 52 + #define K7_NOP4 0x8d,0x44,0x20,0x00 53 + #define K7_NOP5 K7_NOP4,K7_NOP1 54 + #define K7_NOP6 0x8d,0x80,0,0,0,0 55 + #define K7_NOP7 0x8D,0x04,0x05,0,0,0,0 56 + #define K7_NOP8 K7_NOP7,K7_NOP1 57 + #define K7_NOP5_ATOMIC NOP_DS_PREFIX,K7_NOP4 65 58 66 59 /* P6 nops 67 60 uses eax dependencies (Intel-recommended choice) ··· 78 69 There is kernel code that depends on this. 79 70 */ 80 71 #define P6_NOP1 GENERIC_NOP1 81 - #define P6_NOP2 ".byte 0x66,0x90\n" 82 - #define P6_NOP3 ".byte 0x0f,0x1f,0x00\n" 83 - #define P6_NOP4 ".byte 0x0f,0x1f,0x40,0\n" 84 - #define P6_NOP5 ".byte 0x0f,0x1f,0x44,0x00,0\n" 85 - #define P6_NOP6 ".byte 0x66,0x0f,0x1f,0x44,0x00,0\n" 86 - #define P6_NOP7 ".byte 0x0f,0x1f,0x80,0,0,0,0\n" 87 - #define P6_NOP8 ".byte 0x0f,0x1f,0x84,0x00,0,0,0,0\n" 72 + #define P6_NOP2 0x66,0x90 73 + #define P6_NOP3 0x0f,0x1f,0x00 74 + #define P6_NOP4 0x0f,0x1f,0x40,0 75 + #define P6_NOP5 0x0f,0x1f,0x44,0x00,0 76 + #define P6_NOP6 0x66,0x0f,0x1f,0x44,0x00,0 77 + #define P6_NOP7 0x0f,0x1f,0x80,0,0,0,0 78 + #define P6_NOP8 0x0f,0x1f,0x84,0x00,0,0,0,0 79 + #define P6_NOP5_ATOMIC P6_NOP5 80 + 81 + #define _ASM_MK_NOP(x) ".byte " __stringify(x) "\n" 88 82 89 83 #if defined(CONFIG_MK7) 90 - #define ASM_NOP1 K7_NOP1 91 - #define ASM_NOP2 K7_NOP2 92 - #define ASM_NOP3 K7_NOP3 93 - #define ASM_NOP4 K7_NOP4 94 - #define ASM_NOP5 K7_NOP5 95 - #define ASM_NOP6 K7_NOP6 96 - #define ASM_NOP7 K7_NOP7 97 - #define ASM_NOP8 K7_NOP8 84 + #define ASM_NOP1 _ASM_MK_NOP(K7_NOP1) 85 + #define ASM_NOP2 _ASM_MK_NOP(K7_NOP2) 86 + #define ASM_NOP3 _ASM_MK_NOP(K7_NOP3) 87 + #define ASM_NOP4 _ASM_MK_NOP(K7_NOP4) 88 + #define ASM_NOP5 _ASM_MK_NOP(K7_NOP5) 89 + #define ASM_NOP6 _ASM_MK_NOP(K7_NOP6) 90 + #define ASM_NOP7 _ASM_MK_NOP(K7_NOP7) 91 + #define ASM_NOP8 _ASM_MK_NOP(K7_NOP8) 92 + #define ASM_NOP5_ATOMIC _ASM_MK_NOP(K7_NOP5_ATOMIC) 98 93 #elif defined(CONFIG_X86_P6_NOP) 99 - #define ASM_NOP1 P6_NOP1 100 - #define ASM_NOP2 P6_NOP2 101 - #define ASM_NOP3 P6_NOP3 102 - #define ASM_NOP4 P6_NOP4 103 - #define ASM_NOP5 P6_NOP5 104 - #define ASM_NOP6 P6_NOP6 105 - #define ASM_NOP7 P6_NOP7 106 - #define ASM_NOP8 P6_NOP8 94 + #define ASM_NOP1 _ASM_MK_NOP(P6_NOP1) 95 + #define ASM_NOP2 _ASM_MK_NOP(P6_NOP2) 96 + #define ASM_NOP3 _ASM_MK_NOP(P6_NOP3) 97 + #define ASM_NOP4 _ASM_MK_NOP(P6_NOP4) 98 + #define ASM_NOP5 _ASM_MK_NOP(P6_NOP5) 99 + #define ASM_NOP6 _ASM_MK_NOP(P6_NOP6) 100 + #define ASM_NOP7 _ASM_MK_NOP(P6_NOP7) 101 + #define ASM_NOP8 _ASM_MK_NOP(P6_NOP8) 102 + #define ASM_NOP5_ATOMIC _ASM_MK_NOP(P6_NOP5_ATOMIC) 107 103 #elif defined(CONFIG_X86_64) 108 - #define ASM_NOP1 K8_NOP1 109 - #define ASM_NOP2 K8_NOP2 110 - #define ASM_NOP3 K8_NOP3 111 - #define ASM_NOP4 K8_NOP4 112 - #define ASM_NOP5 K8_NOP5 113 - #define ASM_NOP6 K8_NOP6 114 - #define ASM_NOP7 K8_NOP7 115 - #define ASM_NOP8 K8_NOP8 104 + #define ASM_NOP1 _ASM_MK_NOP(K8_NOP1) 105 + #define ASM_NOP2 _ASM_MK_NOP(K8_NOP2) 106 + #define ASM_NOP3 _ASM_MK_NOP(K8_NOP3) 107 + #define ASM_NOP4 _ASM_MK_NOP(K8_NOP4) 108 + #define ASM_NOP5 _ASM_MK_NOP(K8_NOP5) 109 + #define ASM_NOP6 _ASM_MK_NOP(K8_NOP6) 110 + #define ASM_NOP7 _ASM_MK_NOP(K8_NOP7) 111 + #define ASM_NOP8 _ASM_MK_NOP(K8_NOP8) 112 + #define ASM_NOP5_ATOMIC _ASM_MK_NOP(K8_NOP5_ATOMIC) 116 113 #else 117 - #define ASM_NOP1 GENERIC_NOP1 118 - #define ASM_NOP2 GENERIC_NOP2 119 - #define ASM_NOP3 GENERIC_NOP3 120 - #define ASM_NOP4 GENERIC_NOP4 121 - #define ASM_NOP5 GENERIC_NOP5 122 - #define ASM_NOP6 GENERIC_NOP6 123 - #define ASM_NOP7 GENERIC_NOP7 124 - #define ASM_NOP8 GENERIC_NOP8 114 + #define ASM_NOP1 _ASM_MK_NOP(GENERIC_NOP1) 115 + #define ASM_NOP2 _ASM_MK_NOP(GENERIC_NOP2) 116 + #define ASM_NOP3 _ASM_MK_NOP(GENERIC_NOP3) 117 + #define ASM_NOP4 _ASM_MK_NOP(GENERIC_NOP4) 118 + #define ASM_NOP5 _ASM_MK_NOP(GENERIC_NOP5) 119 + #define ASM_NOP6 _ASM_MK_NOP(GENERIC_NOP6) 120 + #define ASM_NOP7 _ASM_MK_NOP(GENERIC_NOP7) 121 + #define ASM_NOP8 _ASM_MK_NOP(GENERIC_NOP8) 122 + #define ASM_NOP5_ATOMIC _ASM_MK_NOP(GENERIC_NOP5_ATOMIC) 125 123 #endif 126 124 127 125 #define ASM_NOP_MAX 8 126 + #define NOP_ATOMIC5 (ASM_NOP_MAX+1) /* Entry for the 5-byte atomic NOP */ 127 + 128 + #ifndef __ASSEMBLY__ 129 + extern const unsigned char * const *ideal_nops; 130 + extern void arch_init_ideal_nops(void); 131 + #endif 128 132 129 133 #endif /* _ASM_X86_NOPS_H */
+1 -1
arch/x86/include/asm/percpu.h
··· 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)), \
+113 -83
arch/x86/kernel/alternative.c
··· 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, ··· 100 87 intelnops + 1 + 2 + 3 + 4 + 5, 101 88 intelnops + 1 + 2 + 3 + 4 + 5 + 6, 102 89 intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7, 90 + intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8, 103 91 }; 104 92 #endif 105 93 106 94 #ifdef K8_NOP1 107 - asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nk8nops: " 108 - K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6 109 - K8_NOP7 K8_NOP8 110 - "\t.previous"); 111 - extern const unsigned char k8nops[]; 112 - static const unsigned char *const __initconst_or_module 113 - k8_nops[ASM_NOP_MAX+1] = { 95 + static const unsigned char k8nops[] = 96 + { 97 + K8_NOP1, 98 + K8_NOP2, 99 + K8_NOP3, 100 + K8_NOP4, 101 + K8_NOP5, 102 + K8_NOP6, 103 + K8_NOP7, 104 + K8_NOP8, 105 + K8_NOP5_ATOMIC 106 + }; 107 + static const unsigned char * const k8_nops[ASM_NOP_MAX+2] = 108 + { 114 109 NULL, 115 110 k8nops, 116 111 k8nops + 1, ··· 128 107 k8nops + 1 + 2 + 3 + 4 + 5, 129 108 k8nops + 1 + 2 + 3 + 4 + 5 + 6, 130 109 k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, 110 + k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8, 131 111 }; 132 112 #endif 133 113 134 114 #if defined(K7_NOP1) && !defined(CONFIG_X86_64) 135 - asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nk7nops: " 136 - K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6 137 - K7_NOP7 K7_NOP8 138 - "\t.previous"); 139 - extern const unsigned char k7nops[]; 140 - static const unsigned char *const __initconst_or_module 141 - k7_nops[ASM_NOP_MAX+1] = { 115 + static const unsigned char k7nops[] = 116 + { 117 + K7_NOP1, 118 + K7_NOP2, 119 + K7_NOP3, 120 + K7_NOP4, 121 + K7_NOP5, 122 + K7_NOP6, 123 + K7_NOP7, 124 + K7_NOP8, 125 + K7_NOP5_ATOMIC 126 + }; 127 + static const unsigned char * const k7_nops[ASM_NOP_MAX+2] = 128 + { 142 129 NULL, 143 130 k7nops, 144 131 k7nops + 1, ··· 156 127 k7nops + 1 + 2 + 3 + 4 + 5, 157 128 k7nops + 1 + 2 + 3 + 4 + 5 + 6, 158 129 k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, 130 + k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8, 159 131 }; 160 132 #endif 161 133 162 134 #ifdef P6_NOP1 163 - asm("\t" __stringify(__INITRODATA_OR_MODULE) "\np6nops: " 164 - P6_NOP1 P6_NOP2 P6_NOP3 P6_NOP4 P6_NOP5 P6_NOP6 165 - P6_NOP7 P6_NOP8 166 - "\t.previous"); 167 - extern const unsigned char p6nops[]; 168 - static const unsigned char *const __initconst_or_module 169 - p6_nops[ASM_NOP_MAX+1] = { 135 + static const unsigned char __initconst_or_module p6nops[] = 136 + { 137 + P6_NOP1, 138 + P6_NOP2, 139 + P6_NOP3, 140 + P6_NOP4, 141 + P6_NOP5, 142 + P6_NOP6, 143 + P6_NOP7, 144 + P6_NOP8, 145 + P6_NOP5_ATOMIC 146 + }; 147 + static const unsigned char * const p6_nops[ASM_NOP_MAX+2] = 148 + { 170 149 NULL, 171 150 p6nops, 172 151 p6nops + 1, ··· 184 147 p6nops + 1 + 2 + 3 + 4 + 5, 185 148 p6nops + 1 + 2 + 3 + 4 + 5 + 6, 186 149 p6nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, 150 + p6nops + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8, 187 151 }; 188 152 #endif 189 153 154 + /* Initialize these to a safe default */ 190 155 #ifdef CONFIG_X86_64 156 + const unsigned char * const *ideal_nops = p6_nops; 157 + #else 158 + const unsigned char * const *ideal_nops = intel_nops; 159 + #endif 191 160 192 - extern char __vsyscall_0; 193 - static const unsigned char *const *__init_or_module find_nop_table(void) 161 + void __init arch_init_ideal_nops(void) 194 162 { 195 - if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && 196 - boot_cpu_has(X86_FEATURE_NOPL)) 197 - return p6_nops; 198 - else 199 - return k8_nops; 163 + switch (boot_cpu_data.x86_vendor) { 164 + case X86_VENDOR_INTEL: 165 + /* 166 + * Due to a decoder implementation quirk, some 167 + * specific Intel CPUs actually perform better with 168 + * the "k8_nops" than with the SDM-recommended NOPs. 169 + */ 170 + if (boot_cpu_data.x86 == 6 && 171 + boot_cpu_data.x86_model >= 0x0f && 172 + boot_cpu_data.x86_model != 0x1c && 173 + boot_cpu_data.x86_model != 0x26 && 174 + boot_cpu_data.x86_model != 0x27 && 175 + boot_cpu_data.x86_model < 0x30) { 176 + ideal_nops = k8_nops; 177 + } else if (boot_cpu_has(X86_FEATURE_NOPL)) { 178 + ideal_nops = p6_nops; 179 + } else { 180 + #ifdef CONFIG_X86_64 181 + ideal_nops = k8_nops; 182 + #else 183 + ideal_nops = intel_nops; 184 + #endif 185 + } 186 + 187 + default: 188 + #ifdef CONFIG_X86_64 189 + ideal_nops = k8_nops; 190 + #else 191 + if (boot_cpu_has(X86_FEATURE_K8)) 192 + ideal_nops = k8_nops; 193 + else if (boot_cpu_has(X86_FEATURE_K7)) 194 + ideal_nops = k7_nops; 195 + else 196 + ideal_nops = intel_nops; 197 + #endif 198 + } 200 199 } 201 - 202 - #else /* CONFIG_X86_64 */ 203 - 204 - static const unsigned char *const *__init_or_module find_nop_table(void) 205 - { 206 - if (boot_cpu_has(X86_FEATURE_K8)) 207 - return k8_nops; 208 - else if (boot_cpu_has(X86_FEATURE_K7)) 209 - return k7_nops; 210 - else if (boot_cpu_has(X86_FEATURE_NOPL)) 211 - return p6_nops; 212 - else 213 - return intel_nops; 214 - } 215 - 216 - #endif /* CONFIG_X86_64 */ 217 200 218 201 /* Use this to add nops to a buffer, then text_poke the whole buffer. */ 219 202 static void __init_or_module add_nops(void *insns, unsigned int len) 220 203 { 221 - const unsigned char *const *noptable = find_nop_table(); 222 - 223 204 while (len > 0) { 224 205 unsigned int noplen = len; 225 206 if (noplen > ASM_NOP_MAX) 226 207 noplen = ASM_NOP_MAX; 227 - memcpy(insns, noptable[noplen], noplen); 208 + memcpy(insns, ideal_nops[noplen], noplen); 228 209 insns += noplen; 229 210 len -= noplen; 230 211 } ··· 250 195 251 196 extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; 252 197 extern s32 __smp_locks[], __smp_locks_end[]; 198 + extern char __vsyscall_0; 253 199 void *text_poke_early(void *addr, const void *opcode, size_t len); 254 200 255 201 /* Replace instructions with better alternatives for this CPU type. ··· 743 687 wrote_text = 0; 744 688 __stop_machine(stop_machine_text_poke, (void *)&tpp, NULL); 745 689 } 746 - 747 - #if defined(CONFIG_DYNAMIC_FTRACE) || defined(CONFIG_JUMP_LABEL) 748 - 749 - #ifdef CONFIG_X86_64 750 - unsigned char ideal_nop5[5] = { 0x66, 0x66, 0x66, 0x66, 0x90 }; 751 - #else 752 - unsigned char ideal_nop5[5] = { 0x3e, 0x8d, 0x74, 0x26, 0x00 }; 753 - #endif 754 - 755 - void __init arch_init_ideal_nop5(void) 756 - { 757 - /* 758 - * There is no good nop for all x86 archs. This selection 759 - * algorithm should be unified with the one in find_nop_table(), 760 - * but this should be good enough for now. 761 - * 762 - * For cases other than the ones below, use the safe (as in 763 - * always functional) defaults above. 764 - */ 765 - #ifdef CONFIG_X86_64 766 - /* Don't use these on 32 bits due to broken virtualizers */ 767 - if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) 768 - memcpy(ideal_nop5, p6_nops[5], 5); 769 - #endif 770 - } 771 - #endif
+4 -6
arch/x86/kernel/cpu/intel.c
··· 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:
+4 -16
arch/x86/kernel/cpu/intel_cacheinfo.c
··· 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 ··· 453 454 { 454 455 int ret = 0; 455 456 456 - #define SUBCACHE_MASK (3UL << 20) 457 - #define SUBCACHE_INDEX 0xfff 458 - 459 - /* 460 - * check whether this slot is already used or 461 - * the index is already disabled 462 - */ 457 + /* check if @slot is already used or the index is already disabled */ 463 458 ret = amd_get_l3_disable_slot(l3, slot); 464 459 if (ret >= 0) 465 460 return -EINVAL; 466 461 467 - /* 468 - * check whether the other slot has disabled the 469 - * same index already 470 - */ 471 - if (index == amd_get_l3_disable_slot(l3, !slot)) 462 + if (index > l3->indices) 472 463 return -EINVAL; 473 464 474 - /* do not allow writes outside of allowed bits */ 475 - if ((index & ~(SUBCACHE_MASK | SUBCACHE_INDEX)) || 476 - ((index & SUBCACHE_INDEX) > l3->indices)) 465 + /* check whether the other slot has disabled the same index already */ 466 + if (index == amd_get_l3_disable_slot(l3, !slot)) 477 467 return -EINVAL; 478 468 479 469 amd_l3_disable_index(l3, cpu, slot, index);
+2 -2
arch/x86/kernel/ftrace.c
··· 260 260 return mod_code_status; 261 261 } 262 262 263 - static unsigned char *ftrace_nop_replace(void) 263 + static const unsigned char *ftrace_nop_replace(void) 264 264 { 265 - return ideal_nop5; 265 + return ideal_nops[NOP_ATOMIC5]; 266 266 } 267 267 268 268 static int
+3 -2
arch/x86/kernel/jump_label.c
··· 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 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
+1 -5
arch/x86/kernel/setup.c
··· 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(); ··· 1039 1041 1040 1042 mcheck_init(); 1041 1043 1042 - local_irq_save(flags); 1043 - arch_init_ideal_nop5(); 1044 - local_irq_restore(flags); 1044 + arch_init_ideal_nops(); 1045 1045 } 1046 1046 1047 1047 #ifdef CONFIG_X86_32
+2 -2
drivers/cpufreq/Kconfig.x86
··· 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 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