Commit 46fee16f authored by Heiko Carstens's avatar Heiko Carstens Committed by Vasily Gorbik

s390/extable: add and use fixup_exception helper function

Add and use fixup_exception helper function in order to remove the
duplicated exception handler fixup code at several places.
Reviewed-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent cfa45c5e
...@@ -49,17 +49,6 @@ ex_fixup_handler(const struct exception_table_entry *x) ...@@ -49,17 +49,6 @@ ex_fixup_handler(const struct exception_table_entry *x)
return (ex_handler_t)((unsigned long)&x->handler + x->handler); return (ex_handler_t)((unsigned long)&x->handler + x->handler);
} }
static inline bool ex_handle(const struct exception_table_entry *x,
struct pt_regs *regs)
{
ex_handler_t handler = ex_fixup_handler(x);
if (unlikely(handler))
return handler(x, regs);
regs->psw.addr = extable_fixup(x);
return true;
}
#define ARCH_HAS_RELATIVE_EXTABLE #define ARCH_HAS_RELATIVE_EXTABLE
static inline void swap_ex_entry_fixup(struct exception_table_entry *a, static inline void swap_ex_entry_fixup(struct exception_table_entry *a,
...@@ -78,4 +67,6 @@ static inline void swap_ex_entry_fixup(struct exception_table_entry *a, ...@@ -78,4 +67,6 @@ static inline void swap_ex_entry_fixup(struct exception_table_entry *a,
} }
#define swap_ex_entry_fixup swap_ex_entry_fixup #define swap_ex_entry_fixup swap_ex_entry_fixup
bool fixup_exception(struct pt_regs *regs);
#endif #endif
...@@ -151,12 +151,8 @@ static __init void setup_topology(void) ...@@ -151,12 +151,8 @@ static __init void setup_topology(void)
static void early_pgm_check_handler(struct pt_regs *regs) static void early_pgm_check_handler(struct pt_regs *regs)
{ {
const struct exception_table_entry *fixup; if (!fixup_exception(regs))
fixup = s390_search_extables(regs->psw.addr);
if (!fixup)
disabled_wait(); disabled_wait();
regs->psw.addr = extable_fixup(fixup);
} }
static noinline __init void setup_lowcore_early(void) static noinline __init void setup_lowcore_early(void)
......
...@@ -465,7 +465,6 @@ static int kprobe_trap_handler(struct pt_regs *regs, int trapnr) ...@@ -465,7 +465,6 @@ static int kprobe_trap_handler(struct pt_regs *regs, int trapnr)
{ {
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
struct kprobe *p = kprobe_running(); struct kprobe *p = kprobe_running();
const struct exception_table_entry *entry;
switch(kcb->kprobe_status) { switch(kcb->kprobe_status) {
case KPROBE_HIT_SS: case KPROBE_HIT_SS:
...@@ -487,10 +486,8 @@ static int kprobe_trap_handler(struct pt_regs *regs, int trapnr) ...@@ -487,10 +486,8 @@ static int kprobe_trap_handler(struct pt_regs *regs, int trapnr)
* In case the user-specified fault handler returned * In case the user-specified fault handler returned
* zero, try to fix up. * zero, try to fix up.
*/ */
entry = s390_search_extables(regs->psw.addr); if (fixup_exception(regs))
if (entry && ex_handle(entry, regs))
return 1; return 1;
/* /*
* fixup_exception() could not handle it, * fixup_exception() could not handle it,
* Let do_page_fault() fix it. * Let do_page_fault() fix it.
......
...@@ -54,9 +54,7 @@ void do_report_trap(struct pt_regs *regs, int si_signo, int si_code, char *str) ...@@ -54,9 +54,7 @@ void do_report_trap(struct pt_regs *regs, int si_signo, int si_code, char *str)
force_sig_fault(si_signo, si_code, get_trap_ip(regs)); force_sig_fault(si_signo, si_code, get_trap_ip(regs));
report_user_fault(regs, si_signo, 0); report_user_fault(regs, si_signo, 0);
} else { } else {
const struct exception_table_entry *fixup; if (!fixup_exception(regs))
fixup = s390_search_extables(regs->psw.addr);
if (!fixup || !ex_handle(fixup, regs))
die(regs, str); die(regs, str);
} }
} }
...@@ -245,16 +243,12 @@ static void space_switch_exception(struct pt_regs *regs) ...@@ -245,16 +243,12 @@ static void space_switch_exception(struct pt_regs *regs)
static void monitor_event_exception(struct pt_regs *regs) static void monitor_event_exception(struct pt_regs *regs)
{ {
const struct exception_table_entry *fixup;
if (user_mode(regs)) if (user_mode(regs))
return; return;
switch (report_bug(regs->psw.addr - (regs->int_code >> 16), regs)) { switch (report_bug(regs->psw.addr - (regs->int_code >> 16), regs)) {
case BUG_TRAP_TYPE_NONE: case BUG_TRAP_TYPE_NONE:
fixup = s390_search_extables(regs->psw.addr); fixup_exception(regs);
if (fixup)
ex_handle(fixup, regs);
break; break;
case BUG_TRAP_TYPE_WARN: case BUG_TRAP_TYPE_WARN:
break; break;
......
...@@ -14,3 +14,18 @@ const struct exception_table_entry *s390_search_extables(unsigned long addr) ...@@ -14,3 +14,18 @@ const struct exception_table_entry *s390_search_extables(unsigned long addr)
num = __stop_amode31_ex_table - __start_amode31_ex_table; num = __stop_amode31_ex_table - __start_amode31_ex_table;
return search_extable(__start_amode31_ex_table, num, addr); return search_extable(__start_amode31_ex_table, num, addr);
} }
bool fixup_exception(struct pt_regs *regs)
{
const struct exception_table_entry *ex;
ex_handler_t handler;
ex = s390_search_extables(instruction_pointer(regs));
if (!ex)
return false;
handler = ex_fixup_handler(ex);
if (unlikely(handler))
return handler(ex, regs);
regs->psw.addr = extable_fixup(ex);
return true;
}
...@@ -230,13 +230,8 @@ static noinline void do_sigsegv(struct pt_regs *regs, int si_code) ...@@ -230,13 +230,8 @@ static noinline void do_sigsegv(struct pt_regs *regs, int si_code)
static noinline void do_no_context(struct pt_regs *regs) static noinline void do_no_context(struct pt_regs *regs)
{ {
const struct exception_table_entry *fixup; if (fixup_exception(regs))
/* Are we prepared to handle this kernel fault? */
fixup = s390_search_extables(regs->psw.addr);
if (fixup && ex_handle(fixup, regs))
return; return;
/* /*
* Oops. The kernel tried to access some bad page. We'll have to * Oops. The kernel tried to access some bad page. We'll have to
* terminate things with extreme prejudice. * terminate things with extreme prejudice.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment