diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-01 10:43:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-01 10:43:05 -0400 |
commit | d70b1e06eb331afe1576ac23bb9523708026ba1f (patch) | |
tree | a6e430d45f8f7f37285369dcfd863a0358080c83 /arch/hexagon/kernel/traps.c | |
parent | b0b885657b6c8ef63a46bc9299b2a7715d19acde (diff) | |
parent | 426d29ccb2a8d44c18d3167327ee82b38287e7bf (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.c | 36 |
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 | ||
349 | void do_trap0(struct pt_regs *regs) | 359 | void 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 | |||
451 | void 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 | } | ||