Skip to content

Commit

Permalink
s390/cmpxchg: fix 1 and 2 byte memory accesses
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Heiko Carstens authored and Martin Schwidefsky committed May 30, 2012
1 parent 6b894a4 commit bf3db85
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions arch/s390/include/asm/cmpxchg.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand Down

0 comments on commit bf3db85

Please sign in to comment.