blob: ada5c11a16e5adb20cfcd7f9908296eb1ac6cbb9 [file] [log] [blame]
Greg Kroah-Hartmana17ae4c2017-11-24 15:00:32 +01001/* SPDX-License-Identifier: GPL-2.0 */
Martin Schwidefskyb0206322008-12-25 13:38:36 +01002/*
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)
Martin Schwidefskyb0206322008-12-25 13:38:36 +01008 */
9#include <asm/vdso.h>
10#include <asm/asm-offsets.h>
11#include <asm/unistd.h>
Hendrik Bruecknerbc3703f2017-11-20 11:41:07 +010012#include <asm/dwarf.h>
Vasily Gorbik26f44142018-09-14 18:08:10 +020013#include <asm/ptrace.h>
Martin Schwidefskyb0206322008-12-25 13:38:36 +010014
15 .text
16 .align 4
17 .globl __kernel_clock_gettime
18 .type __kernel_clock_gettime,@function
19__kernel_clock_gettime:
Hendrik Brueckner7bceec42017-11-20 11:46:13 +010020 CFI_STARTPROC
Heiko Carstens9b2efe02014-10-27 08:28:08 +010021 ahi %r15,-16
Vasily Gorbik26f44142018-09-14 18:08:10 +020022 CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD+16
23 CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD
Martin Schwidefskyb0206322008-12-25 13:38:36 +010024 basr %r5,0
250: al %r5,21f-0b(%r5) /* get &_vdso_data */
Martin Schwidefskyb7eacb52014-08-29 12:31:45 +020026 chi %r2,__CLOCK_REALTIME_COARSE
27 je 10f
Heiko Carstensb3423982010-10-29 16:50:41 +020028 chi %r2,__CLOCK_REALTIME
Martin Schwidefsky5da76152014-08-29 10:16:03 +020029 je 11f
Martin Schwidefskyb7eacb52014-08-29 12:31:45 +020030 chi %r2,__CLOCK_MONOTONIC_COARSE
31 je 9f
Heiko Carstensb3423982010-10-29 16:50:41 +020032 chi %r2,__CLOCK_MONOTONIC
Martin Schwidefskyb0206322008-12-25 13:38:36 +010033 jne 19f
34
35 /* CLOCK_MONOTONIC */
Martin Schwidefskyb0206322008-12-25 13:38:36 +0100361: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */
37 tml %r4,0x0001 /* pending update ? loop */
38 jnz 1b
Heiko Carstens9b2efe02014-10-27 08:28:08 +010039 stcke 0(%r15) /* Store TOD clock */
40 lm %r0,%r1,1(%r15)
Martin Schwidefskyb0206322008-12-25 13:38:36 +010041 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
Martin Schwidefsky79c74ec2013-11-22 10:04:53 +0100452: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */
Martin Schwidefskyb0206322008-12-25 13:38:36 +010046 lr %r2,%r0
Martin Schwidefsky79c74ec2013-11-22 10:04:53 +010047 l %r0,__VDSO_TK_MULT(%r5)
Martin Schwidefskyb0206322008-12-25 13:38:36 +010048 ltr %r1,%r1
49 mr %r0,%r0
50 jnm 3f
Martin Schwidefsky79c74ec2013-11-22 10:04:53 +010051 a %r0,__VDSO_TK_MULT(%r5)
Martin Schwidefskyb0206322008-12-25 13:38:36 +0100523: alr %r0,%r2
Martin Schwidefskyca5de582013-12-02 18:00:36 +010053 al %r0,__VDSO_WTOM_NSEC(%r5)
Martin Schwidefskyb0206322008-12-25 13:38:36 +010054 al %r1,__VDSO_WTOM_NSEC+4(%r5)
55 brc 12,5f
56 ahi %r0,1
Martin Schwidefsky79c74ec2013-11-22 10:04:53 +0100575: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
58 srdl %r0,0(%r2) /* >> tk->shift */
Martin Schwidefskyca5de582013-12-02 18:00:36 +010059 l %r2,__VDSO_WTOM_SEC+4(%r5)
Martin Schwidefskyb0206322008-12-25 13:38:36 +010060 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 */
Martin Schwidefsky5da76152014-08-29 10:16:03 +020074 lhi %r2,0
Heiko Carstens9b2efe02014-10-27 08:28:08 +010075 ahi %r15,16
Vasily Gorbik26f44142018-09-14 18:08:10 +020076 CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD
Hendrik Brueckner7bceec42017-11-20 11:46:13 +010077 CFI_RESTORE 15
Martin Schwidefskyb0206322008-12-25 13:38:36 +010078 br %r14
79
Martin Schwidefskyb7eacb52014-08-29 12:31:45 +020080 /* CLOCK_MONOTONIC_COARSE */
Vasily Gorbik26f44142018-09-14 18:08:10 +020081 CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD+16
82 CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD
Martin Schwidefskyb7eacb52014-08-29 12:31:45 +0200839: 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
Martin Schwidefskyb0206322008-12-25 13:38:36 +0100102 /* CLOCK_REALTIME */
Martin Schwidefskyb0206322008-12-25 13:38:36 +010010311: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */
104 tml %r4,0x0001 /* pending update ? loop */
105 jnz 11b
Heiko Carstens9b2efe02014-10-27 08:28:08 +0100106 stcke 0(%r15) /* Store TOD clock */
Martin Schwidefsky75c7b6f2016-10-11 12:49:50 +0200107 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 */
Martin Schwidefskyb0206322008-12-25 13:38:36 +0100128 sl %r1,__VDSO_XTIME_STAMP+4(%r5)
129 brc 3,12f
130 ahi %r0,-1
Martin Schwidefsky79c74ec2013-11-22 10:04:53 +010013112: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */
Martin Schwidefskyb0206322008-12-25 13:38:36 +0100132 lr %r2,%r0
Martin Schwidefsky79c74ec2013-11-22 10:04:53 +0100133 l %r0,__VDSO_TK_MULT(%r5)
Martin Schwidefskyb0206322008-12-25 13:38:36 +0100134 ltr %r1,%r1
135 mr %r0,%r0
136 jnm 13f
Martin Schwidefsky79c74ec2013-11-22 10:04:53 +0100137 a %r0,__VDSO_TK_MULT(%r5)
Martin Schwidefskyb0206322008-12-25 13:38:36 +010013813: alr %r0,%r2
Martin Schwidefsky79c74ec2013-11-22 10:04:53 +0100139 al %r0,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
Martin Schwidefskyb0206322008-12-25 13:38:36 +0100140 al %r1,__VDSO_XTIME_NSEC+4(%r5)
141 brc 12,14f
142 ahi %r0,1
Martin Schwidefsky79c74ec2013-11-22 10:04:53 +010014314: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
144 srdl %r0,0(%r2) /* >> tk->shift */
145 l %r2,__VDSO_XTIME_SEC+4(%r5)
Martin Schwidefskyb0206322008-12-25 13:38:36 +0100146 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 */
Martin Schwidefsky5da76152014-08-29 10:16:03 +0200160 lhi %r2,0
Heiko Carstens9b2efe02014-10-27 08:28:08 +0100161 ahi %r15,16
Vasily Gorbik26f44142018-09-14 18:08:10 +0200162 CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD
Hendrik Brueckner7bceec42017-11-20 11:46:13 +0100163 CFI_RESTORE 15
Martin Schwidefskyb0206322008-12-25 13:38:36 +0100164 br %r14
165
166 /* Fallback to system call */
Vasily Gorbik26f44142018-09-14 18:08:10 +0200167 CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD+16
168 CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD
Martin Schwidefskyb0206322008-12-25 13:38:36 +010016919: lhi %r1,__NR_clock_gettime
170 svc 0
Heiko Carstens9b2efe02014-10-27 08:28:08 +0100171 ahi %r15,16
Vasily Gorbik26f44142018-09-14 18:08:10 +0200172 CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD
Hendrik Brueckner7bceec42017-11-20 11:46:13 +0100173 CFI_RESTORE 15
Martin Schwidefskyb0206322008-12-25 13:38:36 +0100174 br %r14
Hendrik Brueckner7bceec42017-11-20 11:46:13 +0100175 CFI_ENDPROC
Martin Schwidefskyb0206322008-12-25 13:38:36 +0100176
17720: .long 1000000000
17821: .long _vdso_data - 0b
Martin Schwidefskyb0206322008-12-25 13:38:36 +0100179 .size __kernel_clock_gettime,.-__kernel_clock_gettime