2
2
/*
3
3
* Generic userspace implementations of gettimeofday() and similar.
4
4
*/
5
+ #include <vdso/auxclock.h>
5
6
#include <vdso/datapage.h>
6
7
#include <vdso/helpers.h>
7
8
@@ -74,7 +75,7 @@ static inline bool vdso_cycles_ok(u64 cycles)
74
75
static __always_inline bool vdso_clockid_valid (clockid_t clock )
75
76
{
76
77
/* Check for negative values or invalid clocks */
77
- return likely ((u32 ) clock < MAX_CLOCKS );
78
+ return likely ((u32 ) clock <= CLOCK_AUX_LAST );
78
79
}
79
80
80
81
/*
@@ -268,6 +269,48 @@ bool do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
268
269
return true;
269
270
}
270
271
272
+ static __always_inline
273
+ bool do_aux (const struct vdso_time_data * vd , clockid_t clock , struct __kernel_timespec * ts )
274
+ {
275
+ const struct vdso_clock * vc ;
276
+ u32 seq , idx ;
277
+ u64 sec , ns ;
278
+
279
+ if (!IS_ENABLED (CONFIG_POSIX_AUX_CLOCKS ))
280
+ return false;
281
+
282
+ idx = clock - CLOCK_AUX ;
283
+ vc = & vd -> aux_clock_data [idx ];
284
+
285
+ do {
286
+ /*
287
+ * Open coded function vdso_read_begin() to handle
288
+ * VDSO_CLOCK_TIMENS. See comment in do_hres().
289
+ */
290
+ while ((seq = READ_ONCE (vc -> seq )) & 1 ) {
291
+ if (IS_ENABLED (CONFIG_TIME_NS ) && vc -> clock_mode == VDSO_CLOCKMODE_TIMENS ) {
292
+ vd = __arch_get_vdso_u_timens_data (vd );
293
+ vc = & vd -> aux_clock_data [idx ];
294
+ /* Re-read from the real time data page */
295
+ continue ;
296
+ }
297
+ cpu_relax ();
298
+ }
299
+ smp_rmb ();
300
+
301
+ /* Auxclock disabled? */
302
+ if (vc -> clock_mode == VDSO_CLOCKMODE_NONE )
303
+ return false;
304
+
305
+ if (!vdso_get_timestamp (vd , vc , VDSO_BASE_AUX , & sec , & ns ))
306
+ return false;
307
+ } while (unlikely (vdso_read_retry (vc , seq )));
308
+
309
+ vdso_set_timespec (ts , sec , ns );
310
+
311
+ return true;
312
+ }
313
+
271
314
static __always_inline bool
272
315
__cvdso_clock_gettime_common (const struct vdso_time_data * vd , clockid_t clock ,
273
316
struct __kernel_timespec * ts )
@@ -289,6 +332,8 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
289
332
return do_coarse (vd , & vc [CS_HRES_COARSE ], clock , ts );
290
333
else if (msk & VDSO_RAW )
291
334
vc = & vc [CS_RAW ];
335
+ else if (msk & VDSO_AUX )
336
+ return do_aux (vd , clock , ts );
292
337
else
293
338
return false;
294
339
@@ -433,6 +478,8 @@ bool __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t cloc
433
478
* Preserves the behaviour of posix_get_coarse_res().
434
479
*/
435
480
ns = LOW_RES_NSEC ;
481
+ } else if (msk & VDSO_AUX ) {
482
+ ns = aux_clock_resolution_ns ();
436
483
} else {
437
484
return false;
438
485
}
0 commit comments