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

alpha/extable: use generic search and sort routines

Replace the arch specific versions of search_extable() and
sort_extable() with calls to the generic ones, which now support
relative exception tables as well.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Acked-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Ard Biesheuvel and committed by
Linus Torvalds
e77986b5 a395d6a7

+9 -95
+8 -2
arch/alpha/include/asm/uaccess.h
··· 483 483 (pc) + (_fixup)->fixup.bits.nextinsn; \ 484 484 }) 485 485 486 - #define ARCH_HAS_SORT_EXTABLE 487 - #define ARCH_HAS_SEARCH_EXTABLE 486 + #define ARCH_HAS_RELATIVE_EXTABLE 487 + 488 + #define swap_ex_entry_fixup(a, b, tmp, delta) \ 489 + do { \ 490 + (a)->fixup.unit = (b)->fixup.unit; \ 491 + (b)->fixup.unit = (tmp).fixup.unit; \ 492 + } while (0) 493 + 488 494 489 495 #endif /* __ALPHA_UACCESS_H */
+1 -1
arch/alpha/mm/Makefile
··· 4 4 5 5 ccflags-y := -Werror 6 6 7 - obj-y := init.o fault.o extable.o 7 + obj-y := init.o fault.o 8 8 9 9 obj-$(CONFIG_DISCONTIGMEM) += numa.o
-92
arch/alpha/mm/extable.c
··· 1 - /* 2 - * linux/arch/alpha/mm/extable.c 3 - */ 4 - 5 - #include <linux/module.h> 6 - #include <linux/sort.h> 7 - #include <asm/uaccess.h> 8 - 9 - static inline unsigned long ex_to_addr(const struct exception_table_entry *x) 10 - { 11 - return (unsigned long)&x->insn + x->insn; 12 - } 13 - 14 - static void swap_ex(void *a, void *b, int size) 15 - { 16 - struct exception_table_entry *ex_a = a, *ex_b = b; 17 - unsigned long addr_a = ex_to_addr(ex_a), addr_b = ex_to_addr(ex_b); 18 - unsigned int t = ex_a->fixup.unit; 19 - 20 - ex_a->fixup.unit = ex_b->fixup.unit; 21 - ex_b->fixup.unit = t; 22 - ex_a->insn = (int)(addr_b - (unsigned long)&ex_a->insn); 23 - ex_b->insn = (int)(addr_a - (unsigned long)&ex_b->insn); 24 - } 25 - 26 - /* 27 - * The exception table needs to be sorted so that the binary 28 - * search that we use to find entries in it works properly. 29 - * This is used both for the kernel exception table and for 30 - * the exception tables of modules that get loaded. 31 - */ 32 - static int cmp_ex(const void *a, const void *b) 33 - { 34 - const struct exception_table_entry *x = a, *y = b; 35 - 36 - /* avoid overflow */ 37 - if (ex_to_addr(x) > ex_to_addr(y)) 38 - return 1; 39 - if (ex_to_addr(x) < ex_to_addr(y)) 40 - return -1; 41 - return 0; 42 - } 43 - 44 - void sort_extable(struct exception_table_entry *start, 45 - struct exception_table_entry *finish) 46 - { 47 - sort(start, finish - start, sizeof(struct exception_table_entry), 48 - cmp_ex, swap_ex); 49 - } 50 - 51 - #ifdef CONFIG_MODULES 52 - /* 53 - * Any entry referring to the module init will be at the beginning or 54 - * the end. 55 - */ 56 - void trim_init_extable(struct module *m) 57 - { 58 - /*trim the beginning*/ 59 - while (m->num_exentries && 60 - within_module_init(ex_to_addr(&m->extable[0]), m)) { 61 - m->extable++; 62 - m->num_exentries--; 63 - } 64 - /*trim the end*/ 65 - while (m->num_exentries && 66 - within_module_init(ex_to_addr(&m->extable[m->num_exentries-1]), 67 - m)) 68 - m->num_exentries--; 69 - } 70 - #endif /* CONFIG_MODULES */ 71 - 72 - const struct exception_table_entry * 73 - search_extable(const struct exception_table_entry *first, 74 - const struct exception_table_entry *last, 75 - unsigned long value) 76 - { 77 - while (first <= last) { 78 - const struct exception_table_entry *mid; 79 - unsigned long mid_value; 80 - 81 - mid = (last - first) / 2 + first; 82 - mid_value = ex_to_addr(mid); 83 - if (mid_value == value) 84 - return mid; 85 - else if (mid_value < value) 86 - first = mid+1; 87 - else 88 - last = mid-1; 89 - } 90 - 91 - return NULL; 92 - }