mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 13:41:51 +00:00
[PATCH] powerpc: Merge futex.h
This patch merges the ppc32 and ppc64 versions of futex.h, essentially by taking the ppc64 version as the powerpc version. The old ppc32 version did not implement the futex_atomic_op_inuser() callback (it always returned -ENOSYS), so FUTEX_WAKE_OP would not work on ppc32. In fact the ppc64 version of this function is almost suitable for ppc32 as well - the only change needed is to extend ppc_asm.h with a macro expanding to to the right pseudo-op to store a pointer (either ".long" or ".llong"). Built and booted on pSeries. Built for 32-bit powermac. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
parent
847aeb6bad
commit
2ff2ae7a0d
@ -1,5 +1,5 @@
|
||||
#ifndef _ASM_FUTEX_H
|
||||
#define _ASM_FUTEX_H
|
||||
#ifndef _ASM_POWERPC_FUTEX_H
|
||||
#define _ASM_POWERPC_FUTEX_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
@ -7,28 +7,29 @@
|
||||
#include <asm/errno.h>
|
||||
#include <asm/synch.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/ppc_asm.h>
|
||||
|
||||
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
|
||||
__asm__ __volatile (SYNC_ON_SMP \
|
||||
"1: lwarx %0,0,%2\n" \
|
||||
insn \
|
||||
"2: stwcx. %1,0,%2\n\
|
||||
bne- 1b\n\
|
||||
li %1,0\n\
|
||||
3: .section .fixup,\"ax\"\n\
|
||||
4: li %1,%3\n\
|
||||
b 3b\n\
|
||||
.previous\n\
|
||||
.section __ex_table,\"a\"\n\
|
||||
.align 3\n\
|
||||
.llong 1b,4b,2b,4b\n\
|
||||
.previous" \
|
||||
: "=&r" (oldval), "=&r" (ret) \
|
||||
: "b" (uaddr), "i" (-EFAULT), "1" (oparg) \
|
||||
__asm__ __volatile ( \
|
||||
SYNC_ON_SMP \
|
||||
"1: lwarx %0,0,%2\n" \
|
||||
insn \
|
||||
"2: stwcx. %1,0,%2\n" \
|
||||
"bne- 1b\n" \
|
||||
"li %1,0\n" \
|
||||
"3: .section .fixup,\"ax\"\n" \
|
||||
"4: li %1,%3\n" \
|
||||
"b 3b\n" \
|
||||
".previous\n" \
|
||||
".section __ex_table,\"a\"\n" \
|
||||
".align 3\n" \
|
||||
DATAL " 1b,4b,2b,4b\n" \
|
||||
".previous" \
|
||||
: "=&r" (oldval), "=&r" (ret) \
|
||||
: "b" (uaddr), "i" (-EFAULT), "1" (oparg) \
|
||||
: "cr0", "memory")
|
||||
|
||||
static inline int
|
||||
futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
|
||||
static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
@ -79,5 +80,5 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _ASM_POWERPC_FUTEX_H */
|
@ -506,6 +506,13 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
|
||||
#else
|
||||
#define __ASM_CONST(x) x##UL
|
||||
#define ASM_CONST(x) __ASM_CONST(x)
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
#define DATAL ".llong"
|
||||
#else
|
||||
#define DATAL ".long"
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_POWERPC_PPC_ASM_H */
|
||||
|
@ -1,53 +0,0 @@
|
||||
#ifndef _ASM_FUTEX_H
|
||||
#define _ASM_FUTEX_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/futex.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
static inline int
|
||||
futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret;
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
|
||||
return -EFAULT;
|
||||
|
||||
inc_preempt_count();
|
||||
|
||||
switch (op) {
|
||||
case FUTEX_OP_SET:
|
||||
case FUTEX_OP_ADD:
|
||||
case FUTEX_OP_OR:
|
||||
case FUTEX_OP_ANDN:
|
||||
case FUTEX_OP_XOR:
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
}
|
||||
|
||||
dec_preempt_count();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user