tm-signal.S 3.0 KB

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