https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86673
Arnd Bergmann <arnd at linaro dot org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |mkuvyrkov at gcc dot gnu.org --- Comment #2 from Arnd Bergmann <arnd at linaro dot org> --- Forcing constant inputs for put_user to be read from a volatile variable avoids this problem and lets me cleanly build all files that showed it. diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h index 35c9db857ebe..23e92a9a5ef4 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h @@ -251,7 +251,8 @@ extern int __put_user_8(void *, unsigned long long); ({ \ unsigned long __limit = current_thread_info()->addr_limit - 1; \ const typeof(*(p)) __user *__tmp_p = (p); \ - register const typeof(*(p)) __r2 asm("r2") = (x); \ + const typeof(*(p)) __x = (x); \ + register const typeof(*(p)) __r2 asm("r2") = READ_ONCE(__x); \ register const typeof(*(p)) __user *__p asm("r0") = __tmp_p; \ register unsigned long __l asm("r1") = __limit; \ register int __e asm("r0"); \ This confirms that constant inputs are what leads to the problem.