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);
|
static DEFINE_PER_CPU_READ_MOSTLY(bool, crash_save_done);
|
||||||
|
|
||||||
/* This becomes the NMI handler for non-crashing CPUs, when Xen is crashing. */
|
/* 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();
|
stac();
|
||||||
|
|
||||||
/* nmi_shootdown_cpus() should ensure that this assertion is correct. */
|
/* 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);
|
SYS_DESC_irq_gate, 0, &trap_nop);
|
||||||
set_ist(&idt_tables[cpu][TRAP_machine_check], IST_NONE);
|
set_ist(&idt_tables[cpu][TRAP_machine_check], IST_NONE);
|
||||||
|
|
||||||
/*
|
set_nmi_callback(do_nmi_crash);
|
||||||
* 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);
|
|
||||||
|
|
||||||
smp_send_nmi_allbutself();
|
smp_send_nmi_allbutself();
|
||||||
|
|
||||||
msecs = 1000; /* Wait at most a second for the other cpus to stop */
|
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) ==
|
((intr_info & INTR_INFO_INTR_TYPE_MASK) ==
|
||||||
MASK_INSR(X86_EVENTTYPE_NMI, 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();
|
enable_nmis();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1883,6 +1883,11 @@ void do_nmi(const struct cpu_user_regs *regs)
|
|||||||
this_cpu(nmi_count)++;
|
this_cpu(nmi_count)++;
|
||||||
nmi_enter();
|
nmi_enter();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Think carefully before putting any logic before this point.
|
||||||
|
* nmi_callback() might be the crash quiesce...
|
||||||
|
*/
|
||||||
|
|
||||||
callback = ACCESS_ONCE(nmi_callback);
|
callback = ACCESS_ONCE(nmi_callback);
|
||||||
if ( unlikely(callback) && callback(regs, cpu) )
|
if ( unlikely(callback) && callback(regs, cpu) )
|
||||||
goto out;
|
goto out;
|
||||||
|
|||||||