root/kernel/traps.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. die_if_kernel
  2. do_double_fault
  3. do_general_protection
  4. do_alignment_check
  5. do_divide_error
  6. do_int3
  7. do_nmi
  8. do_debug
  9. do_overflow
  10. do_bounds
  11. do_invalid_op
  12. do_device_not_available
  13. do_coprocessor_segment_overrun
  14. do_invalid_TSS
  15. do_segment_not_present
  16. do_stack_segment
  17. do_coprocessor_error
  18. do_reserved
  19. trap_init

   1 /*
   2  *  linux/kernel/traps.c
   3  *
   4  *  Copyright (C) 1991, 1992  Linus Torvalds
   5  */
   6 
   7 /*
   8  * 'Traps.c' handles hardware traps and faults after we have saved some
   9  * state in 'asm.s'. Currently mostly a debugging-aid, will be extended
  10  * to mainly kill the offending process (probably by giving it a signal,
  11  * but possibly by killing it outright if necessary).
  12  */
  13 #include <linux/head.h>
  14 #include <linux/sched.h>
  15 #include <linux/kernel.h>
  16 #include <linux/string.h>
  17 #include <linux/errno.h>
  18 
  19 #include <asm/system.h>
  20 #include <asm/segment.h>
  21 #include <asm/io.h>
  22 
  23 #define get_seg_byte(seg,addr) ({ \
  24 register char __res; \
  25 __asm__("push %%fs;mov %%ax,%%fs;movb %%fs:%2,%%al;pop %%fs" \
  26         :"=a" (__res):"0" (seg),"m" (*(addr))); \
  27 __res;})
  28 
  29 #define get_seg_long(seg,addr) ({ \
  30 register unsigned long __res; \
  31 __asm__("push %%fs;mov %%ax,%%fs;movl %%fs:%2,%%eax;pop %%fs" \
  32         :"=a" (__res):"0" (seg),"m" (*(addr))); \
  33 __res;})
  34 
  35 #define _fs() ({ \
  36 register unsigned short __res; \
  37 __asm__("mov %%fs,%%ax":"=a" (__res):); \
  38 __res;})
  39 
  40 void page_exception(void);
  41 
  42 void divide_error(void);
  43 void debug(void);
  44 void nmi(void);
  45 void int3(void);
  46 void overflow(void);
  47 void bounds(void);
  48 void invalid_op(void);
  49 void device_not_available(void);
  50 void double_fault(void);
  51 void coprocessor_segment_overrun(void);
  52 void invalid_TSS(void);
  53 void segment_not_present(void);
  54 void stack_segment(void);
  55 void general_protection(void);
  56 void page_fault(void);
  57 void coprocessor_error(void);
  58 void reserved(void);
  59 void alignment_check(void);
  60 
  61 static void die_if_kernel(char * str,long esp_ptr,long nr)
     /* [previous][next][first][last][top][bottom][index][help] */
  62 {
  63         long * esp = (long *) esp_ptr;
  64         int i;
  65 
  66         if ((0xffff & esp[1]) == 0xf)
  67                 return;
  68         printk("%s: %04x\n\r",str,nr&0xffff);
  69         printk("EIP:    %04x:%p\nEFLAGS: %p\n", 0xffff & esp[1],esp[0],esp[2]);
  70         printk("fs: %04x\n",_fs());
  71         printk("base: %p, limit: %p\n",get_base(current->ldt[1]),get_limit(0x17));
  72         str(i);
  73         printk("Pid: %d, process nr: %d\n\r",current->pid,0xffff & i);
  74         for(i=0;i<10;i++)
  75                 printk("%02x ",0xff & get_seg_byte(esp[1],(i+(char *)esp[0])));
  76         printk("\n\r");
  77         do_exit(SIGSEGV);
  78 }
  79 
  80 void do_double_fault(long esp, long error_code)
     /* [previous][next][first][last][top][bottom][index][help] */
  81 {
  82         send_sig(SIGSEGV, current, 1);
  83         die_if_kernel("double fault",esp,error_code);
  84 }
  85 
  86 void do_general_protection(long esp, long error_code)
     /* [previous][next][first][last][top][bottom][index][help] */
  87 {
  88         send_sig(SIGSEGV, current, 1);
  89         die_if_kernel("general protection",esp,error_code);
  90 }
  91 
  92 void do_alignment_check(long esp, long error_code)
     /* [previous][next][first][last][top][bottom][index][help] */
  93 {
  94         send_sig(SIGSEGV, current, 1);
  95         die_if_kernel("alignment check",esp,error_code);
  96 }
  97 
  98 void do_divide_error(long esp, long error_code)
     /* [previous][next][first][last][top][bottom][index][help] */
  99 {
 100         send_sig(SIGFPE, current, 1);
 101         die_if_kernel("divide error",esp,error_code);
 102 }
 103 
 104 void do_int3(long esp, long error_code)
     /* [previous][next][first][last][top][bottom][index][help] */
 105 {
 106         send_sig(SIGTRAP, current, 1);
 107         die_if_kernel("int3",esp,error_code);
 108 }
 109 
 110 void do_nmi(long esp, long error_code)
     /* [previous][next][first][last][top][bottom][index][help] */
 111 {
 112         printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n");
 113 }
 114 
 115 void do_debug(long esp, long error_code)
     /* [previous][next][first][last][top][bottom][index][help] */
 116 {
 117         send_sig(SIGTRAP, current, 1);
 118         die_if_kernel("debug",esp,error_code);
 119 }
 120 
 121 void do_overflow(long esp, long error_code)
     /* [previous][next][first][last][top][bottom][index][help] */
 122 {
 123         send_sig(SIGSEGV, current, 1);
 124         die_if_kernel("overflow",esp,error_code);
 125 }
 126 
 127 void do_bounds(long esp, long error_code)
     /* [previous][next][first][last][top][bottom][index][help] */
 128 {
 129         send_sig(SIGSEGV, current, 1);
 130         die_if_kernel("bounds",esp,error_code);
 131 }
 132 
 133 void do_invalid_op(long esp, long error_code)
     /* [previous][next][first][last][top][bottom][index][help] */
 134 {
 135         send_sig(SIGILL, current, 1);
 136         die_if_kernel("invalid operand",esp,error_code);
 137 }
 138 
 139 void do_device_not_available(long esp, long error_code)
     /* [previous][next][first][last][top][bottom][index][help] */
 140 {
 141         send_sig(SIGSEGV, current, 1);
 142         die_if_kernel("device not available",esp,error_code);
 143 }
 144 
 145 void do_coprocessor_segment_overrun(long esp, long error_code)
     /* [previous][next][first][last][top][bottom][index][help] */
 146 {
 147         send_sig(SIGFPE, last_task_used_math, 1);
 148         die_if_kernel("coprocessor segment overrun",esp,error_code);
 149 }
 150 
 151 void do_invalid_TSS(long esp,long error_code)
     /* [previous][next][first][last][top][bottom][index][help] */
 152 {
 153         send_sig(SIGSEGV, current, 1);
 154         die_if_kernel("invalid TSS",esp,error_code);
 155 }
 156 
 157 void do_segment_not_present(long esp,long error_code)
     /* [previous][next][first][last][top][bottom][index][help] */
 158 {
 159         send_sig(SIGSEGV, current, 1);
 160         die_if_kernel("segment not present",esp,error_code);
 161 }
 162 
 163 void do_stack_segment(long esp,long error_code)
     /* [previous][next][first][last][top][bottom][index][help] */
 164 {
 165         send_sig(SIGSEGV, current, 1);
 166         die_if_kernel("stack segment",esp,error_code);
 167 }
 168 
 169 void do_coprocessor_error(long esp, long error_code)
     /* [previous][next][first][last][top][bottom][index][help] */
 170 {
 171         send_sig(SIGFPE, last_task_used_math, 1);
 172         __asm__("fnclex");
 173 }
 174 
 175 void do_reserved(long esp, long error_code)
     /* [previous][next][first][last][top][bottom][index][help] */
 176 {
 177         send_sig(SIGSEGV, current, 1);
 178         die_if_kernel("reserved (15,17-47) error",esp,error_code);
 179 }
 180 
 181 void trap_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 182 {
 183         int i;
 184 
 185         set_trap_gate(0,&divide_error);
 186         set_trap_gate(1,&debug);
 187         set_trap_gate(2,&nmi);
 188         set_system_gate(3,&int3);       /* int3-5 can be called from all */
 189         set_system_gate(4,&overflow);
 190         set_system_gate(5,&bounds);
 191         set_trap_gate(6,&invalid_op);
 192         set_trap_gate(7,&device_not_available);
 193         set_trap_gate(8,&double_fault);
 194         set_trap_gate(9,&coprocessor_segment_overrun);
 195         set_trap_gate(10,&invalid_TSS);
 196         set_trap_gate(11,&segment_not_present);
 197         set_trap_gate(12,&stack_segment);
 198         set_trap_gate(13,&general_protection);
 199         set_trap_gate(14,&page_fault);
 200         set_trap_gate(15,&reserved);
 201         set_trap_gate(16,&coprocessor_error);
 202         set_trap_gate(17,&alignment_check);
 203         for (i=18;i<48;i++)
 204                 set_trap_gate(i,&reserved);
 205 }

/* [previous][next][first][last][top][bottom][index][help] */