Merge tag 'gvt-fixes-2018-01-08' of https://github.com/intel/gvt-linux into drm-intel...
[sfrench/cifs-2.6.git] / arch / s390 / kernel / vdso32 / clock_gettime.S
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
13         .text
14         .align 4
15         .globl __kernel_clock_gettime
16         .type  __kernel_clock_gettime,@function
17 __kernel_clock_gettime:
18         .cfi_startproc
19         ahi     %r15,-16
20         basr    %r5,0
21 0:      al      %r5,21f-0b(%r5)                 /* get &_vdso_data */
22         chi     %r2,__CLOCK_REALTIME_COARSE
23         je      10f
24         chi     %r2,__CLOCK_REALTIME
25         je      11f
26         chi     %r2,__CLOCK_MONOTONIC_COARSE
27         je      9f
28         chi     %r2,__CLOCK_MONOTONIC
29         jne     19f
30
31         /* CLOCK_MONOTONIC */
32 1:      l       %r4,__VDSO_UPD_COUNT+4(%r5)     /* load update counter */
33         tml     %r4,0x0001                      /* pending update ? loop */
34         jnz     1b
35         stcke   0(%r15)                         /* Store TOD clock */
36         lm      %r0,%r1,1(%r15)
37         s       %r0,__VDSO_XTIME_STAMP(%r5)     /* TOD - cycle_last */
38         sl      %r1,__VDSO_XTIME_STAMP+4(%r5)
39         brc     3,2f
40         ahi     %r0,-1
41 2:      ms      %r0,__VDSO_TK_MULT(%r5)         /*  * tk->mult */
42         lr      %r2,%r0
43         l       %r0,__VDSO_TK_MULT(%r5)
44         ltr     %r1,%r1
45         mr      %r0,%r0
46         jnm     3f
47         a       %r0,__VDSO_TK_MULT(%r5)
48 3:      alr     %r0,%r2
49         al      %r0,__VDSO_WTOM_NSEC(%r5)
50         al      %r1,__VDSO_WTOM_NSEC+4(%r5)
51         brc     12,5f
52         ahi     %r0,1
53 5:      l       %r2,__VDSO_TK_SHIFT(%r5)        /* Timekeeper shift */
54         srdl    %r0,0(%r2)                      /*  >> tk->shift */
55         l       %r2,__VDSO_WTOM_SEC+4(%r5)
56         cl      %r4,__VDSO_UPD_COUNT+4(%r5)     /* check update counter */
57         jne     1b
58         basr    %r5,0
59 6:      ltr     %r0,%r0
60         jnz     7f
61         cl      %r1,20f-6b(%r5)
62         jl      8f
63 7:      ahi     %r2,1
64         sl      %r1,20f-6b(%r5)
65         brc     3,6b
66         ahi     %r0,-1
67         j       6b
68 8:      st      %r2,0(%r3)                      /* store tp->tv_sec */
69         st      %r1,4(%r3)                      /* store tp->tv_nsec */
70         lhi     %r2,0
71         ahi     %r15,16
72         br      %r14
73
74         /* CLOCK_MONOTONIC_COARSE */
75 9:      l       %r4,__VDSO_UPD_COUNT+4(%r5)     /* load update counter */
76         tml     %r4,0x0001                      /* pending update ? loop */
77         jnz     9b
78         l       %r2,__VDSO_WTOM_CRS_SEC+4(%r5)
79         l       %r1,__VDSO_WTOM_CRS_NSEC+4(%r5)
80         cl      %r4,__VDSO_UPD_COUNT+4(%r5)     /* check update counter */
81         jne     9b
82         j       8b
83
84         /* CLOCK_REALTIME_COARSE */
85 10:     l       %r4,__VDSO_UPD_COUNT+4(%r5)     /* load update counter */
86         tml     %r4,0x0001                      /* pending update ? loop */
87         jnz     10b
88         l       %r2,__VDSO_XTIME_CRS_SEC+4(%r5)
89         l       %r1,__VDSO_XTIME_CRS_NSEC+4(%r5)
90         cl      %r4,__VDSO_UPD_COUNT+4(%r5)     /* check update counter */
91         jne     10b
92         j       17f
93
94         /* CLOCK_REALTIME */
95 11:     l       %r4,__VDSO_UPD_COUNT+4(%r5)     /* load update counter */
96         tml     %r4,0x0001                      /* pending update ? loop */
97         jnz     11b
98         stcke   0(%r15)                         /* Store TOD clock */
99         lm      %r0,%r1,__VDSO_TS_END(%r5)      /* TOD steering end time */
100         s       %r0,1(%r15)                     /* no - ts_steering_end */
101         sl      %r1,5(%r15)
102         brc     3,22f
103         ahi     %r0,-1
104 22:     ltr     %r0,%r0                         /* past end of steering? */
105         jm      24f
106         srdl    %r0,15                          /* 1 per 2^16 */
107         tm      __VDSO_TS_DIR+3(%r5),0x01       /* steering direction? */
108         jz      23f
109         lcr     %r0,%r0                         /* negative TOD offset */
110         lcr     %r1,%r1
111         je      23f
112         ahi     %r0,-1
113 23:     a       %r0,1(%r15)                     /* add TOD timestamp */
114         al      %r1,5(%r15)
115         brc     12,25f
116         ahi     %r0,1
117         j       25f
118 24:     lm      %r0,%r1,1(%r15)                 /* load TOD timestamp */
119 25:     s       %r0,__VDSO_XTIME_STAMP(%r5)     /* TOD - cycle_last */
120         sl      %r1,__VDSO_XTIME_STAMP+4(%r5)
121         brc     3,12f
122         ahi     %r0,-1
123 12:     ms      %r0,__VDSO_TK_MULT(%r5)         /*  * tk->mult */
124         lr      %r2,%r0
125         l       %r0,__VDSO_TK_MULT(%r5)
126         ltr     %r1,%r1
127         mr      %r0,%r0
128         jnm     13f
129         a       %r0,__VDSO_TK_MULT(%r5)
130 13:     alr     %r0,%r2
131         al      %r0,__VDSO_XTIME_NSEC(%r5)      /*  + tk->xtime_nsec */
132         al      %r1,__VDSO_XTIME_NSEC+4(%r5)
133         brc     12,14f
134         ahi     %r0,1
135 14:     l       %r2,__VDSO_TK_SHIFT(%r5)        /* Timekeeper shift */
136         srdl    %r0,0(%r2)                      /*  >> tk->shift */
137         l       %r2,__VDSO_XTIME_SEC+4(%r5)
138         cl      %r4,__VDSO_UPD_COUNT+4(%r5)     /* check update counter */
139         jne     11b
140         basr    %r5,0
141 15:     ltr     %r0,%r0
142         jnz     16f
143         cl      %r1,20f-15b(%r5)
144         jl      17f
145 16:     ahi     %r2,1
146         sl      %r1,20f-15b(%r5)
147         brc     3,15b
148         ahi     %r0,-1
149         j       15b
150 17:     st      %r2,0(%r3)                      /* store tp->tv_sec */
151         st      %r1,4(%r3)                      /* store tp->tv_nsec */
152         lhi     %r2,0
153         ahi     %r15,16
154         br      %r14
155
156         /* Fallback to system call */
157 19:     lhi     %r1,__NR_clock_gettime
158         svc     0
159         ahi     %r15,16
160         br      %r14
161
162 20:     .long   1000000000
163 21:     .long   _vdso_data - 0b
164         .cfi_endproc
165         .size   __kernel_clock_gettime,.-__kernel_clock_gettime