1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Based on arch/arm/mm/extable.c 4 */ 5 6 #include <linux/extable.h> 7 #include <linux/uaccess.h> 8 9 #include <asm/asm-extable.h> 10 11 typedef bool (*ex_handler_t)(const struct exception_table_entry *, 12 struct pt_regs *); 13 14 static inline unsigned long 15 get_ex_fixup(const struct exception_table_entry *ex) 16 { 17 return ((unsigned long)&ex->fixup + ex->fixup); 18 } 19 20 static bool ex_handler_fixup(const struct exception_table_entry *ex, 21 struct pt_regs *regs) 22 { 23 regs->pc = get_ex_fixup(ex); 24 return true; 25 } 26 27 bool fixup_exception(struct pt_regs *regs) 28 { 29 const struct exception_table_entry *ex; 30 31 ex = search_exception_tables(instruction_pointer(regs)); 32 if (!ex) 33 return false; 34 35 switch (ex->type) { 36 case EX_TYPE_FIXUP: 37 return ex_handler_fixup(ex, regs); 38 case EX_TYPE_BPF: 39 return ex_handler_bpf(ex, regs); 40 } 41 42 BUG(); 43 } 44