diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 6 | ||||
-rw-r--r-- | arch/i386/kernel/alternative.c | 23 |
2 files changed, 25 insertions, 4 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 94ce0d20253d..242b3a09b6ce 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1164,6 +1164,9 @@ and is between 256 and 4096 characters. It is defined in the file | |||
1164 | 1164 | ||
1165 | nomce [IA-32] Machine Check Exception | 1165 | nomce [IA-32] Machine Check Exception |
1166 | 1166 | ||
1167 | noreplace-smp [IA-32,SMP] Don't replace SMP instructions | ||
1168 | with UP alternatives | ||
1169 | |||
1167 | noresidual [PPC] Don't use residual data on PReP machines. | 1170 | noresidual [PPC] Don't use residual data on PReP machines. |
1168 | 1171 | ||
1169 | noresume [SWSUSP] Disables resume and restores original swap | 1172 | noresume [SWSUSP] Disables resume and restores original swap |
@@ -1569,6 +1572,9 @@ and is between 256 and 4096 characters. It is defined in the file | |||
1569 | smart2= [HW] | 1572 | smart2= [HW] |
1570 | Format: <io1>[,<io2>[,...,<io8>]] | 1573 | Format: <io1>[,<io2>[,...,<io8>]] |
1571 | 1574 | ||
1575 | smp-alt-once [IA-32,SMP] On a hotplug CPU system, only | ||
1576 | attempt to substitute SMP alternatives once at boot. | ||
1577 | |||
1572 | snd-ad1816a= [HW,ALSA] | 1578 | snd-ad1816a= [HW,ALSA] |
1573 | 1579 | ||
1574 | snd-ad1848= [HW,ALSA] | 1580 | snd-ad1848= [HW,ALSA] |
diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index f09635408049..9b8e85a8edec 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <asm/alternative.h> | 5 | #include <asm/alternative.h> |
6 | #include <asm/sections.h> | 6 | #include <asm/sections.h> |
7 | 7 | ||
8 | static int noreplace_smp = 0; | ||
8 | static int smp_alt_once = 0; | 9 | static int smp_alt_once = 0; |
9 | static int debug_alternative = 0; | 10 | static int debug_alternative = 0; |
10 | 11 | ||
@@ -13,15 +14,23 @@ static int __init bootonly(char *str) | |||
13 | smp_alt_once = 1; | 14 | smp_alt_once = 1; |
14 | return 1; | 15 | return 1; |
15 | } | 16 | } |
17 | __setup("smp-alt-boot", bootonly); | ||
18 | |||
16 | static int __init debug_alt(char *str) | 19 | static int __init debug_alt(char *str) |
17 | { | 20 | { |
18 | debug_alternative = 1; | 21 | debug_alternative = 1; |
19 | return 1; | 22 | return 1; |
20 | } | 23 | } |
21 | |||
22 | __setup("smp-alt-boot", bootonly); | ||
23 | __setup("debug-alternative", debug_alt); | 24 | __setup("debug-alternative", debug_alt); |
24 | 25 | ||
26 | static int __init setup_noreplace_smp(char *str) | ||
27 | { | ||
28 | noreplace_smp = 1; | ||
29 | return 1; | ||
30 | } | ||
31 | __setup("noreplace-smp", setup_noreplace_smp); | ||
32 | |||
33 | |||
25 | #define DPRINTK(fmt, args...) if (debug_alternative) \ | 34 | #define DPRINTK(fmt, args...) if (debug_alternative) \ |
26 | printk(KERN_DEBUG fmt, args) | 35 | printk(KERN_DEBUG fmt, args) |
27 | 36 | ||
@@ -185,6 +194,9 @@ static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end | |||
185 | { | 194 | { |
186 | u8 **ptr; | 195 | u8 **ptr; |
187 | 196 | ||
197 | if (noreplace_smp) | ||
198 | return; | ||
199 | |||
188 | for (ptr = start; ptr < end; ptr++) { | 200 | for (ptr = start; ptr < end; ptr++) { |
189 | if (*ptr < text) | 201 | if (*ptr < text) |
190 | continue; | 202 | continue; |
@@ -219,6 +231,9 @@ void alternatives_smp_module_add(struct module *mod, char *name, | |||
219 | struct smp_alt_module *smp; | 231 | struct smp_alt_module *smp; |
220 | unsigned long flags; | 232 | unsigned long flags; |
221 | 233 | ||
234 | if (noreplace_smp) | ||
235 | return; | ||
236 | |||
222 | if (smp_alt_once) { | 237 | if (smp_alt_once) { |
223 | if (boot_cpu_has(X86_FEATURE_UP)) | 238 | if (boot_cpu_has(X86_FEATURE_UP)) |
224 | alternatives_smp_unlock(locks, locks_end, | 239 | alternatives_smp_unlock(locks, locks_end, |
@@ -253,7 +268,7 @@ void alternatives_smp_module_del(struct module *mod) | |||
253 | struct smp_alt_module *item; | 268 | struct smp_alt_module *item; |
254 | unsigned long flags; | 269 | unsigned long flags; |
255 | 270 | ||
256 | if (smp_alt_once) | 271 | if (smp_alt_once || noreplace_smp) |
257 | return; | 272 | return; |
258 | 273 | ||
259 | spin_lock_irqsave(&smp_alt, flags); | 274 | spin_lock_irqsave(&smp_alt, flags); |
@@ -284,7 +299,7 @@ void alternatives_smp_switch(int smp) | |||
284 | return; | 299 | return; |
285 | #endif | 300 | #endif |
286 | 301 | ||
287 | if (smp_alt_once) | 302 | if (noreplace_smp || smp_alt_once) |
288 | return; | 303 | return; |
289 | BUG_ON(!smp && (num_online_cpus() > 1)); | 304 | BUG_ON(!smp && (num_online_cpus() > 1)); |
290 | 305 | ||