summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeiko Carstens <hca@linux.ibm.com>2022-02-28 14:29:25 +0100
committerVasily Gorbik <gor@linux.ibm.com>2022-03-08 00:33:00 +0100
commit46fee16f571250d6cef74af73ffd47512da981a2 (patch)
tree074b3194069d030927a944091daa36b63f4e8032
parentcfa45c5e0d36b87f99e76f1060526eac032dd624 (diff)
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: Alexander Gordeev <agordeev@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
-rw-r--r--arch/s390/include/asm/extable.h13
-rw-r--r--arch/s390/kernel/early.c6
-rw-r--r--arch/s390/kernel/kprobes.c5
-rw-r--r--arch/s390/kernel/traps.c10
-rw-r--r--arch/s390/mm/extable.c15
-rw-r--r--arch/s390/mm/fault.c7
6 files changed, 22 insertions, 34 deletions
diff --git a/arch/s390/include/asm/extable.h b/arch/s390/include/asm/extable.h
index 8511f0e59290..d39d7159832a 100644
--- a/arch/s390/include/asm/extable.h
+++ b/arch/s390/include/asm/extable.h
@@ -49,17 +49,6 @@ ex_fixup_handler(const struct exception_table_entry *x)
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
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
+bool fixup_exception(struct pt_regs *regs);
+
#endif
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index 5715d1aab173..08cc86a0db90 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -151,12 +151,8 @@ static __init void setup_topology(void)
static void early_pgm_check_handler(struct pt_regs *regs)
{
- const struct exception_table_entry *fixup;
-
- fixup = s390_search_extables(regs->psw.addr);
- if (!fixup)
+ if (!fixup_exception(regs))
disabled_wait();
- regs->psw.addr = extable_fixup(fixup);
}
static noinline __init void setup_lowcore_early(void)
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index e27a7d3b0364..7e2910e4172b 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -465,7 +465,6 @@ static int kprobe_trap_handler(struct pt_regs *regs, int trapnr)
{
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
struct kprobe *p = kprobe_running();
- const struct exception_table_entry *entry;
switch(kcb->kprobe_status) {
case KPROBE_HIT_SS:
@@ -487,10 +486,8 @@ static int kprobe_trap_handler(struct pt_regs *regs, int trapnr)
* In case the user-specified fault handler returned
* zero, try to fix up.
*/
- entry = s390_search_extables(regs->psw.addr);
- if (entry && ex_handle(entry, regs))
+ if (fixup_exception(regs))
return 1;
-
/*
* fixup_exception() could not handle it,
* Let do_page_fault() fix it.
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 309cb0503feb..7f0fadd10d68 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -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));
report_user_fault(regs, si_signo, 0);
} else {
- const struct exception_table_entry *fixup;
- fixup = s390_search_extables(regs->psw.addr);
- if (!fixup || !ex_handle(fixup, regs))
+ if (!fixup_exception(regs))
die(regs, str);
}
}
@@ -245,16 +243,12 @@ static void space_switch_exception(struct pt_regs *regs)
static void monitor_event_exception(struct pt_regs *regs)
{
- const struct exception_table_entry *fixup;
-
if (user_mode(regs))
return;
switch (report_bug(regs->psw.addr - (regs->int_code >> 16), regs)) {
case BUG_TRAP_TYPE_NONE:
- fixup = s390_search_extables(regs->psw.addr);
- if (fixup)
- ex_handle(fixup, regs);
+ fixup_exception(regs);
break;
case BUG_TRAP_TYPE_WARN:
break;
diff --git a/arch/s390/mm/extable.c b/arch/s390/mm/extable.c
index a4eb3d8aae7b..d6ca75570dcf 100644
--- a/arch/s390/mm/extable.c
+++ b/arch/s390/mm/extable.c
@@ -14,3 +14,18 @@ const struct exception_table_entry *s390_search_extables(unsigned long addr)
num = __stop_amode31_ex_table - __start_amode31_ex_table;
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;
+}
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index caa4ab0ff80a..e173b6187ad5 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -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)
{
- const struct exception_table_entry *fixup;
-
- /* Are we prepared to handle this kernel fault? */
- fixup = s390_search_extables(regs->psw.addr);
- if (fixup && ex_handle(fixup, regs))
+ if (fixup_exception(regs))
return;
-
/*
* Oops. The kernel tried to access some bad page. We'll have to
* terminate things with extreme prejudice.