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