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