1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 21d18c47cSCatalin Marinas /* 31d18c47cSCatalin Marinas * Based on arch/arm/mm/extable.c 41d18c47cSCatalin Marinas */ 51d18c47cSCatalin Marinas 60edfa839SPaul Gortmaker #include <linux/extable.h> 71d18c47cSCatalin Marinas #include <linux/uaccess.h> 81d18c47cSCatalin Marinas 9*d6e2cc56SMark Rutland #include <asm/asm-extable.h> 10*d6e2cc56SMark Rutland 11*d6e2cc56SMark Rutland typedef bool (*ex_handler_t)(const struct exception_table_entry *, 12*d6e2cc56SMark Rutland struct pt_regs *); 13*d6e2cc56SMark Rutland 14*d6e2cc56SMark Rutland static inline unsigned long 15*d6e2cc56SMark Rutland get_ex_fixup(const struct exception_table_entry *ex) 16*d6e2cc56SMark Rutland { 17*d6e2cc56SMark Rutland return ((unsigned long)&ex->fixup + ex->fixup); 18*d6e2cc56SMark Rutland } 19*d6e2cc56SMark Rutland 20*d6e2cc56SMark Rutland static bool ex_handler_fixup(const struct exception_table_entry *ex, 21*d6e2cc56SMark Rutland struct pt_regs *regs) 22*d6e2cc56SMark Rutland { 23*d6e2cc56SMark Rutland regs->pc = get_ex_fixup(ex); 24*d6e2cc56SMark Rutland return true; 25*d6e2cc56SMark Rutland } 26*d6e2cc56SMark Rutland 27e8c328d7SMark Rutland bool fixup_exception(struct pt_regs *regs) 281d18c47cSCatalin Marinas { 295d0e7905SMark Rutland const struct exception_table_entry *ex; 301d18c47cSCatalin Marinas 315d0e7905SMark Rutland ex = search_exception_tables(instruction_pointer(regs)); 325d0e7905SMark Rutland if (!ex) 33e8c328d7SMark Rutland return false; 341d18c47cSCatalin Marinas 35*d6e2cc56SMark Rutland switch (ex->type) { 36*d6e2cc56SMark Rutland case EX_TYPE_FIXUP: 37*d6e2cc56SMark Rutland return ex_handler_fixup(ex, regs); 38*d6e2cc56SMark Rutland case EX_TYPE_BPF: 39*d6e2cc56SMark Rutland return ex_handler_bpf(ex, regs); 40*d6e2cc56SMark Rutland } 4180083428SJean-Philippe Brucker 42*d6e2cc56SMark Rutland BUG(); 431d18c47cSCatalin Marinas } 44