Skip to content

Commit 24d3ba0

Browse files
masahir0yRussell King (Oracle)
authored andcommitted
ARM: 9324/1: fix get_user() broken with veneer
The 32-bit ARM kernel stops working if the kernel grows to the point where veneers for __get_user_* are created. AAPCS32 [1] states, "Register r12 (IP) may be used by a linker as a scratch register between a routine and any subroutine it calls. It can also be used within a routine to hold intermediate values between subroutine calls." However, bl instructions buried within the inline asm are unpredictable for compilers; hence, "ip" must be added to the clobber list. This becomes critical when veneers for __get_user_* are created because veneers use the ip register since commit 02e541d ("ARM: 8323/1: force linker to use PIC veneers"). [1]: https://github.com/ARM-software/abi-aa/blob/2023Q1/aapcs32/aapcs32.rst Signed-off-by: Masahiro Yamada <[email protected]> Reviewed-by: Ard Biesheuvel <[email protected]> Signed-off-by: Russell King (Oracle) <[email protected]>
1 parent 399da29 commit 24d3ba0

File tree

1 file changed

+2
-12
lines changed

1 file changed

+2
-12
lines changed

arch/arm/include/asm/uaccess.h

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -109,24 +109,14 @@ extern int __get_user_64t_1(void *);
109109
extern int __get_user_64t_2(void *);
110110
extern int __get_user_64t_4(void *);
111111

112-
#define __GUP_CLOBBER_1 "lr", "cc"
113-
#ifdef CONFIG_CPU_USE_DOMAINS
114-
#define __GUP_CLOBBER_2 "ip", "lr", "cc"
115-
#else
116-
#define __GUP_CLOBBER_2 "lr", "cc"
117-
#endif
118-
#define __GUP_CLOBBER_4 "lr", "cc"
119-
#define __GUP_CLOBBER_32t_8 "lr", "cc"
120-
#define __GUP_CLOBBER_8 "lr", "cc"
121-
122112
#define __get_user_x(__r2, __p, __e, __l, __s) \
123113
__asm__ __volatile__ ( \
124114
__asmeq("%0", "r0") __asmeq("%1", "r2") \
125115
__asmeq("%3", "r1") \
126116
"bl __get_user_" #__s \
127117
: "=&r" (__e), "=r" (__r2) \
128118
: "0" (__p), "r" (__l) \
129-
: __GUP_CLOBBER_##__s)
119+
: "ip", "lr", "cc")
130120

131121
/* narrowing a double-word get into a single 32bit word register: */
132122
#ifdef __ARMEB__
@@ -148,7 +138,7 @@ extern int __get_user_64t_4(void *);
148138
"bl __get_user_64t_" #__s \
149139
: "=&r" (__e), "=r" (__r2) \
150140
: "0" (__p), "r" (__l) \
151-
: __GUP_CLOBBER_##__s)
141+
: "ip", "lr", "cc")
152142
#else
153143
#define __get_user_x_64t __get_user_x
154144
#endif

0 commit comments

Comments
 (0)