x86 Fix VMI crash on boot in 2.6.28-rc8
VMI initialiation can relocate the fixmap, causing early_ioremap to malfunction if it is initialized before the relocation. To fix this, VMI activation is split into two phases; the detection, which must happen before setting up ioremap, and the activation, which must happen after parsing early boot parameters. This fixes a crash on boot when VMI is enabled under VMware. Signed-off-by: Zachary Amsden <zach@vmware.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Родитель
ca7e716c78
Коммит
ae8d04e2ec
|
@ -223,9 +223,15 @@ struct pci_header {
|
|||
} __attribute__((packed));
|
||||
|
||||
/* Function prototypes for bootstrapping */
|
||||
#ifdef CONFIG_VMI
|
||||
extern void vmi_init(void);
|
||||
extern void vmi_activate(void);
|
||||
extern void vmi_bringup(void);
|
||||
extern void vmi_apply_boot_page_allocations(void);
|
||||
#else
|
||||
static inline void vmi_init(void) {}
|
||||
static inline void vmi_activate(void) {}
|
||||
static inline void vmi_bringup(void) {}
|
||||
#endif
|
||||
|
||||
/* State needed to start an application processor in an SMP system. */
|
||||
struct vmi_ap_state {
|
||||
|
|
|
@ -794,6 +794,9 @@ void __init setup_arch(char **cmdline_p)
|
|||
printk(KERN_INFO "Command line: %s\n", boot_command_line);
|
||||
#endif
|
||||
|
||||
/* VMI may relocate the fixmap; do this before touching ioremap area */
|
||||
vmi_init();
|
||||
|
||||
early_cpu_init();
|
||||
early_ioremap_init();
|
||||
|
||||
|
@ -880,13 +883,8 @@ void __init setup_arch(char **cmdline_p)
|
|||
check_efer();
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_VMI) && defined(CONFIG_X86_32)
|
||||
/*
|
||||
* Must be before kernel pagetables are setup
|
||||
* or fixmap area is touched.
|
||||
*/
|
||||
vmi_init();
|
||||
#endif
|
||||
/* Must be before kernel pagetables are setup */
|
||||
vmi_activate();
|
||||
|
||||
/* after early param, so could get panic from serial */
|
||||
reserve_early_setup_data();
|
||||
|
|
|
@ -294,9 +294,7 @@ static void __cpuinit start_secondary(void *unused)
|
|||
* fragile that we want to limit the things done here to the
|
||||
* most necessary things.
|
||||
*/
|
||||
#ifdef CONFIG_VMI
|
||||
vmi_bringup();
|
||||
#endif
|
||||
cpu_init();
|
||||
preempt_disable();
|
||||
smp_callin();
|
||||
|
|
|
@ -960,8 +960,6 @@ static inline int __init activate_vmi(void)
|
|||
|
||||
void __init vmi_init(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (!vmi_rom)
|
||||
probe_vmi_rom();
|
||||
else
|
||||
|
@ -973,13 +971,21 @@ void __init vmi_init(void)
|
|||
|
||||
reserve_top_address(-vmi_rom->virtual_top);
|
||||
|
||||
local_irq_save(flags);
|
||||
activate_vmi();
|
||||
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
/* This is virtual hardware; timer routing is wired correctly */
|
||||
no_timer_check = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void vmi_activate(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (!vmi_rom)
|
||||
return;
|
||||
|
||||
local_irq_save(flags);
|
||||
activate_vmi();
|
||||
local_irq_restore(flags & X86_EFLAGS_IF);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче