[PATCH 3.10 79/97] xtensa: introduce spill_registers_kernel macro

2014-03-04 Thread Greg Kroah-Hartman
3.10-stable review patch.  If anyone has any objections, please let me know.

--

From: Max Filippov 

commit e2fd1374c705abe4661df3fb6fadb3879c7c1846 upstream.

Most in-kernel users want registers spilled on the kernel stack and
don't require PS.EXCM to be set. That means that they don't need fixup
routine and could reuse regular window overflow mechanism for that,
which makes spill routine very simple.

Suggested-by: Chris Zankel 
Signed-off-by: Max Filippov 
Signed-off-by: Greg Kroah-Hartman 

---
 arch/xtensa/include/asm/traps.h |   44 ++---
 arch/xtensa/kernel/entry.S  |   60 
 2 files changed, 76 insertions(+), 28 deletions(-)

--- a/arch/xtensa/include/asm/traps.h
+++ b/arch/xtensa/include/asm/traps.h
@@ -22,25 +22,37 @@ extern void do_unhandled(struct pt_regs
 
 static inline void spill_registers(void)
 {
-
+#if XCHAL_NUM_AREGS > 16
__asm__ __volatile__ (
-   "movi   a14, "__stringify((1 << PS_EXCM_BIT) | LOCKLEVEL)"\n\t"
-   "mova12, a0\n\t"
-   "rsra13, sar\n\t"
-   "xsra14, ps\n\t"
-   "movi   a0, _spill_registers\n\t"
-   "rsync\n\t"
-   "callx0 a0\n\t"
-   "mova0, a12\n\t"
-   "wsra13, sar\n\t"
-   "wsra14, ps\n\t"
-   : :
-#if defined(CONFIG_FRAME_POINTER)
-   : "a2", "a3", "a4",   "a11", "a12", "a13", "a14", "a15",
+   "   call12  1f\n"
+   "   _j  2f\n"
+   "   retw\n"
+   "   .align  4\n"
+   "1:\n"
+   "   _entry  a1, 48\n"
+   "   addia12, a0, 3\n"
+#if XCHAL_NUM_AREGS > 32
+   "   .rept   (" __stringify(XCHAL_NUM_AREGS) " - 32) / 12\n"
+   "   _entry  a1, 48\n"
+   "   mov a12, a0\n"
+   "   .endr\n"
+#endif
+   "   _entry  a1, 48\n"
+#if XCHAL_NUM_AREGS % 12 == 0
+   "   mov a8, a8\n"
+#elif XCHAL_NUM_AREGS % 12 == 4
+   "   mov a12, a12\n"
+#elif XCHAL_NUM_AREGS % 12 == 8
+   "   mov a4, a4\n"
+#endif
+   "   retw\n"
+   "2:\n"
+   : : : "a12", "a13", "memory");
 #else
-   : "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15",
+   __asm__ __volatile__ (
+   "   mov a12, a12\n"
+   : : : "memory");
 #endif
- "memory");
 }
 
 #endif /* _XTENSA_TRAPS_H */
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -1912,6 +1912,43 @@ ENTRY(system_call)
 
 ENDPROC(system_call)
 
+/*
+ * Spill live registers on the kernel stack macro.
+ *
+ * Entry condition: ps.woe is set, ps.excm is cleared
+ * Exit condition: windowstart has single bit set
+ * May clobber: a12, a13
+ */
+   .macro  spill_registers_kernel
+
+#if XCHAL_NUM_AREGS > 16
+   call12  1f
+   _j  2f
+   retw
+   .align  4
+1:
+   _entry  a1, 48
+   addia12, a0, 3
+#if XCHAL_NUM_AREGS > 32
+   .rept   (XCHAL_NUM_AREGS - 32) / 12
+   _entry  a1, 48
+   mov a12, a0
+   .endr
+#endif
+   _entry  a1, 48
+#if XCHAL_NUM_AREGS % 12 == 0
+   mov a8, a8
+#elif XCHAL_NUM_AREGS % 12 == 4
+   mov a12, a12
+#elif XCHAL_NUM_AREGS % 12 == 8
+   mov a4, a4
+#endif
+   retw
+2:
+#else
+   mov a12, a12
+#endif
+   .endm
 
 /*
  * Task switch.
@@ -1924,21 +1961,20 @@ ENTRY(_switch_to)
 
entry   a1, 16
 
-   mov a12, a2 # preserve 'prev' (a2)
-   mov a13, a3 # and 'next' (a3)
+   mov a10, a2 # preserve 'prev' (a2)
+   mov a11, a3 # and 'next' (a3)
 
l32ia4, a2, TASK_THREAD_INFO
l32ia5, a3, TASK_THREAD_INFO
 
-   save_xtregs_user a4 a6 a8 a9 a10 a11 THREAD_XTREGS_USER
+   save_xtregs_user a4 a6 a8 a9 a12 a13 THREAD_XTREGS_USER
 
-   s32ia0, a12, THREAD_RA  # save return address
-   s32ia1, a12, THREAD_SP  # save stack pointer
+   s32ia0, a10, THREAD_RA  # save return address
+   s32ia1, a10, THREAD_SP  # save stack pointer
 
/* Disable ints while we manipulate the stack pointer. */
 
-   movia14, (1 << PS_EXCM_BIT) | LOCKLEVEL
-   xsr a14, ps
+   rsila14, LOCKLEVEL
rsr a3, excsave1
rsync
s32ia3, a3, EXC_TABLE_FIXUP /* enter critical section */
@@ -1953,7 +1989,7 @@ ENTRY(_switch_to)
 
/* Flush register file. */
 
-   call0   _spill_registers# destroys a3, a4, and SAR
+   spill_registers_kernel
 
/* Set kernel stack (and leave critical section)
 * Note: It's save to set it here. The stack will not be overwritten
@@ -1969,13 +2005,13 @@ 

[PATCH 3.10 79/97] xtensa: introduce spill_registers_kernel macro

2014-03-04 Thread Greg Kroah-Hartman
3.10-stable review patch.  If anyone has any objections, please let me know.

--

From: Max Filippov jcmvb...@gmail.com

commit e2fd1374c705abe4661df3fb6fadb3879c7c1846 upstream.

Most in-kernel users want registers spilled on the kernel stack and
don't require PS.EXCM to be set. That means that they don't need fixup
routine and could reuse regular window overflow mechanism for that,
which makes spill routine very simple.

Suggested-by: Chris Zankel ch...@zankel.net
Signed-off-by: Max Filippov jcmvb...@gmail.com
Signed-off-by: Greg Kroah-Hartman gre...@linuxfoundation.org

---
 arch/xtensa/include/asm/traps.h |   44 ++---
 arch/xtensa/kernel/entry.S  |   60 
 2 files changed, 76 insertions(+), 28 deletions(-)

--- a/arch/xtensa/include/asm/traps.h
+++ b/arch/xtensa/include/asm/traps.h
@@ -22,25 +22,37 @@ extern void do_unhandled(struct pt_regs
 
 static inline void spill_registers(void)
 {
-
+#if XCHAL_NUM_AREGS  16
__asm__ __volatile__ (
-   movi   a14, __stringify((1  PS_EXCM_BIT) | LOCKLEVEL)\n\t
-   mova12, a0\n\t
-   rsra13, sar\n\t
-   xsra14, ps\n\t
-   movi   a0, _spill_registers\n\t
-   rsync\n\t
-   callx0 a0\n\t
-   mova0, a12\n\t
-   wsra13, sar\n\t
-   wsra14, ps\n\t
-   : :
-#if defined(CONFIG_FRAME_POINTER)
-   : a2, a3, a4,   a11, a12, a13, a14, a15,
+  call12  1f\n
+  _j  2f\n
+  retw\n
+  .align  4\n
+   1:\n
+  _entry  a1, 48\n
+  addia12, a0, 3\n
+#if XCHAL_NUM_AREGS  32
+  .rept   ( __stringify(XCHAL_NUM_AREGS)  - 32) / 12\n
+  _entry  a1, 48\n
+  mov a12, a0\n
+  .endr\n
+#endif
+  _entry  a1, 48\n
+#if XCHAL_NUM_AREGS % 12 == 0
+  mov a8, a8\n
+#elif XCHAL_NUM_AREGS % 12 == 4
+  mov a12, a12\n
+#elif XCHAL_NUM_AREGS % 12 == 8
+  mov a4, a4\n
+#endif
+  retw\n
+   2:\n
+   : : : a12, a13, memory);
 #else
-   : a2, a3, a4, a7, a11, a12, a13, a14, a15,
+   __asm__ __volatile__ (
+  mov a12, a12\n
+   : : : memory);
 #endif
- memory);
 }
 
 #endif /* _XTENSA_TRAPS_H */
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -1912,6 +1912,43 @@ ENTRY(system_call)
 
 ENDPROC(system_call)
 
+/*
+ * Spill live registers on the kernel stack macro.
+ *
+ * Entry condition: ps.woe is set, ps.excm is cleared
+ * Exit condition: windowstart has single bit set
+ * May clobber: a12, a13
+ */
+   .macro  spill_registers_kernel
+
+#if XCHAL_NUM_AREGS  16
+   call12  1f
+   _j  2f
+   retw
+   .align  4
+1:
+   _entry  a1, 48
+   addia12, a0, 3
+#if XCHAL_NUM_AREGS  32
+   .rept   (XCHAL_NUM_AREGS - 32) / 12
+   _entry  a1, 48
+   mov a12, a0
+   .endr
+#endif
+   _entry  a1, 48
+#if XCHAL_NUM_AREGS % 12 == 0
+   mov a8, a8
+#elif XCHAL_NUM_AREGS % 12 == 4
+   mov a12, a12
+#elif XCHAL_NUM_AREGS % 12 == 8
+   mov a4, a4
+#endif
+   retw
+2:
+#else
+   mov a12, a12
+#endif
+   .endm
 
 /*
  * Task switch.
@@ -1924,21 +1961,20 @@ ENTRY(_switch_to)
 
entry   a1, 16
 
-   mov a12, a2 # preserve 'prev' (a2)
-   mov a13, a3 # and 'next' (a3)
+   mov a10, a2 # preserve 'prev' (a2)
+   mov a11, a3 # and 'next' (a3)
 
l32ia4, a2, TASK_THREAD_INFO
l32ia5, a3, TASK_THREAD_INFO
 
-   save_xtregs_user a4 a6 a8 a9 a10 a11 THREAD_XTREGS_USER
+   save_xtregs_user a4 a6 a8 a9 a12 a13 THREAD_XTREGS_USER
 
-   s32ia0, a12, THREAD_RA  # save return address
-   s32ia1, a12, THREAD_SP  # save stack pointer
+   s32ia0, a10, THREAD_RA  # save return address
+   s32ia1, a10, THREAD_SP  # save stack pointer
 
/* Disable ints while we manipulate the stack pointer. */
 
-   movia14, (1  PS_EXCM_BIT) | LOCKLEVEL
-   xsr a14, ps
+   rsila14, LOCKLEVEL
rsr a3, excsave1
rsync
s32ia3, a3, EXC_TABLE_FIXUP /* enter critical section */
@@ -1953,7 +1989,7 @@ ENTRY(_switch_to)
 
/* Flush register file. */
 
-   call0   _spill_registers# destroys a3, a4, and SAR
+   spill_registers_kernel
 
/* Set kernel stack (and leave critical section)
 * Note: It's save to set it here. The stack will not be overwritten
@@ -1969,13 +2005,13 @@ ENTRY(_switch_to)
 
/*