futex_64.S 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. /*
  2. * Copyright 2011 Tilera Corporation. All Rights Reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation, version 2.
  7. *
  8. * This program is distributed in the hope that it will be useful, but
  9. * WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  11. * NON INFRINGEMENT. See the GNU General Public License for
  12. * more details.
  13. *
  14. * Atomically access user memory, but use MMU to avoid propagating
  15. * kernel exceptions.
  16. */
  17. #include <linux/linkage.h>
  18. #include <asm/errno.h>
  19. #include <asm/futex.h>
  20. #include <asm/page.h>
  21. #include <asm/processor.h>
  22. /*
  23. * Provide a set of atomic memory operations supporting <asm/futex.h>.
  24. *
  25. * r0: user address to manipulate
  26. * r1: new value to write, or for cmpxchg, old value to compare against
  27. * r2: (cmpxchg only) new value to write
  28. *
  29. * Return __get_user struct, r0 with value, r1 with error.
  30. */
  31. #define FUTEX_OP(name, ...) \
  32. STD_ENTRY(futex_##name) \
  33. __VA_ARGS__; \
  34. { \
  35. move r1, zero; \
  36. jrp lr \
  37. }; \
  38. STD_ENDPROC(futex_##name); \
  39. .pushsection __ex_table,"a"; \
  40. .quad 1b, get_user_fault; \
  41. .popsection
  42. .pushsection .fixup,"ax"
  43. get_user_fault:
  44. { movei r1, -EFAULT; jrp lr }
  45. ENDPROC(get_user_fault)
  46. .popsection
  47. FUTEX_OP(cmpxchg, mtspr CMPEXCH_VALUE, r1; 1: cmpexch4 r0, r0, r2)
  48. FUTEX_OP(set, 1: exch4 r0, r0, r1)
  49. FUTEX_OP(add, 1: fetchadd4 r0, r0, r1)
  50. FUTEX_OP(or, 1: fetchor4 r0, r0, r1)
  51. FUTEX_OP(andn, nor r1, r1, zero; 1: fetchand4 r0, r0, r1)