2
* linux/arch/i386/traps.c
4
* Copyright (C) 1991, 1992 Linus Torvalds
6
* Pentium III FXSR, SSE support
7
* Gareth Hughes <gareth@valinux.com>, May 2000
11
* 'Traps.c' handles hardware traps and faults after we have saved some
14
#include <linux/config.h>
15
#include <linux/sched.h>
16
#include <linux/kernel.h>
17
#include <linux/string.h>
18
#include <linux/errno.h>
19
#include <linux/ptrace.h>
20
#include <linux/timer.h>
22
#include <linux/init.h>
23
#include <linux/delay.h>
24
#include <linux/spinlock.h>
25
#include <linux/interrupt.h>
26
#include <linux/highmem.h>
28
#include <asm/system.h>
29
#include <asm/uaccess.h>
31
#include <asm/atomic.h>
32
#include <asm/debugreg.h>
37
#include <asm/pgalloc.h>
39
#include <asm/hypervisor.h>
41
#include <linux/irq.h>
42
#include <linux/module.h>
44
asmlinkage int system_call(void);
45
asmlinkage void lcall7(void);
46
asmlinkage void lcall27(void);
48
asmlinkage void divide_error(void);
49
asmlinkage void debug(void);
50
asmlinkage void int3(void);
51
asmlinkage void overflow(void);
52
asmlinkage void bounds(void);
53
asmlinkage void invalid_op(void);
54
asmlinkage void device_not_available(void);
55
asmlinkage void double_fault(void);
56
asmlinkage void coprocessor_segment_overrun(void);
57
asmlinkage void invalid_TSS(void);
58
asmlinkage void segment_not_present(void);
59
asmlinkage void stack_segment(void);
60
asmlinkage void general_protection(void);
61
asmlinkage void page_fault(void);
62
asmlinkage void safe_page_fault(void);
63
asmlinkage void coprocessor_error(void);
64
asmlinkage void simd_coprocessor_error(void);
65
asmlinkage void alignment_check(void);
66
asmlinkage void spurious_interrupt_bug(void);
67
asmlinkage void machine_check(void);
69
int kstack_depth_to_print = 24;
73
* If the address is either in the .text section of the
74
* kernel, or in the vmalloc'ed module regions, it *may*
75
* be the address of a calling routine
80
extern struct module *module_list;
81
extern struct module kernel_module;
83
static inline int kernel_text_address(unsigned long addr)
88
if (addr >= (unsigned long) &_stext &&
89
addr <= (unsigned long) &_etext)
92
for (mod = module_list; mod != &kernel_module; mod = mod->next) {
93
/* mod_bound tests for addr being inside the vmalloc'ed
94
* module area. Of course it'd be better to test only
95
* for the .text subset... */
96
if (mod_bound(addr, 0, mod)) {
107
static inline int kernel_text_address(unsigned long addr)
109
return (addr >= (unsigned long) &_stext &&
110
addr <= (unsigned long) &_etext);
115
void show_trace(unsigned long * stack)
121
stack = (unsigned long*)&stack;
123
printk("Call Trace: ");
125
while (((long) stack & (THREAD_SIZE-1)) != 0) {
127
if (kernel_text_address(addr)) {
128
if (i && ((i % 6) == 0))
130
printk("[<%08lx>] ", addr);
137
void show_trace_task(struct task_struct *tsk)
139
unsigned long esp = tsk->thread.esp;
141
/* User space on another CPU? */
142
if ((esp ^ (unsigned long)tsk) & (PAGE_MASK<<1))
144
show_trace((unsigned long *)esp);
147
void show_stack(unsigned long * esp)
149
unsigned long *stack;
152
// debugging aid: "show_stack(NULL);" prints the
153
// back trace for this cpu.
156
esp=(unsigned long*)&esp;
159
for(i=0; i < kstack_depth_to_print; i++) {
160
if (((long) stack & (THREAD_SIZE-1)) == 0)
162
if (i && ((i % 8) == 0))
164
printk("%08lx ", *stack++);
170
void show_registers(struct pt_regs *regs)
176
esp = (unsigned long) (®s->esp);
181
ss = regs->xss & 0xffff;
183
printk(KERN_ALERT "CPU: %d\n", smp_processor_id() );
184
printk(KERN_ALERT "EIP: %04x:[<%08lx>] %s\n",
185
0xffff & regs->xcs, regs->eip, print_tainted());
186
printk(KERN_ALERT "EFLAGS: %08lx\n",regs->eflags);
187
printk(KERN_ALERT "eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n",
188
regs->eax, regs->ebx, regs->ecx, regs->edx);
189
printk(KERN_ALERT "esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n",
190
regs->esi, regs->edi, regs->ebp, esp);
191
printk(KERN_ALERT "ds: %04x es: %04x ss: %04x\n",
192
regs->xds & 0xffff, regs->xes & 0xffff, ss);
193
printk(KERN_ALERT "Process %s (pid: %d, stackpage=%08lx)",
194
current->comm, current->pid, 4096+(unsigned long)current);
196
* When in-kernel, we also print out the stack and code at the
197
* time of the fault..
201
printk(KERN_ALERT "\nStack: ");
202
show_stack((unsigned long*)esp);
207
printk(KERN_ALERT "\nCode: ");
208
if(regs->eip < PAGE_OFFSET)
214
if(__get_user(c, &((unsigned char*)regs->eip)[i])) {
216
printk(KERN_ALERT " Bad EIP value.");
224
printk(KERN_ALERT "\n");
227
spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
229
void die(const char * str, struct pt_regs * regs, long err)
232
spin_lock_irq(&die_lock);
234
printk("%s: %04lx\n", str, err & 0xffff);
235
show_registers(regs);
237
spin_unlock_irq(&die_lock);
241
static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
243
if (!(2 & regs->xcs))
248
static void inline do_trap(int trapnr, int signr, char *str,
249
struct pt_regs * regs, long error_code,
252
if (!(regs->xcs & 2))
256
struct task_struct *tsk = current;
257
tsk->thread.error_code = error_code;
258
tsk->thread.trap_no = trapnr;
260
force_sig_info(signr, info, tsk);
262
force_sig(signr, tsk);
267
unsigned long fixup = search_exception_table(regs->eip);
271
die(str, regs, error_code);
276
#define DO_ERROR(trapnr, signr, str, name) \
277
asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
279
do_trap(trapnr, signr, str, regs, error_code, NULL); \
282
#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
283
asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
286
info.si_signo = signr; \
288
info.si_code = sicode; \
289
info.si_addr = (void *)siaddr; \
290
do_trap(trapnr, signr, str, regs, error_code, &info); \
293
DO_ERROR_INFO( 0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->eip)
294
DO_ERROR( 3, SIGTRAP, "int3", int3)
295
DO_ERROR( 4, SIGSEGV, "overflow", overflow)
296
DO_ERROR( 5, SIGSEGV, "bounds", bounds)
297
DO_ERROR_INFO( 6, SIGILL, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
298
DO_ERROR( 7, SIGSEGV, "device not available", device_not_available)
299
DO_ERROR( 8, SIGSEGV, "double fault", double_fault)
300
DO_ERROR( 9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun)
301
DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
302
DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)
303
DO_ERROR(12, SIGBUS, "stack segment", stack_segment)
304
DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
305
DO_ERROR(18, SIGBUS, "machine check", machine_check)
307
asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
310
* If we trapped on an LDT access then ensure that the default_ldt is
311
* loaded, if nothing else. We load default_ldt lazily because LDT
312
* switching costs time and many applications don't need it.
314
if ( unlikely((error_code & 6) == 4) )
317
__asm__ __volatile__ ( "sldt %0" : "=r" (ldt) );
321
u.ptr = MMU_EXTENDED_COMMAND;
322
u.ptr |= (unsigned long)&default_ldt[0];
323
u.val = MMUEXT_SET_LDT | (5 << MMUEXT_CMD_SHIFT);
324
HYPERVISOR_mmu_update(&u, 1);
329
if (!(regs->xcs & 2))
332
current->thread.error_code = error_code;
333
current->thread.trap_no = 13;
334
force_sig(SIGSEGV, current);
340
fixup = search_exception_table(regs->eip);
345
die("general protection fault", regs, error_code);
350
asmlinkage void do_debug(struct pt_regs * regs, long error_code)
352
unsigned int condition;
353
struct task_struct *tsk = current;
356
condition = HYPERVISOR_get_debugreg(6);
358
/* Mask out spurious debug traps due to lazy DR7 setting */
359
if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
360
if (!tsk->thread.debugreg[7])
364
/* Save debug status register where ptrace can see it */
365
tsk->thread.debugreg[6] = condition;
367
/* Mask out spurious TF errors due to lazy TF clearing */
368
if (condition & DR_STEP) {
370
* The TF error should be masked out only if the current
371
* process is not traced and if the TRAP flag has been set
372
* previously by a tracing process (condition detected by
373
* the PT_DTRACE flag); remember that the i386 TRAP flag
374
* can be modified by the process itself in user mode,
375
* allowing programs to debug themselves without the ptrace()
378
if ((tsk->ptrace & (PT_DTRACE|PT_PTRACED)) == PT_DTRACE)
382
/* Ok, finally something we can handle */
383
tsk->thread.trap_no = 1;
384
tsk->thread.error_code = error_code;
385
info.si_signo = SIGTRAP;
387
info.si_code = TRAP_BRKPT;
389
/* If this is a kernel mode trap, save the user PC on entry to
390
* the kernel, that's what the debugger can make sense of.
392
info.si_addr = ((regs->xcs & 2) == 0) ? (void *)tsk->thread.eip :
394
force_sig_info(SIGTRAP, &info, tsk);
396
/* Disable additional traps. They'll be re-enabled when
397
* the signal is delivered.
400
HYPERVISOR_set_debugreg(7, 0);
404
regs->eflags &= ~TF_MASK;
410
* Note that we play around with the 'TS' bit in an attempt to get
411
* the correct behaviour even in the presence of the asynchronous
414
void math_error(void *eip)
416
struct task_struct * task;
418
unsigned short cwd, swd;
421
* Save the info for the exception handler and clear the error.
425
task->thread.trap_no = 16;
426
task->thread.error_code = 0;
427
info.si_signo = SIGFPE;
429
info.si_code = __SI_FAULT;
432
* (~cwd & swd) will mask out exceptions that are not set to unmasked
433
* status. 0x3f is the exception bits in these regs, 0x200 is the
434
* C1 reg you need in case of a stack fault, 0x040 is the stack
435
* fault bit. We should only be taking one exception at a time,
436
* so if this combination doesn't produce any single exception,
437
* then we have a bad program that isn't syncronizing its FPU usage
438
* and it will suffer the consequences since we won't be able to
439
* fully reproduce the context of the exception
441
cwd = get_fpu_cwd(task);
442
swd = get_fpu_swd(task);
443
switch (((~cwd) & swd & 0x3f) | (swd & 0x240)) {
447
case 0x001: /* Invalid Op */
448
case 0x040: /* Stack Fault */
449
case 0x240: /* Stack Fault | Direction */
450
info.si_code = FPE_FLTINV;
452
case 0x002: /* Denormalize */
453
case 0x010: /* Underflow */
454
info.si_code = FPE_FLTUND;
456
case 0x004: /* Zero Divide */
457
info.si_code = FPE_FLTDIV;
459
case 0x008: /* Overflow */
460
info.si_code = FPE_FLTOVF;
462
case 0x020: /* Precision */
463
info.si_code = FPE_FLTRES;
466
force_sig_info(SIGFPE, &info, task);
469
asmlinkage void do_coprocessor_error(struct pt_regs * regs, long error_code)
472
math_error((void *)regs->eip);
475
void simd_math_error(void *eip)
477
struct task_struct * task;
479
unsigned short mxcsr;
482
* Save the info for the exception handler and clear the error.
486
task->thread.trap_no = 19;
487
task->thread.error_code = 0;
488
info.si_signo = SIGFPE;
490
info.si_code = __SI_FAULT;
493
* The SIMD FPU exceptions are handled a little differently, as there
494
* is only a single status/control register. Thus, to determine which
495
* unmasked exception was caught we must mask the exception mask bits
496
* at 0x1f80, and then use these to mask the exception bits at 0x3f.
498
mxcsr = get_fpu_mxcsr(task);
499
switch (~((mxcsr & 0x1f80) >> 7) & (mxcsr & 0x3f)) {
503
case 0x001: /* Invalid Op */
504
info.si_code = FPE_FLTINV;
506
case 0x002: /* Denormalize */
507
case 0x010: /* Underflow */
508
info.si_code = FPE_FLTUND;
510
case 0x004: /* Zero Divide */
511
info.si_code = FPE_FLTDIV;
513
case 0x008: /* Overflow */
514
info.si_code = FPE_FLTOVF;
516
case 0x020: /* Precision */
517
info.si_code = FPE_FLTRES;
520
force_sig_info(SIGFPE, &info, task);
523
asmlinkage void do_simd_coprocessor_error(struct pt_regs * regs,
527
/* Handle SIMD FPU exceptions on PIII+ processors. */
529
simd_math_error((void *)regs->eip);
531
die_if_kernel("cache flush denied", regs, error_code);
532
current->thread.trap_no = 19;
533
current->thread.error_code = error_code;
534
force_sig(SIGSEGV, current);
538
asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs,
544
* 'math_state_restore()' saves the current math information in the
545
* old math state array, and gets the new ones from the current task
547
* Careful.. There are problems with IBM-designed IRQ13 behaviour.
548
* Don't touch unless you *really* know how it works.
550
asmlinkage void math_state_restore(struct pt_regs regs)
552
if (current->used_math) {
553
restore_fpu(current);
557
current->flags |= PF_USEDFPU; /* So we fnsave on switch_to() */
561
#define _set_gate(gate_addr,type,dpl,addr) \
564
__asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
566
"movl %%eax,%0\n\t" \
568
:"=m" (*((long *) (gate_addr))), \
569
"=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \
570
:"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
571
"3" ((char *) (addr)),"2" (__KERNEL_CS << 16)); \
574
static void __init set_call_gate(void *a, void *addr)
576
_set_gate(a,12,3,addr);
580
/* NB. All these are "trap gates" (i.e. events_mask isn't cleared). */
581
static trap_info_t trap_table[] = {
582
{ 0, 0, __KERNEL_CS, (unsigned long)divide_error },
583
{ 1, 0, __KERNEL_CS, (unsigned long)debug },
584
{ 3, 3, __KERNEL_CS, (unsigned long)int3 },
585
{ 4, 3, __KERNEL_CS, (unsigned long)overflow },
586
{ 5, 3, __KERNEL_CS, (unsigned long)bounds },
587
{ 6, 0, __KERNEL_CS, (unsigned long)invalid_op },
588
{ 7, 0, __KERNEL_CS, (unsigned long)device_not_available },
589
{ 8, 0, __KERNEL_CS, (unsigned long)double_fault },
590
{ 9, 0, __KERNEL_CS, (unsigned long)coprocessor_segment_overrun },
591
{ 10, 0, __KERNEL_CS, (unsigned long)invalid_TSS },
592
{ 11, 0, __KERNEL_CS, (unsigned long)segment_not_present },
593
{ 12, 0, __KERNEL_CS, (unsigned long)stack_segment },
594
{ 13, 0, __KERNEL_CS, (unsigned long)general_protection },
595
{ 14, 0, __KERNEL_CS, (unsigned long)page_fault },
596
{ 15, 0, __KERNEL_CS, (unsigned long)spurious_interrupt_bug },
597
{ 16, 0, __KERNEL_CS, (unsigned long)coprocessor_error },
598
{ 17, 0, __KERNEL_CS, (unsigned long)alignment_check },
599
{ 18, 0, __KERNEL_CS, (unsigned long)machine_check },
600
{ 19, 0, __KERNEL_CS, (unsigned long)simd_coprocessor_error },
602
3, __KERNEL_CS, (unsigned long)system_call },
607
void __init trap_init(void)
609
HYPERVISOR_set_trap_table(trap_table);
610
HYPERVISOR_set_fast_trap(SYSCALL_VECTOR);
613
* The default LDT is a single-entry callgate to lcall7 for iBCS and a
614
* callgate to lcall27 for Solaris/x86 binaries.
616
clear_page(&default_ldt[0]);
617
set_call_gate(&default_ldt[0],lcall7);
618
set_call_gate(&default_ldt[4],lcall27);
619
__make_page_readonly(&default_ldt[0]);
626
* install_safe_pf_handler / install_normal_pf_handler:
628
* These are used within the failsafe_callback handler in entry.S to avoid
629
* taking a full page fault when reloading FS and GS. This is because FS and
630
* GS could be invalid at pretty much any point while Xenolinux executes (we
631
* don't set them to safe values on entry to the kernel). At *any* point Xen
632
* may be entered due to a hardware interrupt --- on exit from Xen an invalid
633
* FS/GS will cause our failsafe_callback to be executed. This could occur,
634
* for example, while the mmmu_update_queue is in an inconsistent state. This
635
* is disastrous because the normal page-fault handler touches the update
638
* Fortunately, within the failsafe handler it is safe to force DS/ES/FS/GS
639
* to zero if they cannot be reloaded -- at this point executing a normal
640
* page fault would not change this effect. The safe page-fault handler
641
* ensures this end result (blow away the selector value) without the dangers
642
* of the normal page-fault handler.
644
* NB. Perhaps this can all go away after we have implemented writeable
648
asmlinkage void do_safe_page_fault(struct pt_regs *regs,
649
unsigned long error_code,
650
unsigned long address)
654
if ( (fixup = search_exception_table(regs->eip)) != 0 )
660
die("Unhandleable 'safe' page fault!", regs, error_code);
663
unsigned long install_safe_pf_handler(void)
665
static trap_info_t safe_pf[] = {
666
{ 14, 0, __KERNEL_CS, (unsigned long)safe_page_fault },
670
local_irq_save(flags);
671
HYPERVISOR_set_trap_table(safe_pf);
672
return flags; /* This is returned in %%eax */
675
__attribute__((regparm(3))) /* This function take its arg in %%eax */
676
void install_normal_pf_handler(unsigned long flags)
678
static trap_info_t normal_pf[] = {
679
{ 14, 0, __KERNEL_CS, (unsigned long)page_fault },
682
HYPERVISOR_set_trap_table(normal_pf);
683
local_irq_restore(flags);