aboutsummaryrefslogtreecommitdiffstats
path: root/arch/hexagon/kernel/traps.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-01 10:43:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-01 10:43:05 -0400
commitd70b1e06eb331afe1576ac23bb9523708026ba1f (patch)
treea6e430d45f8f7f37285369dcfd863a0358080c83 /arch/hexagon/kernel/traps.c
parentb0b885657b6c8ef63a46bc9299b2a7715d19acde (diff)
parent426d29ccb2a8d44c18d3167327ee82b38287e7bf (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rkuo/linux-hexagon-kernel
Pull Hexagon fixes from Richard Kuo: "Changes for the Hexagon architecture (and one touching OpenRISC). They include various fixes to make use of additional arch features and cleanups. The largest functional change is a cleanup of the signal and event return paths" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rkuo/linux-hexagon-kernel: (32 commits) Hexagon: add v4 CS regs to core copyout macro Hexagon: use correct translation for VMALLOC_START Hexagon: use correct translations for DMA mappings Hexagon: fix return value for notify_resume case in do_work_pending Hexagon: fix signal number for user mem faults Hexagon: remove two Kconfig entries arch: remove CONFIG_GENERIC_FIND_NEXT_BIT again Hexagon: update copyright dates Hexagon: add translation types for __vmnewmap Hexagon: fix signal.c compile error Hexagon: break up user fn/arg register setting Hexagon: use generic sys_fork, sys_vfork, and sys_clone Hexagon: fix psp/sp macro Hexagon: fix up int enable/disable at ret_from_fork Hexagon: add IOMEM and _relaxed IO macros Hexagon: switch to using the device type for IO mappings Hexagon: don't print info for offline CPU's Hexagon: add support for single-stepping (v4+) Hexagon: use correct work mask when checking for more work Hexagon: add support for additional exceptions ...
Diffstat (limited to 'arch/hexagon/kernel/traps.c')
-rw-r--r--arch/hexagon/kernel/traps.c36
1 files changed, 23 insertions, 13 deletions
diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c
index cc2171b2aa04..7858663352b9 100644
--- a/arch/hexagon/kernel/traps.c
+++ b/arch/hexagon/kernel/traps.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Kernel traps/events for Hexagon processor 2 * Kernel traps/events for Hexagon processor
3 * 3 *
4 * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 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 7 * it under the terms of the GNU General Public License version 2 and
@@ -65,6 +65,10 @@ static const char *ex_name(int ex)
65 return "Write protection fault"; 65 return "Write protection fault";
66 case HVM_GE_C_XMAL: 66 case HVM_GE_C_XMAL:
67 return "Misaligned instruction"; 67 return "Misaligned instruction";
68 case HVM_GE_C_WREG:
69 return "Multiple writes to same register in packet";
70 case HVM_GE_C_PCAL:
71 return "Program counter values that are not properly aligned";
68 case HVM_GE_C_RMAL: 72 case HVM_GE_C_RMAL:
69 return "Misaligned data load"; 73 return "Misaligned data load";
70 case HVM_GE_C_WMAL: 74 case HVM_GE_C_WMAL:
@@ -316,6 +320,12 @@ void do_genex(struct pt_regs *regs)
316 case HVM_GE_C_XMAL: 320 case HVM_GE_C_XMAL:
317 misaligned_instruction(regs); 321 misaligned_instruction(regs);
318 break; 322 break;
323 case HVM_GE_C_WREG:
324 illegal_instruction(regs);
325 break;
326 case HVM_GE_C_PCAL:
327 misaligned_instruction(regs);
328 break;
319 case HVM_GE_C_RMAL: 329 case HVM_GE_C_RMAL:
320 misaligned_data_load(regs); 330 misaligned_data_load(regs);
321 break; 331 break;
@@ -348,7 +358,6 @@ long sys_syscall(void)
348 358
349void do_trap0(struct pt_regs *regs) 359void do_trap0(struct pt_regs *regs)
350{ 360{
351 unsigned long syscallret = 0;
352 syscall_fn syscall; 361 syscall_fn syscall;
353 362
354 switch (pt_cause(regs)) { 363 switch (pt_cause(regs)) {
@@ -388,21 +397,11 @@ void do_trap0(struct pt_regs *regs)
388 } else { 397 } else {
389 syscall = (syscall_fn) 398 syscall = (syscall_fn)
390 (sys_call_table[regs->syscall_nr]); 399 (sys_call_table[regs->syscall_nr]);
391 syscallret = syscall(regs->r00, regs->r01, 400 regs->r00 = syscall(regs->r00, regs->r01,
392 regs->r02, regs->r03, 401 regs->r02, regs->r03,
393 regs->r04, regs->r05); 402 regs->r04, regs->r05);
394 } 403 }
395 404
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 */ 405 /* allow strace to get the syscall return state */
407 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE))) 406 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE)))
408 tracehook_report_syscall_exit(regs, 0); 407 tracehook_report_syscall_exit(regs, 0);
@@ -444,3 +443,14 @@ void do_machcheck(struct pt_regs *regs)
444 /* Halt and catch fire */ 443 /* Halt and catch fire */
445 __vmstop(); 444 __vmstop();
446} 445}
446
447/*
448 * Treat this like the old 0xdb trap.
449 */
450
451void do_debug_exception(struct pt_regs *regs)
452{
453 regs->hvmer.vmest &= ~HVM_VMEST_CAUSE_MSK;
454 regs->hvmer.vmest |= (TRAP_DEBUG << HVM_VMEST_CAUSE_SFT);
455 do_trap0(regs);
456}