lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Thu, 2 Nov 2017 16:28:45 -0400 (EDT) From: Alan Stern <stern@...land.harvard.edu> To: Andrea Parri <parri.andrea@...il.com> cc: Peter Zijlstra <peterz@...radead.org>, "Reshetova, Elena" <elena.reshetova@...el.com>, "linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>, "gregkh@...uxfoundation.org" <gregkh@...uxfoundation.org>, "keescook@...omium.org" <keescook@...omium.org>, "tglx@...utronix.de" <tglx@...utronix.de>, "mingo@...hat.com" <mingo@...hat.com>, "ishkamiel@...il.com" <ishkamiel@...il.com>, Will Deacon <will.deacon@....com>, Paul McKenney <paulmck@...ux.vnet.ibm.com>, <boqun.feng@...il.com>, <dhowells@...hat.com>, <david@...morbit.com> Subject: Re: [PATCH] refcount: provide same memory ordering guarantees as in atomic_t On Thu, 2 Nov 2017, Andrea Parri wrote: > > This is forbidden. It would remain forbidden even if the smp_mb in P1 > > were replaced by a similar release/acquire pair for the same memory > > location. > > Hopefully, the LKMM does not agree with this assessment... ;-) No, it doesn't. > Here's a two-threads example showing that "(w)mb is _not_ rfi-rel-acq": > > C rfi-rel-acq-is-not-mb > > {} > > P0(int *x, int *y, int *a) > { > WRITE_ONCE(*x, 1); > smp_store_release(a, 1); > r1 = smp_load_acquire(a); > WRITE_ONCE(*y, 1); > } > > P1(int *x, int *y) > { > int r0; > int r1; > > r0 = READ_ONCE(*y); > smp_rmb(); > r1 = READ_ONCE(*x); > } > > exists (1:r0=1 /\ 1:r1=0) Right. There is a happens-before edge between the two WRITE_ONCE calls in P0 but no cumul-fence edge, and therefore the test is allowed. Here is an example where a happens-before edge suffices to provide ordering: P0(int *x, int *y) { WRITE_ONCE(*x, 1); smp_wmb(); WRITE_ONCE(*y, 1); } P1(int *x, int *y, int *a) { int rx, ry, ra; ry = READ_ONCE(*y); smp_store_release(a, 1); ra = smp_load_acquire(a); rx = READ_ONCE(*x); } exists (1:rx=0 /\ 1:ry=1) This test is forbidden, but it would be allowed if the release and acquire accessed different locations. Alan Stern
Powered by blists - more mailing lists