Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 #include <linux/module.h>
  2 #include <linux/spinlock.h>
  3 #include <asm/uaccess.h>
  4 
  5 
  6 int fixup_exception(struct pt_regs *regs)
  7 {
  8         const struct exception_table_entry *fixup;
  9 
 10 #ifdef CONFIG_PNPBIOS
 11         if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
 12                 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
 13                 extern u32 pnp_bios_is_utter_crap;
 14                 pnp_bios_is_utter_crap = 1;
 15                 printk(KERN_CRIT "PNPBIOS fault.. attempting recovery.\n");
 16                 __asm__ volatile(
 17                         "movl %0, %%esp\n\t"
 18                         "jmp *%1\n\t"
 19                         : : "g" (pnp_bios_fault_esp), "g" (pnp_bios_fault_eip));
 20                 panic("do_trap: can't hit this");
 21         }
 22 #endif
 23 
 24         fixup = search_exception_tables(regs->ip);
 25         if (fixup) {
 26                 /* If fixup is less than 16, it means uaccess error */
 27                 if (fixup->fixup < 16) {
 28                         current_thread_info()->uaccess_err = -EFAULT;
 29                         regs->ip += fixup->fixup;
 30                         return 1;
 31                 }
 32                 regs->ip = fixup->fixup;
 33                 return 1;
 34         }
 35 
 36         return 0;
 37 }
 38 
 39 #ifdef CONFIG_X86_64
 40 /*
 41  * Need to defined our own search_extable on X86_64 to work around
 42  * a B stepping K8 bug.
 43  */
 44 const struct exception_table_entry *
 45 search_extable(const struct exception_table_entry *first,
 46                const struct exception_table_entry *last,
 47                unsigned long value)
 48 {
 49         /* B stepping K8 bug */
 50         if ((value >> 32) == 0)
 51                 value |= 0xffffffffUL << 32;
 52 
 53         while (first <= last) {
 54                 const struct exception_table_entry *mid;
 55                 long diff;
 56 
 57                 mid = (last - first) / 2 + first;
 58                 diff = mid->insn - value;
 59                 if (diff == 0)
 60                         return mid;
 61                 else if (diff < 0)
 62                         first = mid+1;
 63                 else
 64                         last = mid-1;
 65         }
 66         return NULL;
 67 }
 68 #endif
 69 
  This page was automatically generated by the LXR engine.