[PATCH v2 56/76] ARC: Unaligned access emulation

2013-01-18 Thread Vineet Gupta
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 

Signed-off-by: Vineet Gupta 
Cc: Tim Yao 
---
 arch/arc/Kconfig |   11 ++
 arch/arc/include/asm/Kbuild  |1 -
 arch/arc/include/asm/ptrace.h|3 +
 arch/arc/include/asm/unaligned.h |   29 +
 arch/arc/kernel/Makefile |1 +
 arch/arc/kernel/disasm.c |2 +-
 arch/arc/kernel/entry.S  |   13 ++
 arch/arc/kernel/traps.c  |   26 
 arch/arc/kernel/unaligned.c  |  245 ++
 9 files changed, 329 insertions(+), 2 deletions(-)
 create mode 100644 arch/arc/include/asm/unaligned.h
 create mode 100644 arch/arc/kernel/unaligned.c

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index c34f3c3..d735de8 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -341,6 +341,17 @@ config ARC_CURR_IN_REG
  This reserved Register R25 to point to Current Task in
  kernel mode. This saves memory access for each such access
 
+
+config ARC_MISALIGN_ACCESS
+   bool "Emulate unaligned memory access (userspace only)"
+   default N
+   select SYSCTL_ARCH_UNALIGN_NO_WARN
+   select SYSCTL_ARCH_UNALIGN_ALLOW
+   help
+ This enables misaligned 16 & 32 bit memory access from user space.
+ Use ONLY-IF-ABS-NECESSARY as it will be very slow and also can hide
+ potential bugs in code
+
 config ARC_STACK_NONEXEC
bool "Make stack non-executable"
default n
diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild
index 78e982d..b24089c 100644
--- a/arch/arc/include/asm/Kbuild
+++ b/arch/arc/include/asm/Kbuild
@@ -52,7 +52,6 @@ generic-y += topology.h
 generic-y += trace_clock.h
 generic-y += types.h
 generic-y += ucontext.h
-generic-y += unaligned.h
 generic-y += user.h
 generic-y += vga.h
 generic-y += xor.h
diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h
index e4e1ac6..fd68c4b 100644
--- a/arch/arc/include/asm/ptrace.h
+++ b/arch/arc/include/asm/ptrace.h
@@ -127,6 +127,9 @@ struct user_regs_struct {
sp; \
 })
 
+/* return 1 if PC in delay slot */
+#define delay_mode(regs) ((regs->status32 & STATUS_DE_MASK) == STATUS_DE_MASK)
+
 #define in_syscall(regs) (regs->orig_r8 & orig_r8_IS_SCALL)
 #define in_brkpt_trap(regs) (regs->orig_r8 & orig_r8_IS_BRKPT)
 
diff --git a/arch/arc/include/asm/unaligned.h b/arch/arc/include/asm/unaligned.h
new file mode 100644
index 000..5dbe63f
--- /dev/null
+++ b/arch/arc/include/asm/unaligned.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _ASM_ARC_UNALIGNED_H
+#define _ASM_ARC_UNALIGNED_H
+
+/* ARC700 can't handle unaligned Data accesses. */
+
+#include 
+#include 
+
+#ifdef CONFIG_ARC_MISALIGN_ACCESS
+int misaligned_fixup(unsigned long address, struct pt_regs *regs,
+unsigned long cause, struct callee_regs *cregs);
+#else
+static inline int
+misaligned_fixup(unsigned long address, struct pt_regs *regs,
+unsigned long cause, struct callee_regs *cregs)
+{
+   return 0;
+}
+#endif
+
+#endif /* _ASM_ARC_UNALIGNED_H */
diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile
index f11318f..eda40d7 100644
--- a/arch/arc/kernel/Makefile
+++ b/arch/arc/kernel/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_MODULES) += arcksyms.o module.o
 obj-$(CONFIG_SMP)  += smp.o
 obj-$(CONFIG_ARC_DW2_UNWIND)   += unwind.o
 obj-$(CONFIG_KPROBES)  += kprobes.o
+obj-$(CONFIG_ARC_MISALIGN_ACCESS)  += unaligned.o
 
 obj-$(CONFIG_ARC_FPU_SAVE_RESTORE) += fpu.o
 CFLAGS_fpu.o   += -mdpfp
diff --git a/arch/arc/kernel/disasm.c b/arch/arc/kernel/disasm.c
index 51bad8f..2f39028 100644
--- a/arch/arc/kernel/disasm.c
+++ b/arch/arc/kernel/disasm.c
@@ -15,7 +15,7 @@
 #include 
 #include 
 
-#if defined(CONFIG_KGDB) || defined(CONFIG_MISALIGN_ACCESS) || \
+#if defined(CONFIG_KGDB) || defined(CONFIG_ARC_MISALIGN_ACCESS) || \
defined(CONFIG_KPROBES)
 
 /* disasm_instr: Analyses instruction at addr, stores
diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S
index 7e392d4..0ef234e 100644
--- a/arch/arc/kernel/entry.S
+++ b/arch/arc/kernel/entry.S
@@ -12,6 +12,9 @@
  *   needed before task_pt_regs was invented. This saves a branch per call
  *   and more importantly allows clean invocation of post-syscall ptrace hook
  *
+ * vineetg: May 

Re: [PATCH v2 56/76] ARC: Unaligned access emulation

2013-01-18 Thread Arnd Bergmann
On Friday 18 January 2013, Vineet Gupta wrote:
> 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 
> 
> Signed-off-by: Vineet Gupta 
> Cc: Tim Yao 

Acked-by: Arnd Bergmann 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/