Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+13 -4
+5
arch/xtensa/include/asm/uaccess.h
··· 52 52 */ 53 53 .macro get_fs ad, sp 54 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 59 l32i \ad, \ad, THREAD_CURRENT_DS 60 + #endif 56 61 .endm 57 62 58 63 /*
+8 -4
arch/xtensa/kernel/entry.S
··· 1820 1820 1821 1821 entry a1, 16 1822 1822 1823 - mov a10, a2 # preserve 'prev' (a2) 1824 1823 mov a11, a3 # and 'next' (a3) 1825 1824 1826 1825 l32i a4, a2, TASK_THREAD_INFO ··· 1827 1828 1828 1829 save_xtregs_user a4 a6 a8 a9 a12 a13 THREAD_XTREGS_USER 1829 1830 1830 - s32i a0, a10, THREAD_RA # save return address 1831 - s32i a1, a10, THREAD_SP # save stack pointer 1831 + #if THREAD_RA > 1020 || THREAD_SP > 1020 1832 + addi a10, a2, TASK_THREAD 1833 + s32i a0, a10, THREAD_RA - TASK_THREAD # save return address 1834 + s32i a1, a10, THREAD_SP - TASK_THREAD # save stack pointer 1835 + #else 1836 + s32i a0, a2, THREAD_RA # save return address 1837 + s32i a1, a2, THREAD_SP # save stack pointer 1838 + #endif 1832 1839 1833 1840 /* Disable ints while we manipulate the stack pointer. */ 1834 1841 ··· 1875 1870 load_xtregs_user a5 a6 a8 a9 a12 a13 THREAD_XTREGS_USER 1876 1871 1877 1872 wsr a14, ps 1878 - mov a2, a10 # return 'prev' 1879 1873 rsync 1880 1874 1881 1875 retw