aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/traps.c
diff options
context:
space:
mode:
authorRobin Getz <robin.getz@analog.com>2007-10-29 05:20:41 -0400
committerBryan Wu <bryan.wu@analog.com>2007-10-29 05:20:41 -0400
commit885be03b069131d242506f0f717d38659b2bdb6c (patch)
tree52c1858645ee28b9d0bc7166744da3eef5bc6f1f /arch/blackfin/kernel/traps.c
parent64307f7db3690140a16c6748e65068f8a279877c (diff)
Blackfin arch: fix bug: kernel prints out error message twice
This fixes two things: - stop calling write_lock_irq/write_unlock_irq which can turn modify irq levels - don't calling mmput when handing exceptions - since this might_sleep, which does a rti, and leaves us in kernel space (irq15, rather than irq5). Signed-off-by: Robin Getz <robin.getz@analog.com> Signed-off-by: Bryan Wu <bryan.wu@analog.com>
Diffstat (limited to 'arch/blackfin/kernel/traps.c')
-rw-r--r--arch/blackfin/kernel/traps.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index afd044e78af6..ce86659f9b65 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -54,12 +54,13 @@ void __init trap_init(void)
54int kstack_depth_to_print = 48; 54int kstack_depth_to_print = 48;
55 55
56#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON 56#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
57static int printk_address(unsigned long address) 57static void printk_address(unsigned long address)
58{ 58{
59 struct vm_list_struct *vml; 59 struct vm_list_struct *vml;
60 struct task_struct *p; 60 struct task_struct *p;
61 struct mm_struct *mm; 61 struct mm_struct *mm;
62 unsigned long offset; 62 unsigned long flags, offset;
63 unsigned int in_exception = bfin_read_IPEND() & 0x10;
63 64
64#ifdef CONFIG_KALLSYMS 65#ifdef CONFIG_KALLSYMS
65 unsigned long symsize; 66 unsigned long symsize;
@@ -75,9 +76,10 @@ static int printk_address(unsigned long address)
75 /* yeah! kernel space! */ 76 /* yeah! kernel space! */
76 if (!modname) 77 if (!modname)
77 modname = delim = ""; 78 modname = delim = "";
78 return printk("<0x%p> { %s%s%s%s + 0x%lx }", 79 printk("<0x%p> { %s%s%s%s + 0x%lx }",
79 (void *)address, delim, modname, delim, symname, 80 (void *)address, delim, modname, delim, symname,
80 (unsigned long)offset); 81 (unsigned long)offset);
82 return;
81 83
82 } 84 }
83#endif 85#endif
@@ -86,9 +88,9 @@ static int printk_address(unsigned long address)
86 * mappings of all our processes and see if we can't be a whee 88 * mappings of all our processes and see if we can't be a whee
87 * bit more specific 89 * bit more specific
88 */ 90 */
89 write_lock_irq(&tasklist_lock); 91 write_lock_irqsave(&tasklist_lock, flags);
90 for_each_process(p) { 92 for_each_process(p) {
91 mm = get_task_mm(p); 93 mm = (in_exception ? p->mm : get_task_mm(p));
92 if (!mm) 94 if (!mm)
93 continue; 95 continue;
94 96
@@ -117,20 +119,24 @@ static int printk_address(unsigned long address)
117 else 119 else
118 offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); 120 offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT);
119 121
120 write_unlock_irq(&tasklist_lock); 122 printk("<0x%p> [ %s + 0x%lx ]",
121 mmput(mm); 123 (void *)address, name, offset);
122 return printk("<0x%p> [ %s + 0x%lx ]", 124 if (!in_exception)
123 (void *)address, name, offset); 125 mmput(mm);
126 goto done;
124 } 127 }
125 128
126 vml = vml->next; 129 vml = vml->next;
127 } 130 }
128 mmput(mm); 131 if (!in_exception)
132 mmput(mm);
129 } 133 }
130 write_unlock_irq(&tasklist_lock);
131 134
132 /* we were unable to find this address anywhere */ 135 /* we were unable to find this address anywhere */
133 return printk("[<0x%p>]", (void *)address); 136 printk("[<0x%p>]", (void *)address);
137
138done:
139 write_unlock_irqrestore(&tasklist_lock, flags);
134} 140}
135#endif 141#endif
136 142