]> git.hungrycats.org Git - linux/commitdiff
xtensa: fix kernel register spilling
authorMax Filippov <jcmvbkbc@gmail.com>
Thu, 16 Jul 2015 07:41:02 +0000 (10:41 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 21 Sep 2015 17:05:42 +0000 (10:05 -0700)
commit 77d6273e79e3a86552fcf10cdd31a69b46ed2ce6 upstream.

call12 can't be safely used as the first call in the inline function,
because the compiler does not extend the stack frame of the bounding
function accordingly, which may result in corruption of local variables.

If a call needs to be done, do call8 first followed by call12.

For pure assembly code in _switch_to increase stack frame size of the
bounding function.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/xtensa/include/asm/traps.h
arch/xtensa/kernel/entry.S

index 677bfcf4ee5ddab2207ed0e5f2885b4accd29f16..28f33a8b7f5f5b5b70d7d2f6cb6c0533bdc80a05 100644 (file)
@@ -25,30 +25,39 @@ static inline void spill_registers(void)
 {
 #if XCHAL_NUM_AREGS > 16
        __asm__ __volatile__ (
-               "       call12  1f\n"
+               "       call  1f\n"
                "       _j      2f\n"
                "       retw\n"
                "       .align  4\n"
                "1:\n"
+#if XCHAL_NUM_AREGS == 32
+               "       _entry  a1, 32\n"
+               "       addi    a8, a0, 3\n"
+               "       _entry  a1, 16\n"
+               "       mov     a12, a12\n"
+               "       retw\n"
+#else
                "       _entry  a1, 48\n"
-               "       addi    a12, a0, 3\n"
-#if XCHAL_NUM_AREGS > 32
-               "       .rept   (" __stringify(XCHAL_NUM_AREGS) " - 32) / 12\n"
+               "       call12  1f\n"
+               "       retw\n"
+               "       .align  4\n"
+               "1:\n"
+               "       .rept   (" __stringify(XCHAL_NUM_AREGS) " - 16) / 12\n"
                "       _entry  a1, 48\n"
                "       mov     a12, a0\n"
                "       .endr\n"
-#endif
-               "       _entry  a1, 48\n"
+               "       _entry  a1, 16\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
+#elif XCHAL_NUM_AREGS % 12 == 4
                "       mov     a4, a4\n"
+#elif XCHAL_NUM_AREGS % 12 == 8
+               "       mov     a8, a8\n"
 #endif
                "       retw\n"
+#endif
                "2:\n"
-               : : : "a12", "a13", "memory");
+               : : : "a8", "a9", "memory");
 #else
        __asm__ __volatile__ (
                "       mov     a12, a12\n"
index 51e9877ced06ac0a97a369f94719437409679dd1..a2a902140c4e50575e30dbf365edd247ead02f72 100644 (file)
@@ -1821,7 +1821,7 @@ ENDPROC(system_call)
        mov     a12, a0
        .endr
 #endif
-       _entry  a1, 48
+       _entry  a1, 16
 #if XCHAL_NUM_AREGS % 12 == 0
        mov     a8, a8
 #elif XCHAL_NUM_AREGS % 12 == 4
@@ -1845,7 +1845,7 @@ ENDPROC(system_call)
 
 ENTRY(_switch_to)
 
-       entry   a1, 16
+       entry   a1, 48
 
        mov     a11, a3                 # and 'next' (a3)