From cdabc5f7542fe26b530f68c0adc17731518e5b1c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 29 May 2012 10:11:21 +0200 Subject: [PATCH] s390/cmpxchg: fix 1 and 2 byte memory accesses When accessing a 1 or 2 byte memory operand we cannot use the passed address since the compare and swap instruction only works for 4 byte aligned memory operands. Hence we calculate an aligned address so that compare and swap works correctly. However we don't pass the calculated address to the inline assembly. This results in incorrect memory accesses and in a specification exception if used on non 4 byte aligned memory operands. Since this didn't happen until now, there don't seem to be too many users of cmpxchg on unaligned addresses. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/cmpxchg.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/s390/include/asm/cmpxchg.h b/arch/s390/include/asm/cmpxchg.h index 13c8b2eb6983f..26f2cb1aa9ff3 100644 --- a/arch/s390/include/asm/cmpxchg.h +++ b/arch/s390/include/asm/cmpxchg.h @@ -113,9 +113,9 @@ static inline unsigned long __cmpxchg(void *ptr, unsigned long old, " nr %1,%5\n" " jnz 0b\n" "1:" - : "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr) + : "=&d" (prev), "=&d" (tmp), "+Q" (*(int *) addr) : "d" (old << shift), "d" (new << shift), - "d" (~(255 << shift)), "Q" (*(int *) ptr) + "d" (~(255 << shift)) : "memory", "cc"); return prev >> shift; case 2: @@ -134,9 +134,9 @@ static inline unsigned long __cmpxchg(void *ptr, unsigned long old, " nr %1,%5\n" " jnz 0b\n" "1:" - : "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr) + : "=&d" (prev), "=&d" (tmp), "+Q" (*(int *) addr) : "d" (old << shift), "d" (new << shift), - "d" (~(65535 << shift)), "Q" (*(int *) ptr) + "d" (~(65535 << shift)) : "memory", "cc"); return prev >> shift; case 4: -- 2.39.5