futex.h 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #ifndef _ASM_M68K_FUTEX_H
  2. #define _ASM_M68K_FUTEX_H
  3. #ifdef __KERNEL__
  4. #if !defined(CONFIG_MMU)
  5. #include <asm-generic/futex.h>
  6. #else /* CONFIG_MMU */
  7. #include <linux/futex.h>
  8. #include <linux/uaccess.h>
  9. #include <asm/errno.h>
  10. static inline int
  11. futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
  12. u32 oldval, u32 newval)
  13. {
  14. u32 val;
  15. if (unlikely(get_user(val, uaddr) != 0))
  16. return -EFAULT;
  17. if (val == oldval && unlikely(put_user(newval, uaddr) != 0))
  18. return -EFAULT;
  19. *uval = val;
  20. return 0;
  21. }
  22. static inline int
  23. futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
  24. {
  25. int op = (encoded_op >> 28) & 7;
  26. int cmp = (encoded_op >> 24) & 15;
  27. int oparg = (encoded_op << 8) >> 20;
  28. int cmparg = (encoded_op << 20) >> 20;
  29. int oldval, ret;
  30. u32 tmp;
  31. if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
  32. oparg = 1 << oparg;
  33. pagefault_disable(); /* implies preempt_disable() */
  34. ret = -EFAULT;
  35. if (unlikely(get_user(oldval, uaddr) != 0))
  36. goto out_pagefault_enable;
  37. ret = 0;
  38. tmp = oldval;
  39. switch (op) {
  40. case FUTEX_OP_SET:
  41. tmp = oparg;
  42. break;
  43. case FUTEX_OP_ADD:
  44. tmp += oparg;
  45. break;
  46. case FUTEX_OP_OR:
  47. tmp |= oparg;
  48. break;
  49. case FUTEX_OP_ANDN:
  50. tmp &= ~oparg;
  51. break;
  52. case FUTEX_OP_XOR:
  53. tmp ^= oparg;
  54. break;
  55. default:
  56. ret = -ENOSYS;
  57. }
  58. if (ret == 0 && unlikely(put_user(tmp, uaddr) != 0))
  59. ret = -EFAULT;
  60. out_pagefault_enable:
  61. pagefault_enable(); /* subsumes preempt_enable() */
  62. if (ret == 0) {
  63. switch (cmp) {
  64. case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
  65. case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
  66. case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
  67. case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
  68. case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
  69. case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
  70. default: ret = -ENOSYS;
  71. }
  72. }
  73. return ret;
  74. }
  75. #endif /* CONFIG_MMU */
  76. #endif /* __KERNEL__ */
  77. #endif /* _ASM_M68K_FUTEX_H */