On Mon, Nov 24, 2014 at 2:58 PM, Alexei Starovoitov <alexei.starovoitov@xxxxxxxxx> wrote: > > I've changed gcc pr58145-1.c reproducer to use > __read_once_size() approach above I don't think you did. > modified reproducer: > struct S { unsigned int data; }; > void bar(int val) > { > struct S _s = { .data = val }; > *(volatile struct S *) 0x880000UL = ACCESS_ONCE(&_s); > } My approach never had "volatile struct S *". The only volatile pointers were the actual byte/word/etc pointers, and those generated temporary values that were then assigned to the final type through a cast. Also, note that the kernel is compiled without strict aliasing, so the casting to 'void *' and various smaller types is "safe" - even if the C standard doesn't like it. With strict aliasing, you'd need to make the read_once() macro not just pass in the size, there would have to be some kind of union of the type, and that would effectively mean that you can't use an inline function, you'd have to do it in a big macro (because the type would be per-site). So with strict aliasing, you'd have to make it something like #define ACCESS_ONCE(p) \ ({ union { typeof(*p) __val; char __array[sizeof(*p)]} __u; __read_once_size(p, __u.__array, sizeof(__u)); __u.__val; }) Pretty? No. But then, the standard C aliasing rules are so broken that "pretty" doesn't really come into play.. Linus -- To unsubscribe from this list: send the line "unsubscribe linux-x86_64" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html