Commit 9b2ea4ae authored by Brian Gerst's avatar Brian Gerst Committed by Linus Torvalds

[PATCH] Fix PnP BIOS fault handling

Check for PnP BIOS in all fault paths, not just in do_trap().
parent 8e517818
...@@ -297,26 +297,7 @@ static inline void do_trap(int trapnr, int signr, char *str, int vm86, ...@@ -297,26 +297,7 @@ static inline void do_trap(int trapnr, int signr, char *str, int vm86,
} }
kernel_trap: { kernel_trap: {
const struct exception_table_entry *fixup; if (!fixup_exception(regs))
#ifdef CONFIG_PNPBIOS
if (unlikely((regs->xcs | 8) == 0x88)) /* 0x80 or 0x88 */
{
extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
extern u32 pnp_bios_is_utter_crap;
pnp_bios_is_utter_crap = 1;
printk(KERN_CRIT "PNPBIOS fault.. attempting recovery.\n");
__asm__ volatile(
"movl %0, %%esp\n\t"
"jmp *%1\n\t"
: "=a" (pnp_bios_fault_esp), "=b" (pnp_bios_fault_eip));
panic("do_trap: can't hit this");
}
#endif
fixup = search_exception_tables(regs->eip);
if (fixup)
regs->eip = fixup->fixup;
else
die(str, regs, error_code); die(str, regs, error_code);
return; return;
} }
...@@ -393,15 +374,8 @@ asmlinkage void do_general_protection(struct pt_regs * regs, long error_code) ...@@ -393,15 +374,8 @@ asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
return; return;
gp_in_kernel: gp_in_kernel:
{ if (!fixup_exception(regs))
const struct exception_table_entry *fixup;
fixup = search_exception_tables(regs->eip);
if (fixup) {
regs->eip = fixup->fixup;
return;
}
die("general protection fault", regs, error_code); die("general protection fault", regs, error_code);
}
} }
static void mem_parity_error(unsigned char reason, struct pt_regs * regs) static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
......
...@@ -28,3 +28,31 @@ search_extable(const struct exception_table_entry *first, ...@@ -28,3 +28,31 @@ search_extable(const struct exception_table_entry *first,
} }
return NULL; return NULL;
} }
int fixup_exception(struct pt_regs *regs)
{
const struct exception_table_entry *fixup;
#ifdef CONFIG_PNPBIOS
if (unlikely((regs->xcs | 8) == 0x88)) /* 0x80 or 0x88 */
{
extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
extern u32 pnp_bios_is_utter_crap;
pnp_bios_is_utter_crap = 1;
printk(KERN_CRIT "PNPBIOS fault.. attempting recovery.\n");
__asm__ volatile(
"movl %0, %%esp\n\t"
"jmp *%1\n\t"
: "=a" (pnp_bios_fault_esp), "=b" (pnp_bios_fault_eip));
panic("do_trap: can't hit this");
}
#endif
fixup = search_exception_tables(regs->eip);
if (fixup) {
regs->eip = fixup->fixup;
return 1;
}
return 0;
}
...@@ -155,7 +155,6 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -155,7 +155,6 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
struct vm_area_struct * vma; struct vm_area_struct * vma;
unsigned long address; unsigned long address;
unsigned long page; unsigned long page;
const struct exception_table_entry *fixup;
int write; int write;
siginfo_t info; siginfo_t info;
...@@ -311,10 +310,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -311,10 +310,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
no_context: no_context:
/* Are we prepared to handle this kernel fault? */ /* Are we prepared to handle this kernel fault? */
if ((fixup = search_exception_tables(regs->eip)) != NULL) { if (fixup_exception(regs))
regs->eip = fixup->fixup;
return; return;
}
/* /*
* Oops. The kernel tried to access some bad page. We'll have to * Oops. The kernel tried to access some bad page. We'll have to
......
...@@ -92,6 +92,8 @@ struct exception_table_entry ...@@ -92,6 +92,8 @@ struct exception_table_entry
unsigned long insn, fixup; unsigned long insn, fixup;
}; };
extern int fixup_exception(struct pt_regs *regs);
/* /*
* These are the main single-value transfer routines. They automatically * These are the main single-value transfer routines. They automatically
* use the right size if we just have the right pointer type. * use the right size if we just have the right pointer type.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment