瀏覽代碼

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 <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Heiko Carstens 13 年之前
父節點
當前提交
bf3db85311
共有 1 個文件被更改,包括 4 次插入4 次删除
  1. 4 4
      arch/s390/include/asm/cmpxchg.h

+ 4 - 4
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: