Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/extable: convert to relative table with data

Follow arm64, riscv, and x86 and change extable layout to common
"relative table with data". This allows to get rid of s390 specific
code in sorttable.c.

The main difference to before is that extable entries do not contain a
relative function pointer anymore. Instead data and type fields are
added.

The type field is used to indicate which exception handler needs to be
called, while the data field is currently unused.

Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>

authored by

Heiko Carstens and committed by
Vasily Gorbik
3d66718c 46fee16f

+46 -74
+10 -5
arch/s390/include/asm/asm-extable.h
··· 5 5 #include <linux/stringify.h> 6 6 #include <asm/asm-const.h> 7 7 8 - #define __EX_TABLE(_section, _fault, _target) \ 8 + #define EX_TYPE_NONE 0 9 + #define EX_TYPE_FIXUP 1 10 + #define EX_TYPE_BPF 2 11 + 12 + #define __EX_TABLE(_section, _fault, _target, _type) \ 9 13 stringify_in_c(.section _section,"a";) \ 10 - stringify_in_c(.align 8;) \ 14 + stringify_in_c(.align 4;) \ 11 15 stringify_in_c(.long (_fault) - .;) \ 12 16 stringify_in_c(.long (_target) - .;) \ 13 - stringify_in_c(.quad 0;) \ 17 + stringify_in_c(.short (_type);) \ 18 + stringify_in_c(.short 0;) \ 14 19 stringify_in_c(.previous) 15 20 16 21 #define EX_TABLE(_fault, _target) \ 17 - __EX_TABLE(__ex_table, _fault, _target) 22 + __EX_TABLE(__ex_table, _fault, _target, EX_TYPE_FIXUP) 18 23 #define EX_TABLE_AMODE31(_fault, _target) \ 19 - __EX_TABLE(.amode31.ex_table, _fault, _target) 24 + __EX_TABLE(.amode31.ex_table, _fault, _target, EX_TYPE_FIXUP) 20 25 21 26 #endif /* __ASM_EXTABLE_H */
+18 -18
arch/s390/include/asm/extable.h
··· 25 25 struct exception_table_entry 26 26 { 27 27 int insn, fixup; 28 - long handler; 28 + short type, data; 29 29 }; 30 30 31 31 extern struct exception_table_entry *__start_amode31_ex_table; ··· 38 38 return (unsigned long)&x->fixup + x->fixup; 39 39 } 40 40 41 - typedef bool (*ex_handler_t)(const struct exception_table_entry *, 42 - struct pt_regs *); 43 - 44 - static inline ex_handler_t 45 - ex_fixup_handler(const struct exception_table_entry *x) 46 - { 47 - if (likely(!x->handler)) 48 - return NULL; 49 - return (ex_handler_t)((unsigned long)&x->handler + x->handler); 50 - } 51 - 52 41 #define ARCH_HAS_RELATIVE_EXTABLE 53 42 54 43 static inline void swap_ex_entry_fixup(struct exception_table_entry *a, ··· 47 58 { 48 59 a->fixup = b->fixup + delta; 49 60 b->fixup = tmp.fixup - delta; 50 - a->handler = b->handler; 51 - if (a->handler) 52 - a->handler += delta; 53 - b->handler = tmp.handler; 54 - if (b->handler) 55 - b->handler -= delta; 61 + a->type = b->type; 62 + b->type = tmp.type; 63 + a->data = b->data; 64 + b->data = tmp.data; 56 65 } 57 66 #define swap_ex_entry_fixup swap_ex_entry_fixup 67 + 68 + #ifdef CONFIG_BPF_JIT 69 + 70 + bool ex_handler_bpf(const struct exception_table_entry *ex, struct pt_regs *regs); 71 + 72 + #else /* !CONFIG_BPF_JIT */ 73 + 74 + static inline bool ex_handler_bpf(const struct exception_table_entry *ex, struct pt_regs *regs) 75 + { 76 + return false; 77 + } 78 + 79 + #endif /* CONFIG_BPF_JIT */ 58 80 59 81 bool fixup_exception(struct pt_regs *regs); 60 82
+15 -6
arch/s390/mm/extable.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 3 3 #include <linux/extable.h> 4 + #include <linux/panic.h> 5 + #include <asm/asm-extable.h> 4 6 #include <asm/extable.h> 5 7 6 8 const struct exception_table_entry *s390_search_extables(unsigned long addr) ··· 17 15 return search_extable(__start_amode31_ex_table, num, addr); 18 16 } 19 17 18 + static bool ex_handler_fixup(const struct exception_table_entry *ex, struct pt_regs *regs) 19 + { 20 + regs->psw.addr = extable_fixup(ex); 21 + return true; 22 + } 23 + 20 24 bool fixup_exception(struct pt_regs *regs) 21 25 { 22 26 const struct exception_table_entry *ex; 23 - ex_handler_t handler; 24 27 25 28 ex = s390_search_extables(instruction_pointer(regs)); 26 29 if (!ex) 27 30 return false; 28 - handler = ex_fixup_handler(ex); 29 - if (unlikely(handler)) 30 - return handler(ex, regs); 31 - regs->psw.addr = extable_fixup(ex); 32 - return true; 31 + switch (ex->type) { 32 + case EX_TYPE_FIXUP: 33 + return ex_handler_fixup(ex, regs); 34 + case EX_TYPE_BPF: 35 + return ex_handler_bpf(ex, regs); 36 + } 37 + panic("invalid exception table entry"); 33 38 }
+2 -3
arch/s390/net/bpf_jit_comp.c
··· 622 622 return insn[1] >> 4; 623 623 } 624 624 625 - static bool ex_handler_bpf(const struct exception_table_entry *x, 626 - struct pt_regs *regs) 625 + bool ex_handler_bpf(const struct exception_table_entry *x, struct pt_regs *regs) 627 626 { 628 627 int regno; 629 628 u8 *insn; ··· 677 678 /* JIT bug - landing pad and extable must be close. */ 678 679 return -1; 679 680 ex->fixup = delta; 680 - ex->handler = (u8 *)ex_handler_bpf - (u8 *)&ex->handler; 681 + ex->type = EX_TYPE_BPF; 681 682 jit->excnt++; 682 683 } 683 684 return 0;
+1 -42
scripts/sorttable.c
··· 261 261 } 262 262 } 263 263 264 - static void s390_sort_relative_table(char *extab_image, int image_size) 265 - { 266 - int i; 267 - 268 - for (i = 0; i < image_size; i += 16) { 269 - char *loc = extab_image + i; 270 - uint64_t handler; 271 - 272 - w(r((uint32_t *)loc) + i, (uint32_t *)loc); 273 - w(r((uint32_t *)(loc + 4)) + (i + 4), (uint32_t *)(loc + 4)); 274 - /* 275 - * 0 is a special self-relative handler value, which means that 276 - * handler should be ignored. It is safe, because it means that 277 - * handler field points to itself, which should never happen. 278 - * When creating extable-relative values, keep it as 0, since 279 - * this should never occur either: it would mean that handler 280 - * field points to the first extable entry. 281 - */ 282 - handler = r8((uint64_t *)(loc + 8)); 283 - if (handler) 284 - handler += i + 8; 285 - w8(handler, (uint64_t *)(loc + 8)); 286 - } 287 - 288 - qsort(extab_image, image_size / 16, 16, compare_relative_table); 289 - 290 - for (i = 0; i < image_size; i += 16) { 291 - char *loc = extab_image + i; 292 - uint64_t handler; 293 - 294 - w(r((uint32_t *)loc) - i, (uint32_t *)loc); 295 - w(r((uint32_t *)(loc + 4)) - (i + 4), (uint32_t *)(loc + 4)); 296 - handler = r8((uint64_t *)(loc + 8)); 297 - if (handler) 298 - handler -= i + 8; 299 - w8(handler, (uint64_t *)(loc + 8)); 300 - } 301 - } 302 - 303 264 static int do_file(char const *const fname, void *addr) 304 265 { 305 266 int rc = -1; ··· 301 340 case EM_386: 302 341 case EM_AARCH64: 303 342 case EM_RISCV: 343 + case EM_S390: 304 344 case EM_X86_64: 305 345 custom_sort = sort_relative_table_with_data; 306 - break; 307 - case EM_S390: 308 - custom_sort = s390_sort_relative_table; 309 346 break; 310 347 case EM_PARISC: 311 348 case EM_PPC: