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 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 176 22 CFI_VAL_OFFSET 15, -160 23 basr %r5,0 240: 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 34 /* CLOCK_MONOTONIC */ 351: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ 36 tml %r4,0x0001 /* pending update ? loop */ 37 jnz 1b 38 stcke 0(%r15) /* Store TOD clock */ 39 lm %r0,%r1,1(%r15) 40 s %r0,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ 41 sl %r1,__VDSO_XTIME_STAMP+4(%r5) 42 brc 3,2f 43 ahi %r0,-1 442: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */ 45 lr %r2,%r0 46 l %r0,__VDSO_TK_MULT(%r5) 47 ltr %r1,%r1 48 mr %r0,%r0 49 jnm 3f 50 a %r0,__VDSO_TK_MULT(%r5) 513: alr %r0,%r2 52 al %r0,__VDSO_WTOM_NSEC(%r5) 53 al %r1,__VDSO_WTOM_NSEC+4(%r5) 54 brc 12,5f 55 ahi %r0,1 565: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ 57 srdl %r0,0(%r2) /* >> tk->shift */ 58 l %r2,__VDSO_WTOM_SEC+4(%r5) 59 cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ 60 jne 1b 61 basr %r5,0 626: ltr %r0,%r0 63 jnz 7f 64 cl %r1,20f-6b(%r5) 65 jl 8f 667: ahi %r2,1 67 sl %r1,20f-6b(%r5) 68 brc 3,6b 69 ahi %r0,-1 70 j 6b 718: st %r2,0(%r3) /* store tp->tv_sec */ 72 st %r1,4(%r3) /* store tp->tv_nsec */ 73 lhi %r2,0 74 ahi %r15,16 75 CFI_DEF_CFA_OFFSET 160 76 CFI_RESTORE 15 77 br %r14 78 79 /* CLOCK_MONOTONIC_COARSE */ 80 CFI_DEF_CFA_OFFSET 176 81 CFI_VAL_OFFSET 15, -160 829: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ 83 tml %r4,0x0001 /* pending update ? loop */ 84 jnz 9b 85 l %r2,__VDSO_WTOM_CRS_SEC+4(%r5) 86 l %r1,__VDSO_WTOM_CRS_NSEC+4(%r5) 87 cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ 88 jne 9b 89 j 8b 90 91 /* CLOCK_REALTIME_COARSE */ 9210: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ 93 tml %r4,0x0001 /* pending update ? loop */ 94 jnz 10b 95 l %r2,__VDSO_XTIME_CRS_SEC+4(%r5) 96 l %r1,__VDSO_XTIME_CRS_NSEC+4(%r5) 97 cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ 98 jne 10b 99 j 17f 100 101 /* CLOCK_REALTIME */ 10211: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ 103 tml %r4,0x0001 /* pending update ? loop */ 104 jnz 11b 105 stcke 0(%r15) /* Store TOD clock */ 106 lm %r0,%r1,__VDSO_TS_END(%r5) /* TOD steering end time */ 107 s %r0,1(%r15) /* no - ts_steering_end */ 108 sl %r1,5(%r15) 109 brc 3,22f 110 ahi %r0,-1 11122: ltr %r0,%r0 /* past end of steering? */ 112 jm 24f 113 srdl %r0,15 /* 1 per 2^16 */ 114 tm __VDSO_TS_DIR+3(%r5),0x01 /* steering direction? */ 115 jz 23f 116 lcr %r0,%r0 /* negative TOD offset */ 117 lcr %r1,%r1 118 je 23f 119 ahi %r0,-1 12023: a %r0,1(%r15) /* add TOD timestamp */ 121 al %r1,5(%r15) 122 brc 12,25f 123 ahi %r0,1 124 j 25f 12524: lm %r0,%r1,1(%r15) /* load TOD timestamp */ 12625: s %r0,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ 127 sl %r1,__VDSO_XTIME_STAMP+4(%r5) 128 brc 3,12f 129 ahi %r0,-1 13012: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */ 131 lr %r2,%r0 132 l %r0,__VDSO_TK_MULT(%r5) 133 ltr %r1,%r1 134 mr %r0,%r0 135 jnm 13f 136 a %r0,__VDSO_TK_MULT(%r5) 13713: alr %r0,%r2 138 al %r0,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */ 139 al %r1,__VDSO_XTIME_NSEC+4(%r5) 140 brc 12,14f 141 ahi %r0,1 14214: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ 143 srdl %r0,0(%r2) /* >> tk->shift */ 144 l %r2,__VDSO_XTIME_SEC+4(%r5) 145 cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ 146 jne 11b 147 basr %r5,0 14815: ltr %r0,%r0 149 jnz 16f 150 cl %r1,20f-15b(%r5) 151 jl 17f 15216: ahi %r2,1 153 sl %r1,20f-15b(%r5) 154 brc 3,15b 155 ahi %r0,-1 156 j 15b 15717: st %r2,0(%r3) /* store tp->tv_sec */ 158 st %r1,4(%r3) /* store tp->tv_nsec */ 159 lhi %r2,0 160 ahi %r15,16 161 CFI_DEF_CFA_OFFSET 160 162 CFI_RESTORE 15 163 br %r14 164 165 /* Fallback to system call */ 166 CFI_DEF_CFA_OFFSET 176 167 CFI_VAL_OFFSET 15, -160 16819: lhi %r1,__NR_clock_gettime 169 svc 0 170 ahi %r15,16 171 CFI_DEF_CFA_OFFSET 160 172 CFI_RESTORE 15 173 br %r14 174 CFI_ENDPROC 175 17620: .long 1000000000 17721: .long _vdso_data - 0b 178 .size __kernel_clock_gettime,.-__kernel_clock_gettime 179