On Thu, 11 Jan 2024 at 15:57, Guenter Roeck <linux@xxxxxxxxxxxx> wrote: > > I wonder if something may be wrong with the definition and use of __m > for u64 accesses. The code below also fixes the build problem. Ok, that looks like the right workaround. > But then I really don't know what > > struct __large_struct { unsigned long buf[100]; }; > #define __m(x) (*(struct __large_struct __user *)(x)) This is a historical pattern we've used because the gcc docs weren't 100% clear on what "m" does, and whether it might for example end up loading the value from memory into a register, spilling it to the stack, and then using the stack address... Using the whole "tell the compiler it accesses a big structure" turns the memory access into "BLKmode" (in gcc terms) and makes sure that never happens. NOTE! I'm not sure it ever did happen with gcc, but we have literally seen clang do that "load from memory, spill to stack, and then use the stack address for the asm". Crazy, I know. See https://lore.kernel.org/all/CAHk-=wgobnShg4c2yyMbk2p=U-wmnOmX_0=b3ZY_479Jjey2xw@xxxxxxxxxxxxxx/ where I point to clang doing basically exactly that with the "rm" constraint for another case entirely. I consider it a clang bug, but happily I've never seen the "load only to spill" in a case where the "stupid code generation" turned into "actively buggy code generation". If it ever does, we may need to turn the "m" into a "p" and a memory clobber, which will generate horrendous code. Or we may just need to tell clang developers that enough is enough, and that they actually need to take the asm constraints more seriously. Linus