Skip to content

Commit

Permalink
xtensa: clean up inline assembly in futex.h
Browse files Browse the repository at this point in the history
Replace numeric inline assembly parameters with named parameters.
Drop unused parameters from the futex_atomic_cmpxchg_inatomic.
Use new temporary variable to hold target address in the fixup code in
futex_atomic_cmpxchg_inatomic. Conditionalize function bodies so that
only 'return -ENOSYS' is left in configurations without futex support.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
  • Loading branch information
Max Filippov committed May 7, 2019
1 parent 8f8d574 commit d065fcf
Showing 1 changed file with 42 additions and 38 deletions.
80 changes: 42 additions & 38 deletions arch/xtensa/include/asm/futex.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,59 +19,58 @@
#include <linux/uaccess.h>
#include <linux/errno.h>

#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
#define __futex_atomic_op(insn, ret, old, uaddr, arg) \
__asm__ __volatile( \
"1: l32i %0, %2, 0\n" \
"1: l32i %[oldval], %[addr], 0\n" \
insn "\n" \
" wsr %0, scompare1\n" \
"2: s32c1i %1, %2, 0\n" \
" bne %1, %0, 1b\n" \
" movi %1, 0\n" \
" wsr %[oldval], scompare1\n" \
"2: s32c1i %[newval], %[addr], 0\n" \
" bne %[newval], %[oldval], 1b\n" \
" movi %[newval], 0\n" \
"3:\n" \
" .section .fixup,\"ax\"\n" \
" .align 4\n" \
" .literal_position\n" \
"5: movi %0, 3b\n" \
" movi %1, %3\n" \
" jx %0\n" \
"5: movi %[oldval], 3b\n" \
" movi %[newval], %[fault]\n" \
" jx %[oldval]\n" \
" .previous\n" \
" .section __ex_table,\"a\"\n" \
" .long 1b,5b,2b,5b\n" \
" .long 1b, 5b, 2b, 5b\n" \
" .previous\n" \
: "=&r" (oldval), "=&r" (ret) \
: "r" (uaddr), "I" (-EFAULT), "r" (oparg) \
: [oldval] "=&r" (old), [newval] "=&r" (ret) \
: [addr] "r" (uaddr), [oparg] "r" (arg), \
[fault] "I" (-EFAULT) \
: "memory")

static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
u32 __user *uaddr)
{
#if XCHAL_HAVE_S32C1I
int oldval = 0, ret;

#if !XCHAL_HAVE_S32C1I
return -ENOSYS;
#endif

pagefault_disable();

switch (op) {
case FUTEX_OP_SET:
__futex_atomic_op("mov %1, %4", ret, oldval, uaddr, oparg);
__futex_atomic_op("mov %[newval], %[oparg]",
ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_ADD:
__futex_atomic_op("add %1, %0, %4", ret, oldval, uaddr,
oparg);
__futex_atomic_op("add %[newval], %[oldval], %[oparg]",
ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_OR:
__futex_atomic_op("or %1, %0, %4", ret, oldval, uaddr,
oparg);
__futex_atomic_op("or %[newval], %[oldval], %[oparg]",
ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_ANDN:
__futex_atomic_op("and %1, %0, %4", ret, oldval, uaddr,
~oparg);
__futex_atomic_op("and %[newval], %[oldval], %[oparg]",
ret, oldval, uaddr, ~oparg);
break;
case FUTEX_OP_XOR:
__futex_atomic_op("xor %1, %0, %4", ret, oldval, uaddr,
oparg);
__futex_atomic_op("xor %[newval], %[oldval], %[oparg]",
ret, oldval, uaddr, oparg);
break;
default:
ret = -ENOSYS;
Expand All @@ -83,42 +82,47 @@ static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
*oval = oldval;

return ret;
#else
return -ENOSYS;
#endif
}

static inline int
futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
u32 oldval, u32 newval)
{
#if XCHAL_HAVE_S32C1I
unsigned long tmp;
int ret = 0;

if (!access_ok(uaddr, sizeof(u32)))
return -EFAULT;

#if !XCHAL_HAVE_S32C1I
return -ENOSYS;
#endif

__asm__ __volatile__ (
" # futex_atomic_cmpxchg_inatomic\n"
" wsr %5, scompare1\n"
"1: s32c1i %1, %4, 0\n"
" s32i %1, %6, 0\n"
" wsr %[oldval], scompare1\n"
"1: s32c1i %[newval], %[addr], 0\n"
" s32i %[newval], %[uval], 0\n"
"2:\n"
" .section .fixup,\"ax\"\n"
" .align 4\n"
" .literal_position\n"
"4: movi %1, 2b\n"
" movi %0, %7\n"
" jx %1\n"
"4: movi %[tmp], 2b\n"
" movi %[ret], %[fault]\n"
" jx %[tmp]\n"
" .previous\n"
" .section __ex_table,\"a\"\n"
" .long 1b,4b\n"
" .long 1b, 4b\n"
" .previous\n"
: "+r" (ret), "+r" (newval), "+m" (*uaddr), "+m" (*uval)
: "r" (uaddr), "r" (oldval), "r" (uval), "I" (-EFAULT)
: [ret] "+r" (ret), [newval] "+r" (newval), [tmp] "=&r" (tmp)
: [addr] "r" (uaddr), [oldval] "r" (oldval), [uval] "r" (uval),
[fault] "I" (-EFAULT)
: "memory");

return ret;
#else
return -ENOSYS;
#endif
}

#endif /* _ASM_XTENSA_FUTEX_H */

0 comments on commit d065fcf

Please sign in to comment.