futex.h 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #ifndef _ASM_S390_FUTEX_H
  2. #define _ASM_S390_FUTEX_H
  3. #include <linux/uaccess.h>
  4. #include <linux/futex.h>
  5. #include <asm/mmu_context.h>
  6. #include <asm/errno.h>
  7. #define __futex_atomic_op(insn, ret, oldval, newval, uaddr, oparg) \
  8. asm volatile( \
  9. " sacf 256\n" \
  10. "0: l %1,0(%6)\n" \
  11. "1:"insn \
  12. "2: cs %1,%2,0(%6)\n" \
  13. "3: jl 1b\n" \
  14. " lhi %0,0\n" \
  15. "4: sacf 768\n" \
  16. EX_TABLE(0b,4b) EX_TABLE(2b,4b) EX_TABLE(3b,4b) \
  17. : "=d" (ret), "=&d" (oldval), "=&d" (newval), \
  18. "=m" (*uaddr) \
  19. : "0" (-EFAULT), "d" (oparg), "a" (uaddr), \
  20. "m" (*uaddr) : "cc");
  21. static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
  22. u32 __user *uaddr)
  23. {
  24. int oldval = 0, newval, ret;
  25. load_kernel_asce();
  26. pagefault_disable();
  27. switch (op) {
  28. case FUTEX_OP_SET:
  29. __futex_atomic_op("lr %2,%5\n",
  30. ret, oldval, newval, uaddr, oparg);
  31. break;
  32. case FUTEX_OP_ADD:
  33. __futex_atomic_op("lr %2,%1\nar %2,%5\n",
  34. ret, oldval, newval, uaddr, oparg);
  35. break;
  36. case FUTEX_OP_OR:
  37. __futex_atomic_op("lr %2,%1\nor %2,%5\n",
  38. ret, oldval, newval, uaddr, oparg);
  39. break;
  40. case FUTEX_OP_ANDN:
  41. __futex_atomic_op("lr %2,%1\nnr %2,%5\n",
  42. ret, oldval, newval, uaddr, oparg);
  43. break;
  44. case FUTEX_OP_XOR:
  45. __futex_atomic_op("lr %2,%1\nxr %2,%5\n",
  46. ret, oldval, newval, uaddr, oparg);
  47. break;
  48. default:
  49. ret = -ENOSYS;
  50. }
  51. pagefault_enable();
  52. if (!ret)
  53. *oval = oldval;
  54. return ret;
  55. }
  56. static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
  57. u32 oldval, u32 newval)
  58. {
  59. int ret;
  60. load_kernel_asce();
  61. asm volatile(
  62. " sacf 256\n"
  63. "0: cs %1,%4,0(%5)\n"
  64. "1: la %0,0\n"
  65. "2: sacf 768\n"
  66. EX_TABLE(0b,2b) EX_TABLE(1b,2b)
  67. : "=d" (ret), "+d" (oldval), "=m" (*uaddr)
  68. : "0" (-EFAULT), "d" (newval), "a" (uaddr), "m" (*uaddr)
  69. : "cc", "memory");
  70. *uval = oldval;
  71. return ret;
  72. }
  73. #endif /* _ASM_S390_FUTEX_H */