diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2013-01-23 16:30:36 +0530 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2013-02-15 23:16:06 +0530 |
commit | 2e651ea1596b0ee25af4fcdc4cd13cbb33ffc254 (patch) | |
tree | 51210f1cd80327a00e2fd4b0d20849b6329925d6 /arch/arc/kernel/traps.c | |
parent | bf14e3b979a01cd7298d631736f965fe83c6e2bc (diff) | |
download | talos-obmc-linux-2e651ea1596b0ee25af4fcdc4cd13cbb33ffc254.tar.gz talos-obmc-linux-2e651ea1596b0ee25af4fcdc4cd13cbb33ffc254.zip |
ARC: Unaligned access emulation
ARC700 doesn't natively support unaligned access, but can be emulated
-Unaligned Access Exception
-Disassembly at the Fault address to find the exact insn (long/short)
Also per Arnd's comment, we runtime control it using 2 sysctl knobs:
* SYSCTL_ARCH_UNALIGN_ALLOW: Runtime enable/disble
* SYSCTL_ARCH_UNALIGN_NO_WARN: Warn on each emulation attempt
Originally contributed by Tim Yao <tim.yao@amlogic.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Cc: Tim Yao <tim.yao@amlogic.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arc/kernel/traps.c')
-rw-r--r-- | arch/arc/kernel/traps.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/arch/arc/kernel/traps.c b/arch/arc/kernel/traps.c index c6396b48fcd2..ec802c52a1ca 100644 --- a/arch/arc/kernel/traps.c +++ b/arch/arc/kernel/traps.c @@ -7,6 +7,9 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * + * vineetg: May 2011 + * -user-space unaligned access emulation + * * Rahul Trivedi: Codito Technologies 2004 */ @@ -16,6 +19,7 @@ #include <asm/ptrace.h> #include <asm/setup.h> #include <asm/kprobes.h> +#include <asm/unaligned.h> void __init trap_init(void) { @@ -79,7 +83,29 @@ DO_ERROR_INFO(SIGILL, "Illegal Insn (or Seq)", insterror_is_error, ILL_ILLOPC) DO_ERROR_INFO(SIGBUS, "Invalid Mem Access", do_memory_error, BUS_ADRERR) DO_ERROR_INFO(SIGTRAP, "Breakpoint Set", trap_is_brkpt, TRAP_BRKPT) +#ifdef CONFIG_ARC_MISALIGN_ACCESS +/* + * Entry Point for Misaligned Data access Exception, for emulating in software + */ +int do_misaligned_access(unsigned long cause, unsigned long address, + struct pt_regs *regs, struct callee_regs *cregs) +{ + if (misaligned_fixup(address, regs, cause, cregs) != 0) { + siginfo_t info; + + info.si_signo = SIGBUS; + info.si_errno = 0; + info.si_code = BUS_ADRALN; + info.si_addr = (void __user *)address; + return handle_exception(cause, "Misaligned Access", regs, + &info); + } + return 0; +} + +#else DO_ERROR_INFO(SIGSEGV, "Misaligned Access", do_misaligned_access, SEGV_ACCERR) +#endif /* * Entry point for miscll errors such as Nested Exceptions |