Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/uaccess: Move copy_user_handle_tail() into asm

By writing the function in asm we avoid cross object code flow and
objtool no longer gets confused about a 'stray' CLAC.

Also; the asm version is actually _simpler_.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Peter Zijlstra and committed by
Ingo Molnar
3693ca81 8f4faed0

+48 -47
-24
arch/x86/include/asm/asm.h
··· 148 148 _ASM_PTR (entry); \ 149 149 .popsection 150 150 151 - .macro ALIGN_DESTINATION 152 - /* check for bad alignment of destination */ 153 - movl %edi,%ecx 154 - andl $7,%ecx 155 - jz 102f /* already aligned */ 156 - subl $8,%ecx 157 - negl %ecx 158 - subl %ecx,%edx 159 - 100: movb (%rsi),%al 160 - 101: movb %al,(%rdi) 161 - incq %rsi 162 - incq %rdi 163 - decl %ecx 164 - jnz 100b 165 - 102: 166 - .section .fixup,"ax" 167 - 103: addl %ecx,%edx /* ecx is zerorest also */ 168 - jmp copy_user_handle_tail 169 - .previous 170 - 171 - _ASM_EXTABLE_UA(100b, 103b) 172 - _ASM_EXTABLE_UA(101b, 103b) 173 - .endm 174 - 175 151 #else 176 152 # define _EXPAND_EXTABLE_HANDLE(x) #x 177 153 # define _ASM_EXTABLE_HANDLE(from, to, handler) \
-3
arch/x86/include/asm/uaccess_64.h
··· 208 208 } 209 209 210 210 unsigned long 211 - copy_user_handle_tail(char *to, char *from, unsigned len); 212 - 213 - unsigned long 214 211 mcsafe_handle_tail(char *to, char *from, unsigned len); 215 212 216 213 #endif /* _ASM_X86_UACCESS_64_H */
+48
arch/x86/lib/copy_user_64.S
··· 16 16 #include <asm/smap.h> 17 17 #include <asm/export.h> 18 18 19 + .macro ALIGN_DESTINATION 20 + /* check for bad alignment of destination */ 21 + movl %edi,%ecx 22 + andl $7,%ecx 23 + jz 102f /* already aligned */ 24 + subl $8,%ecx 25 + negl %ecx 26 + subl %ecx,%edx 27 + 100: movb (%rsi),%al 28 + 101: movb %al,(%rdi) 29 + incq %rsi 30 + incq %rdi 31 + decl %ecx 32 + jnz 100b 33 + 102: 34 + .section .fixup,"ax" 35 + 103: addl %ecx,%edx /* ecx is zerorest also */ 36 + jmp copy_user_handle_tail 37 + .previous 38 + 39 + _ASM_EXTABLE_UA(100b, 103b) 40 + _ASM_EXTABLE_UA(101b, 103b) 41 + .endm 42 + 19 43 /* 20 44 * copy_user_generic_unrolled - memory copy with exception handling. 21 45 * This version is for CPUs like P4 that don't have efficient micro ··· 216 192 _ASM_EXTABLE_UA(1b, 12b) 217 193 ENDPROC(copy_user_enhanced_fast_string) 218 194 EXPORT_SYMBOL(copy_user_enhanced_fast_string) 195 + 196 + /* 197 + * Try to copy last bytes and clear the rest if needed. 198 + * Since protection fault in copy_from/to_user is not a normal situation, 199 + * it is not necessary to optimize tail handling. 200 + * 201 + * Input: 202 + * rdi destination 203 + * rsi source 204 + * rdx count 205 + * 206 + * Output: 207 + * eax uncopied bytes or 0 if successful. 208 + */ 209 + ALIGN; 210 + copy_user_handle_tail: 211 + movl %edx,%ecx 212 + 1: rep movsb 213 + 2: mov %ecx,%eax 214 + ASM_CLAC 215 + ret 216 + 217 + _ASM_EXTABLE_UA(1b, 2b) 218 + ENDPROC(copy_user_handle_tail) 219 219 220 220 /* 221 221 * copy_user_nocache - Uncached memory copy with exception handling
-20
arch/x86/lib/usercopy_64.c
··· 55 55 EXPORT_SYMBOL(clear_user); 56 56 57 57 /* 58 - * Try to copy last bytes and clear the rest if needed. 59 - * Since protection fault in copy_from/to_user is not a normal situation, 60 - * it is not necessary to optimize tail handling. 61 - */ 62 - __visible unsigned long 63 - copy_user_handle_tail(char *to, char *from, unsigned len) 64 - { 65 - for (; len; --len, to++) { 66 - char c; 67 - 68 - if (__get_user_nocheck(c, from++, sizeof(char))) 69 - break; 70 - if (__put_user_nocheck(c, to, sizeof(char))) 71 - break; 72 - } 73 - clac(); 74 - return len; 75 - } 76 - 77 - /* 78 58 * Similar to copy_user_handle_tail, probe for the write fault point, 79 59 * but reuse __memcpy_mcsafe in case a new read error is encountered. 80 60 * clac() is handled in _copy_to_iter_mcsafe().