From 548ccc7e0b7d36e6ab67e6ca1c3c16555508a4c4 Mon Sep 17 00:00:00 2001 From: WangYuli Date: Mon, 10 Aug 2026 15:48:24 +0800 Subject: [PATCH] x86: Fix objtool noreturn warnings from Hygon copy_user routines Commit 9590a377b16e2 ("x86: Enhanced copy capabilities for Hygon processor") added copy_user_avx2.S and copy_user_sse2.S, placing the sub-256-byte copy block and the tail handler after SYM_FUNC_END() as separate SYM_CODE_START_LOCAL() (STT_NOTYPE) symbols. Every exit path of copy_user_avx2_pf64_nt_string() jumps into one of those out-of-function blocks, so the function body itself contains no return instruction at all. objtool's __dead_end_function() only scans instructions within the function symbol's bounds for INSN_RETURN, and jump_is_sibling_call() explicitly refuses to treat jumps into STT_NOTYPE symbols as sibling calls. The function is therefore misclassified as noreturn, the code following each call site is treated as unreachable, and validate_unreachables() emits one warning per caller when building x86_64_defconfig with "make CC=\"ccache clang\" LLVM=1": vmlinux.o: warning: objtool: xfpregs_set+0x249: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: fpregs_set+0x2d1: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: copy_fpstate_to_sigframe+0x464: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: fpu__restore_sig+0x1e8: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: regset_tls_set+0x192: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: copy_from_user_nofault+0xbd: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: copy_to_user_nofault+0xb2: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: do_wp_page+0xd07: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: set_fd_set+0x88: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: copyout+0x84: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: copyin+0x84: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: _copy_from_user+0x86: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: _copy_to_user+0x89: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: i915_gem_execbuffer2_ioctl+0x634: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: parse_timeline_fences+0x3c7: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: eb_relocate_vma+0x1cb: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: shmem_pwrite+0x21c: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: i915_gem_shmem_pread+0x280: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: i915_gem_gtt_pread+0x246: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: i915_gem_shmem_pwrite+0x2e6: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: query_memregion_info+0x235: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: copy_mc_to_user+0x8d: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: insn_fetch_from_user_inatomic+0x9f: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation vmlinux.o: warning: objtool: copy_from_user_nmi+0xab: copy_user_avx2_pf64_nt_string() is missing a __noreturn annotation Move the local blocks back between SYM_FUNC_START() and SYM_FUNC_END() and turn them into plain .L local labels, updating the jump references accordingly, in the same style as copy_user_64.S. All returns are then inside the function symbol and objtool can follow every path as normal intra-function control flow, so no annotation games are needed. No instructions are changed: all _ASM_EXTABLE_UA entries, the STAC/CLAC pairing, and the vzeroupper/sfence ordering on the fault and tail paths are preserved, and no new symbols are introduced. copy_user_sse2_opt_string() escapes the warning only because its normal path happens to keep one RET inside the symbol; its fault path shares the same out-of-symbol tail jump, so fix it the same way. Fixes: 9590a377b16e ("x86: Enhanced copy capabilities for Hygon processor") Assisted-by: Kimi Code:K3 Signed-off-by: WangYuli --- arch/x86/lib/copy_user_avx2.S | 24 ++++++------- arch/x86/lib/copy_user_sse2.S | 65 +++++++++++++++++------------------ 2 files changed, 42 insertions(+), 47 deletions(-) diff --git a/arch/x86/lib/copy_user_avx2.S b/arch/x86/lib/copy_user_avx2.S index a2a785aaccb21..ade681a99c984 100644 --- a/arch/x86/lib/copy_user_avx2.S +++ b/arch/x86/lib/copy_user_avx2.S @@ -66,7 +66,7 @@ 303: addl %ecx,%edx/* ecx is zerorest also */ - jmp Lavx2_copy_user_handle_tail + jmp .Lavx2_copy_user_handle_tail _ASM_EXTABLE_UA(300b, 303b) _ASM_EXTABLE_UA(301b, 303b) @@ -81,9 +81,9 @@ SYM_FUNC_START(copy_user_avx2_pf64_nt_string) ASM_STAC ALIGN_DESTINATION_32 - /* if len < 256 jmp to Lless_than_256_bytes_cpy */ + /* if len < 256 jmp to .Lless_than_256_bytes_cpy */ cmpq $256, %rdx - jb Lless_than_256_bytes_cpy + jb .Lless_than_256_bytes_cpy /* * Check if src is aligned, for 32-bit aligned ones, @@ -142,7 +142,7 @@ large_block_nt_aligned_cpy: vzeroupper sfence - jmp Lless_than_256_bytes_cpy + jmp .Lless_than_256_bytes_cpy large_block_nt_unaligned_cpy: PREFETCH(PREFETCH_DISTANCE(%rsi)) @@ -193,11 +193,11 @@ large_block_nt_unaligned_cpy: vzeroupper sfence - jmp Lless_than_256_bytes_cpy + jmp .Lless_than_256_bytes_cpy 88: vzeroupper - jmp Lavx2_copy_user_handle_tail + jmp .Lavx2_copy_user_handle_tail _ASM_EXTABLE_UA(32b, 88b) _ASM_EXTABLE_UA(33b, 88b) @@ -234,9 +234,6 @@ large_block_nt_unaligned_cpy: _ASM_EXTABLE_UA(61b, 88b) _ASM_EXTABLE_UA(62b, 88b) _ASM_EXTABLE_UA(63b, 88b) -SYM_FUNC_END(copy_user_avx2_pf64_nt_string) -EXPORT_SYMBOL(copy_user_avx2_pf64_nt_string) - /* * If len < 256 bytes, then we use rep mov directly. * @@ -248,7 +245,7 @@ EXPORT_SYMBOL(copy_user_avx2_pf64_nt_string) * Output: * eax uncopied bytes or 0 if successful. */ -SYM_CODE_START_LOCAL(Lless_than_256_bytes_cpy) +.Lless_than_256_bytes_cpy: movl %edx, %ecx 90: rep movsb @@ -264,7 +261,6 @@ SYM_CODE_START_LOCAL(Lless_than_256_bytes_cpy) RET _ASM_EXTABLE_UA(90b, 99b) -SYM_CODE_END(Lless_than_256_bytes_cpy) /* * Try to copy last bytes and clear the rest if needed. @@ -280,8 +276,7 @@ SYM_CODE_END(Lless_than_256_bytes_cpy) * Output: * eax uncopied bytes or 0 if successful. */ - -SYM_CODE_START_LOCAL(Lavx2_copy_user_handle_tail) +.Lavx2_copy_user_handle_tail: movq %rdx,%rcx cmp $X86_TRAP_MC,%eax /* check if X86_TRAP_MC */ je 3f @@ -297,7 +292,8 @@ SYM_CODE_START_LOCAL(Lavx2_copy_user_handle_tail) RET _ASM_EXTABLE_UA(1b, 2b) -SYM_CODE_END(Lavx2_copy_user_handle_tail) +SYM_FUNC_END(copy_user_avx2_pf64_nt_string) +EXPORT_SYMBOL(copy_user_avx2_pf64_nt_string) /* * Called when task schedule. we call fpu_save_%ymm0_7 to save old diff --git a/arch/x86/lib/copy_user_sse2.S b/arch/x86/lib/copy_user_sse2.S index 5422ff03ce2e6..9ce7d73f58d96 100644 --- a/arch/x86/lib/copy_user_sse2.S +++ b/arch/x86/lib/copy_user_sse2.S @@ -65,7 +65,7 @@ 203: addl %ecx,%edx/* ecx is zerorest also */ - jmp Lsse2_copy_user_handle_tail + jmp .Lsse2_copy_user_handle_tail _ASM_EXTABLE_UA(200b, 203b) _ASM_EXTABLE_UA(201b, 203b) @@ -157,7 +157,7 @@ SYM_FUNC_START(copy_user_sse2_opt_string) movl %ecx,%edx /* ecx is zerorest also */ 100: sfence - jmp Lsse2_copy_user_handle_tail + jmp .Lsse2_copy_user_handle_tail _ASM_EXTABLE_UA(10b, 100b) _ASM_EXTABLE_UA(11b, 100b) @@ -182,35 +182,6 @@ SYM_FUNC_START(copy_user_sse2_opt_string) _ASM_EXTABLE_UA(29b, 100b) _ASM_EXTABLE_UA(80b, 99b) -SYM_FUNC_END(copy_user_sse2_opt_string) -EXPORT_SYMBOL(copy_user_sse2_opt_string) - -SYM_FUNC_START(fpu_restore_xmm0_3) - ASM_STAC - movdqu (%rsi),%xmm0 - movdqu 16(%rsi),%xmm1 - movdqu 32(%rsi),%xmm2 - movdqu 48(%rsi),%xmm3 - - xorl %eax,%eax - ASM_CLAC - RET//ret -SYM_FUNC_END(fpu_restore_xmm0_3) -EXPORT_SYMBOL(fpu_restore_xmm0_3) - -SYM_FUNC_START(fpu_save_xmm0_3) - ASM_STAC - - movdqu %xmm0,(%rdi) - movdqu %xmm1,16(%rdi) - movdqu %xmm2,32(%rdi) - movdqu %xmm3,48(%rdi) - - xorl %eax,%eax - ASM_CLAC - RET//ret -SYM_FUNC_END(fpu_save_xmm0_3) -EXPORT_SYMBOL(fpu_save_xmm0_3) /* * Try to copy last bytes and clear the rest if needed. @@ -226,7 +197,7 @@ EXPORT_SYMBOL(fpu_save_xmm0_3) * Output: * eax uncopied bytes or 0 if successful. */ -SYM_CODE_START_LOCAL(Lsse2_copy_user_handle_tail) +.Lsse2_copy_user_handle_tail: movq %rdx,%rcx /* * The trap number and error code are both 32 bits. @@ -250,6 +221,34 @@ SYM_CODE_START_LOCAL(Lsse2_copy_user_handle_tail) RET _ASM_EXTABLE_UA(1b, 2b) -SYM_CODE_END(Lsse2_copy_user_handle_tail) +SYM_FUNC_END(copy_user_sse2_opt_string) +EXPORT_SYMBOL(copy_user_sse2_opt_string) + +SYM_FUNC_START(fpu_restore_xmm0_3) + ASM_STAC + movdqu (%rsi),%xmm0 + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm3 + + xorl %eax,%eax + ASM_CLAC + RET//ret +SYM_FUNC_END(fpu_restore_xmm0_3) +EXPORT_SYMBOL(fpu_restore_xmm0_3) + +SYM_FUNC_START(fpu_save_xmm0_3) + ASM_STAC + + movdqu %xmm0,(%rdi) + movdqu %xmm1,16(%rdi) + movdqu %xmm2,32(%rdi) + movdqu %xmm3,48(%rdi) + + xorl %eax,%eax + ASM_CLAC + RET//ret +SYM_FUNC_END(fpu_save_xmm0_3) +EXPORT_SYMBOL(fpu_save_xmm0_3) /*****************************************************************************/