/* * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Vineetg: August 2010: From Android kernel work */ #ifndef _ASM_FUTEX_H #define _ASM_FUTEX_H #include <linux/futex.h> #include <linux/preempt.h> #include <linux/uaccess.h> #include <asm/errno.h> #ifdef CONFIG_ARC_HAS_LLSC #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)\ \ smp_mb(); \ __asm__ __volatile__( \ "1: llock %1, [%2] \n" \ insn "\n" \ "2: scond %0, [%2] \n" \ " bnz 1b \n" \ " mov %0, 0 \n" \ "3: \n" \ " .section .fixup,\"ax\" \n" \ " .align 4 \n" \ "4: mov %0, %4 \n" \ " j 3b \n" \ " .previous \n" \ " .section __ex_table,\"a\" \n" \ " .align 4 \n" \ " .word 1b, 4b \n" \ " .word 2b, 4b \n" \ " .previous \n" \ \ : "=&r" (ret), "=&r" (oldval) \ : "r" (uaddr), "r" (oparg), "ir" (-EFAULT) \ : "cc", "memory"); \ smp_mb() \ #else /* !CONFIG_ARC_HAS_LLSC */ #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)\ \ smp_mb(); \ __asm__ __volatile__( \ "1: ld %1, [%2] \n" \ insn "\n" \ "2: st %0, [%2] \n" \ " mov %0, 0 \n" \ "3: \n" \ " .section .fixup,\"ax\" \n" \ " .align 4 \n" \ "4: mov %0, %4 \n" \ " j 3b \n" \ " .previous \n" \ " .section __ex_table,\"a\" \n" \ " .align 4 \n" \ " .word 1b, 4b \n" \ " .word 2b, 4b \n" \ " .previous \n" \ \ : "=&r" (ret), "=&r" (oldval) \ : "r" (uaddr), "r" (oparg), "ir" (-EFAULT) \ : "cc", "memory"); \ smp_mb() \ #endif static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { int oldval = 0, ret; #ifndef CONFIG_ARC_HAS_LLSC preempt_disable(); /* to guarantee atomic r-m-w of futex op */ #endif pagefault_disable(); switch (op) { case FUTEX_OP_SET: __futex_atomic_op("mov %0, %3", ret, oldval, uaddr, oparg); break; case FUTEX_OP_ADD: /* oldval = *uaddr; *uaddr += oparg ; ret = *uaddr */ __futex_atomic_op("add %0, %1, %3", ret, oldval, uaddr, oparg); break; case FUTEX_OP_OR: __futex_atomic_op("or %0, %1, %3", ret, oldval, uaddr, oparg); break; case FUTEX_OP_ANDN: __futex_atomic_op("bic %0, %1, %3", ret, oldval, uaddr, oparg); break; case FUTEX_OP_XOR: __futex_atomic_op("xor %0, %1, %3", ret, oldval, uaddr, oparg); break; default: ret = -ENOSYS; } pagefault_enable(); #ifndef CONFIG_ARC_HAS_LLSC preempt_enable(); #endif if (!ret) *oval = oldval; return ret; } /* * cmpxchg of futex (pagefaults disabled by caller) * Return 0 for success, -EFAULT otherwise */ static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 expval, u32 newval) { int ret = 0; u32 existval; if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) return -EFAULT; #ifndef CONFIG_ARC_HAS_LLSC preempt_disable(); /* to guarantee atomic r-m-w of futex op */ #endif smp_mb(); __asm__ __volatile__( #ifdef CONFIG_ARC_HAS_LLSC "1: llock %1, [%4] \n" " brne %1, %2, 3f \n" "2: scond %3, [%4] \n" " bnz 1b \n" #else "1: ld %1, [%4] \n" " brne %1, %2, 3f \n" "2: st %3, [%4] \n" #endif "3: \n" " .section .fixup,\"ax\" \n" "4: mov %0, %5 \n" " j 3b \n" " .previous \n" " .section __ex_table,\"a\" \n" " .align 4 \n" " .word 1b, 4b \n" " .word 2b, 4b \n" " .previous\n" : "+&r"(ret), "=&r"(existval) : "r"(expval), "r"(newval), "r"(uaddr), "ir"(-EFAULT) : "cc", "memory"); smp_mb(); #ifndef CONFIG_ARC_HAS_LLSC preempt_enable(); #endif *uval = existval; return ret; } #endif
Name | Type | Size | Permission | Actions |
---|---|---|---|---|
Kbuild | File | 681 B | 0644 |
|
arcregs.h | File | 8.59 KB | 0644 |
|
asm-offsets.h | File | 311 B | 0644 |
|
atomic.h | File | 15.14 KB | 0644 |
|
barrier.h | File | 1.75 KB | 0644 |
|
bitops.h | File | 9.81 KB | 0644 |
|
bug.h | File | 938 B | 0644 |
|
cache.h | File | 3.77 KB | 0644 |
|
cacheflush.h | File | 3.88 KB | 0644 |
|
checksum.h | File | 2.45 KB | 0644 |
|
cmpxchg.h | File | 5.4 KB | 0644 |
|
current.h | File | 695 B | 0644 |
|
delay.h | File | 1.99 KB | 0644 |
|
disasm.h | File | 3.87 KB | 0644 |
|
dma-mapping.h | File | 734 B | 0644 |
|
dma.h | File | 459 B | 0644 |
|
dwarf.h | File | 892 B | 0644 |
|
elf.h | File | 2.15 KB | 0644 |
|
entry-arcv2.h | File | 4.85 KB | 0644 |
|
entry-compact.h | File | 9.29 KB | 0644 |
|
entry.h | File | 6.73 KB | 0644 |
|
exec.h | File | 410 B | 0644 |
|
fb.h | File | 411 B | 0644 |
|
futex.h | File | 3.67 KB | 0644 |
|
highmem.h | File | 1.46 KB | 0644 |
|
hugepage.h | File | 2.41 KB | 0644 |
|
io.h | File | 6.43 KB | 0644 |
|
irq.h | File | 825 B | 0644 |
|
irqflags-arcv2.h | File | 3.45 KB | 0644 |
|
irqflags-compact.h | File | 4.25 KB | 0644 |
|
irqflags.h | File | 509 B | 0644 |
|
kdebug.h | File | 400 B | 0644 |
|
kgdb.h | File | 1.35 KB | 0644 |
|
kmap_types.h | File | 489 B | 0644 |
|
kprobes.h | File | 1.37 KB | 0644 |
|
linkage.h | File | 1.42 KB | 0644 |
|
mach_desc.h | File | 2.06 KB | 0644 |
|
mmu.h | File | 2.44 KB | 0644 |
|
mmu_context.h | File | 5.67 KB | 0644 |
|
mmzone.h | File | 989 B | 0644 |
|
module.h | File | 661 B | 0644 |
|
page.h | File | 2.99 KB | 0644 |
|
pci.h | File | 705 B | 0644 |
|
perf_event.h | File | 6.86 KB | 0644 |
|
pgalloc.h | File | 3.79 KB | 0644 |
|
pgtable.h | File | 14.2 KB | 0644 |
|
processor.h | File | 4.69 KB | 0644 |
|
ptrace.h | File | 3.87 KB | 0644 |
|
sections.h | File | 407 B | 0644 |
|
segment.h | File | 612 B | 0644 |
|
serial.h | File | 644 B | 0644 |
|
setup.h | File | 1.18 KB | 0644 |
|
shmparam.h | File | 442 B | 0644 |
|
smp.h | File | 4.25 KB | 0644 |
|
spinlock.h | File | 8.79 KB | 0644 |
|
spinlock_types.h | File | 1.03 KB | 0644 |
|
stacktrace.h | File | 1.29 KB | 0644 |
|
string.h | File | 1.15 KB | 0644 |
|
switch_to.h | File | 1.17 KB | 0644 |
|
syscall.h | File | 1.57 KB | 0644 |
|
syscalls.h | File | 653 B | 0644 |
|
thread_info.h | File | 3.39 KB | 0644 |
|
timex.h | File | 508 B | 0644 |
|
tlb-mmu1.h | File | 3.48 KB | 0644 |
|
tlb.h | File | 1.23 KB | 0644 |
|
tlbflush.h | File | 1.76 KB | 0644 |
|
uaccess.h | File | 18.45 KB | 0644 |
|
unaligned.h | File | 771 B | 0644 |
|
unwind.h | File | 3.51 KB | 0644 |
|