Skip to content

Commit 2d43cc7

Browse files
committed
powerpc/uaccess: Fix build errors seen with GCC 13/14
Building ppc64le_defconfig with GCC 14 fails with assembler errors: CC fs/readdir.o /tmp/ccdQn0mD.s: Assembler messages: /tmp/ccdQn0mD.s:212: Error: operand out of domain (18 is not a multiple of 4) /tmp/ccdQn0mD.s:226: Error: operand out of domain (18 is not a multiple of 4) ... [6 lines] /tmp/ccdQn0mD.s:1699: Error: operand out of domain (18 is not a multiple of 4) A snippet of the asm shows: # ../fs/readdir.c:210: unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end); ld 9,0(29) # MEM[(u64 *)name_38(D) + _88 * 1], MEM[(u64 *)name_38(D) + _88 * 1] # 210 "../fs/readdir.c" 1 1: std 9,18(8) # put_user # *__pus_addr_52, MEM[(u64 *)name_38(D) + _88 * 1] The 'std' instruction requires a 4-byte aligned displacement because it is a DS-form instruction, and as the assembler says, 18 is not a multiple of 4. A similar error is seen with GCC 13 and CONFIG_UBSAN_SIGNED_WRAP=y. The fix is to change the constraint on the memory operand to put_user(), from "m" which is a general memory reference to "YZ". The "Z" constraint is documented in the GCC manual PowerPC machine constraints, and specifies a "memory operand accessed with indexed or indirect addressing". "Y" is not documented in the manual but specifies a "memory operand for a DS-form instruction". Using both allows the compiler to generate a DS-form "std" or X-form "stdx" as appropriate. The change has to be conditional on CONFIG_PPC_KERNEL_PREFIXED because the "Y" constraint does not guarantee 4-byte alignment when prefixed instructions are enabled. Unfortunately clang doesn't support the "Y" constraint so that has to be behind an ifdef. Although the build error is only seen with GCC 13/14, that appears to just be luck. The constraint has been incorrect since it was first added. Fixes: c20beff ("powerpc/uaccess: Use flexible addressing with __put_user()/__get_user()") Cc: stable@vger.kernel.org # v5.10+ Suggested-by: Kewen Lin <linkw@gcc.gnu.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://msgid.link/20240529123029.146953-1-mpe@ellerman.id.au
1 parent 12870ae commit 2d43cc7

File tree

1 file changed

+16
-0
lines changed

1 file changed

+16
-0
lines changed

arch/powerpc/include/asm/uaccess.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,25 @@ __pu_failed: \
9292
: label)
9393
#endif
9494

95+
#ifdef CONFIG_CC_IS_CLANG
96+
#define DS_FORM_CONSTRAINT "Z<>"
97+
#else
98+
#define DS_FORM_CONSTRAINT "YZ<>"
99+
#endif
100+
95101
#ifdef __powerpc64__
102+
#ifdef CONFIG_PPC_KERNEL_PREFIXED
96103
#define __put_user_asm2_goto(x, ptr, label) \
97104
__put_user_asm_goto(x, ptr, label, "std")
105+
#else
106+
#define __put_user_asm2_goto(x, addr, label) \
107+
asm goto ("1: std%U1%X1 %0,%1 # put_user\n" \
108+
EX_TABLE(1b, %l2) \
109+
: \
110+
: "r" (x), DS_FORM_CONSTRAINT (*addr) \
111+
: \
112+
: label)
113+
#endif // CONFIG_PPC_KERNEL_PREFIXED
98114
#else /* __powerpc64__ */
99115
#define __put_user_asm2_goto(x, addr, label) \
100116
asm goto( \

0 commit comments

Comments
 (0)