tm-signal.S 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * Copyright 2015, Cyril Bur, IBM Corp.
  4. */
  5. #include "basic_asm.h"
  6. #include "gpr_asm.h"
  7. #include "fpu_asm.h"
  8. #include "vmx_asm.h"
  9. #include "vsx_asm.h"
  10. /*
  11. * Large caveat here being that the caller cannot expect the
  12. * signal to always be sent! The hardware can (AND WILL!) abort
  13. * the transaction between the tbegin and the tsuspend (however
  14. * unlikely it seems or infrequently it actually happens).
  15. * You have been warned.
  16. */
  17. /* long tm_signal_self(pid_t pid, long *gprs, double *fps, vector *vms, vector *vss); */
  18. FUNC_START(tm_signal_self_context_load)
  19. PUSH_BASIC_STACK(512)
  20. /*
  21. * Don't strictly need to save and restore as it depends on if
  22. * we're going to use them, however this reduces messy logic
  23. */
  24. PUSH_VMX(STACK_FRAME_LOCAL(5,0),r8)
  25. PUSH_FPU(512)
  26. PUSH_NVREGS_BELOW_FPU(512)
  27. std r3, STACK_FRAME_PARAM(0)(sp) /* pid */
  28. std r4, STACK_FRAME_PARAM(1)(sp) /* gps */
  29. std r5, STACK_FRAME_PARAM(2)(sp) /* fps */
  30. std r6, STACK_FRAME_PARAM(3)(sp) /* vms */
  31. std r7, STACK_FRAME_PARAM(4)(sp) /* vss */
  32. ld r3, STACK_FRAME_PARAM(1)(sp)
  33. cmpdi r3, 0
  34. beq skip_gpr_lc
  35. bl load_gpr
  36. skip_gpr_lc:
  37. ld r3, STACK_FRAME_PARAM(2)(sp)
  38. cmpdi r3, 0
  39. beq skip_fpu_lc
  40. bl load_fpu
  41. skip_fpu_lc:
  42. ld r3, STACK_FRAME_PARAM(3)(sp)
  43. cmpdi r3, 0
  44. beq skip_vmx_lc
  45. bl load_vmx
  46. skip_vmx_lc:
  47. ld r3, STACK_FRAME_PARAM(4)(sp)
  48. cmpdi r3, 0
  49. beq skip_vsx_lc
  50. bl load_vsx
  51. skip_vsx_lc:
  52. /*
  53. * Set r3 (return value) before tbegin. Use the pid as a known
  54. * 'all good' return value, zero is used to indicate a non-doomed
  55. * transaction.
  56. */
  57. ld r3, STACK_FRAME_PARAM(0)(sp)
  58. tbegin.
  59. beq 1f
  60. tsuspend. /* Can't enter a syscall transactionally */
  61. ld r3, STACK_FRAME_PARAM(1)(sp)
  62. cmpdi r3, 0
  63. beq skip_gpr_lt
  64. /* Get the second half of the array */
  65. addi r3, r3, 8 * 18
  66. bl load_gpr
  67. skip_gpr_lt:
  68. ld r3, STACK_FRAME_PARAM(2)(sp)
  69. cmpdi r3, 0
  70. beq skip_fpu_lt
  71. /* Get the second half of the array */
  72. addi r3, r3, 8 * 18
  73. bl load_fpu
  74. skip_fpu_lt:
  75. ld r3, STACK_FRAME_PARAM(3)(sp)
  76. cmpdi r3, 0
  77. beq skip_vmx_lt
  78. /* Get the second half of the array */
  79. addi r3, r3, 16 * 12
  80. bl load_vmx
  81. skip_vmx_lt:
  82. ld r3, STACK_FRAME_PARAM(4)(sp)
  83. cmpdi r3, 0
  84. beq skip_vsx_lt
  85. /* Get the second half of the array */
  86. addi r3, r3, 16 * 12
  87. bl load_vsx
  88. skip_vsx_lt:
  89. li r0, 37 /* sys_kill */
  90. ld r3, STACK_FRAME_PARAM(0)(sp) /* pid */
  91. li r4, 10 /* SIGUSR1 */
  92. sc /* Taking the signal will doom the transaction */
  93. tabort. 0
  94. tresume. /* Be super sure we abort */
  95. /*
  96. * This will cause us to resume doomed transaction and cause
  97. * hardware to cleanup, we'll end up at 1: anything between
  98. * tresume. and 1: shouldn't ever run.
  99. */
  100. li r3, 0
  101. 1:
  102. POP_VMX(STACK_FRAME_LOCAL(5,0),r4)
  103. POP_FPU(512)
  104. POP_NVREGS_BELOW_FPU(512)
  105. POP_BASIC_STACK(512)
  106. blr
  107. FUNC_END(tm_signal_self_context_load)