xref: /linux/arch/arm64/mm/extable.c (revision d6e2cc56477538255160ed02fdb11b0da60356cc)
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