1 /* 2 * Kernel traps/events for Hexagon processor 3 * 4 * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 and 8 * only version 2 as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 * 02110-1301, USA. 19 */ 20 21 #include <linux/init.h> 22 #include <linux/sched/signal.h> 23 #include <linux/sched/debug.h> 24 #include <linux/sched/task_stack.h> 25 #include <linux/module.h> 26 #include <linux/kallsyms.h> 27 #include <linux/kdebug.h> 28 #include <linux/syscalls.h> 29 #include <linux/signal.h> 30 #include <linux/tracehook.h> 31 #include <asm/traps.h> 32 #include <asm/vm_fault.h> 33 #include <asm/syscall.h> 34 #include <asm/registers.h> 35 #include <asm/unistd.h> 36 #include <asm/sections.h> 37 #ifdef CONFIG_KGDB 38 # include <linux/kgdb.h> 39 #endif 40 41 #define TRAP_SYSCALL 1 42 #define TRAP_DEBUG 0xdb 43 44 void __init trap_init(void) 45 { 46 } 47 48 #ifdef CONFIG_GENERIC_BUG 49 /* Maybe should resemble arch/sh/kernel/traps.c ?? */ 50 int is_valid_bugaddr(unsigned long addr) 51 { 52 return 1; 53 } 54 #endif /* CONFIG_GENERIC_BUG */ 55 56 static const char *ex_name(int ex) 57 { 58 switch (ex) { 59 case HVM_GE_C_XPROT: 60 case HVM_GE_C_XUSER: 61 return "Execute protection fault"; 62 case HVM_GE_C_RPROT: 63 case HVM_GE_C_RUSER: 64 return "Read protection fault"; 65 case HVM_GE_C_WPROT: 66 case HVM_GE_C_WUSER: 67 return "Write protection fault"; 68 case HVM_GE_C_XMAL: 69 return "Misaligned instruction"; 70 case HVM_GE_C_WREG: 71 return "Multiple writes to same register in packet"; 72 case HVM_GE_C_PCAL: 73 return "Program counter values that are not properly aligned"; 74 case HVM_GE_C_RMAL: 75 return "Misaligned data load"; 76 case HVM_GE_C_WMAL: 77 return "Misaligned data store"; 78 case HVM_GE_C_INVI: 79 case HVM_GE_C_PRIVI: 80 return "Illegal instruction"; 81 case HVM_GE_C_BUS: 82 return "Precise bus error"; 83 case HVM_GE_C_CACHE: 84 return "Cache error"; 85 86 case 0xdb: 87 return "Debugger trap"; 88 89 default: 90 return "Unrecognized exception"; 91 } 92 } 93 94 static void do_show_stack(struct task_struct *task, unsigned long *fp, 95 unsigned long ip) 96 { 97 int kstack_depth_to_print = 24; 98 unsigned long offset, size; 99 const char *name = NULL; 100 unsigned long *newfp; 101 unsigned long low, high; 102 char tmpstr[128]; 103 char *modname; 104 int i; 105 106 if (task == NULL) 107 task = current; 108 109 printk(KERN_INFO "CPU#%d, %s/%d, Call Trace:\n", 110 raw_smp_processor_id(), task->comm, 111 task_pid_nr(task)); 112 113 if (fp == NULL) { 114 if (task == current) { 115 asm("%0 = r30" : "=r" (fp)); 116 } else { 117 fp = (unsigned long *) 118 ((struct hexagon_switch_stack *) 119 task->thread.switch_sp)->fp; 120 } 121 } 122 123 if ((((unsigned long) fp) & 0x3) || ((unsigned long) fp < 0x1000)) { 124 printk(KERN_INFO "-- Corrupt frame pointer %p\n", fp); 125 return; 126 } 127 128 /* Saved link reg is one word above FP */ 129 if (!ip) 130 ip = *(fp+1); 131 132 /* Expect kernel stack to be in-bounds */ 133 low = (unsigned long)task_stack_page(task); 134 high = low + THREAD_SIZE - 8; 135 low += sizeof(struct thread_info); 136 137 for (i = 0; i < kstack_depth_to_print; i++) { 138 139 name = kallsyms_lookup(ip, &size, &offset, &modname, tmpstr); 140 141 printk(KERN_INFO "[%p] 0x%lx: %s + 0x%lx", fp, ip, name, 142 offset); 143 if (((unsigned long) fp < low) || (high < (unsigned long) fp)) 144 printk(KERN_CONT " (FP out of bounds!)"); 145 if (modname) 146 printk(KERN_CONT " [%s] ", modname); 147 printk(KERN_CONT "\n"); 148 149 newfp = (unsigned long *) *fp; 150 151 if (((unsigned long) newfp) & 0x3) { 152 printk(KERN_INFO "-- Corrupt frame pointer %p\n", 153 newfp); 154 break; 155 } 156 157 /* Attempt to continue past exception. */ 158 if (0 == newfp) { 159 struct pt_regs *regs = (struct pt_regs *) (((void *)fp) 160 + 8); 161 162 if (regs->syscall_nr != -1) { 163 printk(KERN_INFO "-- trap0 -- syscall_nr: %ld", 164 regs->syscall_nr); 165 printk(KERN_CONT " psp: %lx elr: %lx\n", 166 pt_psp(regs), pt_elr(regs)); 167 break; 168 } else { 169 /* really want to see more ... */ 170 kstack_depth_to_print += 6; 171 printk(KERN_INFO "-- %s (0x%lx) badva: %lx\n", 172 ex_name(pt_cause(regs)), pt_cause(regs), 173 pt_badva(regs)); 174 } 175 176 newfp = (unsigned long *) regs->r30; 177 ip = pt_elr(regs); 178 } else { 179 ip = *(newfp + 1); 180 } 181 182 /* If link reg is null, we are done. */ 183 if (ip == 0x0) 184 break; 185 186 /* If newfp isn't larger, we're tracing garbage. */ 187 if (newfp > fp) 188 fp = newfp; 189 else 190 break; 191 } 192 } 193 194 void show_stack(struct task_struct *task, unsigned long *fp) 195 { 196 /* Saved link reg is one word above FP */ 197 do_show_stack(task, fp, 0); 198 } 199 200 int die(const char *str, struct pt_regs *regs, long err) 201 { 202 static struct { 203 spinlock_t lock; 204 int counter; 205 } die = { 206 .lock = __SPIN_LOCK_UNLOCKED(die.lock), 207 .counter = 0 208 }; 209 210 console_verbose(); 211 oops_enter(); 212 213 spin_lock_irq(&die.lock); 214 bust_spinlocks(1); 215 printk(KERN_EMERG "Oops: %s[#%d]:\n", str, ++die.counter); 216 217 if (notify_die(DIE_OOPS, str, regs, err, pt_cause(regs), SIGSEGV) == 218 NOTIFY_STOP) 219 return 1; 220 221 print_modules(); 222 show_regs(regs); 223 do_show_stack(current, ®s->r30, pt_elr(regs)); 224 225 bust_spinlocks(0); 226 add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); 227 228 spin_unlock_irq(&die.lock); 229 230 if (in_interrupt()) 231 panic("Fatal exception in interrupt"); 232 233 if (panic_on_oops) 234 panic("Fatal exception"); 235 236 oops_exit(); 237 do_exit(err); 238 return 0; 239 } 240 241 int die_if_kernel(char *str, struct pt_regs *regs, long err) 242 { 243 if (!user_mode(regs)) 244 return die(str, regs, err); 245 else 246 return 0; 247 } 248 249 /* 250 * It's not clear that misaligned fetches are ever recoverable. 251 */ 252 static void misaligned_instruction(struct pt_regs *regs) 253 { 254 die_if_kernel("Misaligned Instruction", regs, 0); 255 force_sig(SIGBUS, current); 256 } 257 258 /* 259 * Misaligned loads and stores, on the other hand, can be 260 * emulated, and probably should be, some day. But for now 261 * they will be considered fatal. 262 */ 263 static void misaligned_data_load(struct pt_regs *regs) 264 { 265 die_if_kernel("Misaligned Data Load", regs, 0); 266 force_sig(SIGBUS, current); 267 } 268 269 static void misaligned_data_store(struct pt_regs *regs) 270 { 271 die_if_kernel("Misaligned Data Store", regs, 0); 272 force_sig(SIGBUS, current); 273 } 274 275 static void illegal_instruction(struct pt_regs *regs) 276 { 277 die_if_kernel("Illegal Instruction", regs, 0); 278 force_sig(SIGILL, current); 279 } 280 281 /* 282 * Precise bus errors may be recoverable with a a retry, 283 * but for now, treat them as irrecoverable. 284 */ 285 static void precise_bus_error(struct pt_regs *regs) 286 { 287 die_if_kernel("Precise Bus Error", regs, 0); 288 force_sig(SIGBUS, current); 289 } 290 291 /* 292 * If anything is to be done here other than panic, 293 * it will probably be complex and migrate to another 294 * source module. For now, just die. 295 */ 296 static void cache_error(struct pt_regs *regs) 297 { 298 die("Cache Error", regs, 0); 299 } 300 301 /* 302 * General exception handler 303 */ 304 void do_genex(struct pt_regs *regs) 305 { 306 /* 307 * Decode Cause and Dispatch 308 */ 309 switch (pt_cause(regs)) { 310 case HVM_GE_C_XPROT: 311 case HVM_GE_C_XUSER: 312 execute_protection_fault(regs); 313 break; 314 case HVM_GE_C_RPROT: 315 case HVM_GE_C_RUSER: 316 read_protection_fault(regs); 317 break; 318 case HVM_GE_C_WPROT: 319 case HVM_GE_C_WUSER: 320 write_protection_fault(regs); 321 break; 322 case HVM_GE_C_XMAL: 323 misaligned_instruction(regs); 324 break; 325 case HVM_GE_C_WREG: 326 illegal_instruction(regs); 327 break; 328 case HVM_GE_C_PCAL: 329 misaligned_instruction(regs); 330 break; 331 case HVM_GE_C_RMAL: 332 misaligned_data_load(regs); 333 break; 334 case HVM_GE_C_WMAL: 335 misaligned_data_store(regs); 336 break; 337 case HVM_GE_C_INVI: 338 case HVM_GE_C_PRIVI: 339 illegal_instruction(regs); 340 break; 341 case HVM_GE_C_BUS: 342 precise_bus_error(regs); 343 break; 344 case HVM_GE_C_CACHE: 345 cache_error(regs); 346 break; 347 default: 348 /* Halt and catch fire */ 349 panic("Unrecognized exception 0x%lx\n", pt_cause(regs)); 350 break; 351 } 352 } 353 354 /* Indirect system call dispatch */ 355 long sys_syscall(void) 356 { 357 printk(KERN_ERR "sys_syscall invoked!\n"); 358 return -ENOSYS; 359 } 360 361 void do_trap0(struct pt_regs *regs) 362 { 363 syscall_fn syscall; 364 365 switch (pt_cause(regs)) { 366 case TRAP_SYSCALL: 367 /* System call is trap0 #1 */ 368 369 /* allow strace to catch syscall args */ 370 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE) && 371 tracehook_report_syscall_entry(regs))) 372 return; /* return -ENOSYS somewhere? */ 373 374 /* Interrupts should be re-enabled for syscall processing */ 375 __vmsetie(VM_INT_ENABLE); 376 377 /* 378 * System call number is in r6, arguments in r0..r5. 379 * Fortunately, no Linux syscall has more than 6 arguments, 380 * and Hexagon ABI passes first 6 arguments in registers. 381 * 64-bit arguments are passed in odd/even register pairs. 382 * Fortunately, we have no system calls that take more 383 * than three arguments with more than one 64-bit value. 384 * Should that change, we'd need to redesign to copy 385 * between user and kernel stacks. 386 */ 387 regs->syscall_nr = regs->r06; 388 389 /* 390 * GPR R0 carries the first parameter, and is also used 391 * to report the return value. We need a backup of 392 * the user's value in case we need to do a late restart 393 * of the system call. 394 */ 395 regs->restart_r0 = regs->r00; 396 397 if ((unsigned long) regs->syscall_nr >= __NR_syscalls) { 398 regs->r00 = -1; 399 } else { 400 syscall = (syscall_fn) 401 (sys_call_table[regs->syscall_nr]); 402 regs->r00 = syscall(regs->r00, regs->r01, 403 regs->r02, regs->r03, 404 regs->r04, regs->r05); 405 } 406 407 /* allow strace to get the syscall return state */ 408 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE))) 409 tracehook_report_syscall_exit(regs, 0); 410 411 break; 412 case TRAP_DEBUG: 413 /* Trap0 0xdb is debug breakpoint */ 414 if (user_mode(regs)) { 415 /* 416 * Some architecures add some per-thread state 417 * to distinguish between breakpoint traps and 418 * trace traps. We may want to do that, and 419 * set the si_code value appropriately, or we 420 * may want to use a different trap0 flavor. 421 */ 422 force_sig_fault(SIGTRAP, TRAP_BRKPT, 423 (void __user *) pt_elr(regs), current); 424 } else { 425 #ifdef CONFIG_KGDB 426 kgdb_handle_exception(pt_cause(regs), SIGTRAP, 427 TRAP_BRKPT, regs); 428 #endif 429 } 430 break; 431 } 432 /* Ignore other trap0 codes for now, especially 0 (Angel calls) */ 433 } 434 435 /* 436 * Machine check exception handler 437 */ 438 void do_machcheck(struct pt_regs *regs) 439 { 440 /* Halt and catch fire */ 441 __vmstop(); 442 } 443 444 /* 445 * Treat this like the old 0xdb trap. 446 */ 447 448 void do_debug_exception(struct pt_regs *regs) 449 { 450 regs->hvmer.vmest &= ~HVM_VMEST_CAUSE_MSK; 451 regs->hvmer.vmest |= (TRAP_DEBUG << HVM_VMEST_CAUSE_SFT); 452 do_trap0(regs); 453 } 454