clock_gettime.S 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Userland implementation of clock_gettime() for 32 bits processes in a
  4. * s390 kernel for use in the vDSO
  5. *
  6. * Copyright IBM Corp. 2008
  7. * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
  8. */
  9. #include <asm/vdso.h>
  10. #include <asm/asm-offsets.h>
  11. #include <asm/unistd.h>
  12. #include <asm/dwarf.h>
  13. #include <asm/ptrace.h>
  14. .text
  15. .align 4
  16. .globl __kernel_clock_gettime
  17. .type __kernel_clock_gettime,@function
  18. __kernel_clock_gettime:
  19. CFI_STARTPROC
  20. ahi %r15,-16
  21. CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD+16
  22. CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD
  23. basr %r5,0
  24. 0: al %r5,21f-0b(%r5) /* get &_vdso_data */
  25. chi %r2,__CLOCK_REALTIME_COARSE
  26. je 10f
  27. chi %r2,__CLOCK_REALTIME
  28. je 11f
  29. chi %r2,__CLOCK_MONOTONIC_COARSE
  30. je 9f
  31. chi %r2,__CLOCK_MONOTONIC
  32. jne 19f
  33. /* CLOCK_MONOTONIC */
  34. 1: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */
  35. tml %r4,0x0001 /* pending update ? loop */
  36. jnz 1b
  37. stcke 0(%r15) /* Store TOD clock */
  38. lm %r0,%r1,1(%r15)
  39. s %r0,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
  40. sl %r1,__VDSO_XTIME_STAMP+4(%r5)
  41. brc 3,2f
  42. ahi %r0,-1
  43. 2: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */
  44. lr %r2,%r0
  45. l %r0,__VDSO_TK_MULT(%r5)
  46. ltr %r1,%r1
  47. mr %r0,%r0
  48. jnm 3f
  49. a %r0,__VDSO_TK_MULT(%r5)
  50. 3: alr %r0,%r2
  51. al %r0,__VDSO_WTOM_NSEC(%r5)
  52. al %r1,__VDSO_WTOM_NSEC+4(%r5)
  53. brc 12,5f
  54. ahi %r0,1
  55. 5: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
  56. srdl %r0,0(%r2) /* >> tk->shift */
  57. l %r2,__VDSO_WTOM_SEC+4(%r5)
  58. cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */
  59. jne 1b
  60. basr %r5,0
  61. 6: ltr %r0,%r0
  62. jnz 7f
  63. cl %r1,20f-6b(%r5)
  64. jl 8f
  65. 7: ahi %r2,1
  66. sl %r1,20f-6b(%r5)
  67. brc 3,6b
  68. ahi %r0,-1
  69. j 6b
  70. 8: st %r2,0(%r3) /* store tp->tv_sec */
  71. st %r1,4(%r3) /* store tp->tv_nsec */
  72. lhi %r2,0
  73. ahi %r15,16
  74. CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD
  75. CFI_RESTORE 15
  76. br %r14
  77. /* CLOCK_MONOTONIC_COARSE */
  78. CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD+16
  79. CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD
  80. 9: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */
  81. tml %r4,0x0001 /* pending update ? loop */
  82. jnz 9b
  83. l %r2,__VDSO_WTOM_CRS_SEC+4(%r5)
  84. l %r1,__VDSO_WTOM_CRS_NSEC+4(%r5)
  85. cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */
  86. jne 9b
  87. j 8b
  88. /* CLOCK_REALTIME_COARSE */
  89. 10: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */
  90. tml %r4,0x0001 /* pending update ? loop */
  91. jnz 10b
  92. l %r2,__VDSO_XTIME_CRS_SEC+4(%r5)
  93. l %r1,__VDSO_XTIME_CRS_NSEC+4(%r5)
  94. cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */
  95. jne 10b
  96. j 17f
  97. /* CLOCK_REALTIME */
  98. 11: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */
  99. tml %r4,0x0001 /* pending update ? loop */
  100. jnz 11b
  101. stcke 0(%r15) /* Store TOD clock */
  102. lm %r0,%r1,__VDSO_TS_END(%r5) /* TOD steering end time */
  103. s %r0,1(%r15) /* no - ts_steering_end */
  104. sl %r1,5(%r15)
  105. brc 3,22f
  106. ahi %r0,-1
  107. 22: ltr %r0,%r0 /* past end of steering? */
  108. jm 24f
  109. srdl %r0,15 /* 1 per 2^16 */
  110. tm __VDSO_TS_DIR+3(%r5),0x01 /* steering direction? */
  111. jz 23f
  112. lcr %r0,%r0 /* negative TOD offset */
  113. lcr %r1,%r1
  114. je 23f
  115. ahi %r0,-1
  116. 23: a %r0,1(%r15) /* add TOD timestamp */
  117. al %r1,5(%r15)
  118. brc 12,25f
  119. ahi %r0,1
  120. j 25f
  121. 24: lm %r0,%r1,1(%r15) /* load TOD timestamp */
  122. 25: s %r0,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
  123. sl %r1,__VDSO_XTIME_STAMP+4(%r5)
  124. brc 3,12f
  125. ahi %r0,-1
  126. 12: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */
  127. lr %r2,%r0
  128. l %r0,__VDSO_TK_MULT(%r5)
  129. ltr %r1,%r1
  130. mr %r0,%r0
  131. jnm 13f
  132. a %r0,__VDSO_TK_MULT(%r5)
  133. 13: alr %r0,%r2
  134. al %r0,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
  135. al %r1,__VDSO_XTIME_NSEC+4(%r5)
  136. brc 12,14f
  137. ahi %r0,1
  138. 14: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
  139. srdl %r0,0(%r2) /* >> tk->shift */
  140. l %r2,__VDSO_XTIME_SEC+4(%r5)
  141. cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */
  142. jne 11b
  143. basr %r5,0
  144. 15: ltr %r0,%r0
  145. jnz 16f
  146. cl %r1,20f-15b(%r5)
  147. jl 17f
  148. 16: ahi %r2,1
  149. sl %r1,20f-15b(%r5)
  150. brc 3,15b
  151. ahi %r0,-1
  152. j 15b
  153. 17: st %r2,0(%r3) /* store tp->tv_sec */
  154. st %r1,4(%r3) /* store tp->tv_nsec */
  155. lhi %r2,0
  156. ahi %r15,16
  157. CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD
  158. CFI_RESTORE 15
  159. br %r14
  160. /* Fallback to system call */
  161. CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD+16
  162. CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD
  163. 19: lhi %r1,__NR_clock_gettime
  164. svc 0
  165. ahi %r15,16
  166. CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD
  167. CFI_RESTORE 15
  168. br %r14
  169. CFI_ENDPROC
  170. 20: .long 1000000000
  171. 21: .long _vdso_data - 0b
  172. .size __kernel_clock_gettime,.-__kernel_clock_gettime