The default handler for #DE, #UD, and #GP is check_exception_table. Test_for_exception should restore the original handler before returning, rather than blindly clobbering it with NULL. Signed-off-by: Jim Mattson <jmattson@xxxxxxxxxx> --- lib/x86/desc.c | 16 ++++++++++------ lib/x86/desc.h | 4 +++- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/x86/desc.c b/lib/x86/desc.c index 402204ddcac4..830c5d127dbc 100644 --- a/lib/x86/desc.c +++ b/lib/x86/desc.c @@ -117,13 +117,16 @@ static void check_exception_table(struct ex_regs *regs) unhandled_exception(regs, false); } -static void (*exception_handlers[32])(struct ex_regs *regs); +static handler exception_handlers[32]; - -void handle_exception(u8 v, void (*func)(struct ex_regs *regs)) +handler handle_exception(u8 v, handler fn) { + handler old; + + old = exception_handlers[v]; if (v < 32) - exception_handlers[v] = func; + exception_handlers[v] = fn; + return old; } #ifndef __x86_64__ @@ -390,14 +393,15 @@ static void exception_handler(struct ex_regs *regs) bool test_for_exception(unsigned int ex, void (*trigger_func)(void *data), void *data) { + handler old; jmp_buf jmpbuf; int ret; - handle_exception(ex, exception_handler); + old = handle_exception(ex, exception_handler); ret = set_exception_jmpbuf(jmpbuf); if (ret == 0) trigger_func(data); - handle_exception(ex, NULL); + handle_exception(ex, old); return ret; } diff --git a/lib/x86/desc.h b/lib/x86/desc.h index be52fd4e1d92..a2500e0f6006 100644 --- a/lib/x86/desc.h +++ b/lib/x86/desc.h @@ -20,6 +20,8 @@ struct ex_regs { unsigned long rflags; }; +typedef void (*handler)(struct ex_regs *regs); + typedef struct { u16 prev; u16 res1; @@ -153,7 +155,7 @@ void set_idt_dpl(int vec, u16 dpl); void set_gdt_entry(int sel, u32 base, u32 limit, u8 access, u8 gran); void set_intr_alt_stack(int e, void *fn); void print_current_tss_info(void); -void handle_exception(u8 v, void (*func)(struct ex_regs *regs)); +handler handle_exception(u8 v, handler fn); bool test_for_exception(unsigned int ex, void (*trigger_func)(void *data), void *data); -- 2.13.2.725.g09c95d1e9-goog