Commit ae8d04e2 authored by Zachary Amsden's avatar Zachary Amsden Committed by Linus Torvalds

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: default avatarZachary Amsden <zach@vmware.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent ca7e716c
...@@ -223,9 +223,15 @@ struct pci_header { ...@@ -223,9 +223,15 @@ struct pci_header {
} __attribute__((packed)); } __attribute__((packed));
/* Function prototypes for bootstrapping */ /* Function prototypes for bootstrapping */
#ifdef CONFIG_VMI
extern void vmi_init(void); extern void vmi_init(void);
extern void vmi_activate(void);
extern void vmi_bringup(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. */ /* State needed to start an application processor in an SMP system. */
struct vmi_ap_state { struct vmi_ap_state {
......
...@@ -794,6 +794,9 @@ void __init setup_arch(char **cmdline_p) ...@@ -794,6 +794,9 @@ void __init setup_arch(char **cmdline_p)
printk(KERN_INFO "Command line: %s\n", boot_command_line); printk(KERN_INFO "Command line: %s\n", boot_command_line);
#endif #endif
/* VMI may relocate the fixmap; do this before touching ioremap area */
vmi_init();
early_cpu_init(); early_cpu_init();
early_ioremap_init(); early_ioremap_init();
...@@ -880,13 +883,8 @@ void __init setup_arch(char **cmdline_p) ...@@ -880,13 +883,8 @@ void __init setup_arch(char **cmdline_p)
check_efer(); check_efer();
#endif #endif
#if defined(CONFIG_VMI) && defined(CONFIG_X86_32) /* Must be before kernel pagetables are setup */
/* vmi_activate();
* Must be before kernel pagetables are setup
* or fixmap area is touched.
*/
vmi_init();
#endif
/* after early param, so could get panic from serial */ /* after early param, so could get panic from serial */
reserve_early_setup_data(); reserve_early_setup_data();
......
...@@ -294,9 +294,7 @@ static void __cpuinit start_secondary(void *unused) ...@@ -294,9 +294,7 @@ static void __cpuinit start_secondary(void *unused)
* fragile that we want to limit the things done here to the * fragile that we want to limit the things done here to the
* most necessary things. * most necessary things.
*/ */
#ifdef CONFIG_VMI
vmi_bringup(); vmi_bringup();
#endif
cpu_init(); cpu_init();
preempt_disable(); preempt_disable();
smp_callin(); smp_callin();
......
...@@ -960,8 +960,6 @@ static inline int __init activate_vmi(void) ...@@ -960,8 +960,6 @@ static inline int __init activate_vmi(void)
void __init vmi_init(void) void __init vmi_init(void)
{ {
unsigned long flags;
if (!vmi_rom) if (!vmi_rom)
probe_vmi_rom(); probe_vmi_rom();
else else
...@@ -973,13 +971,21 @@ void __init vmi_init(void) ...@@ -973,13 +971,21 @@ void __init vmi_init(void)
reserve_top_address(-vmi_rom->virtual_top); reserve_top_address(-vmi_rom->virtual_top);
local_irq_save(flags);
activate_vmi();
#ifdef CONFIG_X86_IO_APIC #ifdef CONFIG_X86_IO_APIC
/* This is virtual hardware; timer routing is wired correctly */ /* This is virtual hardware; timer routing is wired correctly */
no_timer_check = 1; no_timer_check = 1;
#endif #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); local_irq_restore(flags & X86_EFLAGS_IF);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment