Greg Kroah-Hartman | a17ae4c | 2017-11-24 15:00:32 +0100 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 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) |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 8 | */ |
| 9 | #include <asm/vdso.h> |
| 10 | #include <asm/asm-offsets.h> |
| 11 | #include <asm/unistd.h> |
Hendrik Brueckner | bc3703f | 2017-11-20 11:41:07 +0100 | [diff] [blame] | 12 | #include <asm/dwarf.h> |
Vasily Gorbik | 26f4414 | 2018-09-14 18:08:10 +0200 | [diff] [blame] | 13 | #include <asm/ptrace.h> |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 14 | |
| 15 | .text |
| 16 | .align 4 |
| 17 | .globl __kernel_clock_gettime |
| 18 | .type __kernel_clock_gettime,@function |
| 19 | __kernel_clock_gettime: |
Hendrik Brueckner | 7bceec4 | 2017-11-20 11:46:13 +0100 | [diff] [blame] | 20 | CFI_STARTPROC |
Heiko Carstens | 9b2efe0 | 2014-10-27 08:28:08 +0100 | [diff] [blame] | 21 | ahi %r15,-16 |
Vasily Gorbik | 26f4414 | 2018-09-14 18:08:10 +0200 | [diff] [blame] | 22 | CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD+16 |
| 23 | CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 24 | basr %r5,0 |
| 25 | 0: al %r5,21f-0b(%r5) /* get &_vdso_data */ |
Martin Schwidefsky | b7eacb5 | 2014-08-29 12:31:45 +0200 | [diff] [blame] | 26 | chi %r2,__CLOCK_REALTIME_COARSE |
| 27 | je 10f |
Heiko Carstens | b342398 | 2010-10-29 16:50:41 +0200 | [diff] [blame] | 28 | chi %r2,__CLOCK_REALTIME |
Martin Schwidefsky | 5da7615 | 2014-08-29 10:16:03 +0200 | [diff] [blame] | 29 | je 11f |
Martin Schwidefsky | b7eacb5 | 2014-08-29 12:31:45 +0200 | [diff] [blame] | 30 | chi %r2,__CLOCK_MONOTONIC_COARSE |
| 31 | je 9f |
Heiko Carstens | b342398 | 2010-10-29 16:50:41 +0200 | [diff] [blame] | 32 | chi %r2,__CLOCK_MONOTONIC |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 33 | jne 19f |
| 34 | |
| 35 | /* CLOCK_MONOTONIC */ |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 36 | 1: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ |
| 37 | tml %r4,0x0001 /* pending update ? loop */ |
| 38 | jnz 1b |
Heiko Carstens | 9b2efe0 | 2014-10-27 08:28:08 +0100 | [diff] [blame] | 39 | stcke 0(%r15) /* Store TOD clock */ |
| 40 | lm %r0,%r1,1(%r15) |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 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 |
Martin Schwidefsky | 79c74ec | 2013-11-22 10:04:53 +0100 | [diff] [blame] | 45 | 2: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */ |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 46 | lr %r2,%r0 |
Martin Schwidefsky | 79c74ec | 2013-11-22 10:04:53 +0100 | [diff] [blame] | 47 | l %r0,__VDSO_TK_MULT(%r5) |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 48 | ltr %r1,%r1 |
| 49 | mr %r0,%r0 |
| 50 | jnm 3f |
Martin Schwidefsky | 79c74ec | 2013-11-22 10:04:53 +0100 | [diff] [blame] | 51 | a %r0,__VDSO_TK_MULT(%r5) |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 52 | 3: alr %r0,%r2 |
Martin Schwidefsky | ca5de58 | 2013-12-02 18:00:36 +0100 | [diff] [blame] | 53 | al %r0,__VDSO_WTOM_NSEC(%r5) |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 54 | al %r1,__VDSO_WTOM_NSEC+4(%r5) |
| 55 | brc 12,5f |
| 56 | ahi %r0,1 |
Martin Schwidefsky | 79c74ec | 2013-11-22 10:04:53 +0100 | [diff] [blame] | 57 | 5: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ |
| 58 | srdl %r0,0(%r2) /* >> tk->shift */ |
Martin Schwidefsky | ca5de58 | 2013-12-02 18:00:36 +0100 | [diff] [blame] | 59 | l %r2,__VDSO_WTOM_SEC+4(%r5) |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 60 | cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ |
| 61 | jne 1b |
| 62 | basr %r5,0 |
| 63 | 6: ltr %r0,%r0 |
| 64 | jnz 7f |
| 65 | cl %r1,20f-6b(%r5) |
| 66 | jl 8f |
| 67 | 7: ahi %r2,1 |
| 68 | sl %r1,20f-6b(%r5) |
| 69 | brc 3,6b |
| 70 | ahi %r0,-1 |
| 71 | j 6b |
| 72 | 8: st %r2,0(%r3) /* store tp->tv_sec */ |
| 73 | st %r1,4(%r3) /* store tp->tv_nsec */ |
Martin Schwidefsky | 5da7615 | 2014-08-29 10:16:03 +0200 | [diff] [blame] | 74 | lhi %r2,0 |
Heiko Carstens | 9b2efe0 | 2014-10-27 08:28:08 +0100 | [diff] [blame] | 75 | ahi %r15,16 |
Vasily Gorbik | 26f4414 | 2018-09-14 18:08:10 +0200 | [diff] [blame] | 76 | CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD |
Hendrik Brueckner | 7bceec4 | 2017-11-20 11:46:13 +0100 | [diff] [blame] | 77 | CFI_RESTORE 15 |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 78 | br %r14 |
| 79 | |
Martin Schwidefsky | b7eacb5 | 2014-08-29 12:31:45 +0200 | [diff] [blame] | 80 | /* CLOCK_MONOTONIC_COARSE */ |
Vasily Gorbik | 26f4414 | 2018-09-14 18:08:10 +0200 | [diff] [blame] | 81 | CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD+16 |
| 82 | CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD |
Martin Schwidefsky | b7eacb5 | 2014-08-29 12:31:45 +0200 | [diff] [blame] | 83 | 9: 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 */ |
| 93 | 10: 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 Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 102 | /* CLOCK_REALTIME */ |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 103 | 11: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ |
| 104 | tml %r4,0x0001 /* pending update ? loop */ |
| 105 | jnz 11b |
Heiko Carstens | 9b2efe0 | 2014-10-27 08:28:08 +0100 | [diff] [blame] | 106 | stcke 0(%r15) /* Store TOD clock */ |
Martin Schwidefsky | 75c7b6f | 2016-10-11 12:49:50 +0200 | [diff] [blame] | 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 |
| 112 | 22: 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 |
| 121 | 23: a %r0,1(%r15) /* add TOD timestamp */ |
| 122 | al %r1,5(%r15) |
| 123 | brc 12,25f |
| 124 | ahi %r0,1 |
| 125 | j 25f |
| 126 | 24: lm %r0,%r1,1(%r15) /* load TOD timestamp */ |
| 127 | 25: s %r0,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 128 | sl %r1,__VDSO_XTIME_STAMP+4(%r5) |
| 129 | brc 3,12f |
| 130 | ahi %r0,-1 |
Martin Schwidefsky | 79c74ec | 2013-11-22 10:04:53 +0100 | [diff] [blame] | 131 | 12: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */ |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 132 | lr %r2,%r0 |
Martin Schwidefsky | 79c74ec | 2013-11-22 10:04:53 +0100 | [diff] [blame] | 133 | l %r0,__VDSO_TK_MULT(%r5) |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 134 | ltr %r1,%r1 |
| 135 | mr %r0,%r0 |
| 136 | jnm 13f |
Martin Schwidefsky | 79c74ec | 2013-11-22 10:04:53 +0100 | [diff] [blame] | 137 | a %r0,__VDSO_TK_MULT(%r5) |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 138 | 13: alr %r0,%r2 |
Martin Schwidefsky | 79c74ec | 2013-11-22 10:04:53 +0100 | [diff] [blame] | 139 | al %r0,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */ |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 140 | al %r1,__VDSO_XTIME_NSEC+4(%r5) |
| 141 | brc 12,14f |
| 142 | ahi %r0,1 |
Martin Schwidefsky | 79c74ec | 2013-11-22 10:04:53 +0100 | [diff] [blame] | 143 | 14: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ |
| 144 | srdl %r0,0(%r2) /* >> tk->shift */ |
| 145 | l %r2,__VDSO_XTIME_SEC+4(%r5) |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 146 | cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ |
| 147 | jne 11b |
| 148 | basr %r5,0 |
| 149 | 15: ltr %r0,%r0 |
| 150 | jnz 16f |
| 151 | cl %r1,20f-15b(%r5) |
| 152 | jl 17f |
| 153 | 16: ahi %r2,1 |
| 154 | sl %r1,20f-15b(%r5) |
| 155 | brc 3,15b |
| 156 | ahi %r0,-1 |
| 157 | j 15b |
| 158 | 17: st %r2,0(%r3) /* store tp->tv_sec */ |
| 159 | st %r1,4(%r3) /* store tp->tv_nsec */ |
Martin Schwidefsky | 5da7615 | 2014-08-29 10:16:03 +0200 | [diff] [blame] | 160 | lhi %r2,0 |
Heiko Carstens | 9b2efe0 | 2014-10-27 08:28:08 +0100 | [diff] [blame] | 161 | ahi %r15,16 |
Vasily Gorbik | 26f4414 | 2018-09-14 18:08:10 +0200 | [diff] [blame] | 162 | CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD |
Hendrik Brueckner | 7bceec4 | 2017-11-20 11:46:13 +0100 | [diff] [blame] | 163 | CFI_RESTORE 15 |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 164 | br %r14 |
| 165 | |
| 166 | /* Fallback to system call */ |
Vasily Gorbik | 26f4414 | 2018-09-14 18:08:10 +0200 | [diff] [blame] | 167 | CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD+16 |
| 168 | CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 169 | 19: lhi %r1,__NR_clock_gettime |
| 170 | svc 0 |
Heiko Carstens | 9b2efe0 | 2014-10-27 08:28:08 +0100 | [diff] [blame] | 171 | ahi %r15,16 |
Vasily Gorbik | 26f4414 | 2018-09-14 18:08:10 +0200 | [diff] [blame] | 172 | CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD |
Hendrik Brueckner | 7bceec4 | 2017-11-20 11:46:13 +0100 | [diff] [blame] | 173 | CFI_RESTORE 15 |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 174 | br %r14 |
Hendrik Brueckner | 7bceec4 | 2017-11-20 11:46:13 +0100 | [diff] [blame] | 175 | CFI_ENDPROC |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 176 | |
| 177 | 20: .long 1000000000 |
| 178 | 21: .long _vdso_data - 0b |
Martin Schwidefsky | b020632 | 2008-12-25 13:38:36 +0100 | [diff] [blame] | 179 | .size __kernel_clock_gettime,.-__kernel_clock_gettime |