Skip to content

Commit 5b629e6

Browse files
hcahcaAlexander Gordeev
authored andcommitted
s390/uaccess: Implement __get_kernel_nofault()/__put_kernel_nofault() with mvc
Use the mvc instruction in order to implement __get_kernel_nofault() and __put_kernel_nofault(). Both functions have a source and destination address where the code is supposed to read from and write to. Use the mvc instruction to copy from source to destination instead of lg/stg like instructions. This generates slightly better code. Acked-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 722926e commit 5b629e6

File tree

1 file changed

+44
-78
lines changed

1 file changed

+44
-78
lines changed

arch/s390/include/asm/uaccess.h

Lines changed: 44 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -341,109 +341,75 @@ static inline void *s390_kernel_write(void *dst, const void *src, size_t size)
341341
return __s390_kernel_write(dst, src, size);
342342
}
343343

344-
int __noreturn __put_kernel_bad(void);
344+
void __noreturn __mvc_kernel_nofault_bad(void);
345345

346-
#define __put_kernel_asm(val, to, insn) \
347-
({ \
348-
int __rc; \
349-
\
350-
asm volatile( \
351-
"0: " insn " %[_val],%[_to]\n" \
352-
"1: xr %[rc],%[rc]\n" \
353-
"2:\n" \
354-
EX_TABLE_UA_FAULT(0b, 2b, %[rc]) \
355-
EX_TABLE_UA_FAULT(1b, 2b, %[rc]) \
356-
: [rc] "=d" (__rc), [_to] "+Q" (*(to)) \
357-
: [_val] "d" (val) \
358-
: "cc"); \
359-
__rc; \
360-
})
346+
#ifdef CONFIG_CC_HAS_ASM_AOR_FORMAT_FLAGS
361347

362-
#define __put_kernel_nofault(dst, src, type, err_label) \
348+
#define __mvc_kernel_nofault(dst, src, type, err_label) \
363349
do { \
364-
unsigned long __x = (unsigned long)(*((type *)(src))); \
365-
int __pk_err; \
350+
int __rc; \
366351
\
367352
switch (sizeof(type)) { \
368353
case 1: \
369-
__pk_err = __put_kernel_asm(__x, (type *)(dst), "stc"); \
370-
break; \
371354
case 2: \
372-
__pk_err = __put_kernel_asm(__x, (type *)(dst), "sth"); \
373-
break; \
374355
case 4: \
375-
__pk_err = __put_kernel_asm(__x, (type *)(dst), "st"); \
376-
break; \
377356
case 8: \
378-
__pk_err = __put_kernel_asm(__x, (type *)(dst), "stg"); \
357+
asm_inline volatile( \
358+
"0: mvc %O[_dst](%[_len],%R[_dst]),%[_src]\n" \
359+
"1: lhi %[_rc],0\n" \
360+
"2:\n" \
361+
EX_TABLE_UA_FAULT(0b, 2b, %[_rc]) \
362+
EX_TABLE_UA_FAULT(1b, 2b, %[_rc]) \
363+
: [_rc] "=d" (__rc), \
364+
[_dst] "=Q" (*(type *)dst) \
365+
: [_src] "Q" (*(type *)(src)), \
366+
[_len] "I" (sizeof(type))); \
367+
if (__rc) \
368+
goto err_label; \
379369
break; \
380370
default: \
381-
__pk_err = __put_kernel_bad(); \
371+
__mvc_kernel_nofault_bad(); \
382372
break; \
383373
} \
384-
if (unlikely(__pk_err)) \
385-
goto err_label; \
386374
} while (0)
387375

388-
int __noreturn __get_kernel_bad(void);
389-
390-
#define __get_kernel_asm(val, from, insn) \
391-
({ \
392-
int __rc; \
393-
\
394-
asm volatile( \
395-
"0: " insn " %[_val],%[_from]\n" \
396-
"1: xr %[rc],%[rc]\n" \
397-
"2:\n" \
398-
EX_TABLE_UA_LOAD_REG(0b, 2b, %[rc], %[_val]) \
399-
EX_TABLE_UA_LOAD_REG(1b, 2b, %[rc], %[_val]) \
400-
: [rc] "=d" (__rc), [_val] "=d" (val) \
401-
: [_from] "Q" (*(from)) \
402-
: "cc"); \
403-
__rc; \
404-
})
376+
#else /* CONFIG_CC_HAS_ASM_AOR_FORMAT_FLAGS */
405377

406-
#define __get_kernel_nofault(dst, src, type, err_label) \
378+
#define __mvc_kernel_nofault(dst, src, type, err_label) \
407379
do { \
408-
int __gk_err; \
380+
type *(__dst) = (type *)(dst); \
381+
int __rc; \
409382
\
410383
switch (sizeof(type)) { \
411-
case 1: { \
412-
unsigned char __x; \
413-
\
414-
__gk_err = __get_kernel_asm(__x, (type *)(src), "ic"); \
415-
*((type *)(dst)) = (type)__x; \
416-
break; \
417-
}; \
418-
case 2: { \
419-
unsigned short __x; \
420-
\
421-
__gk_err = __get_kernel_asm(__x, (type *)(src), "lh"); \
422-
*((type *)(dst)) = (type)__x; \
423-
break; \
424-
}; \
425-
case 4: { \
426-
unsigned int __x; \
427-
\
428-
__gk_err = __get_kernel_asm(__x, (type *)(src), "l"); \
429-
*((type *)(dst)) = (type)__x; \
430-
break; \
431-
}; \
432-
case 8: { \
433-
unsigned long __x; \
434-
\
435-
__gk_err = __get_kernel_asm(__x, (type *)(src), "lg"); \
436-
*((type *)(dst)) = (type)__x; \
384+
case 1: \
385+
case 2: \
386+
case 4: \
387+
case 8: \
388+
asm_inline volatile( \
389+
"0: mvc 0(%[_len],%[_dst]),%[_src]\n" \
390+
"1: lhi %[_rc],0\n" \
391+
"2:\n" \
392+
EX_TABLE_UA_FAULT(0b, 2b, %[_rc]) \
393+
EX_TABLE_UA_FAULT(1b, 2b, %[_rc]) \
394+
: [_rc] "=d" (__rc), \
395+
"=m" (*__dst) \
396+
: [_src] "Q" (*(type *)(src)), \
397+
[_dst] "a" (__dst), \
398+
[_len] "I" (sizeof(type))); \
399+
if (__rc) \
400+
goto err_label; \
437401
break; \
438-
}; \
439402
default: \
440-
__gk_err = __get_kernel_bad(); \
403+
__mvc_kernel_nofault_bad(); \
441404
break; \
442405
} \
443-
if (unlikely(__gk_err)) \
444-
goto err_label; \
445406
} while (0)
446407

408+
#endif /* CONFIG_CC_HAS_ASM_AOR_FORMAT_FLAGS */
409+
410+
#define __get_kernel_nofault __mvc_kernel_nofault
411+
#define __put_kernel_nofault __mvc_kernel_nofault
412+
447413
void __cmpxchg_user_key_called_with_bad_pointer(void);
448414

449415
#define CMPXCHG_USER_KEY_MAX_LOOPS 128

0 commit comments

Comments
 (0)