1
0
Files
kernel-49/arch/powerpc/include/asm/futex.h
Greg Kroah-Hartman e986e9737d Merge 4.9.245 into android-4.9-q
Changes in 4.9.245
	powerpc/64s: Define MASKABLE_RELON_EXCEPTION_PSERIES_OOL
	powerpc/64s: move some exception handlers out of line
	powerpc/64s: flush L1D on kernel entry
	powerpc: Add a framework for user access tracking
	powerpc: Implement user_access_begin and friends
	powerpc: Fix __clear_user() with KUAP enabled
	powerpc/uaccess: Evaluate macro arguments once, before user access is allowed
	powerpc/64s: flush L1D after user accesses
	i2c: imx: use clk notifier for rate changes
	i2c: imx: Fix external abort on interrupt in exit paths
	i2c: mux: pca954x: Add missing pca9546 definition to chip_desc
	powerpc/8xx: Always fault when _PAGE_ACCESSED is not set
	Input: sunkbd - avoid use-after-free in teardown paths
	mac80211: always wind down STA state
	KVM: x86: clflushopt should be treated as a no-op by emulation
	ACPI: GED: fix -Wformat
	Linux 4.9.245

Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: I688b066e99eeb16270414e0c4cb4dc3bb244486c
2020-11-25 18:21:48 +03:00

109 lines
2.5 KiB
C

#ifndef _ASM_POWERPC_FUTEX_H
#define _ASM_POWERPC_FUTEX_H
#ifdef __KERNEL__
#include <linux/futex.h>
#include <linux/uaccess.h>
#include <asm/errno.h>
#include <asm/synch.h>
#include <asm/asm-compat.h>
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
__asm__ __volatile ( \
PPC_ATOMIC_ENTRY_BARRIER \
"1: lwarx %0,0,%2\n" \
insn \
PPC405_ERR77(0, %2) \
"2: stwcx. %1,0,%2\n" \
"bne- 1b\n" \
PPC_ATOMIC_EXIT_BARRIER \
"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" \
PPC_LONG "1b,4b,2b,4b\n" \
".previous" \
: "=&r" (oldval), "=&r" (ret) \
: "b" (uaddr), "i" (-EFAULT), "r" (oparg) \
: "cr0", "memory")
static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
u32 __user *uaddr)
{
int oldval = 0, ret;
allow_write_to_user(uaddr, sizeof(*uaddr));
pagefault_disable();
switch (op) {
case FUTEX_OP_SET:
__futex_atomic_op("mr %1,%4\n", ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_ADD:
__futex_atomic_op("add %1,%0,%4\n", ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_OR:
__futex_atomic_op("or %1,%0,%4\n", ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_ANDN:
__futex_atomic_op("andc %1,%0,%4\n", ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_XOR:
__futex_atomic_op("xor %1,%0,%4\n", ret, oldval, uaddr, oparg);
break;
default:
ret = -ENOSYS;
}
pagefault_enable();
*oval = oldval;
prevent_write_to_user(uaddr, sizeof(*uaddr));
return ret;
}
static inline int
futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
u32 oldval, u32 newval)
{
int ret = 0;
u32 prev;
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
return -EFAULT;
allow_write_to_user(uaddr, sizeof(*uaddr));
__asm__ __volatile__ (
PPC_ATOMIC_ENTRY_BARRIER
"1: lwarx %1,0,%3 # futex_atomic_cmpxchg_inatomic\n\
cmpw 0,%1,%4\n\
bne- 3f\n"
PPC405_ERR77(0,%3)
"2: stwcx. %5,0,%3\n\
bne- 1b\n"
PPC_ATOMIC_EXIT_BARRIER
"3: .section .fixup,\"ax\"\n\
4: li %0,%6\n\
b 3b\n\
.previous\n\
.section __ex_table,\"a\"\n\
.align 3\n\
" PPC_LONG "1b,4b,2b,4b\n\
.previous" \
: "+r" (ret), "=&r" (prev), "+m" (*uaddr)
: "r" (uaddr), "r" (oldval), "r" (newval), "i" (-EFAULT)
: "cc", "memory");
*uval = prev;
prevent_write_to_user(uaddr, sizeof(*uaddr));
return ret;
}
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_FUTEX_H */