diff options
Diffstat (limited to 'arch/blackfin/kernel/traps.c')
-rw-r--r-- | arch/blackfin/kernel/traps.c | 56 |
1 files changed, 26 insertions, 30 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index bef025b07443..af7cc43630de 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c | |||
@@ -75,16 +75,6 @@ void __init trap_init(void) | |||
75 | CSYNC(); | 75 | CSYNC(); |
76 | } | 76 | } |
77 | 77 | ||
78 | /* | ||
79 | * Used to save the RETX, SEQSTAT, I/D CPLB FAULT ADDR | ||
80 | * values across the transition from exception to IRQ5. | ||
81 | * We put these in L1, so they are going to be in a valid | ||
82 | * location during exception context | ||
83 | */ | ||
84 | __attribute__((l1_data)) | ||
85 | unsigned long saved_retx, saved_seqstat, | ||
86 | saved_icplb_fault_addr, saved_dcplb_fault_addr; | ||
87 | |||
88 | static void decode_address(char *buf, unsigned long address) | 78 | static void decode_address(char *buf, unsigned long address) |
89 | { | 79 | { |
90 | #ifdef CONFIG_DEBUG_VERBOSE | 80 | #ifdef CONFIG_DEBUG_VERBOSE |
@@ -211,18 +201,18 @@ asmlinkage void double_fault_c(struct pt_regs *fp) | |||
211 | printk(KERN_EMERG "\n" KERN_EMERG "Double Fault\n"); | 201 | printk(KERN_EMERG "\n" KERN_EMERG "Double Fault\n"); |
212 | #ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT | 202 | #ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT |
213 | if (((long)fp->seqstat & SEQSTAT_EXCAUSE) == VEC_UNCOV) { | 203 | if (((long)fp->seqstat & SEQSTAT_EXCAUSE) == VEC_UNCOV) { |
204 | unsigned int cpu = smp_processor_id(); | ||
214 | char buf[150]; | 205 | char buf[150]; |
215 | decode_address(buf, saved_retx); | 206 | decode_address(buf, cpu_pda[cpu].retx); |
216 | printk(KERN_EMERG "While handling exception (EXCAUSE = 0x%x) at %s:\n", | 207 | printk(KERN_EMERG "While handling exception (EXCAUSE = 0x%x) at %s:\n", |
217 | (int)saved_seqstat & SEQSTAT_EXCAUSE, buf); | 208 | (unsigned int)cpu_pda[cpu].seqstat & SEQSTAT_EXCAUSE, buf); |
218 | decode_address(buf, saved_dcplb_fault_addr); | 209 | decode_address(buf, cpu_pda[cpu].dcplb_fault_addr); |
219 | printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %s\n", buf); | 210 | printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %s\n", buf); |
220 | decode_address(buf, saved_icplb_fault_addr); | 211 | decode_address(buf, cpu_pda[cpu].icplb_fault_addr); |
221 | printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %s\n", buf); | 212 | printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %s\n", buf); |
222 | 213 | ||
223 | decode_address(buf, fp->retx); | 214 | decode_address(buf, fp->retx); |
224 | printk(KERN_NOTICE "The instruction at %s caused a double exception\n", | 215 | printk(KERN_NOTICE "The instruction at %s caused a double exception\n", buf); |
225 | buf); | ||
226 | } else | 216 | } else |
227 | #endif | 217 | #endif |
228 | { | 218 | { |
@@ -240,6 +230,9 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
240 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON | 230 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON |
241 | int j; | 231 | int j; |
242 | #endif | 232 | #endif |
233 | #ifdef CONFIG_DEBUG_HUNT_FOR_ZERO | ||
234 | unsigned int cpu = smp_processor_id(); | ||
235 | #endif | ||
243 | int sig = 0; | 236 | int sig = 0; |
244 | siginfo_t info; | 237 | siginfo_t info; |
245 | unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE; | 238 | unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE; |
@@ -417,7 +410,7 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
417 | info.si_code = ILL_CPLB_MULHIT; | 410 | info.si_code = ILL_CPLB_MULHIT; |
418 | sig = SIGSEGV; | 411 | sig = SIGSEGV; |
419 | #ifdef CONFIG_DEBUG_HUNT_FOR_ZERO | 412 | #ifdef CONFIG_DEBUG_HUNT_FOR_ZERO |
420 | if (saved_dcplb_fault_addr < FIXED_CODE_START) | 413 | if (cpu_pda[cpu].dcplb_fault_addr < FIXED_CODE_START) |
421 | verbose_printk(KERN_NOTICE "NULL pointer access\n"); | 414 | verbose_printk(KERN_NOTICE "NULL pointer access\n"); |
422 | else | 415 | else |
423 | #endif | 416 | #endif |
@@ -471,7 +464,7 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
471 | info.si_code = ILL_CPLB_MULHIT; | 464 | info.si_code = ILL_CPLB_MULHIT; |
472 | sig = SIGSEGV; | 465 | sig = SIGSEGV; |
473 | #ifdef CONFIG_DEBUG_HUNT_FOR_ZERO | 466 | #ifdef CONFIG_DEBUG_HUNT_FOR_ZERO |
474 | if (saved_icplb_fault_addr < FIXED_CODE_START) | 467 | if (cpu_pda[cpu].icplb_fault_addr < FIXED_CODE_START) |
475 | verbose_printk(KERN_NOTICE "Jump to NULL address\n"); | 468 | verbose_printk(KERN_NOTICE "Jump to NULL address\n"); |
476 | else | 469 | else |
477 | #endif | 470 | #endif |
@@ -960,6 +953,7 @@ void dump_bfin_process(struct pt_regs *fp) | |||
960 | else | 953 | else |
961 | verbose_printk(KERN_NOTICE "COMM= invalid\n"); | 954 | verbose_printk(KERN_NOTICE "COMM= invalid\n"); |
962 | 955 | ||
956 | printk(KERN_NOTICE "CPU = %d\n", current_thread_info()->cpu); | ||
963 | if (!((unsigned long)current->mm & 0x3) && (unsigned long)current->mm >= FIXED_CODE_START) | 957 | if (!((unsigned long)current->mm & 0x3) && (unsigned long)current->mm >= FIXED_CODE_START) |
964 | verbose_printk(KERN_NOTICE "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" | 958 | verbose_printk(KERN_NOTICE "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" |
965 | KERN_NOTICE " BSS = 0x%p-0x%p USER-STACK = 0x%p\n" | 959 | KERN_NOTICE " BSS = 0x%p-0x%p USER-STACK = 0x%p\n" |
@@ -1053,6 +1047,7 @@ void show_regs(struct pt_regs *fp) | |||
1053 | struct irqaction *action; | 1047 | struct irqaction *action; |
1054 | unsigned int i; | 1048 | unsigned int i; |
1055 | unsigned long flags; | 1049 | unsigned long flags; |
1050 | unsigned int cpu = smp_processor_id(); | ||
1056 | 1051 | ||
1057 | verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted()); | 1052 | verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted()); |
1058 | verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", | 1053 | verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", |
@@ -1112,9 +1107,9 @@ unlock: | |||
1112 | 1107 | ||
1113 | if (((long)fp->seqstat & SEQSTAT_EXCAUSE) && | 1108 | if (((long)fp->seqstat & SEQSTAT_EXCAUSE) && |
1114 | (((long)fp->seqstat & SEQSTAT_EXCAUSE) != VEC_HWERR)) { | 1109 | (((long)fp->seqstat & SEQSTAT_EXCAUSE) != VEC_HWERR)) { |
1115 | decode_address(buf, saved_dcplb_fault_addr); | 1110 | decode_address(buf, cpu_pda[cpu].dcplb_fault_addr); |
1116 | verbose_printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf); | 1111 | verbose_printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf); |
1117 | decode_address(buf, saved_icplb_fault_addr); | 1112 | decode_address(buf, cpu_pda[cpu].icplb_fault_addr); |
1118 | verbose_printk(KERN_NOTICE "ICPLB_FAULT_ADDR: %s\n", buf); | 1113 | verbose_printk(KERN_NOTICE "ICPLB_FAULT_ADDR: %s\n", buf); |
1119 | } | 1114 | } |
1120 | 1115 | ||
@@ -1153,20 +1148,21 @@ unlock: | |||
1153 | asmlinkage int sys_bfin_spinlock(int *spinlock)__attribute__((l1_text)); | 1148 | asmlinkage int sys_bfin_spinlock(int *spinlock)__attribute__((l1_text)); |
1154 | #endif | 1149 | #endif |
1155 | 1150 | ||
1156 | asmlinkage int sys_bfin_spinlock(int *spinlock) | 1151 | static DEFINE_SPINLOCK(bfin_spinlock_lock); |
1152 | |||
1153 | asmlinkage int sys_bfin_spinlock(int *p) | ||
1157 | { | 1154 | { |
1158 | int ret = 0; | 1155 | int ret, tmp = 0; |
1159 | int tmp = 0; | ||
1160 | 1156 | ||
1161 | local_irq_disable(); | 1157 | spin_lock(&bfin_spinlock_lock); /* This would also hold kernel preemption. */ |
1162 | ret = get_user(tmp, spinlock); | 1158 | ret = get_user(tmp, p); |
1163 | if (ret == 0) { | 1159 | if (likely(ret == 0)) { |
1164 | if (tmp) | 1160 | if (unlikely(tmp)) |
1165 | ret = 1; | 1161 | ret = 1; |
1166 | tmp = 1; | 1162 | else |
1167 | put_user(tmp, spinlock); | 1163 | put_user(1, p); |
1168 | } | 1164 | } |
1169 | local_irq_enable(); | 1165 | spin_unlock(&bfin_spinlock_lock); |
1170 | return ret; | 1166 | return ret; |
1171 | } | 1167 | } |
1172 | 1168 | ||