| .. | .. |
|---|
| 121 | 121 | } |
|---|
| 122 | 122 | |
|---|
| 123 | 123 | static void |
|---|
| 124 | | -dik_show_trace(unsigned long *sp) |
|---|
| 124 | +dik_show_trace(unsigned long *sp, const char *loglvl) |
|---|
| 125 | 125 | { |
|---|
| 126 | 126 | long i = 0; |
|---|
| 127 | | - printk("Trace:\n"); |
|---|
| 127 | + printk("%sTrace:\n", loglvl); |
|---|
| 128 | 128 | while (0x1ff8 & (unsigned long) sp) { |
|---|
| 129 | 129 | extern char _stext[], _etext[]; |
|---|
| 130 | 130 | unsigned long tmp = *sp; |
|---|
| .. | .. |
|---|
| 133 | 133 | continue; |
|---|
| 134 | 134 | if (tmp >= (unsigned long) &_etext) |
|---|
| 135 | 135 | continue; |
|---|
| 136 | | - printk("[<%lx>] %pSR\n", tmp, (void *)tmp); |
|---|
| 136 | + printk("%s[<%lx>] %pSR\n", loglvl, tmp, (void *)tmp); |
|---|
| 137 | 137 | if (i > 40) { |
|---|
| 138 | | - printk(" ..."); |
|---|
| 138 | + printk("%s ...", loglvl); |
|---|
| 139 | 139 | break; |
|---|
| 140 | 140 | } |
|---|
| 141 | 141 | } |
|---|
| 142 | | - printk("\n"); |
|---|
| 142 | + printk("%s\n", loglvl); |
|---|
| 143 | 143 | } |
|---|
| 144 | 144 | |
|---|
| 145 | 145 | static int kstack_depth_to_print = 24; |
|---|
| 146 | 146 | |
|---|
| 147 | | -void show_stack(struct task_struct *task, unsigned long *sp) |
|---|
| 147 | +void show_stack(struct task_struct *task, unsigned long *sp, const char *loglvl) |
|---|
| 148 | 148 | { |
|---|
| 149 | 149 | unsigned long *stack; |
|---|
| 150 | 150 | int i; |
|---|
| 151 | 151 | |
|---|
| 152 | 152 | /* |
|---|
| 153 | | - * debugging aid: "show_stack(NULL);" prints the |
|---|
| 153 | + * debugging aid: "show_stack(NULL, NULL, KERN_EMERG);" prints the |
|---|
| 154 | 154 | * back trace for this cpu. |
|---|
| 155 | 155 | */ |
|---|
| 156 | 156 | if(sp==NULL) |
|---|
| .. | .. |
|---|
| 163 | 163 | if ((i % 4) == 0) { |
|---|
| 164 | 164 | if (i) |
|---|
| 165 | 165 | pr_cont("\n"); |
|---|
| 166 | | - printk(" "); |
|---|
| 166 | + printk("%s ", loglvl); |
|---|
| 167 | 167 | } else { |
|---|
| 168 | 168 | pr_cont(" "); |
|---|
| 169 | 169 | } |
|---|
| 170 | 170 | pr_cont("%016lx", *stack++); |
|---|
| 171 | 171 | } |
|---|
| 172 | 172 | pr_cont("\n"); |
|---|
| 173 | | - dik_show_trace(sp); |
|---|
| 173 | + dik_show_trace(sp, loglvl); |
|---|
| 174 | 174 | } |
|---|
| 175 | 175 | |
|---|
| 176 | 176 | void |
|---|
| .. | .. |
|---|
| 184 | 184 | printk("%s(%d): %s %ld\n", current->comm, task_pid_nr(current), str, err); |
|---|
| 185 | 185 | dik_show_regs(regs, r9_15); |
|---|
| 186 | 186 | add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); |
|---|
| 187 | | - dik_show_trace((unsigned long *)(regs+1)); |
|---|
| 187 | + dik_show_trace((unsigned long *)(regs+1), KERN_DEFAULT); |
|---|
| 188 | 188 | dik_show_code((unsigned int *)regs->pc); |
|---|
| 189 | 189 | |
|---|
| 190 | 190 | if (test_and_set_thread_flag (TIF_DIE_IF_KERNEL)) { |
|---|
| .. | .. |
|---|
| 192 | 192 | local_irq_enable(); |
|---|
| 193 | 193 | while (1); |
|---|
| 194 | 194 | } |
|---|
| 195 | | - do_exit(SIGSEGV); |
|---|
| 195 | + make_task_dead(SIGSEGV); |
|---|
| 196 | 196 | } |
|---|
| 197 | 197 | |
|---|
| 198 | 198 | #ifndef CONFIG_MATHEMU |
|---|
| .. | .. |
|---|
| 235 | 235 | { |
|---|
| 236 | 236 | int signo, code; |
|---|
| 237 | 237 | |
|---|
| 238 | | - if ((regs->ps & ~IPL_MAX) == 0) { |
|---|
| 238 | + if (type == 3) { /* FEN fault */ |
|---|
| 239 | + /* Irritating users can call PAL_clrfen to disable the |
|---|
| 240 | + FPU for the process. The kernel will then trap in |
|---|
| 241 | + do_switch_stack and undo_switch_stack when we try |
|---|
| 242 | + to save and restore the FP registers. |
|---|
| 243 | + |
|---|
| 244 | + Given that GCC by default generates code that uses the |
|---|
| 245 | + FP registers, PAL_clrfen is not useful except for DoS |
|---|
| 246 | + attacks. So turn the bleeding FPU back on and be done |
|---|
| 247 | + with it. */ |
|---|
| 248 | + current_thread_info()->pcb.flags |= 1; |
|---|
| 249 | + __reload_thread(¤t_thread_info()->pcb); |
|---|
| 250 | + return; |
|---|
| 251 | + } |
|---|
| 252 | + if (!user_mode(regs)) { |
|---|
| 239 | 253 | if (type == 1) { |
|---|
| 240 | 254 | const unsigned int *data |
|---|
| 241 | 255 | = (const unsigned int *) regs->pc; |
|---|
| .. | .. |
|---|
| 368 | 382 | } |
|---|
| 369 | 383 | break; |
|---|
| 370 | 384 | |
|---|
| 371 | | - case 3: /* FEN fault */ |
|---|
| 372 | | - /* Irritating users can call PAL_clrfen to disable the |
|---|
| 373 | | - FPU for the process. The kernel will then trap in |
|---|
| 374 | | - do_switch_stack and undo_switch_stack when we try |
|---|
| 375 | | - to save and restore the FP registers. |
|---|
| 376 | | - |
|---|
| 377 | | - Given that GCC by default generates code that uses the |
|---|
| 378 | | - FP registers, PAL_clrfen is not useful except for DoS |
|---|
| 379 | | - attacks. So turn the bleeding FPU back on and be done |
|---|
| 380 | | - with it. */ |
|---|
| 381 | | - current_thread_info()->pcb.flags |= 1; |
|---|
| 382 | | - __reload_thread(¤t_thread_info()->pcb); |
|---|
| 383 | | - return; |
|---|
| 384 | | - |
|---|
| 385 | 385 | case 5: /* illoc */ |
|---|
| 386 | 386 | default: /* unexpected instruction-fault type */ |
|---|
| 387 | 387 | ; |
|---|
| .. | .. |
|---|
| 402 | 402 | { |
|---|
| 403 | 403 | die_if_kernel("Instruction fault", regs, 0, NULL); |
|---|
| 404 | 404 | |
|---|
| 405 | | - force_sig_fault(SIGILL, ILL_ILLOPC, (void __user *)regs->pc, 0, current); |
|---|
| 405 | + force_sig_fault(SIGILL, ILL_ILLOPC, (void __user *)regs->pc, 0); |
|---|
| 406 | 406 | } |
|---|
| 407 | 407 | |
|---|
| 408 | 408 | |
|---|
| .. | .. |
|---|
| 577 | 577 | |
|---|
| 578 | 578 | printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n", |
|---|
| 579 | 579 | pc, va, opcode, reg); |
|---|
| 580 | | - do_exit(SIGSEGV); |
|---|
| 580 | + make_task_dead(SIGSEGV); |
|---|
| 581 | 581 | |
|---|
| 582 | 582 | got_exception: |
|---|
| 583 | 583 | /* Ok, we caught the exception, but we don't want it. Is there |
|---|
| .. | .. |
|---|
| 625 | 625 | printk("gp = %016lx sp = %p\n", regs->gp, regs+1); |
|---|
| 626 | 626 | |
|---|
| 627 | 627 | dik_show_code((unsigned int *)pc); |
|---|
| 628 | | - dik_show_trace((unsigned long *)(regs+1)); |
|---|
| 628 | + dik_show_trace((unsigned long *)(regs+1), KERN_DEFAULT); |
|---|
| 629 | 629 | |
|---|
| 630 | 630 | if (test_and_set_thread_flag (TIF_DIE_IF_KERNEL)) { |
|---|
| 631 | 631 | printk("die_if_kernel recursion detected.\n"); |
|---|
| 632 | 632 | local_irq_enable(); |
|---|
| 633 | 633 | while (1); |
|---|
| 634 | 634 | } |
|---|
| 635 | | - do_exit(SIGSEGV); |
|---|
| 635 | + make_task_dead(SIGSEGV); |
|---|
| 636 | 636 | } |
|---|
| 637 | 637 | |
|---|
| 638 | 638 | /* |
|---|
| .. | .. |
|---|
| 883 | 883 | |
|---|
| 884 | 884 | case 0x26: /* sts */ |
|---|
| 885 | 885 | fake_reg = s_reg_to_mem(alpha_read_fp_reg(reg)); |
|---|
| 886 | | - /* FALLTHRU */ |
|---|
| 886 | + fallthrough; |
|---|
| 887 | 887 | |
|---|
| 888 | 888 | case 0x2c: /* stl */ |
|---|
| 889 | 889 | __asm__ __volatile__( |
|---|
| .. | .. |
|---|
| 911 | 911 | |
|---|
| 912 | 912 | case 0x27: /* stt */ |
|---|
| 913 | 913 | fake_reg = alpha_read_fp_reg(reg); |
|---|
| 914 | | - /* FALLTHRU */ |
|---|
| 914 | + fallthrough; |
|---|
| 915 | 915 | |
|---|
| 916 | 916 | case 0x2d: /* stq */ |
|---|
| 917 | 917 | __asm__ __volatile__( |
|---|
| .. | .. |
|---|
| 957 | 957 | si_code = SEGV_ACCERR; |
|---|
| 958 | 958 | else { |
|---|
| 959 | 959 | struct mm_struct *mm = current->mm; |
|---|
| 960 | | - down_read(&mm->mmap_sem); |
|---|
| 960 | + mmap_read_lock(mm); |
|---|
| 961 | 961 | if (find_vma(mm, (unsigned long)va)) |
|---|
| 962 | 962 | si_code = SEGV_ACCERR; |
|---|
| 963 | 963 | else |
|---|
| 964 | 964 | si_code = SEGV_MAPERR; |
|---|
| 965 | | - up_read(&mm->mmap_sem); |
|---|
| 965 | + mmap_read_unlock(mm); |
|---|
| 966 | 966 | } |
|---|
| 967 | 967 | send_sig_fault(SIGSEGV, si_code, va, 0, current); |
|---|
| 968 | 968 | return; |
|---|