Make x86-64 compile again after recent extable changes.
conswitchp = &dummy_con;
#endif
#endif
-
- exception_table_check();
}
#ifndef CONFIG_X86_TSC
/* kernel trap */
{
- unsigned long fixup = search_exception_table(regs->rip);
+ const struct exception_table_entry *fixup;
+ fixup = search_exception_tables(regs->rip);
if (fixup) {
extern int exception_trace;
if (exception_trace)
"%s: fixed kernel exception at %lx err:%ld\n",
current->comm, regs->rip, error_code);
- regs->rip = fixup;
+ regs->rip = fixup->fixup;
} else
die(str, regs, error_code);
return;
do_trap(3, SIGTRAP, "int3", regs, error_code, NULL);
}
-extern void dump_pagetable(unsigned long);
-
asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
{
#ifdef CONFIG_CHECKING
/* kernel gp */
{
- unsigned long fixup;
- fixup = search_exception_table(regs->rip);
+ const struct exception_table_entry *fixup;
+ fixup = search_exception_tables(regs->rip);
if (fixup) {
- regs->rip = fixup;
+ regs->rip = fixup->fixup;
return;
}
-// dump_pagetable(regs->rip);
die("general protection fault", regs, error_code);
}
}
#include <linux/module.h>
#include <linux/spinlock.h>
#include <asm/uaccess.h>
-#include <linux/init.h>
-extern const struct exception_table_entry __start___ex_table[];
-extern const struct exception_table_entry __stop___ex_table[];
-
-
-void __init exception_table_check(void)
-{
- const struct exception_table_entry *e;
- unsigned long prev;
-
- prev = 0;
- for (e = __start___ex_table; e < __stop___ex_table; e++) {
- if (e->insn < prev) {
- panic("unordered exception table at %016lx:%016lx and %016lx:%016lx\n",
- prev, e[-1].fixup,
- e->insn, e->fixup);
- }
- prev = e->insn;
- }
-}
-
-static unsigned long
-search_one_table(const struct exception_table_entry *first,
- const struct exception_table_entry *last,
- unsigned long value)
+/* Simple binary search */
+const struct exception_table_entry *
+search_extable(const struct exception_table_entry *first,
+ const struct exception_table_entry *last,
+ unsigned long value)
{
while (first <= last) {
const struct exception_table_entry *mid;
mid = (last - first) / 2 + first;
diff = mid->insn - value;
if (diff == 0)
- return mid->fixup;
+ return mid;
else if (diff < 0)
first = mid+1;
else
last = mid-1;
}
- return 0;
-}
-
-extern spinlock_t modlist_lock;
-
-unsigned long
-search_exception_table(unsigned long addr)
-{
- unsigned long ret = 0;
- unsigned long flags;
-
-#ifndef CONFIG_MODULES
- /* There is only the kernel to search. */
- return search_one_table(__start___ex_table, __stop___ex_table-1, addr);
-#else
- /* The kernel is the last "module" -- no need to treat it special. */
- struct list_head *i;
-
- spin_lock_irqsave(&modlist_lock, flags);
- list_for_each(i, &extables) {
- struct exception_table *ex =
- list_entry(i,struct exception_table, list);
- if (ex->num_entries == 0)
- continue;
- ret = search_one_table(ex->entry,
- ex->entry + ex->num_entries - 1, addr);
- if (ret)
- break;
- }
- spin_unlock_irqrestore(&modlist_lock, flags);
- return ret;
-#endif
+ return NULL;
}
#include <linux/tty.h>
#include <linux/vt_kern.h> /* For unblank_screen() */
#include <linux/compiler.h>
+#include <linux/module.h>
#include <asm/system.h>
#include <asm/uaccess.h>
struct mm_struct *mm;
struct vm_area_struct * vma;
unsigned long address;
- unsigned long fixup;
+ const struct exception_table_entry *fixup;
int write;
siginfo_t info;
no_context:
/* Are we prepared to handle this kernel fault? */
- if ((fixup = search_exception_table(regs->rip)) != 0) {
- regs->rip = fixup;
+ fixup = search_exception_tables(regs->rip);
+ if (fixup) {
+ regs->rip = fixup->fixup;
if (0 && exception_trace)
printk(KERN_ERR
"%s: fixed kernel exception at %lx address %lx err:%ld\n",
unsigned long insn, fixup;
};
-/* Returns 0 if exception not found and fixup otherwise. */
-extern unsigned long search_exception_table(unsigned long);
-
/*
* These are the main single-value transfer routines. They automatically