Skip to content

Commit ea5ae3a

Browse files
hcahcaAlexander Gordeev
authored andcommitted
s390/uaccess: Use asm goto for put_user()/get_user()
Use asm goto if available for put_user() and get_user(). This generates slightly better code. Reviewed-by: Alexander Gordeev <agordeev@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
1 parent 636d35a commit ea5ae3a

File tree

1 file changed

+77
-6
lines changed

1 file changed

+77
-6
lines changed

arch/s390/include/asm/uaccess.h

Lines changed: 77 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,34 @@ int __noreturn __put_user_bad(void);
8686
#define get_put_user_noinstr_attributes __always_inline
8787
#endif
8888

89-
#define DEFINE_PUT_USER(type) \
89+
#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
90+
91+
#define DEFINE_PUT_USER_NOINSTR(type) \
92+
static get_put_user_noinstr_attributes int \
93+
__put_user_##type##_noinstr(unsigned type __user *to, \
94+
unsigned type *from, \
95+
unsigned long size) \
96+
{ \
97+
asm goto( \
98+
" llilh %%r0,%[spec]\n" \
99+
"0: mvcos %[to],%[from],%[size]\n" \
100+
"1: nopr %%r7\n" \
101+
EX_TABLE(0b, %l[Efault]) \
102+
EX_TABLE(1b, %l[Efault]) \
103+
: [to] "+Q" (*to) \
104+
: [size] "d" (size), [from] "Q" (*from), \
105+
[spec] "I" (0x81) \
106+
: "cc", "0" \
107+
: Efault \
108+
); \
109+
return 0; \
110+
Efault: \
111+
return -EFAULT; \
112+
}
113+
114+
#else /* CONFIG_CC_HAS_ASM_GOTO_OUTPUT */
115+
116+
#define DEFINE_PUT_USER_NOINSTR(type) \
90117
static get_put_user_noinstr_attributes int \
91118
__put_user_##type##_noinstr(unsigned type __user *to, \
92119
unsigned type *from, \
@@ -106,8 +133,16 @@ __put_user_##type##_noinstr(unsigned type __user *to, \
106133
[spec] "I" (0x81) \
107134
: "cc", "0"); \
108135
return rc; \
109-
} \
110-
\
136+
}
137+
138+
#endif /* CONFIG_CC_HAS_ASM_GOTO_OUTPUT */
139+
140+
DEFINE_PUT_USER_NOINSTR(char);
141+
DEFINE_PUT_USER_NOINSTR(short);
142+
DEFINE_PUT_USER_NOINSTR(int);
143+
DEFINE_PUT_USER_NOINSTR(long);
144+
145+
#define DEFINE_PUT_USER(type) \
111146
static __always_inline int \
112147
__put_user_##type(unsigned type __user *to, unsigned type *from, \
113148
unsigned long size) \
@@ -166,7 +201,35 @@ DEFINE_PUT_USER(long);
166201

167202
int __noreturn __get_user_bad(void);
168203

169-
#define DEFINE_GET_USER(type) \
204+
#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
205+
206+
#define DEFINE_GET_USER_NOINSTR(type) \
207+
static get_put_user_noinstr_attributes int \
208+
__get_user_##type##_noinstr(unsigned type *to, \
209+
const unsigned type __user *from, \
210+
unsigned long size) \
211+
{ \
212+
asm goto( \
213+
" lhi %%r0,%[spec]\n" \
214+
"0: mvcos %[to],%[from],%[size]\n" \
215+
"1: nopr %%r7\n" \
216+
EX_TABLE(0b, %l[Efault]) \
217+
EX_TABLE(1b, %l[Efault]) \
218+
: [to] "=Q" (*to) \
219+
: [size] "d" (size), [from] "Q" (*from), \
220+
[spec] "I" (0x81) \
221+
: "cc", "0" \
222+
: Efault \
223+
); \
224+
return 0; \
225+
Efault: \
226+
*to = 0; \
227+
return -EFAULT; \
228+
}
229+
230+
#else /* CONFIG_CC_HAS_ASM_GOTO_OUTPUT */
231+
232+
#define DEFINE_GET_USER_NOINSTR(type) \
170233
static get_put_user_noinstr_attributes int \
171234
__get_user_##type##_noinstr(unsigned type *to, \
172235
const unsigned type __user *from, \
@@ -189,8 +252,16 @@ __get_user_##type##_noinstr(unsigned type *to, \
189252
return 0; \
190253
*to = 0; \
191254
return rc; \
192-
} \
193-
\
255+
}
256+
257+
#endif /* CONFIG_CC_HAS_ASM_GOTO_OUTPUT */
258+
259+
DEFINE_GET_USER_NOINSTR(char);
260+
DEFINE_GET_USER_NOINSTR(short);
261+
DEFINE_GET_USER_NOINSTR(int);
262+
DEFINE_GET_USER_NOINSTR(long);
263+
264+
#define DEFINE_GET_USER(type) \
194265
static __always_inline int \
195266
__get_user_##type(unsigned type *to, const unsigned type __user *from, \
196267
unsigned long size) \

0 commit comments

Comments
 (0)