diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2006-06-08 01:36:20 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-08 15:15:30 -0700 |
commit | bafe00cc9297ca77b66e5c83e5e65e17c0c997c8 (patch) | |
tree | c0478b45a084464c515a3201b109d7589773670b /include | |
parent | 71601e2b33dad9acb8d7844f7321f90ed9d1bce8 (diff) | |
download | op-kernel-dev-bafe00cc9297ca77b66e5c83e5e65e17c0c997c8.zip op-kernel-dev-bafe00cc9297ca77b66e5c83e5e65e17c0c997c8.tar.gz |
[PATCH] s390: fix in-user atomic futex operation.
From: Martin Schwidefsky <schwidefsky@de.ibm.com>
__futex_atomic_op needs to do an atomic operation in the user address space,
not the kernel address space. Add the missing sacf 256/sacf 0 to switch to
the secondary mode before doing the compare-and-swap. In addition add
another fixup for catch specification exceptions if the compare-and-swap
address is not aligned.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-s390/futex.h | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/include/asm-s390/futex.h b/include/asm-s390/futex.h index 40c25e1..1802775 100644 --- a/include/asm-s390/futex.h +++ b/include/asm-s390/futex.h @@ -11,23 +11,24 @@ #define __futex_atomic_fixup \ ".section __ex_table,\"a\"\n" \ " .align 4\n" \ - " .long 0b,2b,1b,2b\n" \ + " .long 0b,4b,2b,4b,3b,4b\n" \ ".previous" #else /* __s390x__ */ #define __futex_atomic_fixup \ ".section __ex_table,\"a\"\n" \ " .align 8\n" \ - " .quad 0b,2b,1b,2b\n" \ + " .quad 0b,4b,2b,4b,3b,4b\n" \ ".previous" #endif /* __s390x__ */ #define __futex_atomic_op(insn, ret, oldval, newval, uaddr, oparg) \ - asm volatile(" l %1,0(%6)\n" \ - "0: " insn \ - " cs %1,%2,0(%6)\n" \ - "1: jl 0b\n" \ + asm volatile(" sacf 256\n" \ + "0: l %1,0(%6)\n" \ + "1: " insn \ + "2: cs %1,%2,0(%6)\n" \ + "3: jl 1b\n" \ " lhi %0,0\n" \ - "2:\n" \ + "4: sacf 0\n" \ __futex_atomic_fixup \ : "=d" (ret), "=&d" (oldval), "=&d" (newval), \ "=m" (*uaddr) \ |