extable.c (d6e2cc56477538255160ed02fdb11b0da60356cc) extable.c (2e77a62cb3a6d2eb9dd875516411bcd131dd04e7)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Based on arch/arm/mm/extable.c
4 */
5
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Based on arch/arm/mm/extable.c
4 */
5
6#include <linux/bitfield.h>
6#include <linux/extable.h>
7#include <linux/uaccess.h>
8
9#include <asm/asm-extable.h>
7#include <linux/extable.h>
8#include <linux/uaccess.h>
9
10#include <asm/asm-extable.h>
11#include <asm/ptrace.h>
10
11typedef bool (*ex_handler_t)(const struct exception_table_entry *,
12 struct pt_regs *);
13
14static inline unsigned long
15get_ex_fixup(const struct exception_table_entry *ex)
16{
17 return ((unsigned long)&ex->fixup + ex->fixup);
18}
19
20static 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
12
13typedef bool (*ex_handler_t)(const struct exception_table_entry *,
14 struct pt_regs *);
15
16static inline unsigned long
17get_ex_fixup(const struct exception_table_entry *ex)
18{
19 return ((unsigned long)&ex->fixup + ex->fixup);
20}
21
22static bool ex_handler_fixup(const struct exception_table_entry *ex,
23 struct pt_regs *regs)
24{
25 regs->pc = get_ex_fixup(ex);
26 return true;
27}
28
29static bool ex_handler_uaccess_err_zero(const struct exception_table_entry *ex,
30 struct pt_regs *regs)
31{
32 int reg_err = FIELD_GET(EX_DATA_REG_ERR, ex->data);
33 int reg_zero = FIELD_GET(EX_DATA_REG_ZERO, ex->data);
34
35 pt_regs_write_reg(regs, reg_err, -EFAULT);
36 pt_regs_write_reg(regs, reg_zero, 0);
37
38 regs->pc = get_ex_fixup(ex);
39 return true;
40}
41
27bool 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);
42bool fixup_exception(struct pt_regs *regs)
43{
44 const struct exception_table_entry *ex;
45
46 ex = search_exception_tables(instruction_pointer(regs));
47 if (!ex)
48 return false;
49
50 switch (ex->type) {
51 case EX_TYPE_FIXUP:
52 return ex_handler_fixup(ex, regs);
53 case EX_TYPE_BPF:
54 return ex_handler_bpf(ex, regs);
55 case EX_TYPE_UACCESS_ERR_ZERO:
56 return ex_handler_uaccess_err_zero(ex, regs);
40 }
41
42 BUG();
43}
57 }
58
59 BUG();
60}