hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/arch/powerpc/kernel/vdso32/gettimeofday.S
....@@ -1,28 +1,23 @@
1
+/* SPDX-License-Identifier: GPL-2.0-or-later */
12 /*
23 * Userland implementation of gettimeofday() for 32 bits processes in a
34 * ppc64 kernel for use in the vDSO
45 *
56 * Copyright (C) 2004 Benjamin Herrenschmuidt (benh@kernel.crashing.org,
67 * IBM Corp.
7
- *
8
- * This program is free software; you can redistribute it and/or
9
- * modify it under the terms of the GNU General Public License
10
- * as published by the Free Software Foundation; either version
11
- * 2 of the License, or (at your option) any later version.
128 */
139 #include <asm/processor.h>
1410 #include <asm/ppc_asm.h>
1511 #include <asm/vdso.h>
12
+#include <asm/vdso_datapage.h>
1613 #include <asm/asm-offsets.h>
1714 #include <asm/unistd.h>
1815
1916 /* Offset for the low 32-bit part of a field of long type */
2017 #ifdef CONFIG_PPC64
2118 #define LOPART 4
22
-#define TSPEC_TV_SEC TSPC64_TV_SEC+LOPART
2319 #else
2420 #define LOPART 0
25
-#define TSPEC_TV_SEC TSPC32_TV_SEC
2621 #endif
2722
2823 .text
....@@ -37,28 +32,26 @@
3732 mflr r12
3833 .cfi_register lr,r12
3934
40
- mr r10,r3 /* r10 saves tv */
35
+ mr. r10,r3 /* r10 saves tv */
4136 mr r11,r4 /* r11 saves tz */
42
- bl __get_datapage@local /* get data page */
43
- mr r9, r3 /* datapage ptr in r9 */
44
- cmplwi r10,0 /* check if tv is NULL */
37
+ get_datapage r9, r0
4538 beq 3f
46
- lis r7,1000000@ha /* load up USEC_PER_SEC */
47
- addi r7,r7,1000000@l /* so we get microseconds in r4 */
39
+ LOAD_REG_IMMEDIATE(r7, 1000000) /* load up USEC_PER_SEC */
4840 bl __do_get_tspec@local /* get sec/usec from tb & kernel */
4941 stw r3,TVAL32_TV_SEC(r10)
5042 stw r4,TVAL32_TV_USEC(r10)
5143
5244 3: cmplwi r11,0 /* check if tz is NULL */
53
- beq 1f
45
+ mtlr r12
46
+ crclr cr0*4+so
47
+ li r3,0
48
+ beqlr
49
+
5450 lwz r4,CFG_TZ_MINUTEWEST(r9)/* fill tz */
5551 lwz r5,CFG_TZ_DSTTIME(r9)
5652 stw r4,TZONE_TZ_MINWEST(r11)
5753 stw r5,TZONE_TZ_DSTTIME(r11)
5854
59
-1: mtlr r12
60
- crclr cr0*4+so
61
- li r3,0
6255 blr
6356 .cfi_endproc
6457 V_FUNCTION_END(__kernel_gettimeofday)
....@@ -75,17 +68,23 @@
7568 cmpli cr0,r3,CLOCK_REALTIME
7669 cmpli cr1,r3,CLOCK_MONOTONIC
7770 cror cr0*4+eq,cr0*4+eq,cr1*4+eq
78
- bne cr0,99f
71
+
72
+ cmpli cr5,r3,CLOCK_REALTIME_COARSE
73
+ cmpli cr6,r3,CLOCK_MONOTONIC_COARSE
74
+ cror cr5*4+eq,cr5*4+eq,cr6*4+eq
75
+
76
+ cror cr0*4+eq,cr0*4+eq,cr5*4+eq
77
+ bne cr0, .Lgettime_fallback
7978
8079 mflr r12 /* r12 saves lr */
8180 .cfi_register lr,r12
8281 mr r11,r4 /* r11 saves tp */
83
- bl __get_datapage@local /* get data page */
84
- mr r9,r3 /* datapage ptr in r9 */
85
- lis r7,NSEC_PER_SEC@h /* want nanoseconds */
86
- ori r7,r7,NSEC_PER_SEC@l
87
-50: bl __do_get_tspec@local /* get sec/nsec from tb & kernel */
88
- bne cr1,80f /* not monotonic -> all done */
82
+ get_datapage r9, r0
83
+ LOAD_REG_IMMEDIATE(r7, NSEC_PER_SEC) /* load up NSEC_PER_SEC */
84
+ beq cr5, .Lcoarse_clocks
85
+.Lprecise_clocks:
86
+ bl __do_get_tspec@local /* get sec/nsec from tb & kernel */
87
+ bne cr1, .Lfinish /* not monotonic -> all done */
8988
9089 /*
9190 * CLOCK_MONOTONIC
....@@ -109,12 +108,53 @@
109108 add r9,r9,r0
110109 lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9)
111110 cmpl cr0,r8,r0 /* check if updated */
112
- bne- 50b
111
+ bne- .Lprecise_clocks
112
+ b .Lfinish_monotonic
113
+
114
+ /*
115
+ * For coarse clocks we get data directly from the vdso data page, so
116
+ * we don't need to call __do_get_tspec, but we still need to do the
117
+ * counter trick.
118
+ */
119
+.Lcoarse_clocks:
120
+ lwz r8,(CFG_TB_UPDATE_COUNT+LOPART)(r9)
121
+ andi. r0,r8,1 /* pending update ? loop */
122
+ bne- .Lcoarse_clocks
123
+ add r9,r9,r0 /* r0 is already 0 */
124
+
125
+ /*
126
+ * CLOCK_REALTIME_COARSE, below values are needed for MONOTONIC_COARSE
127
+ * too
128
+ */
129
+ lwz r3,STAMP_XTIME_SEC+LOPART(r9)
130
+ lwz r4,STAMP_XTIME_NSEC+LOPART(r9)
131
+ bne cr6,1f
132
+
133
+ /* CLOCK_MONOTONIC_COARSE */
134
+ lwz r5,(WTOM_CLOCK_SEC+LOPART)(r9)
135
+ lwz r6,WTOM_CLOCK_NSEC(r9)
136
+
137
+ /* check if counter has updated */
138
+ or r0,r6,r5
139
+1: or r0,r0,r3
140
+ or r0,r0,r4
141
+ xor r0,r0,r0
142
+ add r3,r3,r0
143
+ lwz r0,CFG_TB_UPDATE_COUNT+LOPART(r9)
144
+ cmpl cr0,r0,r8 /* check if updated */
145
+ bne- .Lcoarse_clocks
146
+
147
+ /* Counter has not updated, so continue calculating proper values for
148
+ * sec and nsec if monotonic coarse, or just return with the proper
149
+ * values for realtime.
150
+ */
151
+ bne cr6, .Lfinish
113152
114153 /* Calculate and store result. Note that this mimics the C code,
115154 * which may cause funny results if nsec goes negative... is that
116155 * possible at all ?
117156 */
157
+.Lfinish_monotonic:
118158 add r3,r3,r5
119159 add r4,r4,r6
120160 cmpw cr0,r4,r7
....@@ -122,11 +162,12 @@
122162 blt 1f
123163 subf r4,r7,r4
124164 addi r3,r3,1
125
-1: bge cr1,80f
165
+1: bge cr1, .Lfinish
126166 addi r3,r3,-1
127167 add r4,r4,r7
128168
129
-80: stw r3,TSPC32_TV_SEC(r11)
169
+.Lfinish:
170
+ stw r3,TSPC32_TV_SEC(r11)
130171 stw r4,TSPC32_TV_NSEC(r11)
131172
132173 mtlr r12
....@@ -137,7 +178,7 @@
137178 /*
138179 * syscall fallback
139180 */
140
-99:
181
+.Lgettime_fallback:
141182 li r0,__NR_clock_gettime
142183 .cfi_restore lr
143184 sc
....@@ -155,17 +196,20 @@
155196 V_FUNCTION_BEGIN(__kernel_clock_getres)
156197 .cfi_startproc
157198 /* Check for supported clock IDs */
158
- cmpwi cr0,r3,CLOCK_REALTIME
159
- cmpwi cr1,r3,CLOCK_MONOTONIC
160
- cror cr0*4+eq,cr0*4+eq,cr1*4+eq
161
- bne cr0,99f
199
+ cmplwi cr0, r3, CLOCK_MAX
200
+ cmpwi cr1, r3, CLOCK_REALTIME_COARSE
201
+ cmpwi cr7, r3, CLOCK_MONOTONIC_COARSE
202
+ bgt cr0, 99f
203
+ LOAD_REG_IMMEDIATE(r5, KTIME_LOW_RES)
204
+ beq cr1, 1f
205
+ beq cr7, 1f
162206
163207 mflr r12
164208 .cfi_register lr,r12
165
- bl __get_datapage@local /* get data page */
209
+ get_datapage r3, r0
166210 lwz r5, CLOCK_HRTIMER_RES(r3)
167211 mtlr r12
168
- li r3,0
212
+1: li r3,0
169213 cmpli cr0,r4,0
170214 crclr cr0*4+so
171215 beqlr
....@@ -196,16 +240,15 @@
196240 .cfi_register lr,r12
197241
198242 mr r11,r3 /* r11 holds t */
199
- bl __get_datapage@local
200
- mr r9, r3 /* datapage ptr in r9 */
243
+ get_datapage r9, r0
201244
202
- lwz r3,STAMP_XTIME+TSPEC_TV_SEC(r9)
245
+ lwz r3,STAMP_XTIME_SEC+LOPART(r9)
203246
204247 cmplwi r11,0 /* check if t is NULL */
205
- beq 2f
206
- stw r3,0(r11) /* store result at *t */
207
-2: mtlr r12
248
+ mtlr r12
208249 crclr cr0*4+so
250
+ beqlr
251
+ stw r3,0(r11) /* store result at *t */
209252 blr
210253 .cfi_endproc
211254 V_FUNCTION_END(__kernel_time)
....@@ -275,7 +318,7 @@
275318 * as a 32.32 fixed-point number in r3 and r4.
276319 * Load & add the xtime stamp.
277320 */
278
- lwz r5,STAMP_XTIME+TSPEC_TV_SEC(r9)
321
+ lwz r5,STAMP_XTIME_SEC+LOPART(r9)
279322 lwz r6,STAMP_SEC_FRAC(r9)
280323 addc r4,r4,r6
281324 adde r3,r3,r5