Re: [PATCH v7 08/37] nds32: Exception handling

2018-02-14 Thread Arnd Bergmann
On Tue, Feb 13, 2018 at 10:09 AM, Greentime Hu  wrote:
> This patch includes the exception/interrupt entries, pt_reg structure and
> related accessors.
>
> /* Unaligned accessing handling*/
> Andes processors cannot load/store information which is not naturally
> aligned on the bus, i.e., loading a 4 byte data whose start address must
> be divisible by 4. If unaligned data accessing is happened, data
> unaligned exception will be triggered and user will get SIGSEGV or
> kernel oops according to the unaligned address. In order to make user be
> able to load/store data from an unaligned address, software load/store
> emulation is implemented in arch/nds32/mm/alignment.c to address data
> unaligned exception.
>
> Unaligned accessing handling is disabled by default because it is not a
> normal case. User can enable this feature by following steps.
>
> A. Compile time:
> 1. Enable kernel config CONFIG_ALIGNMENT_TRAP
> B. Run time:
> 1. Enter /proc/sys/nds32/unaligned_acess folder
> 2. Write 1 to file enable_mode to enable unaligned accessing
>handling. User can disable it by writing 0 to this file.
> 3. Write 1 to file debug to show which unaligned address is under
>processing. User can disable it by writing 0 to this file.
>
> However, unaligned accessing handler cannot work if this unaligned
> address is not accessible such as protection violation. On this
> condition, the default behaviors for addressing data unaligned exception
> still happen
>
> Signed-off-by: Vincent Chen 
> Signed-off-by: Greentime Hu 

Acked-by: Arnd Bergmann 


[PATCH v7 08/37] nds32: Exception handling

2018-02-13 Thread Greentime Hu
This patch includes the exception/interrupt entries, pt_reg structure and
related accessors.

/* Unaligned accessing handling*/
Andes processors cannot load/store information which is not naturally
aligned on the bus, i.e., loading a 4 byte data whose start address must
be divisible by 4. If unaligned data accessing is happened, data
unaligned exception will be triggered and user will get SIGSEGV or
kernel oops according to the unaligned address. In order to make user be
able to load/store data from an unaligned address, software load/store
emulation is implemented in arch/nds32/mm/alignment.c to address data
unaligned exception.

Unaligned accessing handling is disabled by default because it is not a
normal case. User can enable this feature by following steps.

A. Compile time:
1. Enable kernel config CONFIG_ALIGNMENT_TRAP
B. Run time:
1. Enter /proc/sys/nds32/unaligned_acess folder
2. Write 1 to file enable_mode to enable unaligned accessing
   handling. User can disable it by writing 0 to this file.
3. Write 1 to file debug to show which unaligned address is under
   processing. User can disable it by writing 0 to this file.

However, unaligned accessing handler cannot work if this unaligned
address is not accessible such as protection violation. On this
condition, the default behaviors for addressing data unaligned exception
still happen

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/include/asm/ptrace.h |  77 ++
 arch/nds32/kernel/ex-entry.S| 157 +++
 arch/nds32/kernel/ex-exit.S | 184 +
 arch/nds32/kernel/stacktrace.c  |  47 
 arch/nds32/kernel/traps.c   | 442 ++
 arch/nds32/mm/alignment.c   | 576 
 6 files changed, 1483 insertions(+)
 create mode 100644 arch/nds32/include/asm/ptrace.h
 create mode 100644 arch/nds32/kernel/ex-entry.S
 create mode 100644 arch/nds32/kernel/ex-exit.S
 create mode 100644 arch/nds32/kernel/stacktrace.c
 create mode 100644 arch/nds32/kernel/traps.c
 create mode 100644 arch/nds32/mm/alignment.c

diff --git a/arch/nds32/include/asm/ptrace.h b/arch/nds32/include/asm/ptrace.h
new file mode 100644
index ..c4538839055c
--- /dev/null
+++ b/arch/nds32/include/asm/ptrace.h
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __ASM_NDS32_PTRACE_H
+#define __ASM_NDS32_PTRACE_H
+
+#include 
+
+/*
+ * If pt_regs.syscallno == NO_SYSCALL, then the thread is not executing
+ * a syscall -- i.e., its most recent entry into the kernel from
+ * userspace was not via syscall, or otherwise a tracer cancelled the
+ * syscall.
+ *
+ * This must have the value -1, for ABI compatibility with ptrace etc.
+ */
+#define NO_SYSCALL (-1)
+#ifndef __ASSEMBLY__
+#include 
+
+struct pt_regs {
+   union {
+   struct user_pt_regs user_regs;
+   struct {
+   long uregs[26];
+   long fp;
+   long gp;
+   long lp;
+   long sp;
+   long ipc;
+#if defined(CONFIG_HWZOL)
+   long lb;
+   long le;
+   long lc;
+#else
+   long dummy[3];
+#endif
+   long syscallno;
+   };
+   };
+   long orig_r0;
+   long ir0;
+   long ipsw;
+   long pipsw;
+   long pipc;
+   long pp0;
+   long pp1;
+   long fucop_ctl;
+   long osp;
+};
+
+static inline bool in_syscall(struct pt_regs const *regs)
+{
+   return regs->syscallno != NO_SYSCALL;
+}
+
+static inline void forget_syscall(struct pt_regs *regs)
+{
+   regs->syscallno = NO_SYSCALL;
+}
+static inline unsigned long regs_return_value(struct pt_regs *regs)
+{
+   return regs->uregs[0];
+}
+extern void show_regs(struct pt_regs *);
+/* Avoid circular header include via sched.h */
+struct task_struct;
+
+#define arch_has_single_step() (1)
+#define user_mode(regs)(((regs)->ipsw & PSW_mskPOM) == 
0)
+#define interrupts_enabled(regs)   (!!((regs)->ipsw & PSW_mskGIE))
+#define user_stack_pointer(regs)   ((regs)->sp)
+#define instruction_pointer(regs)  ((regs)->ipc)
+#define profile_pc(regs)   instruction_pointer(regs)
+
+#endif /* __ASSEMBLY__ */
+#endif
diff --git a/arch/nds32/kernel/ex-entry.S b/arch/nds32/kernel/ex-entry.S
new file mode 100644
index ..a72e83d804f5
--- /dev/null
+++ b/arch/nds32/kernel/ex-entry.S
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifdef CONFIG_HWZOL
+   .macro push_zol
+   mfusr   $r14, $LB
+   mfusr   $r15, $LE
+   mfusr   $r16, $LC
+   .endm