aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/traps.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/kernel/traps.c')
-rw-r--r--arch/blackfin/kernel/traps.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index d3cbcd6bd985..ba70c4bc2699 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -138,6 +138,12 @@ static void decode_address(char *buf, unsigned long address)
138 if (!mm) 138 if (!mm)
139 continue; 139 continue;
140 140
141 if (!down_read_trylock(&mm->mmap_sem)) {
142 if (!in_atomic)
143 mmput(mm);
144 continue;
145 }
146
141 for (n = rb_first(&mm->mm_rb); n; n = rb_next(n)) { 147 for (n = rb_first(&mm->mm_rb); n; n = rb_next(n)) {
142 struct vm_area_struct *vma; 148 struct vm_area_struct *vma;
143 149
@@ -177,6 +183,7 @@ static void decode_address(char *buf, unsigned long address)
177 sprintf(buf, "[ %s vma:0x%lx-0x%lx]", 183 sprintf(buf, "[ %s vma:0x%lx-0x%lx]",
178 name, vma->vm_start, vma->vm_end); 184 name, vma->vm_start, vma->vm_end);
179 185
186 up_read(&mm->mmap_sem);
180 if (!in_atomic) 187 if (!in_atomic)
181 mmput(mm); 188 mmput(mm);
182 189
@@ -186,11 +193,16 @@ static void decode_address(char *buf, unsigned long address)
186 goto done; 193 goto done;
187 } 194 }
188 } 195 }
196
197 up_read(&mm->mmap_sem);
189 if (!in_atomic) 198 if (!in_atomic)
190 mmput(mm); 199 mmput(mm);
191 } 200 }
192 201
193 /* we were unable to find this address anywhere */ 202 /*
203 * we were unable to find this address anywhere,
204 * or some MMs were skipped because they were in use.
205 */
194 sprintf(buf, "/* kernel dynamic memory */"); 206 sprintf(buf, "/* kernel dynamic memory */");
195 207
196done: 208done:
@@ -248,9 +260,7 @@ asmlinkage notrace void trap_c(struct pt_regs *fp)
248#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON 260#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
249 int j; 261 int j;
250#endif 262#endif
251#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO
252 unsigned int cpu = raw_smp_processor_id(); 263 unsigned int cpu = raw_smp_processor_id();
253#endif
254 const char *strerror = NULL; 264 const char *strerror = NULL;
255 int sig = 0; 265 int sig = 0;
256 siginfo_t info; 266 siginfo_t info;
@@ -639,7 +649,17 @@ asmlinkage notrace void trap_c(struct pt_regs *fp)
639 { 649 {
640 info.si_signo = sig; 650 info.si_signo = sig;
641 info.si_errno = 0; 651 info.si_errno = 0;
642 info.si_addr = (void __user *)fp->pc; 652 switch (trapnr) {
653 case VEC_CPLB_VL:
654 case VEC_MISALI_D:
655 case VEC_CPLB_M:
656 case VEC_CPLB_MHIT:
657 info.si_addr = (void __user *)cpu_pda[cpu].dcplb_fault_addr;
658 break;
659 default:
660 info.si_addr = (void __user *)fp->pc;
661 break;
662 }
643 force_sig_info(sig, &info, current); 663 force_sig_info(sig, &info, current);
644 } 664 }
645 665
@@ -712,7 +732,7 @@ static void decode_instruction(unsigned short *address)
712 verbose_printk("RTE"); 732 verbose_printk("RTE");
713 else if (opcode == 0x0025) 733 else if (opcode == 0x0025)
714 verbose_printk("EMUEXCPT"); 734 verbose_printk("EMUEXCPT");
715 else if (opcode == 0x0040 && opcode <= 0x0047) 735 else if (opcode >= 0x0040 && opcode <= 0x0047)
716 verbose_printk("STI R%i", opcode & 7); 736 verbose_printk("STI R%i", opcode & 7);
717 else if (opcode >= 0x0050 && opcode <= 0x0057) 737 else if (opcode >= 0x0050 && opcode <= 0x0057)
718 verbose_printk("JUMP (P%i)", opcode & 7); 738 verbose_printk("JUMP (P%i)", opcode & 7);
@@ -1096,7 +1116,7 @@ void dump_bfin_mem(struct pt_regs *fp)
1096 /* And the last RETI points to the current userspace context */ 1116 /* And the last RETI points to the current userspace context */
1097 if ((fp + 1)->pc >= current->mm->start_code && 1117 if ((fp + 1)->pc >= current->mm->start_code &&
1098 (fp + 1)->pc <= current->mm->end_code) { 1118 (fp + 1)->pc <= current->mm->end_code) {
1099 verbose_printk(KERN_NOTICE "It might be better to look around here : \n"); 1119 verbose_printk(KERN_NOTICE "It might be better to look around here :\n");
1100 verbose_printk(KERN_NOTICE "-------------------------------------------\n"); 1120 verbose_printk(KERN_NOTICE "-------------------------------------------\n");
1101 show_regs(fp + 1); 1121 show_regs(fp + 1);
1102 verbose_printk(KERN_NOTICE "-------------------------------------------\n"); 1122 verbose_printk(KERN_NOTICE "-------------------------------------------\n");