diff options
author | Rich Felker <dalias@libc.org> | 2016-04-26 00:58:03 +0300 |
---|---|---|
committer | Rich Felker <dalias@libc.org> | 2016-08-05 06:29:36 +0300 |
commit | 00b73d8d1b7131da03aec73011a7286f566fe87f (patch) | |
tree | 5a557b49eeaa1717bba015c730c5a56e8d084985 /arch/sh/include/asm/futex-llsc.h | |
parent | 2b47d54ed41c33baf5825185168b493317c5572f (diff) | |
download | linux-00b73d8d1b7131da03aec73011a7286f566fe87f.tar.xz |
sh: add working futex atomic ops on userspace addresses for smp
The version of futex.h in asm-generic should really be adapted to do
the same thing so that this hideous code does not have to be
duplicated per-arch.
Signed-off-by: Rich Felker <dalias@libc.org>
Diffstat (limited to 'arch/sh/include/asm/futex-llsc.h')
-rw-r--r-- | arch/sh/include/asm/futex-llsc.h | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/arch/sh/include/asm/futex-llsc.h b/arch/sh/include/asm/futex-llsc.h new file mode 100644 index 000000000000..23591703bec0 --- /dev/null +++ b/arch/sh/include/asm/futex-llsc.h @@ -0,0 +1,41 @@ +#ifndef __ASM_SH_FUTEX_LLSC_H +#define __ASM_SH_FUTEX_LLSC_H + +static inline int atomic_futex_op_cmpxchg_inatomic(u32 *uval, + u32 __user *uaddr, + u32 oldval, u32 newval) +{ + int err = 0; + __asm__ __volatile__( + "synco\n" + "1:\n\t" + "movli.l @%2, r0\n\t" + "mov r0, %1\n\t" + "cmp/eq %1, %4\n\t" + "bf 2f\n\t" + "mov %5, r0\n\t" + "movco.l r0, @%2\n\t" + "bf 1b\n" + "2:\n\t" + "synco\n\t" +#ifdef CONFIG_MMU + ".section .fixup,\"ax\"\n" + "3:\n\t" + "mov.l 4f, %0\n\t" + "jmp @%0\n\t" + " mov %3, %0\n\t" + ".balign 4\n" + "4: .long 2b\n\t" + ".previous\n" + ".section __ex_table,\"a\"\n\t" + ".long 1b, 3b\n\t" + ".previous" +#endif + :"+r" (err), "=&r" (*uval) + :"r" (uaddr), "i" (-EFAULT), "r" (oldval), "r" (newval) + :"t", "memory", "r0"); + if (err) return err; + return 0; +} + +#endif /* __ASM_SH_FUTEX_LLSC_H */ |