• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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