diff options
author | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2016-03-22 17:28:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-22 18:36:02 -0400 |
commit | c352e8b6de9808ec5edc792d54f8785de6626d02 (patch) | |
tree | 11b26a5aad05627d6d369de15ee17935430d3f10 | |
parent | e77986b560741f40ac30755afc57074898da31e8 (diff) |
s390/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: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | arch/s390/include/asm/uaccess.h | 8 | ||||
-rw-r--r-- | arch/s390/mm/Makefile | 2 | ||||
-rw-r--r-- | arch/s390/mm/extable.c | 85 |
3 files changed, 2 insertions, 93 deletions
diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h index 9dd4cc47ddc7..e0900ddf91dd 100644 --- a/arch/s390/include/asm/uaccess.h +++ b/arch/s390/include/asm/uaccess.h | |||
@@ -79,18 +79,12 @@ struct exception_table_entry | |||
79 | int insn, fixup; | 79 | int insn, fixup; |
80 | }; | 80 | }; |
81 | 81 | ||
82 | static inline unsigned long extable_insn(const struct exception_table_entry *x) | ||
83 | { | ||
84 | return (unsigned long)&x->insn + x->insn; | ||
85 | } | ||
86 | |||
87 | static inline unsigned long extable_fixup(const struct exception_table_entry *x) | 82 | static inline unsigned long extable_fixup(const struct exception_table_entry *x) |
88 | { | 83 | { |
89 | return (unsigned long)&x->fixup + x->fixup; | 84 | return (unsigned long)&x->fixup + x->fixup; |
90 | } | 85 | } |
91 | 86 | ||
92 | #define ARCH_HAS_SORT_EXTABLE | 87 | #define ARCH_HAS_RELATIVE_EXTABLE |
93 | #define ARCH_HAS_SEARCH_EXTABLE | ||
94 | 88 | ||
95 | /** | 89 | /** |
96 | * __copy_from_user: - Copy a block of data from user space, with less checking. | 90 | * __copy_from_user: - Copy a block of data from user space, with less checking. |
diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile index 2ae54cad2b6a..0aa0ad165d8b 100644 --- a/arch/s390/mm/Makefile +++ b/arch/s390/mm/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := init.o fault.o extmem.o mmap.o vmem.o maccess.o | 5 | obj-y := init.o fault.o extmem.o mmap.o vmem.o maccess.o |
6 | obj-y += page-states.o gup.o extable.o pageattr.o mem_detect.o | 6 | obj-y += page-states.o gup.o pageattr.o mem_detect.o |
7 | obj-y += pgtable.o pgalloc.o | 7 | obj-y += pgtable.o pgalloc.o |
8 | 8 | ||
9 | obj-$(CONFIG_CMM) += cmm.o | 9 | obj-$(CONFIG_CMM) += cmm.o |
diff --git a/arch/s390/mm/extable.c b/arch/s390/mm/extable.c deleted file mode 100644 index 18c8b819b0aa..000000000000 --- a/arch/s390/mm/extable.c +++ /dev/null | |||
@@ -1,85 +0,0 @@ | |||
1 | #include <linux/module.h> | ||
2 | #include <linux/sort.h> | ||
3 | #include <asm/uaccess.h> | ||
4 | |||
5 | /* | ||
6 | * Search one exception table for an entry corresponding to the | ||
7 | * given instruction address, and return the address of the entry, | ||
8 | * or NULL if none is found. | ||
9 | * We use a binary search, and thus we assume that the table is | ||
10 | * already sorted. | ||
11 | */ | ||
12 | const struct exception_table_entry * | ||
13 | search_extable(const struct exception_table_entry *first, | ||
14 | const struct exception_table_entry *last, | ||
15 | unsigned long value) | ||
16 | { | ||
17 | const struct exception_table_entry *mid; | ||
18 | unsigned long addr; | ||
19 | |||
20 | while (first <= last) { | ||
21 | mid = ((last - first) >> 1) + first; | ||
22 | addr = extable_insn(mid); | ||
23 | if (addr < value) | ||
24 | first = mid + 1; | ||
25 | else if (addr > value) | ||
26 | last = mid - 1; | ||
27 | else | ||
28 | return mid; | ||
29 | } | ||
30 | return NULL; | ||
31 | } | ||
32 | |||
33 | /* | ||
34 | * The exception table needs to be sorted so that the binary | ||
35 | * search that we use to find entries in it works properly. | ||
36 | * This is used both for the kernel exception table and for | ||
37 | * the exception tables of modules that get loaded. | ||
38 | * | ||
39 | */ | ||
40 | static int cmp_ex(const void *a, const void *b) | ||
41 | { | ||
42 | const struct exception_table_entry *x = a, *y = b; | ||
43 | |||
44 | /* This compare is only valid after normalization. */ | ||
45 | return x->insn - y->insn; | ||
46 | } | ||
47 | |||
48 | void sort_extable(struct exception_table_entry *start, | ||
49 | struct exception_table_entry *finish) | ||
50 | { | ||
51 | struct exception_table_entry *p; | ||
52 | int i; | ||
53 | |||
54 | /* Normalize entries to being relative to the start of the section */ | ||
55 | for (p = start, i = 0; p < finish; p++, i += 8) { | ||
56 | p->insn += i; | ||
57 | p->fixup += i + 4; | ||
58 | } | ||
59 | sort(start, finish - start, sizeof(*start), cmp_ex, NULL); | ||
60 | /* Denormalize all entries */ | ||
61 | for (p = start, i = 0; p < finish; p++, i += 8) { | ||
62 | p->insn -= i; | ||
63 | p->fixup -= i + 4; | ||
64 | } | ||
65 | } | ||
66 | |||
67 | #ifdef CONFIG_MODULES | ||
68 | /* | ||
69 | * If the exception table is sorted, any referring to the module init | ||
70 | * will be at the beginning or the end. | ||
71 | */ | ||
72 | void trim_init_extable(struct module *m) | ||
73 | { | ||
74 | /* Trim the beginning */ | ||
75 | while (m->num_exentries && | ||
76 | within_module_init(extable_insn(&m->extable[0]), m)) { | ||
77 | m->extable++; | ||
78 | m->num_exentries--; | ||
79 | } | ||
80 | /* Trim the end */ | ||
81 | while (m->num_exentries && | ||
82 | within_module_init(extable_insn(&m->extable[m->num_exentries-1]), m)) | ||
83 | m->num_exentries--; | ||
84 | } | ||
85 | #endif /* CONFIG_MODULES */ | ||