| .. | .. |
|---|
| 29 | 29 | #include <linux/bug.h> |
|---|
| 30 | 30 | #include <linux/ratelimit.h> |
|---|
| 31 | 31 | #include <linux/uaccess.h> |
|---|
| 32 | +#include <linux/kdebug.h> |
|---|
| 32 | 33 | |
|---|
| 33 | 34 | #include <asm/assembly.h> |
|---|
| 34 | 35 | #include <asm/io.h> |
|---|
| .. | .. |
|---|
| 42 | 43 | #include <asm/unwind.h> |
|---|
| 43 | 44 | #include <asm/tlbflush.h> |
|---|
| 44 | 45 | #include <asm/cacheflush.h> |
|---|
| 46 | +#include <linux/kgdb.h> |
|---|
| 47 | +#include <linux/kprobes.h> |
|---|
| 45 | 48 | |
|---|
| 46 | 49 | #include "../math-emu/math-emu.h" /* for handle_fpe() */ |
|---|
| 47 | 50 | |
|---|
| 48 | 51 | static void parisc_show_stack(struct task_struct *task, |
|---|
| 49 | | - struct pt_regs *regs); |
|---|
| 52 | + struct pt_regs *regs, const char *loglvl); |
|---|
| 50 | 53 | |
|---|
| 51 | 54 | static int printbinary(char *buf, unsigned long x, int nbits) |
|---|
| 52 | 55 | { |
|---|
| .. | .. |
|---|
| 72 | 75 | lvl, f, (x), (x+3), (r)[(x)+0], (r)[(x)+1], \ |
|---|
| 73 | 76 | (r)[(x)+2], (r)[(x)+3]) |
|---|
| 74 | 77 | |
|---|
| 75 | | -static void print_gr(char *level, struct pt_regs *regs) |
|---|
| 78 | +static void print_gr(const char *level, struct pt_regs *regs) |
|---|
| 76 | 79 | { |
|---|
| 77 | 80 | int i; |
|---|
| 78 | 81 | char buf[64]; |
|---|
| .. | .. |
|---|
| 86 | 89 | PRINTREGS(level, regs->gr, "r", RFMT, i); |
|---|
| 87 | 90 | } |
|---|
| 88 | 91 | |
|---|
| 89 | | -static void print_fr(char *level, struct pt_regs *regs) |
|---|
| 92 | +static void print_fr(const char *level, struct pt_regs *regs) |
|---|
| 90 | 93 | { |
|---|
| 91 | 94 | int i; |
|---|
| 92 | 95 | char buf[64]; |
|---|
| .. | .. |
|---|
| 116 | 119 | void show_regs(struct pt_regs *regs) |
|---|
| 117 | 120 | { |
|---|
| 118 | 121 | int i, user; |
|---|
| 119 | | - char *level; |
|---|
| 122 | + const char *level; |
|---|
| 120 | 123 | unsigned long cr30, cr31; |
|---|
| 121 | 124 | |
|---|
| 122 | 125 | user = user_mode(regs); |
|---|
| .. | .. |
|---|
| 152 | 155 | printk("%s IAOQ[1]: %pS\n", level, (void *) regs->iaoq[1]); |
|---|
| 153 | 156 | printk("%s RP(r2): %pS\n", level, (void *) regs->gr[2]); |
|---|
| 154 | 157 | |
|---|
| 155 | | - parisc_show_stack(current, regs); |
|---|
| 158 | + parisc_show_stack(current, regs, KERN_DEFAULT); |
|---|
| 156 | 159 | } |
|---|
| 157 | 160 | } |
|---|
| 158 | 161 | |
|---|
| .. | .. |
|---|
| 167 | 170 | } |
|---|
| 168 | 171 | |
|---|
| 169 | 172 | |
|---|
| 170 | | -static void do_show_stack(struct unwind_frame_info *info) |
|---|
| 173 | +static void do_show_stack(struct unwind_frame_info *info, const char *loglvl) |
|---|
| 171 | 174 | { |
|---|
| 172 | 175 | int i = 1; |
|---|
| 173 | 176 | |
|---|
| 174 | | - printk(KERN_CRIT "Backtrace:\n"); |
|---|
| 177 | + printk("%sBacktrace:\n", loglvl); |
|---|
| 175 | 178 | while (i <= MAX_UNWIND_ENTRIES) { |
|---|
| 176 | 179 | if (unwind_once(info) < 0 || info->ip == 0) |
|---|
| 177 | 180 | break; |
|---|
| 178 | 181 | |
|---|
| 179 | 182 | if (__kernel_text_address(info->ip)) { |
|---|
| 180 | | - printk(KERN_CRIT " [<" RFMT ">] %pS\n", |
|---|
| 181 | | - info->ip, (void *) info->ip); |
|---|
| 183 | + printk("%s [<" RFMT ">] %pS\n", |
|---|
| 184 | + loglvl, info->ip, (void *) info->ip); |
|---|
| 182 | 185 | i++; |
|---|
| 183 | 186 | } |
|---|
| 184 | 187 | } |
|---|
| 185 | | - printk(KERN_CRIT "\n"); |
|---|
| 188 | + printk("%s\n", loglvl); |
|---|
| 186 | 189 | } |
|---|
| 187 | 190 | |
|---|
| 188 | 191 | static void parisc_show_stack(struct task_struct *task, |
|---|
| 189 | | - struct pt_regs *regs) |
|---|
| 192 | + struct pt_regs *regs, const char *loglvl) |
|---|
| 190 | 193 | { |
|---|
| 191 | 194 | struct unwind_frame_info info; |
|---|
| 192 | 195 | |
|---|
| 193 | 196 | unwind_frame_init_task(&info, task, regs); |
|---|
| 194 | 197 | |
|---|
| 195 | | - do_show_stack(&info); |
|---|
| 198 | + do_show_stack(&info, loglvl); |
|---|
| 196 | 199 | } |
|---|
| 197 | 200 | |
|---|
| 198 | | -void show_stack(struct task_struct *t, unsigned long *sp) |
|---|
| 201 | +void show_stack(struct task_struct *t, unsigned long *sp, const char *loglvl) |
|---|
| 199 | 202 | { |
|---|
| 200 | | - parisc_show_stack(t, NULL); |
|---|
| 203 | + parisc_show_stack(t, NULL, loglvl); |
|---|
| 201 | 204 | } |
|---|
| 202 | 205 | |
|---|
| 203 | 206 | int is_valid_bugaddr(unsigned long iaoq) |
|---|
| .. | .. |
|---|
| 218 | 221 | return; |
|---|
| 219 | 222 | } |
|---|
| 220 | 223 | |
|---|
| 221 | | - oops_in_progress = 1; |
|---|
| 224 | + bust_spinlocks(1); |
|---|
| 222 | 225 | |
|---|
| 223 | 226 | oops_enter(); |
|---|
| 224 | 227 | |
|---|
| .. | .. |
|---|
| 273 | 276 | static void handle_gdb_break(struct pt_regs *regs, int wot) |
|---|
| 274 | 277 | { |
|---|
| 275 | 278 | force_sig_fault(SIGTRAP, wot, |
|---|
| 276 | | - (void __user *) (regs->iaoq[0] & ~3), current); |
|---|
| 279 | + (void __user *) (regs->iaoq[0] & ~3)); |
|---|
| 277 | 280 | } |
|---|
| 278 | 281 | |
|---|
| 279 | 282 | static void handle_break(struct pt_regs *regs) |
|---|
| .. | .. |
|---|
| 292 | 295 | die_if_kernel("Unknown kernel breakpoint", regs, |
|---|
| 293 | 296 | (tt == BUG_TRAP_TYPE_NONE) ? 9 : 0); |
|---|
| 294 | 297 | } |
|---|
| 298 | + |
|---|
| 299 | +#ifdef CONFIG_KPROBES |
|---|
| 300 | + if (unlikely(iir == PARISC_KPROBES_BREAK_INSN)) { |
|---|
| 301 | + parisc_kprobe_break_handler(regs); |
|---|
| 302 | + return; |
|---|
| 303 | + } |
|---|
| 304 | + |
|---|
| 305 | +#endif |
|---|
| 306 | + |
|---|
| 307 | +#ifdef CONFIG_KGDB |
|---|
| 308 | + if (unlikely(iir == PARISC_KGDB_COMPILED_BREAK_INSN || |
|---|
| 309 | + iir == PARISC_KGDB_BREAK_INSN)) { |
|---|
| 310 | + kgdb_handle_exception(9, SIGTRAP, 0, regs); |
|---|
| 311 | + return; |
|---|
| 312 | + } |
|---|
| 313 | +#endif |
|---|
| 295 | 314 | |
|---|
| 296 | 315 | if (unlikely(iir != GDB_BREAK_INSN)) |
|---|
| 297 | 316 | parisc_printk_ratelimited(0, regs, |
|---|
| .. | .. |
|---|
| 396 | 415 | { |
|---|
| 397 | 416 | static DEFINE_SPINLOCK(terminate_lock); |
|---|
| 398 | 417 | |
|---|
| 399 | | - oops_in_progress = 1; |
|---|
| 418 | + (void)notify_die(DIE_OOPS, msg, regs, 0, code, SIGTRAP); |
|---|
| 419 | + bust_spinlocks(1); |
|---|
| 400 | 420 | |
|---|
| 401 | 421 | set_eiem(0); |
|---|
| 402 | 422 | local_irq_disable(); |
|---|
| .. | .. |
|---|
| 417 | 437 | break; |
|---|
| 418 | 438 | |
|---|
| 419 | 439 | default: |
|---|
| 420 | | - /* Fall through */ |
|---|
| 421 | 440 | break; |
|---|
| 422 | 441 | |
|---|
| 423 | 442 | } |
|---|
| .. | .. |
|---|
| 426 | 445 | /* show_stack(NULL, (unsigned long *)regs->gr[30]); */ |
|---|
| 427 | 446 | struct unwind_frame_info info; |
|---|
| 428 | 447 | unwind_frame_init(&info, current, regs); |
|---|
| 429 | | - do_show_stack(&info); |
|---|
| 448 | + do_show_stack(&info, KERN_CRIT); |
|---|
| 430 | 449 | } |
|---|
| 431 | 450 | |
|---|
| 432 | 451 | printk("\n"); |
|---|
| 433 | | - pr_crit("%s: Code=%d (%s) regs=%p (Addr=" RFMT ")\n", |
|---|
| 434 | | - msg, code, trap_name(code), regs, offset); |
|---|
| 452 | + pr_crit("%s: Code=%d (%s) at addr " RFMT "\n", |
|---|
| 453 | + msg, code, trap_name(code), offset); |
|---|
| 435 | 454 | show_regs(regs); |
|---|
| 436 | 455 | |
|---|
| 437 | 456 | spin_unlock(&terminate_lock); |
|---|
| .. | .. |
|---|
| 518 | 537 | case 3: |
|---|
| 519 | 538 | /* Recovery counter trap */ |
|---|
| 520 | 539 | regs->gr[0] &= ~PSW_R; |
|---|
| 540 | + |
|---|
| 541 | +#ifdef CONFIG_KPROBES |
|---|
| 542 | + if (parisc_kprobe_ss_handler(regs)) |
|---|
| 543 | + return; |
|---|
| 544 | +#endif |
|---|
| 545 | + |
|---|
| 546 | +#ifdef CONFIG_KGDB |
|---|
| 547 | + if (kgdb_single_step) { |
|---|
| 548 | + kgdb_handle_exception(0, SIGTRAP, 0, regs); |
|---|
| 549 | + return; |
|---|
| 550 | + } |
|---|
| 551 | +#endif |
|---|
| 552 | + |
|---|
| 521 | 553 | if (user_space(regs)) |
|---|
| 522 | 554 | handle_gdb_break(regs, TRAP_TRACE); |
|---|
| 523 | 555 | /* else this must be the start of a syscall - just let it run */ |
|---|
| .. | .. |
|---|
| 578 | 610 | si_code = ILL_PRVREG; |
|---|
| 579 | 611 | give_sigill: |
|---|
| 580 | 612 | force_sig_fault(SIGILL, si_code, |
|---|
| 581 | | - (void __user *) regs->iaoq[0], current); |
|---|
| 613 | + (void __user *) regs->iaoq[0]); |
|---|
| 582 | 614 | return; |
|---|
| 583 | 615 | |
|---|
| 584 | 616 | case 12: |
|---|
| 585 | 617 | /* Overflow Trap, let the userland signal handler do the cleanup */ |
|---|
| 586 | 618 | force_sig_fault(SIGFPE, FPE_INTOVF, |
|---|
| 587 | | - (void __user *) regs->iaoq[0], current); |
|---|
| 619 | + (void __user *) regs->iaoq[0]); |
|---|
| 588 | 620 | return; |
|---|
| 589 | 621 | |
|---|
| 590 | 622 | case 13: |
|---|
| .. | .. |
|---|
| 596 | 628 | * to by si_addr. |
|---|
| 597 | 629 | */ |
|---|
| 598 | 630 | force_sig_fault(SIGFPE, FPE_CONDTRAP, |
|---|
| 599 | | - (void __user *) regs->iaoq[0], current); |
|---|
| 631 | + (void __user *) regs->iaoq[0]); |
|---|
| 600 | 632 | return; |
|---|
| 601 | 633 | } |
|---|
| 602 | 634 | /* The kernel doesn't want to handle condition codes */ |
|---|
| .. | .. |
|---|
| 611 | 643 | |
|---|
| 612 | 644 | case 15: |
|---|
| 613 | 645 | /* Data TLB miss fault/Data page fault */ |
|---|
| 614 | | - /* Fall through */ |
|---|
| 646 | + fallthrough; |
|---|
| 615 | 647 | case 16: |
|---|
| 616 | 648 | /* Non-access instruction TLB miss fault */ |
|---|
| 617 | 649 | /* The instruction TLB entry needed for the target address of the FIC |
|---|
| 618 | 650 | is absent, and hardware can't find it, so we get to cleanup */ |
|---|
| 619 | | - /* Fall through */ |
|---|
| 651 | + fallthrough; |
|---|
| 620 | 652 | case 17: |
|---|
| 621 | 653 | /* Non-access data TLB miss fault/Non-access data page fault */ |
|---|
| 622 | 654 | /* FIXME: |
|---|
| .. | .. |
|---|
| 629 | 661 | by hand. Technically we need to emulate: |
|---|
| 630 | 662 | fdc,fdce,pdc,"fic,4f",prober,probeir,probew, probeiw |
|---|
| 631 | 663 | */ |
|---|
| 664 | + if (code == 17 && handle_nadtlb_fault(regs)) |
|---|
| 665 | + return; |
|---|
| 632 | 666 | fault_address = regs->ior; |
|---|
| 633 | 667 | fault_space = regs->isr; |
|---|
| 634 | 668 | break; |
|---|
| .. | .. |
|---|
| 640 | 674 | handle_unaligned(regs); |
|---|
| 641 | 675 | return; |
|---|
| 642 | 676 | } |
|---|
| 643 | | - /* Fall Through */ |
|---|
| 677 | + fallthrough; |
|---|
| 644 | 678 | case 26: |
|---|
| 645 | 679 | /* PCXL: Data memory access rights trap */ |
|---|
| 646 | 680 | fault_address = regs->ior; |
|---|
| .. | .. |
|---|
| 650 | 684 | case 19: |
|---|
| 651 | 685 | /* Data memory break trap */ |
|---|
| 652 | 686 | regs->gr[0] |= PSW_X; /* So we can single-step over the trap */ |
|---|
| 653 | | - /* fall thru */ |
|---|
| 687 | + fallthrough; |
|---|
| 654 | 688 | case 21: |
|---|
| 655 | 689 | /* Page reference trap */ |
|---|
| 656 | 690 | handle_gdb_break(regs, TRAP_HWBKPT); |
|---|
| .. | .. |
|---|
| 684 | 718 | if (user_mode(regs)) { |
|---|
| 685 | 719 | struct vm_area_struct *vma; |
|---|
| 686 | 720 | |
|---|
| 687 | | - down_read(¤t->mm->mmap_sem); |
|---|
| 721 | + mmap_read_lock(current->mm); |
|---|
| 688 | 722 | vma = find_vma(current->mm,regs->iaoq[0]); |
|---|
| 689 | 723 | if (vma && (regs->iaoq[0] >= vma->vm_start) |
|---|
| 690 | 724 | && (vma->vm_flags & VM_EXEC)) { |
|---|
| .. | .. |
|---|
| 692 | 726 | fault_address = regs->iaoq[0]; |
|---|
| 693 | 727 | fault_space = regs->iasq[0]; |
|---|
| 694 | 728 | |
|---|
| 695 | | - up_read(¤t->mm->mmap_sem); |
|---|
| 729 | + mmap_read_unlock(current->mm); |
|---|
| 696 | 730 | break; /* call do_page_fault() */ |
|---|
| 697 | 731 | } |
|---|
| 698 | | - up_read(¤t->mm->mmap_sem); |
|---|
| 732 | + mmap_read_unlock(current->mm); |
|---|
| 699 | 733 | } |
|---|
| 700 | | - /* Fall Through */ |
|---|
| 734 | + /* CPU could not fetch instruction, so clear stale IIR value. */ |
|---|
| 735 | + regs->iir = 0xbaadf00d; |
|---|
| 736 | + fallthrough; |
|---|
| 701 | 737 | case 27: |
|---|
| 702 | 738 | /* Data memory protection ID trap */ |
|---|
| 703 | 739 | if (code == 27 && !user_mode(regs) && |
|---|
| .. | .. |
|---|
| 708 | 744 | force_sig_fault(SIGSEGV, SEGV_MAPERR, |
|---|
| 709 | 745 | (code == 7)? |
|---|
| 710 | 746 | ((void __user *) regs->iaoq[0]) : |
|---|
| 711 | | - ((void __user *) regs->ior), current); |
|---|
| 747 | + ((void __user *) regs->ior)); |
|---|
| 712 | 748 | return; |
|---|
| 713 | 749 | |
|---|
| 714 | 750 | case 28: |
|---|
| .. | .. |
|---|
| 723 | 759 | task_pid_nr(current), current->comm); |
|---|
| 724 | 760 | /* SIGBUS, for lack of a better one. */ |
|---|
| 725 | 761 | force_sig_fault(SIGBUS, BUS_OBJERR, |
|---|
| 726 | | - (void __user *)regs->ior, current); |
|---|
| 762 | + (void __user *)regs->ior); |
|---|
| 727 | 763 | return; |
|---|
| 728 | 764 | } |
|---|
| 729 | 765 | pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC); |
|---|
| .. | .. |
|---|
| 739 | 775 | code, fault_space, |
|---|
| 740 | 776 | task_pid_nr(current), current->comm); |
|---|
| 741 | 777 | force_sig_fault(SIGSEGV, SEGV_MAPERR, |
|---|
| 742 | | - (void __user *)regs->ior, current); |
|---|
| 778 | + (void __user *)regs->ior); |
|---|
| 743 | 779 | return; |
|---|
| 744 | 780 | } |
|---|
| 745 | 781 | } |
|---|