1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __S390_EXTABLE_H
3 #define __S390_EXTABLE_H
5 #include <asm/ptrace.h>
6 #include <linux/compiler.h>
9 * The exception table consists of three addresses:
11 * - Address of an instruction that is allowed to fault.
12 * - Address at which the program should continue.
13 * - Optional address of handler that takes pt_regs * argument and runs in
16 * No registers are modified, so it is entirely up to the continuation code
17 * to figure out what to do.
19 * All the routines below use bits of fixup code that are out of line
20 * with the main instruction path. This means when everything is well,
21 * we don't even have to jump over them. Further, they do not intrude
22 * on our cache or tlb entries.
25 struct exception_table_entry
31 extern struct exception_table_entry
*__start_dma_ex_table
;
32 extern struct exception_table_entry
*__stop_dma_ex_table
;
34 const struct exception_table_entry
*s390_search_extables(unsigned long addr
);
36 static inline unsigned long extable_fixup(const struct exception_table_entry
*x
)
38 return (unsigned long)&x
->fixup
+ x
->fixup
;
41 typedef bool (*ex_handler_t
)(const struct exception_table_entry
*,
44 static inline ex_handler_t
45 ex_fixup_handler(const struct exception_table_entry
*x
)
47 if (likely(!x
->handler
))
49 return (ex_handler_t
)((unsigned long)&x
->handler
+ x
->handler
);
52 static inline bool ex_handle(const struct exception_table_entry
*x
,
55 ex_handler_t handler
= ex_fixup_handler(x
);
57 if (unlikely(handler
))
58 return handler(x
, regs
);
59 regs
->psw
.addr
= extable_fixup(x
);
63 #define ARCH_HAS_RELATIVE_EXTABLE
65 static inline void swap_ex_entry_fixup(struct exception_table_entry
*a
,
66 struct exception_table_entry
*b
,
67 struct exception_table_entry tmp
,
70 a
->fixup
= b
->fixup
+ delta
;
71 b
->fixup
= tmp
.fixup
- delta
;
72 a
->handler
= b
->handler
+ delta
;
73 b
->handler
= tmp
.handler
- delta
;