Skip to content

Commit d2c95f9

Browse files
committed
x86: don't use REP_GOOD or ERMS for user memory clearing
The modern target to use is FSRS (Fast Short REP STOS), and the other cases should only be used for bigger areas (ie mainly things like page clearing). Note! This changes the conditional for the inlining from FSRM ("fast short rep movs") to FSRS ("fast short rep stos"). We'll have a separate fixup for AMD microarchitectures that have a good 'rep stosb' yet do not set the new Intel-specific FSRS bit (because FSRM was there first). Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent adfcf42 commit d2c95f9

File tree

3 files changed

+3
-88
lines changed

3 files changed

+3
-88
lines changed

arch/x86/include/asm/uaccess_64.h

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,6 @@ __copy_from_user_flushcache(void *dst, const void __user *src, unsigned size)
8181

8282
__must_check unsigned long
8383
clear_user_original(void __user *addr, unsigned long len);
84-
__must_check unsigned long
85-
clear_user_rep_good(void __user *addr, unsigned long len);
86-
__must_check unsigned long
87-
clear_user_erms(void __user *addr, unsigned long len);
8884

8985
static __always_inline __must_check unsigned long __clear_user(void __user *addr, unsigned long size)
9086
{
@@ -97,16 +93,12 @@ static __always_inline __must_check unsigned long __clear_user(void __user *addr
9793
*/
9894
asm volatile(
9995
"1:\n\t"
100-
ALTERNATIVE_3("rep stosb",
101-
"call clear_user_erms", ALT_NOT(X86_FEATURE_FSRM),
102-
"call clear_user_rep_good", ALT_NOT(X86_FEATURE_ERMS),
103-
"call clear_user_original", ALT_NOT(X86_FEATURE_REP_GOOD))
96+
ALTERNATIVE("rep stosb",
97+
"call clear_user_original", ALT_NOT(X86_FEATURE_FSRS))
10498
"2:\n"
10599
_ASM_EXTABLE_UA(1b, 2b)
106100
: "+c" (size), "+D" (addr), ASM_CALL_CONSTRAINT
107-
: "a" (0)
108-
/* rep_good clobbers %rdx */
109-
: "rdx");
101+
: "a" (0));
110102

111103
clac();
112104

arch/x86/lib/clear_page_64.S

Lines changed: 0 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -113,78 +113,3 @@ SYM_FUNC_START(clear_user_original)
113113
_ASM_EXTABLE_UA(.Lbytes, .Lbytes_exception)
114114
SYM_FUNC_END(clear_user_original)
115115
EXPORT_SYMBOL(clear_user_original)
116-
117-
/*
118-
* Alternative clear user-space when CPU feature X86_FEATURE_REP_GOOD is
119-
* present.
120-
* Input:
121-
* rdi destination
122-
* rcx count
123-
*
124-
* Output:
125-
* rcx: uncleared bytes or 0 if successful.
126-
*/
127-
SYM_FUNC_START(clear_user_rep_good)
128-
# call the original thing for less than a cacheline
129-
cmp $64, %rcx
130-
jb clear_user_original
131-
132-
.Lprep:
133-
# copy lower 32-bits for rest bytes
134-
mov %ecx, %edx
135-
shr $3, %rcx
136-
jz .Lrep_good_rest_bytes
137-
138-
.Lrep_good_qwords:
139-
rep stosq
140-
141-
.Lrep_good_rest_bytes:
142-
and $7, %edx
143-
jz .Lrep_good_exit
144-
145-
.Lrep_good_bytes:
146-
mov %edx, %ecx
147-
rep stosb
148-
149-
.Lrep_good_exit:
150-
# see .Lexit comment above
151-
xor %eax, %eax
152-
RET
153-
154-
.Lrep_good_qwords_exception:
155-
# convert remaining qwords back into bytes to return to caller
156-
shl $3, %rcx
157-
and $7, %edx
158-
add %rdx, %rcx
159-
jmp .Lrep_good_exit
160-
161-
_ASM_EXTABLE_UA(.Lrep_good_qwords, .Lrep_good_qwords_exception)
162-
_ASM_EXTABLE_UA(.Lrep_good_bytes, .Lrep_good_exit)
163-
SYM_FUNC_END(clear_user_rep_good)
164-
EXPORT_SYMBOL(clear_user_rep_good)
165-
166-
/*
167-
* Alternative clear user-space when CPU feature X86_FEATURE_ERMS is present.
168-
* Input:
169-
* rdi destination
170-
* rcx count
171-
*
172-
* Output:
173-
* rcx: uncleared bytes or 0 if successful.
174-
*
175-
*/
176-
SYM_FUNC_START(clear_user_erms)
177-
# call the original thing for less than a cacheline
178-
cmp $64, %rcx
179-
jb clear_user_original
180-
181-
.Lerms_bytes:
182-
rep stosb
183-
184-
.Lerms_exit:
185-
xorl %eax,%eax
186-
RET
187-
188-
_ASM_EXTABLE_UA(.Lerms_bytes, .Lerms_exit)
189-
SYM_FUNC_END(clear_user_erms)
190-
EXPORT_SYMBOL(clear_user_erms)

tools/objtool/check.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,8 +1284,6 @@ static const char *uaccess_safe_builtin[] = {
12841284
"copy_mc_fragile_handle_tail",
12851285
"copy_mc_enhanced_fast_string",
12861286
"ftrace_likely_update", /* CONFIG_TRACE_BRANCH_PROFILING */
1287-
"clear_user_erms",
1288-
"clear_user_rep_good",
12891287
"clear_user_original",
12901288
NULL
12911289
};

0 commit comments

Comments
 (0)