aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/alternative.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-17 16:13:16 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-17 16:13:16 -0400
commitd20ead9e86881bc7ae84e385f47b5196b7d93aac (patch)
treeed27dd5db5f8447e4b3f541f0ec38219085d2f32 /arch/x86/kernel/alternative.c
parentc56ec7639288f3e5d6371b0c48d37da93642fc93 (diff)
parent88e4d250234fc9e64d6ce51df95efdcf8334fd95 (diff)
Merge ssh://master.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-x86
* ssh://master.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-x86: (114 commits) x86: delete vsyscall files during make clean kbuild: fix typo SRCARCH in find_sources x86: fix kernel rebuild due to vsyscall fallout .gitignore update for x86 arch x86: unify include/asm/debugreg_32/64.h x86: unify include/asm/unwind_32/64.h x86: unify include/asm/types_32/64.h x86: unify include/asm/tlb_32/64.h x86: unify include/asm/siginfo_32/64.h x86: unify include/asm/bug_32/64.h x86: unify include/asm/mman_32/64.h x86: unify include/asm/agp_32/64.h x86: unify include/asm/kdebug_32/64.h x86: unify include/asm/ioctls_32/64.h x86: unify include/asm/floppy_32/64.h x86: apply missing DMA/OOM prevention to floppy_32.h x86: unify include/asm/cache_32/64.h x86: unify include/asm/cache_32/64.h x86: unify include/asm/dmi_32/64.h x86: unify include/asm/delay_32/64.h ...
Diffstat (limited to 'arch/x86/kernel/alternative.c')
-rw-r--r--arch/x86/kernel/alternative.c61
1 files changed, 42 insertions, 19 deletions
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 42421437ded3..3bd2688bd443 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -63,11 +63,11 @@ __setup("noreplace-paravirt", setup_noreplace_paravirt);
63/* Use inline assembly to define this because the nops are defined 63/* Use inline assembly to define this because the nops are defined
64 as inline assembly strings in the include files and we cannot 64 as inline assembly strings in the include files and we cannot
65 get them easily into strings. */ 65 get them easily into strings. */
66asm("\t.data\nintelnops: " 66asm("\t.section .rodata, \"a\"\nintelnops: "
67 GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6 67 GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6
68 GENERIC_NOP7 GENERIC_NOP8); 68 GENERIC_NOP7 GENERIC_NOP8);
69extern unsigned char intelnops[]; 69extern const unsigned char intelnops[];
70static unsigned char *intel_nops[ASM_NOP_MAX+1] = { 70static const unsigned char *const intel_nops[ASM_NOP_MAX+1] = {
71 NULL, 71 NULL,
72 intelnops, 72 intelnops,
73 intelnops + 1, 73 intelnops + 1,
@@ -81,11 +81,11 @@ static unsigned char *intel_nops[ASM_NOP_MAX+1] = {
81#endif 81#endif
82 82
83#ifdef K8_NOP1 83#ifdef K8_NOP1
84asm("\t.data\nk8nops: " 84asm("\t.section .rodata, \"a\"\nk8nops: "
85 K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6 85 K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6
86 K8_NOP7 K8_NOP8); 86 K8_NOP7 K8_NOP8);
87extern unsigned char k8nops[]; 87extern const unsigned char k8nops[];
88static unsigned char *k8_nops[ASM_NOP_MAX+1] = { 88static const unsigned char *const k8_nops[ASM_NOP_MAX+1] = {
89 NULL, 89 NULL,
90 k8nops, 90 k8nops,
91 k8nops + 1, 91 k8nops + 1,
@@ -99,11 +99,11 @@ static unsigned char *k8_nops[ASM_NOP_MAX+1] = {
99#endif 99#endif
100 100
101#ifdef K7_NOP1 101#ifdef K7_NOP1
102asm("\t.data\nk7nops: " 102asm("\t.section .rodata, \"a\"\nk7nops: "
103 K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6 103 K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6
104 K7_NOP7 K7_NOP8); 104 K7_NOP7 K7_NOP8);
105extern unsigned char k7nops[]; 105extern const unsigned char k7nops[];
106static unsigned char *k7_nops[ASM_NOP_MAX+1] = { 106static const unsigned char *const k7_nops[ASM_NOP_MAX+1] = {
107 NULL, 107 NULL,
108 k7nops, 108 k7nops,
109 k7nops + 1, 109 k7nops + 1,
@@ -116,28 +116,49 @@ static unsigned char *k7_nops[ASM_NOP_MAX+1] = {
116}; 116};
117#endif 117#endif
118 118
119#ifdef P6_NOP1
120asm("\t.section .rodata, \"a\"\np6nops: "
121 P6_NOP1 P6_NOP2 P6_NOP3 P6_NOP4 P6_NOP5 P6_NOP6
122 P6_NOP7 P6_NOP8);
123extern const unsigned char p6nops[];
124static 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#ifdef CONFIG_X86_64 137#ifdef CONFIG_X86_64
120 138
121extern char __vsyscall_0; 139extern char __vsyscall_0;
122static inline unsigned char** find_nop_table(void) 140static 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#else /* CONFIG_X86_64 */ 146#else /* CONFIG_X86_64 */
128 147
129static struct nop { 148static const struct nop {
130 int cpuid; 149 int cpuid;
131 unsigned char **noptable; 150 const unsigned char *const *noptable;
132} noptypes[] = { 151} noptypes[] = {
133 { X86_FEATURE_K8, k8_nops }, 152 { X86_FEATURE_K8, k8_nops },
134 { X86_FEATURE_K7, k7_nops }, 153 { X86_FEATURE_K7, k7_nops },
154 { X86_FEATURE_P4, p6_nops },
155 { X86_FEATURE_P3, p6_nops },
135 { -1, NULL } 156 { -1, NULL }
136}; 157};
137 158
138static unsigned char** find_nop_table(void) 159static const unsigned char*const * find_nop_table(void)
139{ 160{
140 unsigned char **noptable = intel_nops; 161 const unsigned char *const *noptable = intel_nops;
141 int i; 162 int i;
142 163
143 for (i = 0; noptypes[i].cpuid >= 0; i++) { 164 for (i = 0; noptypes[i].cpuid >= 0; i++) {
@@ -154,7 +175,7 @@ static unsigned char** find_nop_table(void)
154/* Use this to add nops to a buffer, then text_poke the whole buffer. */ 175/* Use this to add nops to a buffer, then text_poke the whole buffer. */
155static void add_nops(void *insns, unsigned int len) 176static void add_nops(void *insns, unsigned int len)
156{ 177{
157 unsigned char **noptable = find_nop_table(); 178 const unsigned char *const *noptable = find_nop_table();
158 179
159 while (len > 0) { 180 while (len > 0) {
160 unsigned int noplen = len; 181 unsigned int noplen = len;
@@ -415,9 +436,6 @@ void __init alternative_instructions(void)
415 alternatives_smp_unlock(__smp_locks, __smp_locks_end, 436 alternatives_smp_unlock(__smp_locks, __smp_locks_end,
416 _text, _etext); 437 _text, _etext);
417 } 438 }
418 free_init_pages("SMP alternatives",
419 (unsigned long)__smp_locks,
420 (unsigned long)__smp_locks_end);
421 } else { 439 } else {
422 alternatives_smp_module_add(NULL, "core kernel", 440 alternatives_smp_module_add(NULL, "core kernel",
423 __smp_locks, __smp_locks_end, 441 __smp_locks, __smp_locks_end,
@@ -428,6 +446,11 @@ void __init alternative_instructions(void)
428 apply_paravirt(__parainstructions, __parainstructions_end); 446 apply_paravirt(__parainstructions, __parainstructions_end);
429 local_irq_restore(flags); 447 local_irq_restore(flags);
430 448
449 if (smp_alt_once)
450 free_init_pages("SMP alternatives",
451 (unsigned long)__smp_locks,
452 (unsigned long)__smp_locks_end);
453
431 restart_nmi(); 454 restart_nmi();
432#ifdef CONFIG_X86_MCE 455#ifdef CONFIG_X86_MCE
433 restart_mce(); 456 restart_mce();