rwsem_64.S 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /*
  2. * x86-64 rwsem wrappers
  3. *
  4. * This interfaces the inline asm code to the slow-path
  5. * C routines. We need to save the call-clobbered regs
  6. * that the asm does not mark as clobbered, and move the
  7. * argument from %rax to %rdi.
  8. *
  9. * NOTE! We don't need to save %rax, because the functions
  10. * will always return the semaphore pointer in %rax (which
  11. * is also the input argument to these helpers)
  12. *
  13. * The following can clobber %rdx because the asm clobbers it:
  14. * call_rwsem_down_write_failed
  15. * call_rwsem_wake
  16. * but %rdi, %rsi, %rcx, %r8-r11 always need saving.
  17. */
  18. #include <linux/linkage.h>
  19. #include <asm/rwlock.h>
  20. #include <asm/alternative-asm.h>
  21. #include <asm/frame.h>
  22. #include <asm/dwarf2.h>
  23. #define save_common_regs \
  24. pushq %rdi; \
  25. pushq %rsi; \
  26. pushq %rcx; \
  27. pushq %r8; \
  28. pushq %r9; \
  29. pushq %r10; \
  30. pushq %r11
  31. #define restore_common_regs \
  32. popq %r11; \
  33. popq %r10; \
  34. popq %r9; \
  35. popq %r8; \
  36. popq %rcx; \
  37. popq %rsi; \
  38. popq %rdi
  39. /* Fix up special calling conventions */
  40. ENTRY(call_rwsem_down_read_failed)
  41. save_common_regs
  42. pushq %rdx
  43. movq %rax,%rdi
  44. call rwsem_down_read_failed
  45. popq %rdx
  46. restore_common_regs
  47. ret
  48. ENDPROC(call_rwsem_down_read_failed)
  49. ENTRY(call_rwsem_down_write_failed)
  50. save_common_regs
  51. movq %rax,%rdi
  52. call rwsem_down_write_failed
  53. restore_common_regs
  54. ret
  55. ENDPROC(call_rwsem_down_write_failed)
  56. ENTRY(call_rwsem_wake)
  57. decl %edx /* do nothing if still outstanding active readers */
  58. jnz 1f
  59. save_common_regs
  60. movq %rax,%rdi
  61. call rwsem_wake
  62. restore_common_regs
  63. 1: ret
  64. ENDPROC(call_rwsem_wake)
  65. /* Fix up special calling conventions */
  66. ENTRY(call_rwsem_downgrade_wake)
  67. save_common_regs
  68. pushq %rdx
  69. movq %rax,%rdi
  70. call rwsem_downgrade_wake
  71. popq %rdx
  72. restore_common_regs
  73. ret
  74. ENDPROC(call_rwsem_downgrade_wake)