diff options
Diffstat (limited to 'arch/mips/kernel/traps.c')
-rw-r--r-- | arch/mips/kernel/traps.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index e9b3af27d84..cbea618af0b 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/bug.h> | 14 | #include <linux/bug.h> |
15 | #include <linux/compiler.h> | 15 | #include <linux/compiler.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/kernel.h> | ||
17 | #include <linux/mm.h> | 18 | #include <linux/mm.h> |
18 | #include <linux/module.h> | 19 | #include <linux/module.h> |
19 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
@@ -364,21 +365,26 @@ static int regs_to_trapnr(struct pt_regs *regs) | |||
364 | return (regs->cp0_cause >> 2) & 0x1f; | 365 | return (regs->cp0_cause >> 2) & 0x1f; |
365 | } | 366 | } |
366 | 367 | ||
367 | static DEFINE_SPINLOCK(die_lock); | 368 | static DEFINE_RAW_SPINLOCK(die_lock); |
368 | 369 | ||
369 | void __noreturn die(const char *str, struct pt_regs *regs) | 370 | void __noreturn die(const char *str, struct pt_regs *regs) |
370 | { | 371 | { |
371 | static int die_counter; | 372 | static int die_counter; |
372 | int sig = SIGSEGV; | 373 | int sig = SIGSEGV; |
373 | #ifdef CONFIG_MIPS_MT_SMTC | 374 | #ifdef CONFIG_MIPS_MT_SMTC |
374 | unsigned long dvpret = dvpe(); | 375 | unsigned long dvpret; |
375 | #endif /* CONFIG_MIPS_MT_SMTC */ | 376 | #endif /* CONFIG_MIPS_MT_SMTC */ |
376 | 377 | ||
378 | oops_enter(); | ||
379 | |||
377 | if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV) == NOTIFY_STOP) | 380 | if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV) == NOTIFY_STOP) |
378 | sig = 0; | 381 | sig = 0; |
379 | 382 | ||
380 | console_verbose(); | 383 | console_verbose(); |
381 | spin_lock_irq(&die_lock); | 384 | raw_spin_lock_irq(&die_lock); |
385 | #ifdef CONFIG_MIPS_MT_SMTC | ||
386 | dvpret = dvpe(); | ||
387 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
382 | bust_spinlocks(1); | 388 | bust_spinlocks(1); |
383 | #ifdef CONFIG_MIPS_MT_SMTC | 389 | #ifdef CONFIG_MIPS_MT_SMTC |
384 | mips_mt_regdump(dvpret); | 390 | mips_mt_regdump(dvpret); |
@@ -387,7 +393,9 @@ void __noreturn die(const char *str, struct pt_regs *regs) | |||
387 | printk("%s[#%d]:\n", str, ++die_counter); | 393 | printk("%s[#%d]:\n", str, ++die_counter); |
388 | show_registers(regs); | 394 | show_registers(regs); |
389 | add_taint(TAINT_DIE); | 395 | add_taint(TAINT_DIE); |
390 | spin_unlock_irq(&die_lock); | 396 | raw_spin_unlock_irq(&die_lock); |
397 | |||
398 | oops_exit(); | ||
391 | 399 | ||
392 | if (in_interrupt()) | 400 | if (in_interrupt()) |
393 | panic("Fatal exception in interrupt"); | 401 | panic("Fatal exception in interrupt"); |
@@ -578,12 +586,12 @@ static int simulate_llsc(struct pt_regs *regs, unsigned int opcode) | |||
578 | { | 586 | { |
579 | if ((opcode & OPCODE) == LL) { | 587 | if ((opcode & OPCODE) == LL) { |
580 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, | 588 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, |
581 | 1, 0, regs, 0); | 589 | 1, regs, 0); |
582 | return simulate_ll(regs, opcode); | 590 | return simulate_ll(regs, opcode); |
583 | } | 591 | } |
584 | if ((opcode & OPCODE) == SC) { | 592 | if ((opcode & OPCODE) == SC) { |
585 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, | 593 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, |
586 | 1, 0, regs, 0); | 594 | 1, regs, 0); |
587 | return simulate_sc(regs, opcode); | 595 | return simulate_sc(regs, opcode); |
588 | } | 596 | } |
589 | 597 | ||
@@ -602,7 +610,7 @@ static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode) | |||
602 | int rd = (opcode & RD) >> 11; | 610 | int rd = (opcode & RD) >> 11; |
603 | int rt = (opcode & RT) >> 16; | 611 | int rt = (opcode & RT) >> 16; |
604 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, | 612 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, |
605 | 1, 0, regs, 0); | 613 | 1, regs, 0); |
606 | switch (rd) { | 614 | switch (rd) { |
607 | case 0: /* CPU number */ | 615 | case 0: /* CPU number */ |
608 | regs->regs[rt] = smp_processor_id(); | 616 | regs->regs[rt] = smp_processor_id(); |
@@ -640,7 +648,7 @@ static int simulate_sync(struct pt_regs *regs, unsigned int opcode) | |||
640 | { | 648 | { |
641 | if ((opcode & OPCODE) == SPEC0 && (opcode & FUNC) == SYNC) { | 649 | if ((opcode & OPCODE) == SPEC0 && (opcode & FUNC) == SYNC) { |
642 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, | 650 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, |
643 | 1, 0, regs, 0); | 651 | 1, regs, 0); |
644 | return 0; | 652 | return 0; |
645 | } | 653 | } |
646 | 654 | ||