|
|
1.1 root 1: /* 1.1.1.2 ! root 2: * linux/kernel/traps.c ! 3: * ! 4: * (C) 1991 Linus Torvalds ! 5: */ ! 6: ! 7: /* 1.1 root 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 <string.h> 14: 15: #include <linux/head.h> 16: #include <linux/sched.h> 17: #include <linux/kernel.h> 18: #include <asm/system.h> 19: #include <asm/segment.h> 1.1.1.2 ! root 20: #include <asm/io.h> 1.1 root 21: 22: #define get_seg_byte(seg,addr) ({ \ 23: register char __res; \ 24: __asm__("push %%fs;mov %%ax,%%fs;movb %%fs:%2,%%al;pop %%fs" \ 25: :"=a" (__res):"0" (seg),"m" (*(addr))); \ 26: __res;}) 27: 28: #define get_seg_long(seg,addr) ({ \ 29: register unsigned long __res; \ 30: __asm__("push %%fs;mov %%ax,%%fs;movl %%fs:%2,%%eax;pop %%fs" \ 31: :"=a" (__res):"0" (seg),"m" (*(addr))); \ 32: __res;}) 33: 34: #define _fs() ({ \ 35: register unsigned short __res; \ 36: __asm__("mov %%fs,%%ax":"=a" (__res):); \ 37: __res;}) 38: 39: int do_exit(long code); 40: 41: void page_exception(void); 42: 43: void divide_error(void); 44: void debug(void); 45: void nmi(void); 46: void int3(void); 47: void overflow(void); 48: void bounds(void); 49: void invalid_op(void); 50: void device_not_available(void); 51: void double_fault(void); 52: void coprocessor_segment_overrun(void); 53: void invalid_TSS(void); 54: void segment_not_present(void); 55: void stack_segment(void); 56: void general_protection(void); 57: void page_fault(void); 58: void coprocessor_error(void); 59: void reserved(void); 1.1.1.2 ! root 60: void parallel_interrupt(void); ! 61: void irq13(void); 1.1 root 62: 63: static void die(char * str,long esp_ptr,long nr) 64: { 65: long * esp = (long *) esp_ptr; 66: int i; 67: 68: printk("%s: %04x\n\r",str,nr&0xffff); 69: printk("EIP:\t%04x:%p\nEFLAGS:\t%p\nESP:\t%04x:%p\n", 70: esp[1],esp[0],esp[2],esp[4],esp[3]); 71: printk("fs: %04x\n",_fs()); 72: printk("base: %p, limit: %p\n",get_base(current->ldt[1]),get_limit(0x17)); 73: if (esp[4] == 0x17) { 74: printk("Stack: "); 75: for (i=0;i<4;i++) 76: printk("%p ",get_seg_long(0x17,i+(long *)esp[3])); 77: printk("\n"); 78: } 79: str(i); 80: printk("Pid: %d, process nr: %d\n\r",current->pid,0xffff & i); 81: for(i=0;i<10;i++) 82: printk("%02x ",0xff & get_seg_byte(esp[1],(i+(char *)esp[0]))); 83: printk("\n\r"); 84: do_exit(11); /* play segment exception */ 85: } 86: 87: void do_double_fault(long esp, long error_code) 88: { 89: die("double fault",esp,error_code); 90: } 91: 92: void do_general_protection(long esp, long error_code) 93: { 94: die("general protection",esp,error_code); 95: } 96: 97: void do_divide_error(long esp, long error_code) 98: { 99: die("divide error",esp,error_code); 100: } 101: 102: void do_int3(long * esp, long error_code, 103: long fs,long es,long ds, 104: long ebp,long esi,long edi, 105: long edx,long ecx,long ebx,long eax) 106: { 107: int tr; 108: 109: __asm__("str %%ax":"=a" (tr):"0" (0)); 110: printk("eax\t\tebx\t\tecx\t\tedx\n\r%8x\t%8x\t%8x\t%8x\n\r", 111: eax,ebx,ecx,edx); 112: printk("esi\t\tedi\t\tebp\t\tesp\n\r%8x\t%8x\t%8x\t%8x\n\r", 113: esi,edi,ebp,(long) esp); 114: printk("\n\rds\tes\tfs\ttr\n\r%4x\t%4x\t%4x\t%4x\n\r", 115: ds,es,fs,tr); 116: printk("EIP: %8x CS: %4x EFLAGS: %8x\n\r",esp[0],esp[1],esp[2]); 117: } 118: 119: void do_nmi(long esp, long error_code) 120: { 121: die("nmi",esp,error_code); 122: } 123: 124: void do_debug(long esp, long error_code) 125: { 126: die("debug",esp,error_code); 127: } 128: 129: void do_overflow(long esp, long error_code) 130: { 131: die("overflow",esp,error_code); 132: } 133: 134: void do_bounds(long esp, long error_code) 135: { 136: die("bounds",esp,error_code); 137: } 138: 139: void do_invalid_op(long esp, long error_code) 140: { 141: die("invalid operand",esp,error_code); 142: } 143: 144: void do_device_not_available(long esp, long error_code) 145: { 146: die("device not available",esp,error_code); 147: } 148: 149: void do_coprocessor_segment_overrun(long esp, long error_code) 150: { 151: die("coprocessor segment overrun",esp,error_code); 152: } 153: 154: void do_invalid_TSS(long esp,long error_code) 155: { 156: die("invalid TSS",esp,error_code); 157: } 158: 159: void do_segment_not_present(long esp,long error_code) 160: { 161: die("segment not present",esp,error_code); 162: } 163: 164: void do_stack_segment(long esp,long error_code) 165: { 166: die("stack segment",esp,error_code); 167: } 168: 169: void do_coprocessor_error(long esp, long error_code) 170: { 1.1.1.2 ! root 171: if (last_task_used_math != current) ! 172: return; 1.1 root 173: die("coprocessor error",esp,error_code); 174: } 175: 176: void do_reserved(long esp, long error_code) 177: { 1.1.1.2 ! root 178: die("reserved (15,17-47) error",esp,error_code); 1.1 root 179: } 180: 181: void trap_init(void) 182: { 183: int i; 184: 185: set_trap_gate(0,÷_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); 1.1.1.2 ! root 202: for (i=17;i<48;i++) 1.1 root 203: set_trap_gate(i,&reserved); 1.1.1.2 ! root 204: set_trap_gate(45,&irq13); ! 205: outb_p(inb_p(0x21)&0xfb,0x21); ! 206: outb(inb_p(0xA1)&0xdf,0xA1); ! 207: set_trap_gate(39,¶llel_interrupt); 1.1 root 208: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.