linux/arch/alpha/kernel/traps.c
<<
>>
Prefs
   1/*
   2 * arch/alpha/kernel/traps.c
   3 *
   4 * (C) Copyright 1994 Linus Torvalds
   5 */
   6
   7/*
   8 * This file initializes the trap entry points
   9 */
  10
  11#include <linux/config.h>
  12#include <linux/mm.h>
  13#include <linux/sched.h>
  14#include <linux/tty.h>
  15#include <linux/delay.h>
  16#include <linux/smp_lock.h>
  17#include <linux/module.h>
  18#include <linux/init.h>
  19#include <linux/kallsyms.h>
  20
  21#include <asm/gentrap.h>
  22#include <asm/uaccess.h>
  23#include <asm/unaligned.h>
  24#include <asm/sysinfo.h>
  25#include <asm/hwrpb.h>
  26#include <asm/mmu_context.h>
  27
  28#include "proto.h"
  29
  30/* Work-around for some SRMs which mishandle opDEC faults.  */
  31
  32static int opDEC_fix;
  33
  34static void __init
  35opDEC_check(void)
  36{
  37        __asm__ __volatile__ (
  38        /* Load the address of... */
  39        "       br      $16, 1f\n"
  40        /* A stub instruction fault handler.  Just add 4 to the
  41           pc and continue.  */
  42        "       ldq     $16, 8($sp)\n"
  43        "       addq    $16, 4, $16\n"
  44        "       stq     $16, 8($sp)\n"
  45        "       call_pal %[rti]\n"
  46        /* Install the instruction fault handler.  */
  47        "1:     lda     $17, 3\n"
  48        "       call_pal %[wrent]\n"
  49        /* With that in place, the fault from the round-to-minf fp
  50           insn will arrive either at the "lda 4" insn (bad) or one
  51           past that (good).  This places the correct fixup in %0.  */
  52        "       lda %[fix], 0\n"
  53        "       cvttq/svm $f31,$f31\n"
  54        "       lda %[fix], 4"
  55        : [fix] "=r" (opDEC_fix)
  56        : [rti] "n" (PAL_rti), [wrent] "n" (PAL_wrent)
  57        : "$0", "$1", "$16", "$17", "$22", "$23", "$24", "$25");
  58
  59        if (opDEC_fix)
  60                printk("opDEC fixup enabled.\n");
  61}
  62
  63void
  64dik_show_regs(struct pt_regs *regs, unsigned long *r9_15)
  65{
  66        printk("pc = [<%016lx>]  ra = [<%016lx>]  ps = %04lx    %s\n",
  67               regs->pc, regs->r26, regs->ps, print_tainted());
  68        print_symbol("pc is at %s\n", regs->pc);
  69        print_symbol("ra is at %s\n", regs->r26 );
  70        printk("v0 = %016lx  t0 = %016lx  t1 = %016lx\n",
  71               regs->r0, regs->r1, regs->r2);
  72        printk("t2 = %016lx  t3 = %016lx  t4 = %016lx\n",
  73               regs->r3, regs->r4, regs->r5);
  74        printk("t5 = %016lx  t6 = %016lx  t7 = %016lx\n",
  75               regs->r6, regs->r7, regs->r8);
  76
  77        if (r9_15) {
  78                printk("s0 = %016lx  s1 = %016lx  s2 = %016lx\n",
  79                       r9_15[9], r9_15[10], r9_15[11]);
  80                printk("s3 = %016lx  s4 = %016lx  s5 = %016lx\n",
  81                       r9_15[12], r9_15[13], r9_15[14]);
  82                printk("s6 = %016lx\n", r9_15[15]);
  83        }
  84
  85        printk("a0 = %016lx  a1 = %016lx  a2 = %016lx\n",
  86               regs->r16, regs->r17, regs->r18);
  87        printk("a3 = %016lx  a4 = %016lx  a5 = %016lx\n",
  88               regs->r19, regs->r20, regs->r21);
  89        printk("t8 = %016lx  t9 = %016lx  t10= %016lx\n",
  90               regs->r22, regs->r23, regs->r24);
  91        printk("t11= %016lx  pv = %016lx  at = %016lx\n",
  92               regs->r25, regs->r27, regs->r28);
  93        printk("gp = %016lx  sp = %p\n", regs->gp, regs+1);
  94#if 0
  95__halt();
  96#endif
  97}
  98
  99#if 0
 100static char * ireg_name[] = {"v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6",
 101                           "t7", "s0", "s1", "s2", "s3", "s4", "s5", "s6",
 102                           "a0", "a1", "a2", "a3", "a4", "a5", "t8", "t9",
 103                           "t10", "t11", "ra", "pv", "at", "gp", "sp", "zero"};
 104#endif
 105
 106static void
 107dik_show_code(unsigned int *pc)
 108{
 109        long i;
 110
 111        printk("Code:");
 112        for (i = -6; i < 2; i++) {
 113                unsigned int insn;
 114                if (__get_user(insn, (unsigned int __user *)pc + i))
 115                        break;
 116                printk("%c%08x%c", i ? ' ' : '<', insn, i ? ' ' : '>');
 117        }
 118        printk("\n");
 119}
 120
 121static void
 122dik_show_trace(unsigned long *sp)
 123{
 124        long i = 0;
 125        printk("Trace:\n");
 126        while (0x1ff8 & (unsigned long) sp) {
 127                extern char _stext[], _etext[];
 128                unsigned long tmp = *sp;
 129                sp++;
 130                if (tmp < (unsigned long) &_stext)
 131                        continue;
 132                if (tmp >= (unsigned long) &_etext)
 133                        continue;
 134                printk("[<%lx>]", tmp);
 135                print_symbol(" %s", tmp);
 136                printk("\n");
 137                if (i > 40) {
 138                        printk(" ...");
 139                        break;
 140                }
 141        }
 142        printk("\n");
 143}
 144
 145static int kstack_depth_to_print = 24;
 146
 147void show_stack(struct task_struct *task, unsigned long *sp)
 148{
 149        unsigned long *stack;
 150        int i;
 151
 152        /*
 153         * debugging aid: "show_stack(NULL);" prints the
 154         * back trace for this cpu.
 155         */
 156        if(sp==NULL)
 157                sp=(unsigned long*)&sp;
 158
 159        stack = sp;
 160        for(i=0; i < kstack_depth_to_print; i++) {
 161                if (((long) stack & (THREAD_SIZE-1)) == 0)
 162                        break;
 163                if (i && ((i % 4) == 0))
 164                        printk("\n       ");
 165                printk("%016lx ", *stack++);
 166        }
 167        printk("\n");
 168        dik_show_trace(sp);
 169}
 170
 171void dump_stack(void)
 172{
 173        show_stack(NULL, NULL);
 174}
 175
 176EXPORT_SYMBOL(dump_stack);
 177
 178void
 179die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)
 180{
 181        if (regs->ps & 8)
 182                return;
 183#ifdef CONFIG_SMP
 184        printk("CPU %d ", hard_smp_processor_id());
 185#endif
 186        printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err);
 187        dik_show_regs(regs, r9_15);
 188        dik_show_trace((unsigned long *)(regs+1));
 189        dik_show_code((unsigned int *)regs->pc);
 190
 191        if (test_and_set_thread_flag (TIF_DIE_IF_KERNEL)) {
 192                printk("die_if_kernel recursion detected.\n");
 193                local_irq_enable();
 194                while (1);
 195        }
 196        do_exit(SIGSEGV);
 197}
 198
 199#ifndef CONFIG_MATHEMU
 200static long dummy_emul(void) { return 0; }
 201long (*alpha_fp_emul_imprecise)(struct pt_regs *regs, unsigned long writemask)
 202  = (void *)dummy_emul;
 203long (*alpha_fp_emul) (unsigned long pc)
 204  = (void *)dummy_emul;
 205#else
 206long alpha_fp_emul_imprecise(struct pt_regs *regs, unsigned long writemask);
 207long alpha_fp_emul (unsigned long pc);
 208#endif
 209
 210asmlinkage void
 211do_entArith(unsigned long summary, unsigned long write_mask,
 212            struct pt_regs *regs)
 213{
 214        long si_code = FPE_FLTINV;
 215        siginfo_t info;
 216
 217        if (summary & 1) {
 218                /* Software-completion summary bit is set, so try to
 219                   emulate the instruction.  If the processor supports
 220                   precise exceptions, we don't have to search.  */
 221                if (!amask(AMASK_PRECISE_TRAP))
 222                        si_code = alpha_fp_emul(regs->pc - 4);
 223                else
 224                        si_code = alpha_fp_emul_imprecise(regs, write_mask);
 225                if (si_code == 0)
 226                        return;
 227        }
 228        die_if_kernel("Arithmetic fault", regs, 0, NULL);
 229
 230        info.si_signo = SIGFPE;
 231        info.si_errno = 0;
 232        info.si_code = si_code;
 233        info.si_addr = (void __user *) regs->pc;
 234        send_sig_info(SIGFPE, &info, current);
 235}
 236
 237asmlinkage void
 238do_entIF(unsigned long type, struct pt_regs *regs)
 239{
 240        siginfo_t info;
 241        int signo, code;
 242
 243        if (regs->ps == 0) {
 244                if (type == 1) {
 245                        const unsigned int *data
 246                          = (const unsigned int *) regs->pc;
 247                        printk("Kernel bug at %s:%d\n",
 248                               (const char *)(data[1] | (long)data[2] << 32), 
 249                               data[0]);
 250                }
 251                die_if_kernel((type == 1 ? "Kernel Bug" : "Instruction fault"),
 252                              regs, type, NULL);
 253        }
 254
 255        switch (type) {
 256              case 0: /* breakpoint */
 257                info.si_signo = SIGTRAP;
 258                info.si_errno = 0;
 259                info.si_code = TRAP_BRKPT;
 260                info.si_trapno = 0;
 261                info.si_addr = (void __user *) regs->pc;
 262
 263                if (ptrace_cancel_bpt(current)) {
 264                        regs->pc -= 4;  /* make pc point to former bpt */
 265                }
 266
 267                send_sig_info(SIGTRAP, &info, current);
 268                return;
 269
 270              case 1: /* bugcheck */
 271                info.si_signo = SIGTRAP;
 272                info.si_errno = 0;
 273                info.si_code = __SI_FAULT;
 274                info.si_addr = (void __user *) regs->pc;
 275                info.si_trapno = 0;
 276                send_sig_info(SIGTRAP, &info, current);
 277                return;
 278                
 279              case 2: /* gentrap */
 280                info.si_addr = (void __user *) regs->pc;
 281                info.si_trapno = regs->r16;
 282                switch ((long) regs->r16) {
 283                case GEN_INTOVF:
 284                        signo = SIGFPE;
 285                        code = FPE_INTOVF;
 286                        break;
 287                case GEN_INTDIV:
 288                        signo = SIGFPE;
 289                        code = FPE_INTDIV;
 290                        break;
 291                case GEN_FLTOVF:
 292                        signo = SIGFPE;
 293                        code = FPE_FLTOVF;
 294                        break;
 295                case GEN_FLTDIV:
 296                        signo = SIGFPE;
 297                        code = FPE_FLTDIV;
 298                        break;
 299                case GEN_FLTUND:
 300                        signo = SIGFPE;
 301                        code = FPE_FLTUND;
 302                        break;
 303                case GEN_FLTINV:
 304                        signo = SIGFPE;
 305                        code = FPE_FLTINV;
 306                        break;
 307                case GEN_FLTINE:
 308                        signo = SIGFPE;
 309                        code = FPE_FLTRES;
 310                        break;
 311                case GEN_ROPRAND:
 312                        signo = SIGFPE;
 313                        code = __SI_FAULT;
 314                        break;
 315
 316                case GEN_DECOVF:
 317                case GEN_DECDIV:
 318                case GEN_DECINV:
 319                case GEN_ASSERTERR:
 320                case GEN_NULPTRERR:
 321                case GEN_STKOVF:
 322                case GEN_STRLENERR:
 323                case GEN_SUBSTRERR:
 324                case GEN_RANGERR:
 325                case GEN_SUBRNG:
 326                case GEN_SUBRNG1:
 327                case GEN_SUBRNG2:
 328                case GEN_SUBRNG3:
 329                case GEN_SUBRNG4:
 330                case GEN_SUBRNG5:
 331                case GEN_SUBRNG6:
 332                case GEN_SUBRNG7:
 333                default:
 334                        signo = SIGTRAP;
 335                        code = __SI_FAULT;
 336                        break;
 337                }
 338
 339                info.si_signo = signo;
 340                info.si_errno = 0;
 341                info.si_code = code;
 342                info.si_addr = (void __user *) regs->pc;
 343                send_sig_info(signo, &info, current);
 344                return;
 345
 346              case 4: /* opDEC */
 347                if (implver() == IMPLVER_EV4) {
 348                        long si_code;
 349
 350                        /* The some versions of SRM do not handle
 351                           the opDEC properly - they return the PC of the
 352                           opDEC fault, not the instruction after as the
 353                           Alpha architecture requires.  Here we fix it up.
 354                           We do this by intentionally causing an opDEC
 355                           fault during the boot sequence and testing if
 356                           we get the correct PC.  If not, we set a flag
 357                           to correct it every time through.  */
 358                        regs->pc += opDEC_fix; 
 359                        
 360                        /* EV4 does not implement anything except normal
 361                           rounding.  Everything else will come here as
 362                           an illegal instruction.  Emulate them.  */
 363                        si_code = alpha_fp_emul(regs->pc - 4);
 364                        if (si_code == 0)
 365                                return;
 366                        if (si_code > 0) {
 367                                info.si_signo = SIGFPE;
 368                                info.si_errno = 0;
 369                                info.si_code = si_code;
 370                                info.si_addr = (void __user *) regs->pc;
 371                                send_sig_info(SIGFPE, &info, current);
 372                                return;
 373                        }
 374                }
 375                break;
 376
 377              case 3: /* FEN fault */
 378                /* Irritating users can call PAL_clrfen to disable the
 379                   FPU for the process.  The kernel will then trap in
 380                   do_switch_stack and undo_switch_stack when we try
 381                   to save and restore the FP registers.
 382
 383                   Given that GCC by default generates code that uses the
 384                   FP registers, PAL_clrfen is not useful except for DoS
 385                   attacks.  So turn the bleeding FPU back on and be done
 386                   with it.  */
 387                current_thread_info()->pcb.flags |= 1;
 388                __reload_thread(&current_thread_info()->pcb);
 389                return;
 390
 391              case 5: /* illoc */
 392              default: /* unexpected instruction-fault type */
 393                      ;
 394        }
 395
 396        info.si_signo = SIGILL;
 397        info.si_errno = 0;
 398        info.si_code = ILL_ILLOPC;
 399        info.si_addr = (void __user *) regs->pc;
 400        send_sig_info(SIGILL, &info, current);
 401}
 402
 403/* There is an ifdef in the PALcode in MILO that enables a 
 404   "kernel debugging entry point" as an unprivileged call_pal.
 405
 406   We don't want to have anything to do with it, but unfortunately
 407   several versions of MILO included in distributions have it enabled,
 408   and if we don't put something on the entry point we'll oops.  */
 409
 410asmlinkage void
 411do_entDbg(struct pt_regs *regs)
 412{
 413        siginfo_t info;
 414
 415        die_if_kernel("Instruction fault", regs, 0, NULL);
 416
 417        info.si_signo = SIGILL;
 418        info.si_errno = 0;
 419        info.si_code = ILL_ILLOPC;
 420        info.si_addr = (void __user *) regs->pc;
 421        force_sig_info(SIGILL, &info, current);
 422}
 423
 424
 425/*
 426 * entUna has a different register layout to be reasonably simple. It
 427 * needs access to all the integer registers (the kernel doesn't use
 428 * fp-regs), and it needs to have them in order for simpler access.
 429 *
 430 * Due to the non-standard register layout (and because we don't want
 431 * to handle floating-point regs), user-mode unaligned accesses are
 432 * handled separately by do_entUnaUser below.
 433 *
 434 * Oh, btw, we don't handle the "gp" register correctly, but if we fault
 435 * on a gp-register unaligned load/store, something is _very_ wrong
 436 * in the kernel anyway..
 437 */
 438struct allregs {
 439        unsigned long regs[32];
 440        unsigned long ps, pc, gp, a0, a1, a2;
 441};
 442
 443struct unaligned_stat {
 444        unsigned long count, va, pc;
 445} unaligned[2];
 446
 447
 448/* Macro for exception fixup code to access integer registers.  */
 449#define una_reg(r)  (regs.regs[(r) >= 16 && (r) <= 18 ? (r)+19 : (r)])
 450
 451
 452asmlinkage void
 453do_entUna(void * va, unsigned long opcode, unsigned long reg,
 454          unsigned long a3, unsigned long a4, unsigned long a5,
 455          struct allregs regs)
 456{
 457        long error, tmp1, tmp2, tmp3, tmp4;
 458        unsigned long pc = regs.pc - 4;
 459        const struct exception_table_entry *fixup;
 460
 461        unaligned[0].count++;
 462        unaligned[0].va = (unsigned long) va;
 463        unaligned[0].pc = pc;
 464
 465        /* We don't want to use the generic get/put unaligned macros as
 466           we want to trap exceptions.  Only if we actually get an
 467           exception will we decide whether we should have caught it.  */
 468
 469        switch (opcode) {
 470        case 0x0c: /* ldwu */
 471                __asm__ __volatile__(
 472                "1:     ldq_u %1,0(%3)\n"
 473                "2:     ldq_u %2,1(%3)\n"
 474                "       extwl %1,%3,%1\n"
 475                "       extwh %2,%3,%2\n"
 476                "3:\n"
 477                ".section __ex_table,\"a\"\n"
 478                "       .long 1b - .\n"
 479                "       lda %1,3b-1b(%0)\n"
 480                "       .long 2b - .\n"
 481                "       lda %2,3b-2b(%0)\n"
 482                ".previous"
 483                        : "=r"(error), "=&r"(tmp1), "=&r"(tmp2)
 484                        : "r"(va), "0"(0));
 485                if (error)
 486                        goto got_exception;
 487                una_reg(reg) = tmp1|tmp2;
 488                return;
 489
 490        case 0x28: /* ldl */
 491                __asm__ __volatile__(
 492                "1:     ldq_u %1,0(%3)\n"
 493                "2:     ldq_u %2,3(%3)\n"
 494                "       extll %1,%3,%1\n"
 495                "       extlh %2,%3,%2\n"
 496                "3:\n"
 497                ".section __ex_table,\"a\"\n"
 498                "       .long 1b - .\n"
 499                "       lda %1,3b-1b(%0)\n"
 500                "       .long 2b - .\n"
 501                "       lda %2,3b-2b(%0)\n"
 502                ".previous"
 503                        : "=r"(error), "=&r"(tmp1), "=&r"(tmp2)
 504                        : "r"(va), "0"(0));
 505                if (error)
 506                        goto got_exception;
 507                una_reg(reg) = (int)(tmp1|tmp2);
 508                return;
 509
 510        case 0x29: /* ldq */
 511                __asm__ __volatile__(
 512                "1:     ldq_u %1,0(%3)\n"
 513                "2:     ldq_u %2,7(%3)\n"
 514                "       extql %1,%3,%1\n"
 515                "       extqh %2,%3,%2\n"
 516                "3:\n"
 517                ".section __ex_table,\"a\"\n"
 518                "       .long 1b - .\n"
 519                "       lda %1,3b-1b(%0)\n"
 520                "       .long 2b - .\n"
 521                "       lda %2,3b-2b(%0)\n"
 522                ".previous"
 523                        : "=r"(error), "=&r"(tmp1), "=&r"(tmp2)
 524                        : "r"(va), "0"(0));
 525                if (error)
 526                        goto got_exception;
 527                una_reg(reg) = tmp1|tmp2;
 528                return;
 529
 530        /* Note that the store sequences do not indicate that they change
 531           memory because it _should_ be affecting nothing in this context.
 532           (Otherwise we have other, much larger, problems.)  */
 533        case 0x0d: /* stw */
 534                __asm__ __volatile__(
 535                "1:     ldq_u %2,1(%5)\n"
 536                "2:     ldq_u %1,0(%5)\n"
 537                "       inswh %6,%5,%4\n"
 538                "       inswl %6,%5,%3\n"
 539                "       mskwh %2,%5,%2\n"
 540                "       mskwl %1,%5,%1\n"
 541                "       or %2,%4,%2\n"
 542                "       or %1,%3,%1\n"
 543                "3:     stq_u %2,1(%5)\n"
 544                "4:     stq_u %1,0(%5)\n"
 545                "5:\n"
 546                ".section __ex_table,\"a\"\n"
 547                "       .long 1b - .\n"
 548                "       lda %2,5b-1b(%0)\n"
 549                "       .long 2b - .\n"
 550                "       lda %1,5b-2b(%0)\n"
 551                "       .long 3b - .\n"
 552                "       lda $31,5b-3b(%0)\n"
 553                "       .long 4b - .\n"
 554                "       lda $31,5b-4b(%0)\n"
 555                ".previous"
 556                        : "=r"(error), "=&r"(tmp1), "=&r"(tmp2),
 557                          "=&r"(tmp3), "=&r"(tmp4)
 558                        : "r"(va), "r"(una_reg(reg)), "0"(0));
 559                if (error)
 560                        goto got_exception;
 561                return;
 562
 563        case 0x2c: /* stl */
 564                __asm__ __volatile__(
 565                "1:     ldq_u %2,3(%5)\n"
 566                "2:     ldq_u %1,0(%5)\n"
 567                "       inslh %6,%5,%4\n"
 568                "       insll %6,%5,%3\n"
 569                "       msklh %2,%5,%2\n"
 570                "       mskll %1,%5,%1\n"
 571                "       or %2,%4,%2\n"
 572                "       or %1,%3,%1\n"
 573                "3:     stq_u %2,3(%5)\n"
 574                "4:     stq_u %1,0(%5)\n"
 575                "5:\n"
 576                ".section __ex_table,\"a\"\n"
 577                "       .long 1b - .\n"
 578                "       lda %2,5b-1b(%0)\n"
 579                "       .long 2b - .\n"
 580                "       lda %1,5b-2b(%0)\n"
 581                "       .long 3b - .\n"
 582                "       lda $31,5b-3b(%0)\n"
 583                "       .long 4b - .\n"
 584                "       lda $31,5b-4b(%0)\n"
 585                ".previous"
 586                        : "=r"(error), "=&r"(tmp1), "=&r"(tmp2),
 587                          "=&r"(tmp3), "=&r"(tmp4)
 588                        : "r"(va), "r"(una_reg(reg)), "0"(0));
 589                if (error)
 590                        goto got_exception;
 591                return;
 592
 593        case 0x2d: /* stq */
 594                __asm__ __volatile__(
 595                "1:     ldq_u %2,7(%5)\n"
 596                "2:     ldq_u %1,0(%5)\n"
 597                "       insqh %6,%5,%4\n"
 598                "       insql %6,%5,%3\n"
 599                "       mskqh %2,%5,%2\n"
 600                "       mskql %1,%5,%1\n"
 601                "       or %2,%4,%2\n"
 602                "       or %1,%3,%1\n"
 603                "3:     stq_u %2,7(%5)\n"
 604                "4:     stq_u %1,0(%5)\n"
 605                "5:\n"
 606                ".section __ex_table,\"a\"\n\t"
 607                "       .long 1b - .\n"
 608                "       lda %2,5b-1b(%0)\n"
 609                "       .long 2b - .\n"
 610                "       lda %1,5b-2b(%0)\n"
 611                "       .long 3b - .\n"
 612                "       lda $31,5b-3b(%0)\n"
 613                "       .long 4b - .\n"
 614                "       lda $31,5b-4b(%0)\n"
 615                ".previous"
 616                        : "=r"(error), "=&r"(tmp1), "=&r"(tmp2),
 617                          "=&r"(tmp3), "=&r"(tmp4)
 618                        : "r"(va), "r"(una_reg(reg)), "0"(0));
 619                if (error)
 620                        goto got_exception;
 621                return;
 622        }
 623
 624        lock_kernel();
 625        printk("Bad unaligned kernel access at %016lx: %p %lx %ld\n",
 626                pc, va, opcode, reg);
 627        do_exit(SIGSEGV);
 628
 629got_exception:
 630        /* Ok, we caught the exception, but we don't want it.  Is there
 631           someone to pass it along to?  */
 632        if ((fixup = search_exception_tables(pc)) != 0) {
 633                unsigned long newpc;
 634                newpc = fixup_exception(una_reg, fixup, pc);
 635
 636                printk("Forwarding unaligned exception at %lx (%lx)\n",
 637                       pc, newpc);
 638
 639                (&regs)->pc = newpc;
 640                return;
 641        }
 642
 643        /*
 644         * Yikes!  No one to forward the exception to.
 645         * Since the registers are in a weird format, dump them ourselves.
 646         */
 647        lock_kernel();
 648
 649        printk("%s(%d): unhandled unaligned exception\n",
 650               current->comm, current->pid);
 651
 652        printk("pc = [<%016lx>]  ra = [<%016lx>]  ps = %04lx\n",
 653               pc, una_reg(26), regs.ps);
 654        printk("r0 = %016lx  r1 = %016lx  r2 = %016lx\n",
 655               una_reg(0), una_reg(1), una_reg(2));
 656        printk("r3 = %016lx  r4 = %016lx  r5 = %016lx\n",
 657               una_reg(3), una_reg(4), una_reg(5));
 658        printk("r6 = %016lx  r7 = %016lx  r8 = %016lx\n",
 659               una_reg(6), una_reg(7), una_reg(8));
 660        printk("r9 = %016lx  r10= %016lx  r11= %016lx\n",
 661               una_reg(9), una_reg(10), una_reg(11));
 662        printk("r12= %016lx  r13= %016lx  r14= %016lx\n",
 663               una_reg(12), una_reg(13), una_reg(14));
 664        printk("r15= %016lx\n", una_reg(15));
 665        printk("r16= %016lx  r17= %016lx  r18= %016lx\n",
 666               una_reg(16), una_reg(17), una_reg(18));
 667        printk("r19= %016lx  r20= %016lx  r21= %016lx\n",
 668               una_reg(19), una_reg(20), una_reg(21));
 669        printk("r22= %016lx  r23= %016lx  r24= %016lx\n",
 670               una_reg(22), una_reg(23), una_reg(24));
 671        printk("r25= %016lx  r27= %016lx  r28= %016lx\n",
 672               una_reg(25), una_reg(27), una_reg(28));
 673        printk("gp = %016lx  sp = %p\n", regs.gp, &regs+1);
 674
 675        dik_show_code((unsigned int *)pc);
 676        dik_show_trace((unsigned long *)(&regs+1));
 677
 678        if (test_and_set_thread_flag (TIF_DIE_IF_KERNEL)) {
 679                printk("die_if_kernel recursion detected.\n");
 680                local_irq_enable();
 681                while (1);
 682        }
 683        do_exit(SIGSEGV);
 684}
 685
 686/*
 687 * Convert an s-floating point value in memory format to the
 688 * corresponding value in register format.  The exponent
 689 * needs to be remapped to preserve non-finite values
 690 * (infinities, not-a-numbers, denormals).
 691 */
 692static inline unsigned long
 693s_mem_to_reg (unsigned long s_mem)
 694{
 695        unsigned long frac    = (s_mem >>  0) & 0x7fffff;
 696        unsigned long sign    = (s_mem >> 31) & 0x1;
 697        unsigned long exp_msb = (s_mem >> 30) & 0x1;
 698        unsigned long exp_low = (s_mem >> 23) & 0x7f;
 699        unsigned long exp;
 700
 701        exp = (exp_msb << 10) | exp_low;        /* common case */
 702        if (exp_msb) {
 703                if (exp_low == 0x7f) {
 704                        exp = 0x7ff;
 705                }
 706        } else {
 707                if (exp_low == 0x00) {
 708                        exp = 0x000;
 709                } else {
 710                        exp |= (0x7 << 7);
 711                }
 712        }
 713        return (sign << 63) | (exp << 52) | (frac << 29);
 714}
 715
 716/*
 717 * Convert an s-floating point value in register format to the
 718 * corresponding value in memory format.
 719 */
 720static inline unsigned long
 721s_reg_to_mem (unsigned long s_reg)
 722{
 723        return ((s_reg >> 62) << 30) | ((s_reg << 5) >> 34);
 724}
 725
 726/*
 727 * Handle user-level unaligned fault.  Handling user-level unaligned
 728 * faults is *extremely* slow and produces nasty messages.  A user
 729 * program *should* fix unaligned faults ASAP.
 730 *
 731 * Notice that we have (almost) the regular kernel stack layout here,
 732 * so finding the appropriate registers is a little more difficult
 733 * than in the kernel case.
 734 *
 735 * Finally, we handle regular integer load/stores only.  In
 736 * particular, load-linked/store-conditionally and floating point
 737 * load/stores are not supported.  The former make no sense with
 738 * unaligned faults (they are guaranteed to fail) and I don't think
 739 * the latter will occur in any decent program.
 740 *
 741 * Sigh. We *do* have to handle some FP operations, because GCC will
 742 * uses them as temporary storage for integer memory to memory copies.
 743 * However, we need to deal with stt/ldt and sts/lds only.
 744 */
 745
 746#define OP_INT_MASK     ( 1L << 0x28 | 1L << 0x2c   /* ldl stl */       \
 747                        | 1L << 0x29 | 1L << 0x2d   /* ldq stq */       \
 748                        | 1L << 0x0c | 1L << 0x0d   /* ldwu stw */      \
 749                        | 1L << 0x0a | 1L << 0x0e ) /* ldbu stb */
 750
 751#define OP_WRITE_MASK   ( 1L << 0x26 | 1L << 0x27   /* sts stt */       \
 752                        | 1L << 0x2c | 1L << 0x2d   /* stl stq */       \
 753                        | 1L << 0x0d | 1L << 0x0e ) /* stw stb */
 754
 755#define R(x)    ((size_t) &((struct pt_regs *)0)->x)
 756
 757static int unauser_reg_offsets[32] = {
 758        R(r0), R(r1), R(r2), R(r3), R(r4), R(r5), R(r6), R(r7), R(r8),
 759        /* r9 ... r15 are stored in front of regs.  */
 760        -56, -48, -40, -32, -24, -16, -8,
 761        R(r16), R(r17), R(r18),
 762        R(r19), R(r20), R(r21), R(r22), R(r23), R(r24), R(r25), R(r26),
 763        R(r27), R(r28), R(gp),
 764        0, 0
 765};
 766
 767#undef R
 768
 769asmlinkage void
 770do_entUnaUser(void __user * va, unsigned long opcode,
 771              unsigned long reg, struct pt_regs *regs)
 772{
 773        static int cnt = 0;
 774        static long last_time = 0;
 775
 776        unsigned long tmp1, tmp2, tmp3, tmp4;
 777        unsigned long fake_reg, *reg_addr = &fake_reg;
 778        siginfo_t info;
 779        long error;
 780
 781        /* Check the UAC bits to decide what the user wants us to do
 782           with the unaliged access.  */
 783
 784        if (!test_thread_flag (TIF_UAC_NOPRINT)) {
 785                if (cnt >= 5 && jiffies - last_time > 5*HZ) {
 786                        cnt = 0;
 787                }
 788                if (++cnt < 5) {
 789                        printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n",
 790                               current->comm, current->pid,
 791                               regs->pc - 4, va, opcode, reg);
 792                }
 793                last_time = jiffies;
 794        }
 795        if (test_thread_flag (TIF_UAC_SIGBUS))
 796                goto give_sigbus;
 797        /* Not sure why you'd want to use this, but... */
 798        if (test_thread_flag (TIF_UAC_NOFIX))
 799                return;
 800
 801        /* Don't bother reading ds in the access check since we already
 802           know that this came from the user.  Also rely on the fact that
 803           the page at TASK_SIZE is unmapped and so can't be touched anyway. */
 804        if (!__access_ok((unsigned long)va, 0, USER_DS))
 805                goto give_sigsegv;
 806
 807        ++unaligned[1].count;
 808        unaligned[1].va = (unsigned long)va;
 809        unaligned[1].pc = regs->pc - 4;
 810
 811        if ((1L << opcode) & OP_INT_MASK) {
 812                /* it's an integer load/store */
 813                if (reg < 30) {
 814                        reg_addr = (unsigned long *)
 815                          ((char *)regs + unauser_reg_offsets[reg]);
 816                } else if (reg == 30) {
 817                        /* usp in PAL regs */
 818                        fake_reg = rdusp();
 819                } else {
 820                        /* zero "register" */
 821                        fake_reg = 0;
 822                }
 823        }
 824
 825        /* We don't want to use the generic get/put unaligned macros as
 826           we want to trap exceptions.  Only if we actually get an
 827           exception will we decide whether we should have caught it.  */
 828
 829        switch (opcode) {
 830        case 0x0c: /* ldwu */
 831                __asm__ __volatile__(
 832                "1:     ldq_u %1,0(%3)\n"
 833                "2:     ldq_u %2,1(%3)\n"
 834                "       extwl %1,%3,%1\n"
 835                "       extwh %2,%3,%2\n"
 836                "3:\n"
 837                ".section __ex_table,\"a\"\n"
 838                "       .long 1b - .\n"
 839                "       lda %1,3b-1b(%0)\n"
 840                "       .long 2b - .\n"
 841                "       lda %2,3b-2b(%0)\n"
 842                ".previous"
 843                        : "=r"(error), "=&r"(tmp1), "=&r"(tmp2)
 844                        : "r"(va), "0"(0));
 845                if (error)
 846                        goto give_sigsegv;
 847                *reg_addr = tmp1|tmp2;
 848                break;
 849
 850        case 0x22: /* lds */
 851                __asm__ __volatile__(
 852                "1:     ldq_u %1,0(%3)\n"
 853                "2:     ldq_u %2,3(%3)\n"
 854                "       extll %1,%3,%1\n"
 855                "       extlh %2,%3,%2\n"
 856                "3:\n"
 857                ".section __ex_table,\"a\"\n"
 858                "       .long 1b - .\n"
 859                "       lda %1,3b-1b(%0)\n"
 860                "       .long 2b - .\n"
 861                "       lda %2,3b-2b(%0)\n"
 862                ".previous"
 863                        : "=r"(error), "=&r"(tmp1), "=&r"(tmp2)
 864                        : "r"(va), "0"(0));
 865                if (error)
 866                        goto give_sigsegv;
 867                alpha_write_fp_reg(reg, s_mem_to_reg((int)(tmp1|tmp2)));
 868                return;
 869
 870        case 0x23: /* ldt */
 871                __asm__ __volatile__(
 872                "1:     ldq_u %1,0(%3)\n"
 873                "2:     ldq_u %2,7(%3)\n"
 874                "       extql %1,%3,%1\n"
 875                "       extqh %2,%3,%2\n"
 876                "3:\n"
 877                ".section __ex_table,\"a\"\n"
 878                "       .long 1b - .\n"
 879                "       lda %1,3b-1b(%0)\n"
 880                "       .long 2b - .\n"
 881                "       lda %2,3b-2b(%0)\n"
 882                ".previous"
 883                        : "=r"(error), "=&r"(tmp1), "=&r"(tmp2)
 884                        : "r"(va), "0"(0));
 885                if (error)
 886                        goto give_sigsegv;
 887                alpha_write_fp_reg(reg, tmp1|tmp2);
 888                return;
 889
 890        case 0x28: /* ldl */
 891                __asm__ __volatile__(
 892                "1:     ldq_u %1,0(%3)\n"
 893                "2:     ldq_u %2,3(%3)\n"
 894                "       extll %1,%3,%1\n"
 895                "       extlh %2,%3,%2\n"
 896                "3:\n"
 897                ".section __ex_table,\"a\"\n"
 898                "       .long 1b - .\n"
 899                "       lda %1,3b-1b(%0)\n"
 900                "       .long 2b - .\n"
 901                "       lda %2,3b-2b(%0)\n"
 902                ".previous"
 903                        : "=r"(error), "=&r"(tmp1), "=&r"(tmp2)
 904                        : "r"(va), "0"(0));
 905                if (error)
 906                        goto give_sigsegv;
 907                *reg_addr = (int)(tmp1|tmp2);
 908                break;
 909
 910        case 0x29: /* ldq */
 911                __asm__ __volatile__(
 912                "1:     ldq_u %1,0(%3)\n"
 913                "2:     ldq_u %2,7(%3)\n"
 914                "       extql %1,%3,%1\n"
 915                "       extqh %2,%3,%2\n"
 916                "3:\n"
 917                ".section __ex_table,\"a\"\n"
 918                "       .long 1b - .\n"
 919                "       lda %1,3b-1b(%0)\n"
 920                "       .long 2b - .\n"
 921                "       lda %2,3b-2b(%0)\n"
 922                ".previous"
 923                        : "=r"(error), "=&r"(tmp1), "=&r"(tmp2)
 924                        : "r"(va), "0"(0));
 925                if (error)
 926                        goto give_sigsegv;
 927                *reg_addr = tmp1|tmp2;
 928                break;
 929
 930        /* Note that the store sequences do not indicate that they change
 931           memory because it _should_ be affecting nothing in this context.
 932           (Otherwise we have other, much larger, problems.)  */
 933        case 0x0d: /* stw */
 934                __asm__ __volatile__(
 935                "1:     ldq_u %2,1(%5)\n"
 936                "2:     ldq_u %1,0(%5)\n"
 937                "       inswh %6,%5,%4\n"
 938                "       inswl %6,%5,%3\n"
 939                "       mskwh %2,%5,%2\n"
 940                "       mskwl %1,%5,%1\n"
 941                "       or %2,%4,%2\n"
 942                "       or %1,%3,%1\n"
 943                "3:     stq_u %2,1(%5)\n"
 944                "4:     stq_u %1,0(%5)\n"
 945                "5:\n"
 946                ".section __ex_table,\"a\"\n"
 947                "       .long 1b - .\n"
 948                "       lda %2,5b-1b(%0)\n"
 949                "       .long 2b - .\n"
 950                "       lda %1,5b-2b(%0)\n"
 951                "       .long 3b - .\n"
 952                "       lda $31,5b-3b(%0)\n"
 953                "       .long 4b - .\n"
 954                "       lda $31,5b-4b(%0)\n"
 955                ".previous"
 956                        : "=r"(error), "=&r"(tmp1), "=&r"(tmp2),
 957                          "=&r"(tmp3), "=&r"(tmp4)
 958                        : "r"(va), "r"(*reg_addr), "0"(0));
 959                if (error)
 960                        goto give_sigsegv;
 961                return;
 962
 963        case 0x26: /* sts */
 964                fake_reg = s_reg_to_mem(alpha_read_fp_reg(reg));
 965                /* FALLTHRU */
 966
 967        case 0x2c: /* stl */
 968                __asm__ __volatile__(
 969                "1:     ldq_u %2,3(%5)\n"
 970                "2:     ldq_u %1,0(%5)\n"
 971                "       inslh %6,%5,%4\n"
 972                "       insll %6,%5,%3\n"
 973                "       msklh %2,%5,%2\n"
 974                "       mskll %1,%5,%1\n"
 975                "       or %2,%4,%2\n"
 976                "       or %1,%3,%1\n"
 977                "3:     stq_u %2,3(%5)\n"
 978                "4:     stq_u %1,0(%5)\n"
 979                "5:\n"
 980                ".section __ex_table,\"a\"\n"
 981                "       .long 1b - .\n"
 982                "       lda %2,5b-1b(%0)\n"
 983                "       .long 2b - .\n"
 984                "       lda %1,5b-2b(%0)\n"
 985                "       .long 3b - .\n"
 986                "       lda $31,5b-3b(%0)\n"
 987                "       .long 4b - .\n"
 988                "       lda $31,5b-4b(%0)\n"
 989                ".previous"
 990                        : "=r"(error), "=&r"(tmp1), "=&r"(tmp2),
 991                          "=&r"(tmp3), "=&r"(tmp4)
 992                        : "r"(va), "r"(*reg_addr), "0"(0));
 993                if (error)
 994                        goto give_sigsegv;
 995                return;
 996
 997        case 0x27: /* stt */
 998                fake_reg = alpha_read_fp_reg(reg);
 999                /* FALLTHRU */
1000
1001        case 0x2d: /* stq */
1002                __asm__ __volatile__(
1003                "1:     ldq_u %2,7(%5)\n"
1004                "2:     ldq_u %1,0(%5)\n"
1005                "       insqh %6,%5,%4\n"
1006                "       insql %6,%5,%3\n"
1007                "       mskqh %2,%5,%2\n"
1008                "       mskql %1,%5,%1\n"
1009                "       or %2,%4,%2\n"
1010                "       or %1,%3,%1\n"
1011                "3:     stq_u %2,7(%5)\n"
1012                "4:     stq_u %1,0(%5)\n"
1013                "5:\n"
1014                ".section __ex_table,\"a\"\n\t"
1015                "       .long 1b - .\n"
1016                "       lda %2,5b-1b(%0)\n"
1017                "       .long 2b - .\n"
1018                "       lda %1,5b-2b(%0)\n"
1019                "       .long 3b - .\n"
1020                "       lda $31,5b-3b(%0)\n"
1021                "       .long 4b - .\n"
1022                "       lda $31,5b-4b(%0)\n"
1023                ".previous"
1024                        : "=r"(error), "=&r"(tmp1), "=&r"(tmp2),
1025                          "=&r"(tmp3), "=&r"(tmp4)
1026                        : "r"(va), "r"(*reg_addr), "0"(0));
1027                if (error)
1028                        goto give_sigsegv;
1029                return;
1030
1031        default:
1032                /* What instruction were you trying to use, exactly?  */
1033                goto give_sigbus;
1034        }
1035
1036        /* Only integer loads should get here; everyone else returns early. */
1037        if (reg == 30)
1038                wrusp(fake_reg);
1039        return;
1040
1041give_sigsegv:
1042        regs->pc -= 4;  /* make pc point to faulting insn */
1043        info.si_signo = SIGSEGV;
1044        info.si_errno = 0;
1045
1046        /* We need to replicate some of the logic in mm/fault.c,
1047           since we don't have access to the fault code in the
1048           exception handling return path.  */
1049        if (!__access_ok((unsigned long)va, 0, USER_DS))
1050                info.si_code = SEGV_ACCERR;
1051        else {
1052                struct mm_struct *mm = current->mm;
1053                down_read(&mm->mmap_sem);
1054                if (find_vma(mm, (unsigned long)va))
1055                        info.si_code = SEGV_ACCERR;
1056                else
1057                        info.si_code = SEGV_MAPERR;
1058                up_read(&mm->mmap_sem);
1059        }
1060        info.si_addr = va;
1061        send_sig_info(SIGSEGV, &info, current);
1062        return;
1063
1064give_sigbus:
1065        regs->pc -= 4;
1066        info.si_signo = SIGBUS;
1067        info.si_errno = 0;
1068        info.si_code = BUS_ADRALN;
1069        info.si_addr = va;
1070        send_sig_info(SIGBUS, &info, current);
1071        return;
1072}
1073
1074void __init
1075trap_init(void)
1076{
1077        /* Tell PAL-code what global pointer we want in the kernel.  */
1078        register unsigned long gptr __asm__("$29");
1079        wrkgp(gptr);
1080
1081        /* Hack for Multia (UDB) and JENSEN: some of their SRMs have
1082           a bug in the handling of the opDEC fault.  Fix it up if so.  */
1083        if (implver() == IMPLVER_EV4)
1084                opDEC_check();
1085
1086        wrent(entArith, 1);
1087        wrent(entMM, 2);
1088        wrent(entIF, 3);
1089        wrent(entUna, 4);
1090        wrent(entSys, 5);
1091        wrent(entDbg, 6);
1092}
1093
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.