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 15 .text 16 .align 4 17 .globl __kernel_clock_gettime 18 .type __kernel_clock_gettime,@function 19__kernel_clock_gettime: 20 CFI_STARTPROC 21 ahi %r15,-16 22 CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD+16 23 CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD 24 basr %r5,0 250: al %r5,21f-0b(%r5) /* get &_vdso_data */ 26 chi %r2,__CLOCK_REALTIME_COARSE 27 je 10f 28 chi %r2,__CLOCK_REALTIME 29 je 11f 30 chi %r2,__CLOCK_MONOTONIC_COARSE 31 je 9f 32 chi %r2,__CLOCK_MONOTONIC 33 jne 19f 34 35 /* CLOCK_MONOTONIC */ 361: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ 37 tml %r4,0x0001 /* pending update ? loop */ 38 jnz 1b 39 stcke 0(%r15) /* Store TOD clock */ 40 lm %r0,%r1,1(%r15) 41 s %r0,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ 42 sl %r1,__VDSO_XTIME_STAMP+4(%r5) 43 brc 3,2f 44 ahi %r0,-1 452: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */ 46 lr %r2,%r0 47 l %r0,__VDSO_TK_MULT(%r5) 48 ltr %r1,%r1 49 mr %r0,%r0 50 jnm 3f 51 a %r0,__VDSO_TK_MULT(%r5) 523: alr %r0,%r2 53 al %r0,__VDSO_WTOM_NSEC(%r5) 54 al %r1,__VDSO_WTOM_NSEC+4(%r5) 55 brc 12,5f 56 ahi %r0,1 575: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ 58 srdl %r0,0(%r2) /* >> tk->shift */ 59 l %r2,__VDSO_WTOM_SEC+4(%r5) 60 cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ 61 jne 1b 62 basr %r5,0 636: ltr %r0,%r0 64 jnz 7f 65 cl %r1,20f-6b(%r5) 66 jl 8f 677: ahi %r2,1 68 sl %r1,20f-6b(%r5) 69 brc 3,6b 70 ahi %r0,-1 71 j 6b 728: st %r2,0(%r3) /* store tp->tv_sec */ 73 st %r1,4(%r3) /* store tp->tv_nsec */ 74 lhi %r2,0 75 ahi %r15,16 76 CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD 77 CFI_RESTORE 15 78 br %r14 79 80 /* CLOCK_MONOTONIC_COARSE */ 81 CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD+16 82 CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD 839: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ 84 tml %r4,0x0001 /* pending update ? loop */ 85 jnz 9b 86 l %r2,__VDSO_WTOM_CRS_SEC+4(%r5) 87 l %r1,__VDSO_WTOM_CRS_NSEC+4(%r5) 88 cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ 89 jne 9b 90 j 8b 91 92 /* CLOCK_REALTIME_COARSE */ 9310: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ 94 tml %r4,0x0001 /* pending update ? loop */ 95 jnz 10b 96 l %r2,__VDSO_XTIME_CRS_SEC+4(%r5) 97 l %r1,__VDSO_XTIME_CRS_NSEC+4(%r5) 98 cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ 99 jne 10b 100 j 17f 101 102 /* CLOCK_REALTIME */ 10311: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ 104 tml %r4,0x0001 /* pending update ? loop */ 105 jnz 11b 106 stcke 0(%r15) /* Store TOD clock */ 107 lm %r0,%r1,__VDSO_TS_END(%r5) /* TOD steering end time */ 108 s %r0,1(%r15) /* no - ts_steering_end */ 109 sl %r1,5(%r15) 110 brc 3,22f 111 ahi %r0,-1 11222: ltr %r0,%r0 /* past end of steering? */ 113 jm 24f 114 srdl %r0,15 /* 1 per 2^16 */ 115 tm __VDSO_TS_DIR+3(%r5),0x01 /* steering direction? */ 116 jz 23f 117 lcr %r0,%r0 /* negative TOD offset */ 118 lcr %r1,%r1 119 je 23f 120 ahi %r0,-1 12123: a %r0,1(%r15) /* add TOD timestamp */ 122 al %r1,5(%r15) 123 brc 12,25f 124 ahi %r0,1 125 j 25f 12624: lm %r0,%r1,1(%r15) /* load TOD timestamp */ 12725: s %r0,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ 128 sl %r1,__VDSO_XTIME_STAMP+4(%r5) 129 brc 3,12f 130 ahi %r0,-1 13112: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */ 132 lr %r2,%r0 133 l %r0,__VDSO_TK_MULT(%r5) 134 ltr %r1,%r1 135 mr %r0,%r0 136 jnm 13f 137 a %r0,__VDSO_TK_MULT(%r5) 13813: alr %r0,%r2 139 al %r0,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */ 140 al %r1,__VDSO_XTIME_NSEC+4(%r5) 141 brc 12,14f 142 ahi %r0,1 14314: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ 144 srdl %r0,0(%r2) /* >> tk->shift */ 145 l %r2,__VDSO_XTIME_SEC+4(%r5) 146 cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ 147 jne 11b 148 basr %r5,0 14915: ltr %r0,%r0 150 jnz 16f 151 cl %r1,20f-15b(%r5) 152 jl 17f 15316: ahi %r2,1 154 sl %r1,20f-15b(%r5) 155 brc 3,15b 156 ahi %r0,-1 157 j 15b 15817: st %r2,0(%r3) /* store tp->tv_sec */ 159 st %r1,4(%r3) /* store tp->tv_nsec */ 160 lhi %r2,0 161 ahi %r15,16 162 CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD 163 CFI_RESTORE 15 164 br %r14 165 166 /* Fallback to system call */ 167 CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD+16 168 CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD 16919: lhi %r1,__NR_clock_gettime 170 svc 0 171 ahi %r15,16 172 CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD 173 CFI_RESTORE 15 174 br %r14 175 CFI_ENDPROC 176 17720: .long 1000000000 17821: .long _vdso_data - 0b 179 .size __kernel_clock_gettime,.-__kernel_clock_gettime 180