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/kernel.h> 17#include <linux/kprobes.h> 18#include <linux/module.h> 19#include <linux/reboot.h> 20#include <linux/uaccess.h> 21#include <linux/ptrace.h> 22#include <asm/opcode-tile.h> 23#include <asm/opcode_constants.h> 24#include <asm/stack.h> 25#include <asm/traps.h> 26 27#include <arch/interrupts.h> 28#include <arch/spr_def.h> 29 30void __init trap_init(void) 31{ 32 /* Nothing needed here since we link code at .intrpt1 */ 33} 34 35int unaligned_fixup = 1; 36 37static int __init setup_unaligned_fixup(char *str) 38{ 39 /* 40 * Say "=-1" to completely disable it. If you just do "=0", we 41 * will still parse the instruction, then fire a SIGBUS with 42 * the correct address from inside the single_step code. 43 */ 44 long val; 45 if (strict_strtol(str, 0, &val) != 0) 46 return 0; 47 unaligned_fixup = val; 48 pr_info("Fixups for unaligned data accesses are %s\n", 49 unaligned_fixup >= 0 ? 50 (unaligned_fixup ? "enabled" : "disabled") : 51 "completely disabled"); 52 return 1; 53} 54__setup("unaligned_fixup=", setup_unaligned_fixup); 55 56#if CHIP_HAS_TILE_DMA() 57 58static int dma_disabled; 59 60static int __init nodma(char *str) 61{ 62 pr_info("User-space DMA is disabled\n"); 63 dma_disabled = 1; 64 return 1; 65} 66__setup("nodma", nodma); 67 68/* How to decode SPR_GPV_REASON */ 69#define IRET_ERROR (1U << 31) 70#define MT_ERROR (1U << 30) 71#define MF_ERROR (1U << 29) 72#define SPR_INDEX ((1U << 15) - 1) 73#define SPR_MPL_SHIFT 9 /* starting bit position for MPL encoded in SPR */ 74 75/* 76 * See if this GPV is just to notify the kernel of SPR use and we can 77 * retry the user instruction after adjusting some MPLs suitably. 78 */ 79static int retry_gpv(unsigned int gpv_reason) 80{ 81 int mpl; 82 83 if (gpv_reason & IRET_ERROR) 84 return 0; 85 86 BUG_ON((gpv_reason & (MT_ERROR|MF_ERROR)) == 0); 87 mpl = (gpv_reason & SPR_INDEX) >> SPR_MPL_SHIFT; 88 if (mpl == INT_DMA_NOTIFY && !dma_disabled) { 89 /* User is turning on DMA. Allow it and retry. */ 90 printk(KERN_DEBUG "Process %d/%s is now enabled for DMA\n", 91 current->pid, current->comm); 92 BUG_ON(current->thread.tile_dma_state.enabled); 93 current->thread.tile_dma_state.enabled = 1; 94 grant_dma_mpls(); 95 return 1; 96 } 97 98 return 0; 99} 100 101#endif /* CHIP_HAS_TILE_DMA() */ 102 103#ifdef __tilegx__ 104#define bundle_bits tilegx_bundle_bits 105#else 106#define bundle_bits tile_bundle_bits 107#endif 108 109extern bundle_bits bpt_code; 110 111asm(".pushsection .rodata.bpt_code,\"a\";" 112 ".align 8;" 113 "bpt_code: bpt;" 114 ".size bpt_code,.-bpt_code;" 115 ".popsection"); 116 117static int special_ill(bundle_bits bundle, int *sigp, int *codep) 118{ 119 int sig, code, maxcode; 120 121 if (bundle == bpt_code) { 122 *sigp = SIGTRAP; 123 *codep = TRAP_BRKPT; 124 return 1; 125 } 126 127 /* If it's a "raise" bundle, then "ill" must be in pipe X1. */ 128#ifdef __tilegx__ 129 if ((bundle & TILEGX_BUNDLE_MODE_MASK) != 0) 130 return 0; 131 if (get_Opcode_X1(bundle) != RRR_0_OPCODE_X1) 132 return 0; 133 if (get_RRROpcodeExtension_X1(bundle) != UNARY_RRR_0_OPCODE_X1) 134 return 0; 135 if (get_UnaryOpcodeExtension_X1(bundle) != ILL_UNARY_OPCODE_X1) 136 return 0; 137#else 138 if (bundle & TILE_BUNDLE_Y_ENCODING_MASK) 139 return 0; 140 if (get_Opcode_X1(bundle) != SHUN_0_OPCODE_X1) 141 return 0; 142 if (get_UnShOpcodeExtension_X1(bundle) != UN_0_SHUN_0_OPCODE_X1) 143 return 0; 144 if (get_UnOpcodeExtension_X1(bundle) != ILL_UN_0_SHUN_0_OPCODE_X1) 145 return 0; 146#endif 147 148 /* Check that the magic distinguishers are set to mean "raise". */ 149 if (get_Dest_X1(bundle) != 29 || get_SrcA_X1(bundle) != 37) 150 return 0; 151 152 /* There must be an "addli zero, zero, VAL" in X0. */ 153 if (get_Opcode_X0(bundle) != ADDLI_OPCODE_X0) 154 return 0; 155 if (get_Dest_X0(bundle) != TREG_ZERO) 156 return 0; 157 if (get_SrcA_X0(bundle) != TREG_ZERO) 158 return 0; 159 160 /* 161 * Validate the proposed signal number and si_code value. 162 * Note that we embed these in the static instruction itself 163 * so that we perturb the register state as little as possible 164 * at the time of the actual fault; it's unlikely you'd ever 165 * need to dynamically choose which kind of fault to raise 166 * from user space. 167 */ 168 sig = get_Imm16_X0(bundle) & 0x3f; 169 switch (sig) { 170 case SIGILL: 171 maxcode = NSIGILL; 172 break; 173 case SIGFPE: 174 maxcode = NSIGFPE; 175 break; 176 case SIGSEGV: 177 maxcode = NSIGSEGV; 178 break; 179 case SIGBUS: 180 maxcode = NSIGBUS; 181 break; 182 case SIGTRAP: 183 maxcode = NSIGTRAP; 184 break; 185 default: 186 return 0; 187 } 188 code = (get_Imm16_X0(bundle) >> 6) & 0xf; 189 if (code <= 0 || code > maxcode) 190 return 0; 191 192 /* Make it the requested signal. */ 193 *sigp = sig; 194 *codep = code | __SI_FAULT; 195 return 1; 196} 197 198void __kprobes do_trap(struct pt_regs *regs, int fault_num, 199 unsigned long reason) 200{ 201 siginfo_t info = { 0 }; 202 int signo, code; 203 unsigned long address; 204 bundle_bits instr; 205 206 /* Re-enable interrupts. */ 207 local_irq_enable(); 208 209 /* 210 * If it hits in kernel mode and we can't fix it up, just exit the 211 * current process and hope for the best. 212 */ 213 if (!user_mode(regs)) { 214 if (fixup_exception(regs)) /* only UNALIGN_DATA in practice */ 215 return; 216 pr_alert("Kernel took bad trap %d at PC %#lx\n", 217 fault_num, regs->pc); 218 if (fault_num == INT_GPV) 219 pr_alert("GPV_REASON is %#lx\n", reason); 220 show_regs(regs); 221 do_exit(SIGKILL); 222 return; 223 } 224 225 switch (fault_num) { 226 case INT_ILL: 227 if (copy_from_user(&instr, (void __user *)regs->pc, 228 sizeof(instr))) { 229 pr_err("Unreadable instruction for INT_ILL:" 230 " %#lx\n", regs->pc); 231 do_exit(SIGKILL); 232 return; 233 } 234 if (!special_ill(instr, &signo, &code)) { 235 signo = SIGILL; 236 code = ILL_ILLOPC; 237 } 238 address = regs->pc; 239 break; 240 case INT_GPV: 241#if CHIP_HAS_TILE_DMA() 242 if (retry_gpv(reason)) 243 return; 244#endif 245 /*FALLTHROUGH*/ 246 case INT_UDN_ACCESS: 247 case INT_IDN_ACCESS: 248#if CHIP_HAS_SN() 249 case INT_SN_ACCESS: 250#endif 251 signo = SIGILL; 252 code = ILL_PRVREG; 253 address = regs->pc; 254 break; 255 case INT_SWINT_3: 256 case INT_SWINT_2: 257 case INT_SWINT_0: 258 signo = SIGILL; 259 code = ILL_ILLTRP; 260 address = regs->pc; 261 break; 262 case INT_UNALIGN_DATA: 263#ifndef __tilegx__ 264 if (unaligned_fixup >= 0) { 265 struct single_step_state *state = 266 current_thread_info()->step_state; 267 if (!state || 268 (void __user *)(regs->pc) != state->buffer) { 269 single_step_once(regs); 270 return; 271 } 272 } 273#endif 274 signo = SIGBUS; 275 code = BUS_ADRALN; 276 address = 0; 277 break; 278 case INT_DOUBLE_FAULT: 279 /* 280 * For double fault, "reason" is actually passed as 281 * SYSTEM_SAVE_1_2, the hypervisor's double-fault info, so 282 * we can provide the original fault number rather than 283 * the uninteresting "INT_DOUBLE_FAULT" so the user can 284 * learn what actually struck while PL0 ICS was set. 285 */ 286 fault_num = reason; 287 signo = SIGILL; 288 code = ILL_DBLFLT; 289 address = regs->pc; 290 break; 291#ifdef __tilegx__ 292 case INT_ILL_TRANS: 293 signo = SIGSEGV; 294 code = SEGV_MAPERR; 295 if (reason & SPR_ILL_TRANS_REASON__I_STREAM_VA_RMASK) 296 address = regs->pc; 297 else 298 address = 0; 299 break; 300#endif 301 default: 302 panic("Unexpected do_trap interrupt number %d", fault_num); 303 return; 304 } 305 306 info.si_signo = signo; 307 info.si_code = code; 308 info.si_addr = (void __user *)address; 309 if (signo == SIGILL) 310 info.si_trapno = fault_num; 311 force_sig_info(signo, &info, current); 312} 313 314void kernel_double_fault(int dummy, ulong pc, ulong lr, ulong sp, ulong r52) 315{ 316 _dump_stack(dummy, pc, lr, sp, r52); 317 pr_emerg("Double fault: exiting\n"); 318 machine_halt(); 319} 320