On Fri, Apr 24, 2020 at 06:31:35PM +0200, Jann Horn wrote: > On Tue, Apr 21, 2020 at 5:15 PM Will Deacon <will@xxxxxxxxxx> wrote: > > {READ,WRITE}_ONCE() cannot guarantee atomicity for arbitrary data sizes. > > This can be surprising to callers that might incorrectly be expecting > > atomicity for accesses to aggregate structures, although there are other > > callers where tearing is actually permissable (e.g. if they are using > > something akin to sequence locking to protect the access). > [...] > > The slight snag is that we also have to support 64-bit accesses on 32-bit > > architectures, as these appear to be widespread and tend to work out ok > > if either the architecture supports atomic 64-bit accesses (x86, armv7) > > or if the variable being accesses represents a virtual address and > > therefore only requires 32-bit atomicity in practice. > > > > Take a step in that direction by introducing a variant of > > 'compiletime_assert_atomic_type()' and use it to check the pointer > > argument to {READ,WRITE}_ONCE(). Expose __{READ,WRITE}_ONCE() variants > > which are allowed to tear and convert the one broken caller over to the > > new macros. > [...] > > +/* > > + * Yes, this permits 64-bit accesses on 32-bit architectures. These will > > + * actually be atomic in many cases (namely x86), but for others we rely on > > I don't think that's correct? [...] > AFAIK 32-bit X86 code that wants to atomically load 8 bytes of memory > has to use CMPXCHG8B; and gcc won't generate such code just based on a > volatile load/store. My apologies, you're completely right. I thought that PAE mandated 64-bit atomicity, like it does on 32-bit ARM, but that's apparently not the case and looking at the 32-bit x86 pgtable code they have to be really careful there. I'll update the comment. Will