diff options
author | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2016-03-22 17:28:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-22 18:36:02 -0400 |
commit | e77986b560741f40ac30755afc57074898da31e8 (patch) | |
tree | 0f27e0bf8b9d0ae7261245a50922ee8d1648f2db /arch/alpha/mm | |
parent | a395d6a7e3d6e3d1d316376db0c4c8b5d2995930 (diff) |
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>
Diffstat (limited to 'arch/alpha/mm')
-rw-r--r-- | arch/alpha/mm/Makefile | 2 | ||||
-rw-r--r-- | arch/alpha/mm/extable.c | 92 |
2 files changed, 1 insertions, 93 deletions
diff --git a/arch/alpha/mm/Makefile b/arch/alpha/mm/Makefile index c993d3f93cf6..5a9807936411 100644 --- a/arch/alpha/mm/Makefile +++ b/arch/alpha/mm/Makefile | |||
@@ -4,6 +4,6 @@ | |||
4 | 4 | ||
5 | ccflags-y := -Werror | 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 | obj-$(CONFIG_DISCONTIGMEM) += numa.o | 9 | obj-$(CONFIG_DISCONTIGMEM) += numa.o |
diff --git a/arch/alpha/mm/extable.c b/arch/alpha/mm/extable.c deleted file mode 100644 index 813c9b63c0e1..000000000000 --- a/arch/alpha/mm/extable.c +++ /dev/null | |||
@@ -1,92 +0,0 @@ | |||
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 | } | ||