|
@@ -132,11 +132,8 @@ static void nop_out(void *insns, unsigned int len)
|
|
}
|
|
}
|
|
|
|
|
|
extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
|
|
extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
|
|
-extern struct alt_instr __smp_alt_instructions[], __smp_alt_instructions_end[];
|
|
|
|
extern u8 *__smp_locks[], *__smp_locks_end[];
|
|
extern u8 *__smp_locks[], *__smp_locks_end[];
|
|
|
|
|
|
-extern u8 __smp_alt_begin[], __smp_alt_end[];
|
|
|
|
-
|
|
|
|
/* Replace instructions with better alternatives for this CPU type.
|
|
/* Replace instructions with better alternatives for this CPU type.
|
|
This runs before SMP is initialized to avoid SMP problems with
|
|
This runs before SMP is initialized to avoid SMP problems with
|
|
self modifying code. This implies that assymetric systems where
|
|
self modifying code. This implies that assymetric systems where
|
|
@@ -171,29 +168,6 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end)
|
|
|
|
|
|
#ifdef CONFIG_SMP
|
|
#ifdef CONFIG_SMP
|
|
|
|
|
|
-static void alternatives_smp_save(struct alt_instr *start, struct alt_instr *end)
|
|
|
|
-{
|
|
|
|
- struct alt_instr *a;
|
|
|
|
-
|
|
|
|
- DPRINTK("%s: alt table %p-%p\n", __FUNCTION__, start, end);
|
|
|
|
- for (a = start; a < end; a++) {
|
|
|
|
- memcpy(a->replacement + a->replacementlen,
|
|
|
|
- a->instr,
|
|
|
|
- a->instrlen);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void alternatives_smp_apply(struct alt_instr *start, struct alt_instr *end)
|
|
|
|
-{
|
|
|
|
- struct alt_instr *a;
|
|
|
|
-
|
|
|
|
- for (a = start; a < end; a++) {
|
|
|
|
- memcpy(a->instr,
|
|
|
|
- a->replacement + a->replacementlen,
|
|
|
|
- a->instrlen);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end)
|
|
static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end)
|
|
{
|
|
{
|
|
u8 **ptr;
|
|
u8 **ptr;
|
|
@@ -319,8 +293,6 @@ void alternatives_smp_switch(int smp)
|
|
printk(KERN_INFO "SMP alternatives: switching to SMP code\n");
|
|
printk(KERN_INFO "SMP alternatives: switching to SMP code\n");
|
|
clear_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability);
|
|
clear_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability);
|
|
clear_bit(X86_FEATURE_UP, cpu_data[0].x86_capability);
|
|
clear_bit(X86_FEATURE_UP, cpu_data[0].x86_capability);
|
|
- alternatives_smp_apply(__smp_alt_instructions,
|
|
|
|
- __smp_alt_instructions_end);
|
|
|
|
list_for_each_entry(mod, &smp_alt_modules, next)
|
|
list_for_each_entry(mod, &smp_alt_modules, next)
|
|
alternatives_smp_lock(mod->locks, mod->locks_end,
|
|
alternatives_smp_lock(mod->locks, mod->locks_end,
|
|
mod->text, mod->text_end);
|
|
mod->text, mod->text_end);
|
|
@@ -328,8 +300,6 @@ void alternatives_smp_switch(int smp)
|
|
printk(KERN_INFO "SMP alternatives: switching to UP code\n");
|
|
printk(KERN_INFO "SMP alternatives: switching to UP code\n");
|
|
set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability);
|
|
set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability);
|
|
set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability);
|
|
set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability);
|
|
- apply_alternatives(__smp_alt_instructions,
|
|
|
|
- __smp_alt_instructions_end);
|
|
|
|
list_for_each_entry(mod, &smp_alt_modules, next)
|
|
list_for_each_entry(mod, &smp_alt_modules, next)
|
|
alternatives_smp_unlock(mod->locks, mod->locks_end,
|
|
alternatives_smp_unlock(mod->locks, mod->locks_end,
|
|
mod->text, mod->text_end);
|
|
mod->text, mod->text_end);
|
|
@@ -396,17 +366,13 @@ void __init alternative_instructions(void)
|
|
printk(KERN_INFO "SMP alternatives: switching to UP code\n");
|
|
printk(KERN_INFO "SMP alternatives: switching to UP code\n");
|
|
set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability);
|
|
set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability);
|
|
set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability);
|
|
set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability);
|
|
- apply_alternatives(__smp_alt_instructions,
|
|
|
|
- __smp_alt_instructions_end);
|
|
|
|
alternatives_smp_unlock(__smp_locks, __smp_locks_end,
|
|
alternatives_smp_unlock(__smp_locks, __smp_locks_end,
|
|
_text, _etext);
|
|
_text, _etext);
|
|
}
|
|
}
|
|
free_init_pages("SMP alternatives",
|
|
free_init_pages("SMP alternatives",
|
|
- __pa_symbol(&__smp_alt_begin),
|
|
|
|
- __pa_symbol(&__smp_alt_end));
|
|
|
|
|
|
+ __pa_symbol(&__smp_locks),
|
|
|
|
+ __pa_symbol(&__smp_locks_end));
|
|
} else {
|
|
} else {
|
|
- alternatives_smp_save(__smp_alt_instructions,
|
|
|
|
- __smp_alt_instructions_end);
|
|
|
|
alternatives_smp_module_add(NULL, "core kernel",
|
|
alternatives_smp_module_add(NULL, "core kernel",
|
|
__smp_locks, __smp_locks_end,
|
|
__smp_locks, __smp_locks_end,
|
|
_text, _etext);
|
|
_text, _etext);
|