[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] x86/nmi: Fix shootdown of pcpus running in VMX non-root mode
In the case of a crash, nmi_shootdown_cpus() patches nmi_crash() into the IDT of each processor, such that the next NMI it receives will force it into the crash path. c/s 7dd3b06ff "vmx: fix handling of NMI VMEXIT" fixed one issue but inadvertently introduced another. The original use of self_nmi() would follow vector #2, but a direct call to do_nmi() does not. Introduce a function pointer which should be used in preference to direct do_nmi() calls, which is updated on the crash path to point at do_nmi_crash() Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CC: Jan Beulich <JBeulich@xxxxxxxx> CC: Tim Deegan <tim@xxxxxxx> --- This patch very certainly functions correctly (it is in active use now in a customer escalation), but I was wondering how paranoid we should be about interleaved reads/writes and whether an atomic write would be better? Performance is not a issue at all but in a crash senario we don't want to be taking any chances with correctness. --- xen/arch/x86/crash.c | 4 +++- xen/arch/x86/hvm/vmx/vmx.c | 2 +- xen/arch/x86/traps.c | 2 ++ xen/include/asm-x86/processor.h | 3 ++- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/crash.c b/xen/arch/x86/crash.c index c0b83df..0822a68 100644 --- a/xen/arch/x86/crash.c +++ b/xen/arch/x86/crash.c @@ -36,7 +36,7 @@ static unsigned int crashing_cpu; static DEFINE_PER_CPU_READ_MOSTLY(bool_t, crash_save_done); /* This becomes the NMI handler for non-crashing CPUs, when Xen is crashing. */ -void do_nmi_crash(struct cpu_user_regs *regs) +void do_nmi_crash(const struct cpu_user_regs *regs) { int cpu = smp_processor_id(); @@ -160,6 +160,8 @@ static void nmi_shootdown_cpus(void) } } + nmi_handler = do_nmi_crash; + /* Ensure the new callback function is set before sending out the NMI. */ wmb(); diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 88b7821..67bdcb4 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -2701,7 +2701,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) && ((intr_info & INTR_INFO_INTR_TYPE_MASK) == (X86_EVENTTYPE_NMI << 8)) ) { - do_nmi(regs); + nmi_handler(regs); enable_nmis(); } break; diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index f5516dc..890e22a 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -105,6 +105,8 @@ idt_entry_t *idt_tables[NR_CPUS] __read_mostly; void (*ioemul_handle_quirk)( u8 opcode, char *io_emul_stub, struct cpu_user_regs *regs); +void (*nmi_handler)(const struct cpu_user_regs *regs) __read_mostly = do_nmi; + static int debug_stack_lines = 20; integer_param("debug_stack_lines", debug_stack_lines); diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h index 20eade6..70c9abc 100644 --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -522,9 +522,10 @@ DECLARE_TRAP_HANDLER(alignment_check); #undef DECLARE_TRAP_HANDLER_CONST #undef DECLARE_TRAP_HANDLER +extern void (*nmi_handler)(const struct cpu_user_regs *regs); void trap_nop(void); void enable_nmis(void); -void noreturn do_nmi_crash(struct cpu_user_regs *regs); +void noreturn do_nmi_crash(const struct cpu_user_regs *regs); void do_reserved_trap(struct cpu_user_regs *regs); void syscall_enter(void); -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |