s390/extable: add and use fixup_exception helper function
authorHeiko Carstens <hca@linux.ibm.com>
Mon, 28 Feb 2022 13:29:25 +0000 (14:29 +0100)
committerVasily Gorbik <gor@linux.ibm.com>
Mon, 7 Mar 2022 23:33:00 +0000 (00:33 +0100)
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>
arch/s390/include/asm/extable.h
arch/s390/kernel/early.c
arch/s390/kernel/kprobes.c
arch/s390/kernel/traps.c
arch/s390/mm/extable.c
arch/s390/mm/fault.c

index 8511f0e..d39d715 100644 (file)
@@ -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
index 5715d1a..08cc86a 100644 (file)
@@ -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)
index e27a7d3..7e2910e 100644 (file)
@@ -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.
index 309cb05..7f0fadd 100644 (file)
@@ -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;
index a4eb3d8..d6ca755 100644 (file)
@@ -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;
+}
index caa4ab0..e173b61 100644 (file)
@@ -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.