#include <linux/module.h>
#include <asm/uaccess.h>
+#include <asm/traps.h>
typedef bool (*ex_handler_t)(const struct exception_table_entry *,
struct pt_regs *, int);
return handler(e, regs, trapnr);
}
+extern unsigned int early_recursion_flag;
+
/* Restricted version used during very early boot */
-int __init early_fixup_exception(unsigned long *ip)
+void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
{
- const struct exception_table_entry *e;
- unsigned long new_ip;
- ex_handler_t handler;
+ /* Ignore early NMIs. */
+ if (trapnr == X86_TRAP_NMI)
+ return;
- e = search_exception_tables(*ip);
- if (!e)
- return 0;
+ if (early_recursion_flag > 2)
+ goto halt_loop;
- new_ip = ex_fixup_addr(e);
- handler = ex_fixup_handler(e);
+ if (regs->cs != __KERNEL_CS)
+ goto fail;
- /* special handling not supported during early boot */
- if (handler != ex_handler_default)
- return 0;
+ if (fixup_exception(regs, trapnr))
+ return;
+
+fail:
+ early_printk("PANIC: early exception 0x%02x IP %lx:%lx error %lx cr2 0x%lx\n",
+ (unsigned)trapnr, (unsigned long)regs->cs, regs->ip,
+ regs->orig_ax, read_cr2());
+
+ show_regs(regs);
- *ip = new_ip;
- return 1;
+halt_loop:
+ while (true)
+ halt();
}