@@ -86,7 +86,34 @@ int __noreturn __put_user_bad(void);
86
86
#define get_put_user_noinstr_attributes __always_inline
87
87
#endif
88
88
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 ) \
90
117
static get_put_user_noinstr_attributes int \
91
118
__put_user_##type##_noinstr(unsigned type __user *to, \
92
119
unsigned type *from, \
@@ -106,8 +133,16 @@ __put_user_##type##_noinstr(unsigned type __user *to, \
106
133
[spec] "I" (0x81) \
107
134
: "cc", "0"); \
108
135
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 ) \
111
146
static __always_inline int \
112
147
__put_user_##type(unsigned type __user *to, unsigned type *from, \
113
148
unsigned long size) \
@@ -166,7 +201,35 @@ DEFINE_PUT_USER(long);
166
201
167
202
int __noreturn __get_user_bad (void );
168
203
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 ) \
170
233
static get_put_user_noinstr_attributes int \
171
234
__get_user_##type##_noinstr(unsigned type *to, \
172
235
const unsigned type __user *from, \
@@ -189,8 +252,16 @@ __get_user_##type##_noinstr(unsigned type *to, \
189
252
return 0; \
190
253
*to = 0; \
191
254
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 ) \
194
265
static __always_inline int \
195
266
__get_user_##type(unsigned type *to, const unsigned type __user *from, \
196
267
unsigned long size) \
0 commit comments