Skip to content

Commit adfcf42

Browse files
committed
x86: don't use REP_GOOD or ERMS for user memory copies
The modern target to use is FSRM (Fast Short REP MOVS), and the other cases should only be used for bigger areas (ie mainly things like page clearing). Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 20f3337 commit adfcf42

File tree

2 files changed

+12
-54
lines changed

2 files changed

+12
-54
lines changed

arch/x86/include/asm/uaccess_64.h

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@
1818

1919
/* Handles exceptions in both to and from, but doesn't do access_ok */
2020
__must_check unsigned long
21-
copy_user_enhanced_fast_string(void *to, const void *from, unsigned len);
22-
__must_check unsigned long
23-
copy_user_generic_string(void *to, const void *from, unsigned len);
21+
copy_user_fast_string(void *to, const void *from, unsigned len);
2422
__must_check unsigned long
2523
copy_user_generic_unrolled(void *to, const void *from, unsigned len);
2624

@@ -30,15 +28,12 @@ copy_user_generic(void *to, const void *from, unsigned len)
3028
unsigned ret;
3129

3230
/*
33-
* If CPU has ERMS feature, use copy_user_enhanced_fast_string.
34-
* Otherwise, if CPU has rep_good feature, use copy_user_generic_string.
31+
* If CPU has FSRM feature, use 'rep movs'.
3532
* Otherwise, use copy_user_generic_unrolled.
3633
*/
37-
alternative_call_2(copy_user_generic_unrolled,
38-
copy_user_generic_string,
39-
X86_FEATURE_REP_GOOD,
40-
copy_user_enhanced_fast_string,
41-
X86_FEATURE_ERMS,
34+
alternative_call(copy_user_generic_unrolled,
35+
copy_user_fast_string,
36+
X86_FEATURE_FSRM,
4237
ASM_OUTPUT2("=a" (ret), "=D" (to), "=S" (from),
4338
"=d" (len)),
4439
"1" (to), "2" (from), "3" (len)

arch/x86/lib/copy_user_64.S

Lines changed: 7 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ SYM_FUNC_START(copy_user_generic_unrolled)
104104
SYM_FUNC_END(copy_user_generic_unrolled)
105105
EXPORT_SYMBOL(copy_user_generic_unrolled)
106106

107-
/* Some CPUs run faster using the string copy instructions.
108-
* This is also a lot simpler. Use them when possible.
107+
/*
108+
* Some CPUs support FSRM for Fast Short REP MOVS.
109109
*
110110
* Only 4GB of copy is supported. This shouldn't be a problem
111111
* because the kernel normally only writes from/to page sized chunks
@@ -122,58 +122,21 @@ EXPORT_SYMBOL(copy_user_generic_unrolled)
122122
* Output:
123123
* eax uncopied bytes or 0 if successful.
124124
*/
125-
SYM_FUNC_START(copy_user_generic_string)
125+
SYM_FUNC_START(copy_user_fast_string)
126126
ASM_STAC
127-
cmpl $8,%edx
128-
jb 2f /* less than 8 bytes, go to byte copy loop */
129-
ALIGN_DESTINATION
130127
movl %edx,%ecx
131-
shrl $3,%ecx
132-
andl $7,%edx
133-
1: rep movsq
134-
2: movl %edx,%ecx
135-
3: rep movsb
128+
1: rep movsb
136129
xorl %eax,%eax
137130
ASM_CLAC
138131
RET
139132

140-
11: leal (%rdx,%rcx,8),%ecx
141-
12: movl %ecx,%edx /* ecx is zerorest also */
142-
jmp .Lcopy_user_handle_tail
143-
144-
_ASM_EXTABLE_CPY(1b, 11b)
145-
_ASM_EXTABLE_CPY(3b, 12b)
146-
SYM_FUNC_END(copy_user_generic_string)
147-
EXPORT_SYMBOL(copy_user_generic_string)
148-
149-
/*
150-
* Some CPUs are adding enhanced REP MOVSB/STOSB instructions.
151-
* It's recommended to use enhanced REP MOVSB/STOSB if it's enabled.
152-
*
153-
* Input:
154-
* rdi destination
155-
* rsi source
156-
* rdx count
157-
*
158-
* Output:
159-
* eax uncopied bytes or 0 if successful.
160-
*/
161-
SYM_FUNC_START(copy_user_enhanced_fast_string)
162-
ASM_STAC
163-
/* CPUs without FSRM should avoid rep movsb for short copies */
164-
ALTERNATIVE "cmpl $64, %edx; jb copy_user_short_string", "", X86_FEATURE_FSRM
165-
movl %edx,%ecx
166-
1: rep movsb
167-
xorl %eax,%eax
133+
12: movl %ecx,%eax /* ecx is zerorest also */
168134
ASM_CLAC
169135
RET
170136

171-
12: movl %ecx,%edx /* ecx is zerorest also */
172-
jmp .Lcopy_user_handle_tail
173-
174137
_ASM_EXTABLE_CPY(1b, 12b)
175-
SYM_FUNC_END(copy_user_enhanced_fast_string)
176-
EXPORT_SYMBOL(copy_user_enhanced_fast_string)
138+
SYM_FUNC_END(copy_user_fast_string)
139+
EXPORT_SYMBOL(copy_user_fast_string)
177140

178141
/*
179142
* Try to copy last bytes and clear the rest if needed.

0 commit comments

Comments
 (0)