Commit 32c464f5d9701db45bc1673288594e664065388e
Committed by
Thomas Gleixner
1 parent
c861eff88c
Exists in
master
and in
7 other branches
x86: multi-byte single instruction NOPs
Add support for and use the multi-byte NOPs recently documented to be available on all PentiumPro and later processors. This patch only applies cleanly on top of the "x86: misc. constifications" patch sent earlier. [ tglx: arch/x86 adaptation ] Signed-off-by: Jan Beulich <jbeulich@novell.com> Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> arch/x86/kernel/alternative.c | 23 ++++++++++++++++++++++- include/asm-x86/processor_32.h | 22 ++++++++++++++++++++++ include/asm-x86/processor_64.h | 22 ++++++++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-)
Showing 3 changed files with 66 additions and 1 deletions Side-by-side Diff
arch/x86/kernel/alternative.c
... | ... | @@ -116,12 +116,31 @@ |
116 | 116 | }; |
117 | 117 | #endif |
118 | 118 | |
119 | +#ifdef P6_NOP1 | |
120 | +asm("\t.section .rodata, \"a\"\np6nops: " | |
121 | + P6_NOP1 P6_NOP2 P6_NOP3 P6_NOP4 P6_NOP5 P6_NOP6 | |
122 | + P6_NOP7 P6_NOP8); | |
123 | +extern const unsigned char p6nops[]; | |
124 | +static const unsigned char *const p6_nops[ASM_NOP_MAX+1] = { | |
125 | + NULL, | |
126 | + p6nops, | |
127 | + p6nops + 1, | |
128 | + p6nops + 1 + 2, | |
129 | + p6nops + 1 + 2 + 3, | |
130 | + p6nops + 1 + 2 + 3 + 4, | |
131 | + p6nops + 1 + 2 + 3 + 4 + 5, | |
132 | + p6nops + 1 + 2 + 3 + 4 + 5 + 6, | |
133 | + p6nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, | |
134 | +}; | |
135 | +#endif | |
136 | + | |
119 | 137 | #ifdef CONFIG_X86_64 |
120 | 138 | |
121 | 139 | extern char __vsyscall_0; |
122 | 140 | static inline const unsigned char*const * find_nop_table(void) |
123 | 141 | { |
124 | - return k8_nops; | |
142 | + return boot_cpu_data.x86_vendor != X86_VENDOR_INTEL || | |
143 | + boot_cpu_data.x86 < 6 ? k8_nops : p6_nops; | |
125 | 144 | } |
126 | 145 | |
127 | 146 | #else /* CONFIG_X86_64 */ |
... | ... | @@ -132,6 +151,8 @@ |
132 | 151 | } noptypes[] = { |
133 | 152 | { X86_FEATURE_K8, k8_nops }, |
134 | 153 | { X86_FEATURE_K7, k7_nops }, |
154 | + { X86_FEATURE_P4, p6_nops }, | |
155 | + { X86_FEATURE_P3, p6_nops }, | |
135 | 156 | { -1, NULL } |
136 | 157 | }; |
137 | 158 |
include/asm-x86/processor_32.h
... | ... | @@ -677,6 +677,17 @@ |
677 | 677 | #define K7_NOP7 ".byte 0x8D,0x04,0x05,0,0,0,0\n" |
678 | 678 | #define K7_NOP8 K7_NOP7 ASM_NOP1 |
679 | 679 | |
680 | +/* P6 nops */ | |
681 | +/* uses eax dependencies (Intel-recommended choice) */ | |
682 | +#define P6_NOP1 GENERIC_NOP1 | |
683 | +#define P6_NOP2 ".byte 0x66,0x90\n" | |
684 | +#define P6_NOP3 ".byte 0x0f,0x1f,0x00\n" | |
685 | +#define P6_NOP4 ".byte 0x0f,0x1f,0x40,0\n" | |
686 | +#define P6_NOP5 ".byte 0x0f,0x1f,0x44,0x00,0\n" | |
687 | +#define P6_NOP6 ".byte 0x66,0x0f,0x1f,0x44,0x00,0\n" | |
688 | +#define P6_NOP7 ".byte 0x0f,0x1f,0x80,0,0,0,0\n" | |
689 | +#define P6_NOP8 ".byte 0x0f,0x1f,0x84,0x00,0,0,0,0\n" | |
690 | + | |
680 | 691 | #ifdef CONFIG_MK8 |
681 | 692 | #define ASM_NOP1 K8_NOP1 |
682 | 693 | #define ASM_NOP2 K8_NOP2 |
... | ... | @@ -695,6 +706,17 @@ |
695 | 706 | #define ASM_NOP6 K7_NOP6 |
696 | 707 | #define ASM_NOP7 K7_NOP7 |
697 | 708 | #define ASM_NOP8 K7_NOP8 |
709 | +#elif defined(CONFIG_M686) || defined(CONFIG_MPENTIUMII) || \ | |
710 | + defined(CONFIG_MPENTIUMIII) || defined(CONFIG_MPENTIUMM) || \ | |
711 | + defined(CONFIG_MCORE2) || defined(CONFIG_PENTIUM4) | |
712 | +#define ASM_NOP1 P6_NOP1 | |
713 | +#define ASM_NOP2 P6_NOP2 | |
714 | +#define ASM_NOP3 P6_NOP3 | |
715 | +#define ASM_NOP4 P6_NOP4 | |
716 | +#define ASM_NOP5 P6_NOP5 | |
717 | +#define ASM_NOP6 P6_NOP6 | |
718 | +#define ASM_NOP7 P6_NOP7 | |
719 | +#define ASM_NOP8 P6_NOP8 | |
698 | 720 | #else |
699 | 721 | #define ASM_NOP1 GENERIC_NOP1 |
700 | 722 | #define ASM_NOP2 GENERIC_NOP2 |
include/asm-x86/processor_64.h
... | ... | @@ -334,6 +334,16 @@ |
334 | 334 | }; |
335 | 335 | |
336 | 336 | |
337 | +#if defined(CONFIG_MPSC) || defined(CONFIG_MCORE2) | |
338 | +#define ASM_NOP1 P6_NOP1 | |
339 | +#define ASM_NOP2 P6_NOP2 | |
340 | +#define ASM_NOP3 P6_NOP3 | |
341 | +#define ASM_NOP4 P6_NOP4 | |
342 | +#define ASM_NOP5 P6_NOP5 | |
343 | +#define ASM_NOP6 P6_NOP6 | |
344 | +#define ASM_NOP7 P6_NOP7 | |
345 | +#define ASM_NOP8 P6_NOP8 | |
346 | +#else | |
337 | 347 | #define ASM_NOP1 K8_NOP1 |
338 | 348 | #define ASM_NOP2 K8_NOP2 |
339 | 349 | #define ASM_NOP3 K8_NOP3 |
... | ... | @@ -342,6 +352,7 @@ |
342 | 352 | #define ASM_NOP6 K8_NOP6 |
343 | 353 | #define ASM_NOP7 K8_NOP7 |
344 | 354 | #define ASM_NOP8 K8_NOP8 |
355 | +#endif | |
345 | 356 | |
346 | 357 | /* Opteron nops */ |
347 | 358 | #define K8_NOP1 ".byte 0x90\n" |
... | ... | @@ -352,6 +363,17 @@ |
352 | 363 | #define K8_NOP6 K8_NOP3 K8_NOP3 |
353 | 364 | #define K8_NOP7 K8_NOP4 K8_NOP3 |
354 | 365 | #define K8_NOP8 K8_NOP4 K8_NOP4 |
366 | + | |
367 | +/* P6 nops */ | |
368 | +/* uses eax dependencies (Intel-recommended choice) */ | |
369 | +#define P6_NOP1 ".byte 0x90\n" | |
370 | +#define P6_NOP2 ".byte 0x66,0x90\n" | |
371 | +#define P6_NOP3 ".byte 0x0f,0x1f,0x00\n" | |
372 | +#define P6_NOP4 ".byte 0x0f,0x1f,0x40,0\n" | |
373 | +#define P6_NOP5 ".byte 0x0f,0x1f,0x44,0x00,0\n" | |
374 | +#define P6_NOP6 ".byte 0x66,0x0f,0x1f,0x44,0x00,0\n" | |
375 | +#define P6_NOP7 ".byte 0x0f,0x1f,0x80,0,0,0,0\n" | |
376 | +#define P6_NOP8 ".byte 0x0f,0x1f,0x84,0x00,0,0,0,0\n" | |
355 | 377 | |
356 | 378 | #define ASM_NOP_MAX 8 |
357 | 379 |