linux/arch/tile/kernel/traps.c
<<
>>
Prefs
   1/*
   2 * Copyright 2010 Tilera Corporation. All Rights Reserved.
   3 *
   4 *   This program is free software; you can redistribute it and/or
   5 *   modify it under the terms of the GNU General Public License
   6 *   as published by the Free Software Foundation, version 2.
   7 *
   8 *   This program is distributed in the hope that it will be useful, but
   9 *   WITHOUT ANY WARRANTY; without even the implied warranty of
  10 *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  11 *   NON INFRINGEMENT.  See the GNU General Public License for
  12 *   more details.
  13 */
  14
  15#include <linux/sched.h>
  16#include <linux/sched/debug.h>
  17#include <linux/kernel.h>
  18#include <linux/kprobes.h>
  19#include <linux/kdebug.h>
  20#include <linux/module.h>
  21#include <linux/reboot.h>
  22#include <linux/uaccess.h>
  23#include <linux/ptrace.h>
  24#include <linux/hardirq.h>
  25#include <linux/nmi.h>
  26#include <asm/stack.h>
  27#include <asm/traps.h>
  28#include <asm/setup.h>
  29
  30#include <arch/interrupts.h>
  31#include <arch/spr_def.h>
  32#include <arch/opcode.h>
  33
  34void __init trap_init(void)
  35{
  36        /* Nothing needed here since we link code at .intrpt */
  37}
  38
  39int unaligned_fixup = 1;
  40
  41static int __init setup_unaligned_fixup(char *str)
  42{
  43        /*
  44         * Say "=-1" to completely disable it.  If you just do "=0", we
  45         * will still parse the instruction, then fire a SIGBUS with
  46         * the correct address from inside the single_step code.
  47         */
  48        if (kstrtoint(str, 0, &unaligned_fixup) != 0)
  49                return 0;
  50
  51        pr_info("Fixups for unaligned data accesses are %s\n",
  52                unaligned_fixup >= 0 ?
  53                (unaligned_fixup ? "enabled" : "disabled") :
  54                "completely disabled");
  55        return 1;
  56}
  57__setup("unaligned_fixup=", setup_unaligned_fixup);
  58
  59#if CHIP_HAS_TILE_DMA()
  60
  61static int dma_disabled;
  62
  63static int __init nodma(char *str)
  64{
  65        pr_info("User-space DMA is disabled\n");
  66        dma_disabled = 1;
  67        return 1;
  68}
  69__setup("nodma", nodma);
  70
  71/* How to decode SPR_GPV_REASON */
  72#define IRET_ERROR (1U << 31)
  73#define MT_ERROR   (1U << 30)
  74#define MF_ERROR   (1U << 29)
  75#define SPR_INDEX  ((1U << 15) - 1)
  76#define SPR_MPL_SHIFT  9  /* starting bit position for MPL encoded in SPR */
  77
  78/*
  79 * See if this GPV is just to notify the kernel of SPR use and we can
  80 * retry the user instruction after adjusting some MPLs suitably.
  81 */
  82static int retry_gpv(unsigned int gpv_reason)
  83{
  84        int mpl;
  85
  86        if (gpv_reason & IRET_ERROR)
  87                return 0;
  88
  89        BUG_ON((gpv_reason & (MT_ERROR|MF_ERROR)) == 0);
  90        mpl = (gpv_reason & SPR_INDEX) >> SPR_MPL_SHIFT;
  91        if (mpl == INT_DMA_NOTIFY && !dma_disabled) {
  92                /* User is turning on DMA. Allow it and retry. */
  93                printk(KERN_DEBUG "Process %d/%s is now enabled for DMA\n",
  94                       current->pid, current->comm);
  95                BUG_ON(current->thread.tile_dma_state.enabled);
  96                current->thread.tile_dma_state.enabled = 1;
  97                grant_dma_mpls();
  98                return 1;
  99        }
 100
 101        return 0;
 102}
 103
 104#endif /* CHIP_HAS_TILE_DMA() */
 105
 106extern tile_bundle_bits bpt_code;
 107
 108asm(".pushsection .rodata.bpt_code,\"a\";"
 109    ".align 8;"
 110    "bpt_code: bpt;"
 111    ".size bpt_code,.-bpt_code;"
 112    ".popsection");
 113
 114static int special_ill(tile_bundle_bits bundle, int *sigp, int *codep)
 115{
 116        int sig, code, maxcode;
 117
 118        if (bundle == bpt_code) {
 119                *sigp = SIGTRAP;
 120                *codep = TRAP_BRKPT;
 121                return 1;
 122        }
 123
 124        /* If it's a "raise" bundle, then "ill" must be in pipe X1. */
 125#ifdef __tilegx__
 126        if ((bundle & TILEGX_BUNDLE_MODE_MASK) != 0)
 127                return 0;
 128        if (get_Opcode_X1(bundle) != RRR_0_OPCODE_X1)
 129                return 0;
 130        if (get_RRROpcodeExtension_X1(bundle) != UNARY_RRR_0_OPCODE_X1)
 131                return 0;
 132        if (get_UnaryOpcodeExtension_X1(bundle) != ILL_UNARY_OPCODE_X1)
 133                return 0;
 134#else
 135        if (bundle & TILEPRO_BUNDLE_Y_ENCODING_MASK)
 136                return 0;
 137        if (get_Opcode_X1(bundle) != SHUN_0_OPCODE_X1)
 138                return 0;
 139        if (get_UnShOpcodeExtension_X1(bundle) != UN_0_SHUN_0_OPCODE_X1)
 140                return 0;
 141        if (get_UnOpcodeExtension_X1(bundle) != ILL_UN_0_SHUN_0_OPCODE_X1)
 142                return 0;
 143#endif
 144
 145        /* Check that the magic distinguishers are set to mean "raise". */
 146        if (get_Dest_X1(bundle) != 29 || get_SrcA_X1(bundle) != 37)
 147                return 0;
 148
 149        /* There must be an "addli zero, zero, VAL" in X0. */
 150        if (get_Opcode_X0(bundle) != ADDLI_OPCODE_X0)
 151                return 0;
 152        if (get_Dest_X0(bundle) != TREG_ZERO)
 153                return 0;
 154        if (get_SrcA_X0(bundle) != TREG_ZERO)
 155                return 0;
 156
 157        /*
 158         * Validate the proposed signal number and si_code value.
 159         * Note that we embed these in the static instruction itself
 160         * so that we perturb the register state as little as possible
 161         * at the time of the actual fault; it's unlikely you'd ever
 162         * need to dynamically choose which kind of fault to raise
 163         * from user space.
 164         */
 165        sig = get_Imm16_X0(bundle) & 0x3f;
 166        switch (sig) {
 167        case SIGILL:
 168                maxcode = NSIGILL;
 169                break;
 170        case SIGFPE:
 171                maxcode = NSIGFPE;
 172                break;
 173        case SIGSEGV:
 174                maxcode = NSIGSEGV;
 175                break;
 176        case SIGBUS:
 177                maxcode = NSIGBUS;
 178                break;
 179        case SIGTRAP:
 180                maxcode = NSIGTRAP;
 181                break;
 182        default:
 183                return 0;
 184        }
 185        code = (get_Imm16_X0(bundle) >> 6) & 0xf;
 186        if (code <= 0 || code > maxcode)
 187                return 0;
 188
 189        /* Make it the requested signal. */
 190        *sigp = sig;
 191        *codep = code | __SI_FAULT;
 192        return 1;
 193}
 194
 195static const char *const int_name[] = {
 196        [INT_MEM_ERROR] = "Memory error",
 197        [INT_ILL] = "Illegal instruction",
 198        [INT_GPV] = "General protection violation",
 199        [INT_UDN_ACCESS] = "UDN access",
 200        [INT_IDN_ACCESS] = "IDN access",
 201#if CHIP_HAS_SN()
 202        [INT_SN_ACCESS] = "SN access",
 203#endif
 204        [INT_SWINT_3] = "Software interrupt 3",
 205        [INT_SWINT_2] = "Software interrupt 2",
 206        [INT_SWINT_0] = "Software interrupt 0",
 207        [INT_UNALIGN_DATA] = "Unaligned data",
 208        [INT_DOUBLE_FAULT] = "Double fault",
 209#ifdef __tilegx__
 210        [INT_ILL_TRANS] = "Illegal virtual address",
 211#endif
 212};
 213
 214static int do_bpt(struct pt_regs *regs)
 215{
 216        unsigned long bundle, bcode, bpt;
 217
 218        bundle = *(unsigned long *)instruction_pointer(regs);
 219
 220        /*
 221         * bpt shoule be { bpt; nop }, which is 0x286a44ae51485000ULL.
 222         * we encode the unused least significant bits for other purpose.
 223         */
 224        bpt = bundle & ~((1ULL << 12) - 1);
 225        if (bpt != TILE_BPT_BUNDLE)
 226                return 0;
 227
 228        bcode = bundle & ((1ULL << 12) - 1);
 229        /*
 230         * notify the kprobe handlers, if instruction is likely to
 231         * pertain to them.
 232         */
 233        switch (bcode) {
 234        /* breakpoint_insn */
 235        case 0:
 236                notify_die(DIE_BREAK, "debug", regs, bundle,
 237                        INT_ILL, SIGTRAP);
 238                break;
 239        /* compiled_bpt */
 240        case DIE_COMPILED_BPT:
 241                notify_die(DIE_COMPILED_BPT, "debug", regs, bundle,
 242                        INT_ILL, SIGTRAP);
 243                break;
 244        /* breakpoint2_insn */
 245        case DIE_SSTEPBP:
 246                notify_die(DIE_SSTEPBP, "single_step", regs, bundle,
 247                        INT_ILL, SIGTRAP);
 248                break;
 249        default:
 250                return 0;
 251        }
 252
 253        return 1;
 254}
 255
 256void __kprobes do_trap(struct pt_regs *regs, int fault_num,
 257                       unsigned long reason)
 258{
 259        siginfo_t info = { 0 };
 260        int signo, code;
 261        unsigned long address = 0;
 262        tile_bundle_bits instr;
 263        int is_kernel = !user_mode(regs);
 264
 265        /* Handle breakpoints, etc. */
 266        if (is_kernel && fault_num == INT_ILL && do_bpt(regs))
 267                return;
 268
 269        /* Re-enable interrupts, if they were previously enabled. */
 270        if (!(regs->flags & PT_FLAGS_DISABLE_IRQ))
 271                local_irq_enable();
 272
 273        /*
 274         * If it hits in kernel mode and we can't fix it up, just exit the
 275         * current process and hope for the best.
 276         */
 277        if (is_kernel) {
 278                const char *name;
 279                char buf[100];
 280                if (fixup_exception(regs))  /* ILL_TRANS or UNALIGN_DATA */
 281                        return;
 282                if (fault_num >= 0 &&
 283                    fault_num < ARRAY_SIZE(int_name) &&
 284                    int_name[fault_num] != NULL)
 285                        name = int_name[fault_num];
 286                else
 287                        name = "Unknown interrupt";
 288                if (fault_num == INT_GPV)
 289                        snprintf(buf, sizeof(buf), "; GPV_REASON %#lx", reason);
 290#ifdef __tilegx__
 291                else if (fault_num == INT_ILL_TRANS)
 292                        snprintf(buf, sizeof(buf), "; address %#lx", reason);
 293#endif
 294                else
 295                        buf[0] = '\0';
 296                pr_alert("Kernel took bad trap %d (%s) at PC %#lx%s\n",
 297                         fault_num, name, regs->pc, buf);
 298                show_regs(regs);
 299                do_exit(SIGKILL);  /* FIXME: implement i386 die() */
 300        }
 301
 302        switch (fault_num) {
 303        case INT_MEM_ERROR:
 304                signo = SIGBUS;
 305                code = BUS_OBJERR;
 306                break;
 307        case INT_ILL:
 308                if (copy_from_user(&instr, (void __user *)regs->pc,
 309                                   sizeof(instr))) {
 310                        pr_err("Unreadable instruction for INT_ILL: %#lx\n",
 311                               regs->pc);
 312                        do_exit(SIGKILL);
 313                }
 314                if (!special_ill(instr, &signo, &code)) {
 315                        signo = SIGILL;
 316                        code = ILL_ILLOPC;
 317                }
 318                address = regs->pc;
 319                break;
 320        case INT_GPV:
 321#if CHIP_HAS_TILE_DMA()
 322                if (retry_gpv(reason))
 323                        return;
 324#endif
 325                /*FALLTHROUGH*/
 326        case INT_UDN_ACCESS:
 327        case INT_IDN_ACCESS:
 328#if CHIP_HAS_SN()
 329        case INT_SN_ACCESS:
 330#endif
 331                signo = SIGILL;
 332                code = ILL_PRVREG;
 333                address = regs->pc;
 334                break;
 335        case INT_SWINT_3:
 336        case INT_SWINT_2:
 337        case INT_SWINT_0:
 338                signo = SIGILL;
 339                code = ILL_ILLTRP;
 340                address = regs->pc;
 341                break;
 342        case INT_UNALIGN_DATA:
 343#ifndef __tilegx__  /* Emulated support for single step debugging */
 344                if (unaligned_fixup >= 0) {
 345                        struct single_step_state *state =
 346                                current_thread_info()->step_state;
 347                        if (!state ||
 348                            (void __user *)(regs->pc) != state->buffer) {
 349                                single_step_once(regs);
 350                                return;
 351                        }
 352                }
 353#endif
 354                signo = SIGBUS;
 355                code = BUS_ADRALN;
 356                address = 0;
 357                break;
 358        case INT_DOUBLE_FAULT:
 359                /*
 360                 * For double fault, "reason" is actually passed as
 361                 * SYSTEM_SAVE_K_2, the hypervisor's double-fault info, so
 362                 * we can provide the original fault number rather than
 363                 * the uninteresting "INT_DOUBLE_FAULT" so the user can
 364                 * learn what actually struck while PL0 ICS was set.
 365                 */
 366                fault_num = reason;
 367                signo = SIGILL;
 368                code = ILL_DBLFLT;
 369                address = regs->pc;
 370                break;
 371#ifdef __tilegx__
 372        case INT_ILL_TRANS: {
 373                /* Avoid a hardware erratum with the return address stack. */
 374                fill_ra_stack();
 375
 376                signo = SIGSEGV;
 377                address = reason;
 378                code = SEGV_MAPERR;
 379                break;
 380        }
 381#endif
 382        default:
 383                panic("Unexpected do_trap interrupt number %d", fault_num);
 384        }
 385
 386        info.si_signo = signo;
 387        info.si_code = code;
 388        info.si_addr = (void __user *)address;
 389        if (signo == SIGILL)
 390                info.si_trapno = fault_num;
 391        if (signo != SIGTRAP)
 392                trace_unhandled_signal("trap", regs, address, signo);
 393        force_sig_info(signo, &info, current);
 394}
 395
 396void do_nmi(struct pt_regs *regs, int fault_num, unsigned long reason)
 397{
 398        nmi_enter();
 399        switch (reason) {
 400#ifdef arch_trigger_cpumask_backtrace
 401        case TILE_NMI_DUMP_STACK:
 402                nmi_cpu_backtrace(regs);
 403                break;
 404#endif
 405        default:
 406                panic("Unexpected do_nmi type %ld", reason);
 407        }
 408        nmi_exit();
 409}
 410
 411/* Deprecated function currently only used here. */
 412extern void _dump_stack(int dummy, ulong pc, ulong lr, ulong sp, ulong r52);
 413
 414void kernel_double_fault(int dummy, ulong pc, ulong lr, ulong sp, ulong r52)
 415{
 416        _dump_stack(dummy, pc, lr, sp, r52);
 417        pr_emerg("Double fault: exiting\n");
 418        machine_halt();
 419}
 420