Signed-off-by: Andrew Morton --- arch/i386/kernel/paravirt.c | 2 ++ arch/i386/kernel/smpboot.c | 7 +++++++ include/asm-i386/paravirt.h | 9 +++++++++ include/asm-i386/smp.h | 5 +++++ 4 files changed, 23 insertions(+) diff -puN arch/i386/kernel/paravirt.c~x86_64-mm-smp-boot-hook-for-paravirt arch/i386/kernel/paravirt.c --- a/arch/i386/kernel/paravirt.c~x86_64-mm-smp-boot-hook-for-paravirt +++ a/arch/i386/kernel/paravirt.c @@ -572,6 +572,8 @@ struct paravirt_ops paravirt_ops = { .irq_enable_sysexit = native_irq_enable_sysexit, .iret = native_iret, + + .startup_ipi_hook = (void *)native_nop, }; /* diff -puN arch/i386/kernel/smpboot.c~x86_64-mm-smp-boot-hook-for-paravirt arch/i386/kernel/smpboot.c --- a/arch/i386/kernel/smpboot.c~x86_64-mm-smp-boot-hook-for-paravirt +++ a/arch/i386/kernel/smpboot.c @@ -834,6 +834,13 @@ wakeup_secondary_cpu(int phys_apicid, un num_starts = 0; /* + * Paravirt / VMI wants a startup IPI hook here to set up the + * target processor state. + */ + startup_ipi_hook(phys_apicid, (unsigned long) start_secondary, + (unsigned long) stack_start.esp); + + /* * Run STARTUP IPI loop. */ Dprintk("#startup loops: %d.\n", num_starts); diff -puN include/asm-i386/paravirt.h~x86_64-mm-smp-boot-hook-for-paravirt include/asm-i386/paravirt.h --- a/include/asm-i386/paravirt.h~x86_64-mm-smp-boot-hook-for-paravirt +++ a/include/asm-i386/paravirt.h @@ -151,6 +151,8 @@ struct paravirt_ops /* These two are jmp to, not actually called. */ void (fastcall *irq_enable_sysexit)(void); void (fastcall *iret)(void); + + void (fastcall *startup_ipi_hook)(int phys_apicid, unsigned long start_eip, unsigned long start_esp); }; /* Mark a paravirt probe function. */ @@ -323,6 +325,13 @@ static inline unsigned long apic_read(un } #endif +#ifdef CONFIG_SMP +static inline void startup_ipi_hook(int phys_apicid, unsigned long start_eip, + unsigned long start_esp) +{ + return paravirt_ops.startup_ipi_hook(phys_apicid, start_eip, start_esp); +} +#endif #define __flush_tlb() paravirt_ops.flush_tlb_user() #define __flush_tlb_global() paravirt_ops.flush_tlb_kernel() diff -puN include/asm-i386/smp.h~x86_64-mm-smp-boot-hook-for-paravirt include/asm-i386/smp.h --- a/include/asm-i386/smp.h~x86_64-mm-smp-boot-hook-for-paravirt +++ a/include/asm-i386/smp.h @@ -52,6 +52,11 @@ extern void cpu_exit_clear(void); extern void cpu_uninit(void); #endif +#ifndef CONFIG_PARAVIRT +#define startup_ipi_hook(phys_apicid, start_eip, start_esp) \ +do { } while (0) +#endif + /* * This function is needed by all SMP systems. It must _always_ be valid * from the initial startup. We map APIC_BASE very early in page_setup(), _