Skip to content

Commit 29934b0

Browse files
Ard Biesheuveltorvalds
authored andcommitted
x86/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: H. Peter Anvin <hpa@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent c352e8b commit 29934b0

File tree

2 files changed

+2
-111
lines changed

2 files changed

+2
-111
lines changed

arch/x86/include/asm/uaccess.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,8 @@ static inline bool __chk_range_not_ok(unsigned long addr, unsigned long size, un
105105
struct exception_table_entry {
106106
int insn, fixup, handler;
107107
};
108-
/* This is not the generic standard exception_table_entry format */
109-
#define ARCH_HAS_SORT_EXTABLE
110-
#define ARCH_HAS_SEARCH_EXTABLE
108+
109+
#define ARCH_HAS_RELATIVE_EXTABLE
111110

112111
extern int fixup_exception(struct pt_regs *regs, int trapnr);
113112
extern bool ex_has_fault_handler(unsigned long ip);

arch/x86/mm/extable.c

Lines changed: 0 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
11
#include <linux/module.h>
2-
#include <linux/spinlock.h>
3-
#include <linux/sort.h>
42
#include <asm/uaccess.h>
53

64
typedef bool (*ex_handler_t)(const struct exception_table_entry *,
75
struct pt_regs *, int);
86

9-
static inline unsigned long
10-
ex_insn_addr(const struct exception_table_entry *x)
11-
{
12-
return (unsigned long)&x->insn + x->insn;
13-
}
147
static inline unsigned long
158
ex_fixup_addr(const struct exception_table_entry *x)
169
{
@@ -110,104 +103,3 @@ int __init early_fixup_exception(unsigned long *ip)
110103
*ip = new_ip;
111104
return 1;
112105
}
113-
114-
/*
115-
* Search one exception table for an entry corresponding to the
116-
* given instruction address, and return the address of the entry,
117-
* or NULL if none is found.
118-
* We use a binary search, and thus we assume that the table is
119-
* already sorted.
120-
*/
121-
const struct exception_table_entry *
122-
search_extable(const struct exception_table_entry *first,
123-
const struct exception_table_entry *last,
124-
unsigned long value)
125-
{
126-
while (first <= last) {
127-
const struct exception_table_entry *mid;
128-
unsigned long addr;
129-
130-
mid = ((last - first) >> 1) + first;
131-
addr = ex_insn_addr(mid);
132-
if (addr < value)
133-
first = mid + 1;
134-
else if (addr > value)
135-
last = mid - 1;
136-
else
137-
return mid;
138-
}
139-
return NULL;
140-
}
141-
142-
/*
143-
* The exception table needs to be sorted so that the binary
144-
* search that we use to find entries in it works properly.
145-
* This is used both for the kernel exception table and for
146-
* the exception tables of modules that get loaded.
147-
*
148-
*/
149-
static int cmp_ex(const void *a, const void *b)
150-
{
151-
const struct exception_table_entry *x = a, *y = b;
152-
153-
/*
154-
* This value will always end up fittin in an int, because on
155-
* both i386 and x86-64 the kernel symbol-reachable address
156-
* space is < 2 GiB.
157-
*
158-
* This compare is only valid after normalization.
159-
*/
160-
return x->insn - y->insn;
161-
}
162-
163-
void sort_extable(struct exception_table_entry *start,
164-
struct exception_table_entry *finish)
165-
{
166-
struct exception_table_entry *p;
167-
int i;
168-
169-
/* Convert all entries to being relative to the start of the section */
170-
i = 0;
171-
for (p = start; p < finish; p++) {
172-
p->insn += i;
173-
i += 4;
174-
p->fixup += i;
175-
i += 4;
176-
p->handler += i;
177-
i += 4;
178-
}
179-
180-
sort(start, finish - start, sizeof(struct exception_table_entry),
181-
cmp_ex, NULL);
182-
183-
/* Denormalize all entries */
184-
i = 0;
185-
for (p = start; p < finish; p++) {
186-
p->insn -= i;
187-
i += 4;
188-
p->fixup -= i;
189-
i += 4;
190-
p->handler -= i;
191-
i += 4;
192-
}
193-
}
194-
195-
#ifdef CONFIG_MODULES
196-
/*
197-
* If the exception table is sorted, any referring to the module init
198-
* will be at the beginning or the end.
199-
*/
200-
void trim_init_extable(struct module *m)
201-
{
202-
/*trim the beginning*/
203-
while (m->num_exentries &&
204-
within_module_init(ex_insn_addr(&m->extable[0]), m)) {
205-
m->extable++;
206-
m->num_exentries--;
207-
}
208-
/*trim the end*/
209-
while (m->num_exentries &&
210-
within_module_init(ex_insn_addr(&m->extable[m->num_exentries-1]), m))
211-
m->num_exentries--;
212-
}
213-
#endif /* CONFIG_MODULES */

0 commit comments

Comments
 (0)