aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/signal_32.c7
-rw-r--r--arch/x86/kernel/signal_64.c7
-rw-r--r--arch/x86/kernel/traps_32.c7
-rw-r--r--arch/x86/kernel/traps_64.c14
-rw-r--r--arch/x86/mm/fault_32.c4
-rw-r--r--arch/x86/mm/fault_64.c4
-rw-r--r--include/linux/mm.h1
-rw-r--r--mm/memory.c31
8 files changed, 63 insertions, 12 deletions
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c
index 74df55895c8c..89a690edf999 100644
--- a/arch/x86/kernel/signal_32.c
+++ b/arch/x86/kernel/signal_32.c
@@ -198,12 +198,15 @@ asmlinkage int sys_sigreturn(unsigned long __unused)
198 return ax; 198 return ax;
199 199
200badframe: 200badframe:
201 if (show_unhandled_signals && printk_ratelimit()) 201 if (show_unhandled_signals && printk_ratelimit()) {
202 printk("%s%s[%d] bad frame in sigreturn frame:%p ip:%lx" 202 printk("%s%s[%d] bad frame in sigreturn frame:%p ip:%lx"
203 " sp:%lx oeax:%lx\n", 203 " sp:%lx oeax:%lx",
204 task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG, 204 task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG,
205 current->comm, task_pid_nr(current), frame, regs->ip, 205 current->comm, task_pid_nr(current), frame, regs->ip,
206 regs->sp, regs->orig_ax); 206 regs->sp, regs->orig_ax);
207 print_vma_addr(" in ", regs->ip);
208 printk("\n");
209 }
207 210
208 force_sig(SIGSEGV, current); 211 force_sig(SIGSEGV, current);
209 return 0; 212 return 0;
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c
index 4eb751c60390..7347bb14e306 100644
--- a/arch/x86/kernel/signal_64.c
+++ b/arch/x86/kernel/signal_64.c
@@ -484,9 +484,12 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
484void signal_fault(struct pt_regs *regs, void __user *frame, char *where) 484void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
485{ 485{
486 struct task_struct *me = current; 486 struct task_struct *me = current;
487 if (show_unhandled_signals && printk_ratelimit()) 487 if (show_unhandled_signals && printk_ratelimit()) {
488 printk("%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx\n", 488 printk("%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx",
489 me->comm,me->pid,where,frame,regs->ip,regs->sp,regs->orig_ax); 489 me->comm,me->pid,where,frame,regs->ip,regs->sp,regs->orig_ax);
490 print_vma_addr(" in ", regs->ip);
491 printk("\n");
492 }
490 493
491 force_sig(SIGSEGV, me); 494 force_sig(SIGSEGV, me);
492} 495}
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c
index 6f3bb287c702..270cfd483160 100644
--- a/arch/x86/kernel/traps_32.c
+++ b/arch/x86/kernel/traps_32.c
@@ -609,11 +609,14 @@ void __kprobes do_general_protection(struct pt_regs * regs,
609 current->thread.error_code = error_code; 609 current->thread.error_code = error_code;
610 current->thread.trap_no = 13; 610 current->thread.trap_no = 13;
611 if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) && 611 if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) &&
612 printk_ratelimit()) 612 printk_ratelimit()) {
613 printk(KERN_INFO 613 printk(KERN_INFO
614 "%s[%d] general protection ip:%lx sp:%lx error:%lx\n", 614 "%s[%d] general protection ip:%lx sp:%lx error:%lx",
615 current->comm, task_pid_nr(current), 615 current->comm, task_pid_nr(current),
616 regs->ip, regs->sp, error_code); 616 regs->ip, regs->sp, error_code);
617 print_vma_addr(" in ", regs->ip);
618 printk("\n");
619 }
617 620
618 force_sig(SIGSEGV, current); 621 force_sig(SIGSEGV, current);
619 return; 622 return;
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c
index 814801f4eb9e..911ed28afff8 100644
--- a/arch/x86/kernel/traps_64.c
+++ b/arch/x86/kernel/traps_64.c
@@ -642,11 +642,14 @@ static void __kprobes do_trap(int trapnr, int signr, char *str,
642 tsk->thread.trap_no = trapnr; 642 tsk->thread.trap_no = trapnr;
643 643
644 if (show_unhandled_signals && unhandled_signal(tsk, signr) && 644 if (show_unhandled_signals && unhandled_signal(tsk, signr) &&
645 printk_ratelimit()) 645 printk_ratelimit()) {
646 printk(KERN_INFO 646 printk(KERN_INFO
647 "%s[%d] trap %s ip:%lx sp:%lx error:%lx\n", 647 "%s[%d] trap %s ip:%lx sp:%lx error:%lx",
648 tsk->comm, tsk->pid, str, 648 tsk->comm, tsk->pid, str,
649 regs->ip, regs->sp, error_code); 649 regs->ip, regs->sp, error_code);
650 print_vma_addr(" in ", regs->ip);
651 printk("\n");
652 }
650 653
651 if (info) 654 if (info)
652 force_sig_info(signr, info, tsk); 655 force_sig_info(signr, info, tsk);
@@ -741,11 +744,14 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs,
741 tsk->thread.trap_no = 13; 744 tsk->thread.trap_no = 13;
742 745
743 if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && 746 if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
744 printk_ratelimit()) 747 printk_ratelimit()) {
745 printk(KERN_INFO 748 printk(KERN_INFO
746 "%s[%d] general protection ip:%lx sp:%lx error:%lx\n", 749 "%s[%d] general protection ip:%lx sp:%lx error:%lx",
747 tsk->comm, tsk->pid, 750 tsk->comm, tsk->pid,
748 regs->ip, regs->sp, error_code); 751 regs->ip, regs->sp, error_code);
752 print_vma_addr(" in ", regs->ip);
753 printk("\n");
754 }
749 755
750 force_sig(SIGSEGV, tsk); 756 force_sig(SIGSEGV, tsk);
751 return; 757 return;
diff --git a/arch/x86/mm/fault_32.c b/arch/x86/mm/fault_32.c
index 13d295506a17..276863dc4bdd 100644
--- a/arch/x86/mm/fault_32.c
+++ b/arch/x86/mm/fault_32.c
@@ -514,11 +514,13 @@ bad_area_nosemaphore:
514#ifdef CONFIG_X86_32 514#ifdef CONFIG_X86_32
515 "%s%s[%d]: segfault at %lx ip %08lx sp %08lx error %lx", 515 "%s%s[%d]: segfault at %lx ip %08lx sp %08lx error %lx",
516#else 516#else
517 "%s%s[%d]: segfault at %lx ip %lx sp %lx error %lx\n", 517 "%s%s[%d]: segfault at %lx ip %lx sp %lx error %lx",
518#endif 518#endif
519 task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, 519 task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
520 tsk->comm, task_pid_nr(tsk), address, regs->ip, 520 tsk->comm, task_pid_nr(tsk), address, regs->ip,
521 regs->sp, error_code); 521 regs->sp, error_code);
522 print_vma_addr(" in ", regs->ip);
523 printk("\n");
522 } 524 }
523 tsk->thread.cr2 = address; 525 tsk->thread.cr2 = address;
524 /* Kernel addresses are always protection faults */ 526 /* Kernel addresses are always protection faults */
diff --git a/arch/x86/mm/fault_64.c b/arch/x86/mm/fault_64.c
index b606bdefbb72..9ef0306efe9e 100644
--- a/arch/x86/mm/fault_64.c
+++ b/arch/x86/mm/fault_64.c
@@ -552,11 +552,13 @@ bad_area_nosemaphore:
552#ifdef CONFIG_X86_32 552#ifdef CONFIG_X86_32
553 "%s%s[%d]: segfault at %lx ip %08lx sp %08lx error %lx", 553 "%s%s[%d]: segfault at %lx ip %08lx sp %08lx error %lx",
554#else 554#else
555 "%s%s[%d]: segfault at %lx ip %lx sp %lx error %lx\n", 555 "%s%s[%d]: segfault at %lx ip %lx sp %lx error %lx",
556#endif 556#endif
557 task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, 557 task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
558 tsk->comm, task_pid_nr(tsk), address, regs->ip, 558 tsk->comm, task_pid_nr(tsk), address, regs->ip,
559 regs->sp, error_code); 559 regs->sp, error_code);
560 print_vma_addr(" in ", regs->ip);
561 printk("\n");
560 } 562 }
561 563
562 tsk->thread.cr2 = address; 564 tsk->thread.cr2 = address;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 1897ca223eca..3c22d971afa7 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1146,6 +1146,7 @@ extern int randomize_va_space;
1146#endif 1146#endif
1147 1147
1148const char * arch_vma_name(struct vm_area_struct *vma); 1148const char * arch_vma_name(struct vm_area_struct *vma);
1149void print_vma_addr(char *prefix, unsigned long rip);
1149 1150
1150struct page *sparse_mem_map_populate(unsigned long pnum, int nid); 1151struct page *sparse_mem_map_populate(unsigned long pnum, int nid);
1151pgd_t *vmemmap_pgd_populate(unsigned long addr, int node); 1152pgd_t *vmemmap_pgd_populate(unsigned long addr, int node);
diff --git a/mm/memory.c b/mm/memory.c
index 673ebbf499c7..d902d0e25edc 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2754,3 +2754,34 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in
2754 2754
2755 return buf - old_buf; 2755 return buf - old_buf;
2756} 2756}
2757
2758/*
2759 * Print the name of a VMA.
2760 */
2761void print_vma_addr(char *prefix, unsigned long ip)
2762{
2763 struct mm_struct *mm = current->mm;
2764 struct vm_area_struct *vma;
2765
2766 down_read(&mm->mmap_sem);
2767 vma = find_vma(mm, ip);
2768 if (vma && vma->vm_file) {
2769 struct file *f = vma->vm_file;
2770 char *buf = (char *)__get_free_page(GFP_KERNEL);
2771 if (buf) {
2772 char *p, *s;
2773
2774 p = d_path(f->f_dentry, f->f_vfsmnt, buf, PAGE_SIZE);
2775 if (IS_ERR(p))
2776 p = "?";
2777 s = strrchr(p, '/');
2778 if (s)
2779 p = s+1;
2780 printk("%s%s[%lx+%lx]", prefix, p,
2781 vma->vm_start,
2782 vma->vm_end - vma->vm_start);
2783 free_page((unsigned long)buf);
2784 }
2785 }
2786 up_read(&current->mm->mmap_sem);
2787}