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:
committed by
Linus Torvalds
parent
ca7e716c78
commit
ae8d04e2ec
@@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
* 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)
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user