1 /* 2 * Kernel traps/events for Hexagon processor 3 * 4 * Copyright (c) 2010-2011, 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.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 int die(const char *str, struct pt_regs *regs, long err) 195 { 196 static struct { 197 spinlock_t lock; 198 int counter; 199 } die = { 200 .lock = __SPIN_LOCK_UNLOCKED(die.lock), 201 .counter = 0 202 }; 203 204 console_verbose(); 205 oops_enter(); 206 207 spin_lock_irq(&die.lock); 208 bust_spinlocks(1); 209 printk(KERN_EMERG "Oops: %s[#%d]:\n", str, ++die.counter); 210 211 if (notify_die(DIE_OOPS, str, regs, err, pt_cause(regs), SIGSEGV) == 212 NOTIFY_STOP) 213 return 1; 214 215 print_modules(); 216 show_regs(regs); 217 do_show_stack(current, ®s->r30, pt_elr(regs)); 218 219 bust_spinlocks(0); 220 add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); 221 222 spin_unlock_irq(&die.lock); 223 224 if (in_interrupt()) 225 panic("Fatal exception in interrupt"); 226 227 if (panic_on_oops) 228 panic("Fatal exception"); 229 230 oops_exit(); 231 do_exit(err); 232 return 0; 233 } 234 235 int die_if_kernel(char *str, struct pt_regs *regs, long err) 236 { 237 if (!user_mode(regs)) 238 return die(str, regs, err); 239 else 240 return 0; 241 } 242 243 /* 244 * It's not clear that misaligned fetches are ever recoverable. 245 */ 246 static void misaligned_instruction(struct pt_regs *regs) 247 { 248 die_if_kernel("Misaligned Instruction", regs, 0); 249 force_sig(SIGBUS, current); 250 } 251 252 /* 253 * Misaligned loads and stores, on the other hand, can be 254 * emulated, and probably should be, some day. But for now 255 * they will be considered fatal. 256 */ 257 static void misaligned_data_load(struct pt_regs *regs) 258 { 259 die_if_kernel("Misaligned Data Load", regs, 0); 260 force_sig(SIGBUS, current); 261 } 262 263 static void misaligned_data_store(struct pt_regs *regs) 264 { 265 die_if_kernel("Misaligned Data Store", regs, 0); 266 force_sig(SIGBUS, current); 267 } 268 269 static void illegal_instruction(struct pt_regs *regs) 270 { 271 die_if_kernel("Illegal Instruction", regs, 0); 272 force_sig(SIGILL, current); 273 } 274 275 /* 276 * Precise bus errors may be recoverable with a a retry, 277 * but for now, treat them as irrecoverable. 278 */ 279 static void precise_bus_error(struct pt_regs *regs) 280 { 281 die_if_kernel("Precise Bus Error", regs, 0); 282 force_sig(SIGBUS, current); 283 } 284 285 /* 286 * If anything is to be done here other than panic, 287 * it will probably be complex and migrate to another 288 * source module. For now, just die. 289 */ 290 static void cache_error(struct pt_regs *regs) 291 { 292 die("Cache Error", regs, 0); 293 } 294 295 /* 296 * General exception handler 297 */ 298 void do_genex(struct pt_regs *regs) 299 { 300 /* 301 * Decode Cause and Dispatch 302 */ 303 switch (pt_cause(regs)) { 304 case HVM_GE_C_XPROT: 305 case HVM_GE_C_XUSER: 306 execute_protection_fault(regs); 307 break; 308 case HVM_GE_C_RPROT: 309 case HVM_GE_C_RUSER: 310 read_protection_fault(regs); 311 break; 312 case HVM_GE_C_WPROT: 313 case HVM_GE_C_WUSER: 314 write_protection_fault(regs); 315 break; 316 case HVM_GE_C_XMAL: 317 misaligned_instruction(regs); 318 break; 319 case HVM_GE_C_RMAL: 320 misaligned_data_load(regs); 321 break; 322 case HVM_GE_C_WMAL: 323 misaligned_data_store(regs); 324 break; 325 case HVM_GE_C_INVI: 326 case HVM_GE_C_PRIVI: 327 illegal_instruction(regs); 328 break; 329 case HVM_GE_C_BUS: 330 precise_bus_error(regs); 331 break; 332 case HVM_GE_C_CACHE: 333 cache_error(regs); 334 break; 335 default: 336 /* Halt and catch fire */ 337 panic("Unrecognized exception 0x%lx\n", pt_cause(regs)); 338 break; 339 } 340 } 341 342 /* Indirect system call dispatch */ 343 long sys_syscall(void) 344 { 345 printk(KERN_ERR "sys_syscall invoked!\n"); 346 return -ENOSYS; 347 } 348 349 void do_trap0(struct pt_regs *regs) 350 { 351 unsigned long syscallret = 0; 352 syscall_fn syscall; 353 354 switch (pt_cause(regs)) { 355 case TRAP_SYSCALL: 356 /* System call is trap0 #1 */ 357 358 /* allow strace to catch syscall args */ 359 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE) && 360 tracehook_report_syscall_entry(regs))) 361 return; /* return -ENOSYS somewhere? */ 362 363 /* Interrupts should be re-enabled for syscall processing */ 364 __vmsetie(VM_INT_ENABLE); 365 366 /* 367 * System call number is in r6, arguments in r0..r5. 368 * Fortunately, no Linux syscall has more than 6 arguments, 369 * and Hexagon ABI passes first 6 arguments in registers. 370 * 64-bit arguments are passed in odd/even register pairs. 371 * Fortunately, we have no system calls that take more 372 * than three arguments with more than one 64-bit value. 373 * Should that change, we'd need to redesign to copy 374 * between user and kernel stacks. 375 */ 376 regs->syscall_nr = regs->r06; 377 378 /* 379 * GPR R0 carries the first parameter, and is also used 380 * to report the return value. We need a backup of 381 * the user's value in case we need to do a late restart 382 * of the system call. 383 */ 384 regs->restart_r0 = regs->r00; 385 386 if ((unsigned long) regs->syscall_nr >= __NR_syscalls) { 387 regs->r00 = -1; 388 } else { 389 syscall = (syscall_fn) 390 (sys_call_table[regs->syscall_nr]); 391 syscallret = syscall(regs->r00, regs->r01, 392 regs->r02, regs->r03, 393 regs->r04, regs->r05); 394 } 395 396 /* 397 * If it was a sigreturn system call, don't overwrite 398 * r0 value in stack frame with return value. 399 * 400 * __NR_sigreturn doesn't seem to exist in new unistd.h 401 */ 402 403 if (regs->syscall_nr != __NR_rt_sigreturn) 404 regs->r00 = syscallret; 405 406 /* allow strace to get the syscall return state */ 407 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE))) 408 tracehook_report_syscall_exit(regs, 0); 409 410 break; 411 case TRAP_DEBUG: 412 /* Trap0 0xdb is debug breakpoint */ 413 if (user_mode(regs)) { 414 struct siginfo info; 415 416 info.si_signo = SIGTRAP; 417 info.si_errno = 0; 418 /* 419 * Some architecures add some per-thread state 420 * to distinguish between breakpoint traps and 421 * trace traps. We may want to do that, and 422 * set the si_code value appropriately, or we 423 * may want to use a different trap0 flavor. 424 */ 425 info.si_code = TRAP_BRKPT; 426 info.si_addr = (void __user *) pt_elr(regs); 427 send_sig_info(SIGTRAP, &info, current); 428 } else { 429 #ifdef CONFIG_KGDB 430 kgdb_handle_exception(pt_cause(regs), SIGTRAP, 431 TRAP_BRKPT, regs); 432 #endif 433 } 434 break; 435 } 436 /* Ignore other trap0 codes for now, especially 0 (Angel calls) */ 437 } 438 439 /* 440 * Machine check exception handler 441 */ 442 void do_machcheck(struct pt_regs *regs) 443 { 444 /* Halt and catch fire */ 445 __vmstop(); 446 } 447