mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86/crash: Drop manual hooking of exception_table[]
NMI hooking in the crash path has undergone several revisions since its introduction. What we have now is not sufficiently different from the regular nmi_callback() mechanism to warrant special casing. Use set_nmi_callback() directly, and do away with patching a read-only data structure via a read-write alias. This also means that the vmx_vmexit_handler() can and should call do_nmi() directly, rather than indirecting through the exception table to pick up the crash path hook. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
04c48ccd75
commit
e7f147bf4a
3 files changed
+8
-14
No files matched your search
+2
-13
@@ -36,10 +36,8 @@ static unsigned int crashing_cpu;
|
||||
static DEFINE_PER_CPU_READ_MOSTLY(bool, crash_save_done);
|
||||
|
||||
/* This becomes the NMI handler for non-crashing CPUs, when Xen is crashing. */
|
||||
static void noreturn do_nmi_crash(const struct cpu_user_regs *regs)
|
||||
static int noreturn do_nmi_crash(const struct cpu_user_regs *regs, int cpu)
|
||||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
|
||||
stac();
|
||||
|
||||
/* nmi_shootdown_cpus() should ensure that this assertion is correct. */
|
||||
@@ -136,16 +134,7 @@ static void nmi_shootdown_cpus(void)
|
||||
SYS_DESC_irq_gate, 0, &trap_nop);
|
||||
set_ist(&idt_tables[cpu][TRAP_machine_check], IST_NONE);
|
||||
|
||||
/*
|
||||
* Ideally would be:
|
||||
* exception_table[TRAP_nmi] = &do_nmi_crash;
|
||||
*
|
||||
* but the exception_table is read only. Access it via its directmap
|
||||
* mappings.
|
||||
*/
|
||||
write_atomic((unsigned long *)__va(__pa(&exception_table[TRAP_nmi])),
|
||||
(unsigned long)&do_nmi_crash);
|
||||
|
||||
set_nmi_callback(do_nmi_crash);
|
||||
smp_send_nmi_allbutself();
|
||||
|
||||
msecs = 1000; /* Wait at most a second for the other cpus to stop */
|
||||
|
||||
@@ -3887,7 +3887,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
|
||||
((intr_info & INTR_INFO_INTR_TYPE_MASK) ==
|
||||
MASK_INSR(X86_EVENTTYPE_NMI, INTR_INFO_INTR_TYPE_MASK)) )
|
||||
{
|
||||
exception_table[TRAP_nmi](regs);
|
||||
do_nmi(regs);
|
||||
enable_nmis();
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1883,6 +1883,11 @@ void do_nmi(const struct cpu_user_regs *regs)
|
||||
this_cpu(nmi_count)++;
|
||||
nmi_enter();
|
||||
|
||||
/*
|
||||
* Think carefully before putting any logic before this point.
|
||||
* nmi_callback() might be the crash quiesce...
|
||||
*/
|
||||
|
||||
callback = ACCESS_ONCE(nmi_callback);
|
||||
if ( unlikely(callback) && callback(regs, cpu) )
|
||||
goto out;
|
||||
|
||||