Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -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 {
+5 −7
Original line number Diff line number Diff line
@@ -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();
+0 −2
Original line number Diff line number Diff line
@@ -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();
+11 −5
Original line number Diff line number Diff line
@@ -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);
}