[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20180528100253.960186828@linuxfoundation.org>
Date: Mon, 28 May 2018 12:01:05 +0200
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org, Will Deacon <will.deacon@....com>,
Andrea Parri <parri.andrea@...il.com>,
"Paul E. McKenney" <paulmck@...ux.vnet.ibm.com>,
Alan Stern <stern@...land.harvard.edu>,
Andrew Morton <akpm@...ux-foundation.org>,
Ivan Kokshaysky <ink@...assic.park.msu.ru>,
Linus Torvalds <torvalds@...ux-foundation.org>,
Matt Turner <mattst88@...il.com>,
Peter Zijlstra <peterz@...radead.org>,
Richard Henderson <rth@...ddle.net>,
Thomas Gleixner <tglx@...utronix.de>,
linux-alpha@...r.kernel.org, Ingo Molnar <mingo@...nel.org>,
Sasha Levin <alexander.levin@...rosoft.com>
Subject: [PATCH 4.9 136/329] locking/xchg/alpha: Fix xchg() and cmpxchg() memory ordering bugs
4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrea Parri <parri.andrea@...il.com>
[ Upstream commit 472e8c55cf6622d1c112dc2bc777f68bbd4189db ]
Successful RMW operations are supposed to be fully ordered, but
Alpha's xchg() and cmpxchg() do not meet this requirement.
Will Deacon noticed the bug:
> So MP using xchg:
>
> WRITE_ONCE(x, 1)
> xchg(y, 1)
>
> smp_load_acquire(y) == 1
> READ_ONCE(x) == 0
>
> would be allowed.
... which thus violates the above requirement.
Fix it by adding a leading smp_mb() to the xchg() and cmpxchg() implementations.
Reported-by: Will Deacon <will.deacon@....com>
Signed-off-by: Andrea Parri <parri.andrea@...il.com>
Acked-by: Paul E. McKenney <paulmck@...ux.vnet.ibm.com>
Cc: Alan Stern <stern@...land.harvard.edu>
Cc: Andrew Morton <akpm@...ux-foundation.org>
Cc: Ivan Kokshaysky <ink@...assic.park.msu.ru>
Cc: Linus Torvalds <torvalds@...ux-foundation.org>
Cc: Matt Turner <mattst88@...il.com>
Cc: Peter Zijlstra <peterz@...radead.org>
Cc: Richard Henderson <rth@...ddle.net>
Cc: Thomas Gleixner <tglx@...utronix.de>
Cc: linux-alpha@...r.kernel.org
Link: http://lkml.kernel.org/r/1519291488-5752-1-git-send-email-parri.andrea@gmail.com
Signed-off-by: Ingo Molnar <mingo@...nel.org>
Signed-off-by: Sasha Levin <alexander.levin@...rosoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
arch/alpha/include/asm/xchg.h | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
--- a/arch/alpha/include/asm/xchg.h
+++ b/arch/alpha/include/asm/xchg.h
@@ -11,6 +11,10 @@
* Atomic exchange.
* Since it can be used to implement critical sections
* it must clobber "memory" (also for interrupts in UP).
+ *
+ * The leading and the trailing memory barriers guarantee that these
+ * operations are fully ordered.
+ *
*/
static inline unsigned long
@@ -18,6 +22,7 @@ ____xchg(_u8, volatile char *m, unsigned
{
unsigned long ret, tmp, addr64;
+ smp_mb();
__asm__ __volatile__(
" andnot %4,7,%3\n"
" insbl %1,%4,%1\n"
@@ -42,6 +47,7 @@ ____xchg(_u16, volatile short *m, unsign
{
unsigned long ret, tmp, addr64;
+ smp_mb();
__asm__ __volatile__(
" andnot %4,7,%3\n"
" inswl %1,%4,%1\n"
@@ -66,6 +72,7 @@ ____xchg(_u32, volatile int *m, unsigned
{
unsigned long dummy;
+ smp_mb();
__asm__ __volatile__(
"1: ldl_l %0,%4\n"
" bis $31,%3,%1\n"
@@ -86,6 +93,7 @@ ____xchg(_u64, volatile long *m, unsigne
{
unsigned long dummy;
+ smp_mb();
__asm__ __volatile__(
"1: ldq_l %0,%4\n"
" bis $31,%3,%1\n"
@@ -127,9 +135,12 @@ ____xchg(, volatile void *ptr, unsigned
* store NEW in MEM. Return the initial value in MEM. Success is
* indicated by comparing RETURN with OLD.
*
- * The memory barrier is placed in SMP unconditionally, in order to
- * guarantee that dependency ordering is preserved when a dependency
- * is headed by an unsuccessful operation.
+ * The leading and the trailing memory barriers guarantee that these
+ * operations are fully ordered.
+ *
+ * The trailing memory barrier is placed in SMP unconditionally, in
+ * order to guarantee that dependency ordering is preserved when a
+ * dependency is headed by an unsuccessful operation.
*/
static inline unsigned long
@@ -137,6 +148,7 @@ ____cmpxchg(_u8, volatile char *m, unsig
{
unsigned long prev, tmp, cmp, addr64;
+ smp_mb();
__asm__ __volatile__(
" andnot %5,7,%4\n"
" insbl %1,%5,%1\n"
@@ -164,6 +176,7 @@ ____cmpxchg(_u16, volatile short *m, uns
{
unsigned long prev, tmp, cmp, addr64;
+ smp_mb();
__asm__ __volatile__(
" andnot %5,7,%4\n"
" inswl %1,%5,%1\n"
@@ -191,6 +204,7 @@ ____cmpxchg(_u32, volatile int *m, int o
{
unsigned long prev, cmp;
+ smp_mb();
__asm__ __volatile__(
"1: ldl_l %0,%5\n"
" cmpeq %0,%3,%1\n"
@@ -214,6 +228,7 @@ ____cmpxchg(_u64, volatile long *m, unsi
{
unsigned long prev, cmp;
+ smp_mb();
__asm__ __volatile__(
"1: ldq_l %0,%5\n"
" cmpeq %0,%3,%1\n"
Powered by blists - more mailing lists