Manual merge of for-linus to upstream (fix conflicts in drivers/infiniband/core/ucm.c)
[linux-2.6] / arch / i386 / mm / extable.c
1 /*
2  * linux/arch/i386/mm/extable.c
3  */
4
5 #include <linux/config.h>
6 #include <linux/module.h>
7 #include <linux/spinlock.h>
8 #include <asm/uaccess.h>
9
10 int fixup_exception(struct pt_regs *regs)
11 {
12         const struct exception_table_entry *fixup;
13
14 #ifdef CONFIG_PNPBIOS
15         if (unlikely((regs->xcs & ~15) == (GDT_ENTRY_PNPBIOS_BASE << 3)))
16         {
17                 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
18                 extern u32 pnp_bios_is_utter_crap;
19                 pnp_bios_is_utter_crap = 1;
20                 printk(KERN_CRIT "PNPBIOS fault.. attempting recovery.\n");
21                 __asm__ volatile(
22                         "movl %0, %%esp\n\t"
23                         "jmp *%1\n\t"
24                         : : "g" (pnp_bios_fault_esp), "g" (pnp_bios_fault_eip));
25                 panic("do_trap: can't hit this");
26         }
27 #endif
28
29         fixup = search_exception_tables(regs->eip);
30         if (fixup) {
31                 regs->eip = fixup->fixup;
32                 return 1;
33         }
34
35         return 0;
36 }