diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-05 17:55:20 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-05 17:55:20 -0400 |
commit | ea62ccd00fd0b6720b033adfc9984f31130ce195 (patch) | |
tree | 9837b797b2466fffcb0af96c388b06eae9c3df18 /arch/x86_64/kernel/traps.c | |
parent | 886a0768affe9a32f18c45f8e1393bca9ece5392 (diff) | |
parent | 35060b6a9a4e1c89bc6fbea61090e302dbc61847 (diff) |
Merge branch 'for-linus' of git://one.firstfloor.org/home/andi/git/linux-2.6
* 'for-linus' of git://one.firstfloor.org/home/andi/git/linux-2.6: (231 commits)
[PATCH] i386: Don't delete cpu_devs data to identify different x86 types in late_initcall
[PATCH] i386: type may be unused
[PATCH] i386: Some additional chipset register values validation.
[PATCH] i386: Add missing !X86_PAE dependincy to the 2G/2G split.
[PATCH] x86-64: Don't exclude asm-offsets.c in Documentation/dontdiff
[PATCH] i386: avoid redundant preempt_disable in __unlazy_fpu
[PATCH] i386: white space fixes in i387.h
[PATCH] i386: Drop noisy e820 debugging printks
[PATCH] x86-64: Fix allnoconfig error in genapic_flat.c
[PATCH] x86-64: Shut up warnings for vfat compat ioctls on other file systems
[PATCH] x86-64: Share identical video.S between i386 and x86-64
[PATCH] x86-64: Remove CONFIG_REORDER
[PATCH] x86-64: Print type and size correctly for unknown compat ioctls
[PATCH] i386: Remove copy_*_user BUG_ONs for (size < 0)
[PATCH] i386: Little cleanups in smpboot.c
[PATCH] x86-64: Don't enable NUMA for a single node in K8 NUMA scanning
[PATCH] x86: Use RDTSCP for synchronous get_cycles if possible
[PATCH] i386: Add X86_FEATURE_RDTSCP
[PATCH] i386: Implement X86_FEATURE_SYNC_RDTSC on i386
[PATCH] i386: Implement alternative_io for i386
...
Fix up trivial conflict in include/linux/highmem.h manually.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/x86_64/kernel/traps.c')
-rw-r--r-- | arch/x86_64/kernel/traps.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 09d2e8a10a49..d76fc32d4599 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -426,8 +426,7 @@ void show_registers(struct pt_regs *regs) | |||
426 | const int cpu = smp_processor_id(); | 426 | const int cpu = smp_processor_id(); |
427 | struct task_struct *cur = cpu_pda(cpu)->pcurrent; | 427 | struct task_struct *cur = cpu_pda(cpu)->pcurrent; |
428 | 428 | ||
429 | rsp = regs->rsp; | 429 | rsp = regs->rsp; |
430 | |||
431 | printk("CPU %d ", cpu); | 430 | printk("CPU %d ", cpu); |
432 | __show_regs(regs); | 431 | __show_regs(regs); |
433 | printk("Process %s (pid: %d, threadinfo %p, task %p)\n", | 432 | printk("Process %s (pid: %d, threadinfo %p, task %p)\n", |
@@ -438,7 +437,6 @@ void show_registers(struct pt_regs *regs) | |||
438 | * time of the fault.. | 437 | * time of the fault.. |
439 | */ | 438 | */ |
440 | if (in_kernel) { | 439 | if (in_kernel) { |
441 | |||
442 | printk("Stack: "); | 440 | printk("Stack: "); |
443 | _show_stack(NULL, regs, (unsigned long*)rsp); | 441 | _show_stack(NULL, regs, (unsigned long*)rsp); |
444 | 442 | ||
@@ -581,10 +579,20 @@ static void __kprobes do_trap(int trapnr, int signr, char *str, | |||
581 | { | 579 | { |
582 | struct task_struct *tsk = current; | 580 | struct task_struct *tsk = current; |
583 | 581 | ||
584 | tsk->thread.error_code = error_code; | ||
585 | tsk->thread.trap_no = trapnr; | ||
586 | |||
587 | if (user_mode(regs)) { | 582 | if (user_mode(regs)) { |
583 | /* | ||
584 | * We want error_code and trap_no set for userspace | ||
585 | * faults and kernelspace faults which result in | ||
586 | * die(), but not kernelspace faults which are fixed | ||
587 | * up. die() gives the process no chance to handle | ||
588 | * the signal and notice the kernel fault information, | ||
589 | * so that won't result in polluting the information | ||
590 | * about previously queued, but not yet delivered, | ||
591 | * faults. See also do_general_protection below. | ||
592 | */ | ||
593 | tsk->thread.error_code = error_code; | ||
594 | tsk->thread.trap_no = trapnr; | ||
595 | |||
588 | if (exception_trace && unhandled_signal(tsk, signr)) | 596 | if (exception_trace && unhandled_signal(tsk, signr)) |
589 | printk(KERN_INFO | 597 | printk(KERN_INFO |
590 | "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n", | 598 | "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n", |
@@ -605,8 +613,11 @@ static void __kprobes do_trap(int trapnr, int signr, char *str, | |||
605 | fixup = search_exception_tables(regs->rip); | 613 | fixup = search_exception_tables(regs->rip); |
606 | if (fixup) | 614 | if (fixup) |
607 | regs->rip = fixup->fixup; | 615 | regs->rip = fixup->fixup; |
608 | else | 616 | else { |
617 | tsk->thread.error_code = error_code; | ||
618 | tsk->thread.trap_no = trapnr; | ||
609 | die(str, regs, error_code); | 619 | die(str, regs, error_code); |
620 | } | ||
610 | return; | 621 | return; |
611 | } | 622 | } |
612 | } | 623 | } |
@@ -682,10 +693,10 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs, | |||
682 | 693 | ||
683 | conditional_sti(regs); | 694 | conditional_sti(regs); |
684 | 695 | ||
685 | tsk->thread.error_code = error_code; | ||
686 | tsk->thread.trap_no = 13; | ||
687 | |||
688 | if (user_mode(regs)) { | 696 | if (user_mode(regs)) { |
697 | tsk->thread.error_code = error_code; | ||
698 | tsk->thread.trap_no = 13; | ||
699 | |||
689 | if (exception_trace && unhandled_signal(tsk, SIGSEGV)) | 700 | if (exception_trace && unhandled_signal(tsk, SIGSEGV)) |
690 | printk(KERN_INFO | 701 | printk(KERN_INFO |
691 | "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n", | 702 | "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n", |
@@ -704,6 +715,9 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs, | |||
704 | regs->rip = fixup->fixup; | 715 | regs->rip = fixup->fixup; |
705 | return; | 716 | return; |
706 | } | 717 | } |
718 | |||
719 | tsk->thread.error_code = error_code; | ||
720 | tsk->thread.trap_no = 13; | ||
707 | if (notify_die(DIE_GPF, "general protection fault", regs, | 721 | if (notify_die(DIE_GPF, "general protection fault", regs, |
708 | error_code, 13, SIGSEGV) == NOTIFY_STOP) | 722 | error_code, 13, SIGSEGV) == NOTIFY_STOP) |
709 | return; | 723 | return; |