diff options
| author | Max Filippov <jcmvbkbc@gmail.com> | 2014-07-26 23:23:41 -0400 |
|---|---|---|
| committer | Max Filippov <jcmvbkbc@gmail.com> | 2014-08-14 03:59:16 -0400 |
| commit | 52247123749cc3cbc30168b33ad8c69515c96d23 (patch) | |
| tree | 2bdc9346c7ce61227d7d68e12aace9b130406bcb /arch/xtensa | |
| parent | 89f77c6f5bb4b0058f40f510809ec07255e02a7e (diff) | |
xtensa: fix access to THREAD_RA/THREAD_SP/THREAD_DS
With SMP and a lot of debug options enabled task_struct::thread gets out
of reach of s32i/l32i instructions with base pointing at task_struct,
breaking build with the following messages:
arch/xtensa/kernel/entry.S: Assembler messages:
arch/xtensa/kernel/entry.S:1002: Error: operand 3 of 'l32i.n' has invalid value '1048'
arch/xtensa/kernel/entry.S:1831: Error: operand 3 of 's32i.n' has invalid value '1040'
arch/xtensa/kernel/entry.S:1832: Error: operand 3 of 's32i.n' has invalid value '1044'
Change base to point to task_struct::thread in such cases.
Don't use a10 in _switch_to to save/restore prev pointer as a2 is not
clobbered.
Cc: stable@vger.kernel.org
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Diffstat (limited to 'arch/xtensa')
| -rw-r--r-- | arch/xtensa/include/asm/uaccess.h | 5 | ||||
| -rw-r--r-- | arch/xtensa/kernel/entry.S | 12 |
2 files changed, 13 insertions, 4 deletions
diff --git a/arch/xtensa/include/asm/uaccess.h b/arch/xtensa/include/asm/uaccess.h index fd686dc45d1a..c7211e7e182d 100644 --- a/arch/xtensa/include/asm/uaccess.h +++ b/arch/xtensa/include/asm/uaccess.h | |||
| @@ -52,7 +52,12 @@ | |||
| 52 | */ | 52 | */ |
| 53 | .macro get_fs ad, sp | 53 | .macro get_fs ad, sp |
| 54 | GET_CURRENT(\ad,\sp) | 54 | GET_CURRENT(\ad,\sp) |
| 55 | #if THREAD_CURRENT_DS > 1020 | ||
| 56 | addi \ad, \ad, TASK_THREAD | ||
| 57 | l32i \ad, \ad, THREAD_CURRENT_DS - TASK_THREAD | ||
| 58 | #else | ||
| 55 | l32i \ad, \ad, THREAD_CURRENT_DS | 59 | l32i \ad, \ad, THREAD_CURRENT_DS |
| 60 | #endif | ||
| 56 | .endm | 61 | .endm |
| 57 | 62 | ||
| 58 | /* | 63 | /* |
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index ef7f4990722b..db96acb1362b 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S | |||
| @@ -1820,7 +1820,6 @@ ENTRY(_switch_to) | |||
| 1820 | 1820 | ||
| 1821 | entry a1, 16 | 1821 | entry a1, 16 |
| 1822 | 1822 | ||
| 1823 | mov a10, a2 # preserve 'prev' (a2) | ||
| 1824 | mov a11, a3 # and 'next' (a3) | 1823 | mov a11, a3 # and 'next' (a3) |
| 1825 | 1824 | ||
| 1826 | l32i a4, a2, TASK_THREAD_INFO | 1825 | l32i a4, a2, TASK_THREAD_INFO |
| @@ -1828,8 +1827,14 @@ ENTRY(_switch_to) | |||
| 1828 | 1827 | ||
| 1829 | save_xtregs_user a4 a6 a8 a9 a12 a13 THREAD_XTREGS_USER | 1828 | save_xtregs_user a4 a6 a8 a9 a12 a13 THREAD_XTREGS_USER |
| 1830 | 1829 | ||
| 1831 | s32i a0, a10, THREAD_RA # save return address | 1830 | #if THREAD_RA > 1020 || THREAD_SP > 1020 |
| 1832 | s32i a1, a10, THREAD_SP # save stack pointer | 1831 | addi a10, a2, TASK_THREAD |
| 1832 | s32i a0, a10, THREAD_RA - TASK_THREAD # save return address | ||
| 1833 | s32i a1, a10, THREAD_SP - TASK_THREAD # save stack pointer | ||
| 1834 | #else | ||
| 1835 | s32i a0, a2, THREAD_RA # save return address | ||
| 1836 | s32i a1, a2, THREAD_SP # save stack pointer | ||
| 1837 | #endif | ||
| 1833 | 1838 | ||
| 1834 | /* Disable ints while we manipulate the stack pointer. */ | 1839 | /* Disable ints while we manipulate the stack pointer. */ |
| 1835 | 1840 | ||
| @@ -1870,7 +1875,6 @@ ENTRY(_switch_to) | |||
| 1870 | load_xtregs_user a5 a6 a8 a9 a12 a13 THREAD_XTREGS_USER | 1875 | load_xtregs_user a5 a6 a8 a9 a12 a13 THREAD_XTREGS_USER |
| 1871 | 1876 | ||
| 1872 | wsr a14, ps | 1877 | wsr a14, ps |
| 1873 | mov a2, a10 # return 'prev' | ||
| 1874 | rsync | 1878 | rsync |
| 1875 | 1879 | ||
| 1876 | retw | 1880 | retw |
