extable.c 883 B

1234567891011121314151617181920212223242526272829303132333435363738
  1. #include <linux/module.h>
  2. #include <linux/spinlock.h>
  3. #include <asm/uaccess.h>
  4. int fixup_exception(struct pt_regs *regs)
  5. {
  6. const struct exception_table_entry *fixup;
  7. #ifdef CONFIG_PNPBIOS
  8. if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
  9. extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
  10. extern u32 pnp_bios_is_utter_crap;
  11. pnp_bios_is_utter_crap = 1;
  12. printk(KERN_CRIT "PNPBIOS fault.. attempting recovery.\n");
  13. __asm__ volatile(
  14. "movl %0, %%esp\n\t"
  15. "jmp *%1\n\t"
  16. : : "g" (pnp_bios_fault_esp), "g" (pnp_bios_fault_eip));
  17. panic("do_trap: can't hit this");
  18. }
  19. #endif
  20. fixup = search_exception_tables(regs->ip);
  21. if (fixup) {
  22. /* If fixup is less than 16, it means uaccess error */
  23. if (fixup->fixup < 16) {
  24. current_thread_info()->uaccess_err = -EFAULT;
  25. regs->ip += fixup->fixup;
  26. return 1;
  27. }
  28. regs->ip = fixup->fixup;
  29. return 1;
  30. }
  31. return 0;
  32. }