1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * Userland implementation of gettimeofday() 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_gettimeofday 18 .type __kernel_gettimeofday,@function 19__kernel_gettimeofday: 20 CFI_STARTPROC 21 ahi %r15,-16 22 CFI_ADJUST_CFA_OFFSET 16 23 CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD 24 basr %r5,0 250: al %r5,13f-0b(%r5) /* get &_vdso_data */ 261: ltr %r3,%r3 /* check if tz is NULL */ 27 je 2f 28 mvc 0(8,%r3),__VDSO_TIMEZONE(%r5) 292: ltr %r2,%r2 /* check if tv is NULL */ 30 je 10f 31 l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ 32 tml %r4,0x0001 /* pending update ? loop */ 33 jnz 1b 34 stcke 0(%r15) /* Store TOD clock */ 35 lm %r0,%r1,__VDSO_TS_END(%r5) /* TOD steering end time */ 36 s %r0,1(%r15) 37 sl %r1,5(%r15) 38 brc 3,14f 39 ahi %r0,-1 4014: ltr %r0,%r0 /* past end of steering? */ 41 jm 16f 42 srdl %r0,15 /* 1 per 2^16 */ 43 tm __VDSO_TS_DIR+3(%r5),0x01 /* steering direction? */ 44 jz 15f 45 lcr %r0,%r0 /* negative TOD offset */ 46 lcr %r1,%r1 47 je 15f 48 ahi %r0,-1 4915: a %r0,1(%r15) /* add TOD timestamp */ 50 al %r1,5(%r15) 51 brc 12,17f 52 ahi %r0,1 53 j 17f 5416: lm %r0,%r1,1(%r15) /* load TOD timestamp */ 5517: s %r0,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ 56 sl %r1,__VDSO_XTIME_STAMP+4(%r5) 57 brc 3,3f 58 ahi %r0,-1 593: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */ 60 st %r0,0(%r15) 61 l %r0,__VDSO_TK_MULT(%r5) 62 ltr %r1,%r1 63 mr %r0,%r0 64 jnm 4f 65 a %r0,__VDSO_TK_MULT(%r5) 664: al %r0,0(%r15) 67 al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */ 68 al %r1,__VDSO_XTIME_NSEC+4(%r5) 69 brc 12,5f 70 ahi %r0,1 715: mvc 0(4,%r15),__VDSO_XTIME_SEC+4(%r5) 72 cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ 73 jne 1b 74 l %r4,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ 75 srdl %r0,0(%r4) /* >> tk->shift */ 76 l %r4,0(%r15) /* get tv_sec from stack */ 77 basr %r5,0 786: ltr %r0,%r0 79 jnz 7f 80 cl %r1,11f-6b(%r5) 81 jl 8f 827: ahi %r4,1 83 sl %r1,11f-6b(%r5) 84 brc 3,6b 85 ahi %r0,-1 86 j 6b 878: st %r4,0(%r2) /* store tv->tv_sec */ 88 ltr %r1,%r1 89 m %r0,12f-6b(%r5) 90 jnm 9f 91 al %r0,12f-6b(%r5) 929: srl %r0,6 93 st %r0,4(%r2) /* store tv->tv_usec */ 9410: slr %r2,%r2 95 ahi %r15,16 96 CFI_ADJUST_CFA_OFFSET -16 97 CFI_RESTORE 15 98 br %r14 99 CFI_ENDPROC 10011: .long 1000000000 10112: .long 274877907 10213: .long _vdso_data - 0b 103 .size __kernel_gettimeofday,.-__kernel_gettimeofday 104