Message ID | 20170629184647.76674-1-jmattson@google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
TOn 29/06/2017 20:46, Jim Mattson wrote: > 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@google.com> Thanks, series tested and applied. Paolo > --- > 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); >
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);
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@google.com> --- lib/x86/desc.c | 16 ++++++++++------ lib/x86/desc.h | 4 +++- 2 files changed, 13 insertions(+), 7 deletions(-)