Skip to content

Commit 9f24c54

Browse files
committed
lib/vdso: Update coarse timekeeper unconditionally
The low resolution parts of the VDSO, i.e.: clock_gettime(CLOCK_*_COARSE), clock_getres(), time() can be used even if there is no VDSO capable clocksource. But if an architecture opts out of the VDSO data update then this information becomes stale. This affects ARM when there is no architected timer available. The lack of update causes userspace to use stale data forever. Make the update of the low resolution parts unconditional and only skip the update of the high resolution parts if the architecture requests it. Fixes: 44f57d7 ("timekeeping: Provide a generic update_vsyscall() implementation") Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 9a6b55a commit 9f24c54

File tree

1 file changed

+17
-20
lines changed

1 file changed

+17
-20
lines changed

kernel/time/vsyscall.c

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,6 @@ static inline void update_vdso_data(struct vdso_data *vdata,
2828
vdata[CS_RAW].mult = tk->tkr_raw.mult;
2929
vdata[CS_RAW].shift = tk->tkr_raw.shift;
3030

31-
/* CLOCK_REALTIME */
32-
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
33-
vdso_ts->sec = tk->xtime_sec;
34-
vdso_ts->nsec = tk->tkr_mono.xtime_nsec;
35-
3631
/* CLOCK_MONOTONIC */
3732
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC];
3833
vdso_ts->sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec;
@@ -70,12 +65,6 @@ static inline void update_vdso_data(struct vdso_data *vdata,
7065
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_TAI];
7166
vdso_ts->sec = tk->xtime_sec + (s64)tk->tai_offset;
7267
vdso_ts->nsec = tk->tkr_mono.xtime_nsec;
73-
74-
/*
75-
* Read without the seqlock held by clock_getres().
76-
* Note: No need to have a second copy.
77-
*/
78-
WRITE_ONCE(vdata[CS_HRES_COARSE].hrtimer_res, hrtimer_resolution);
7968
}
8069

8170
void update_vsyscall(struct timekeeper *tk)
@@ -84,20 +73,17 @@ void update_vsyscall(struct timekeeper *tk)
8473
struct vdso_timestamp *vdso_ts;
8574
u64 nsec;
8675

87-
if (!__arch_update_vdso_data()) {
88-
/*
89-
* Some architectures might want to skip the update of the
90-
* data page.
91-
*/
92-
return;
93-
}
94-
9576
/* copy vsyscall data */
9677
vdso_write_begin(vdata);
9778

9879
vdata[CS_HRES_COARSE].clock_mode = __arch_get_clock_mode(tk);
9980
vdata[CS_RAW].clock_mode = __arch_get_clock_mode(tk);
10081

82+
/* CLOCK_REALTIME also required for time() */
83+
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
84+
vdso_ts->sec = tk->xtime_sec;
85+
vdso_ts->nsec = tk->tkr_mono.xtime_nsec;
86+
10187
/* CLOCK_REALTIME_COARSE */
10288
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME_COARSE];
10389
vdso_ts->sec = tk->xtime_sec;
@@ -110,7 +96,18 @@ void update_vsyscall(struct timekeeper *tk)
11096
nsec = nsec + tk->wall_to_monotonic.tv_nsec;
11197
vdso_ts->sec += __iter_div_u64_rem(nsec, NSEC_PER_SEC, &vdso_ts->nsec);
11298

113-
update_vdso_data(vdata, tk);
99+
/*
100+
* Read without the seqlock held by clock_getres().
101+
* Note: No need to have a second copy.
102+
*/
103+
WRITE_ONCE(vdata[CS_HRES_COARSE].hrtimer_res, hrtimer_resolution);
104+
105+
/*
106+
* Architectures can opt out of updating the high resolution part
107+
* of the VDSO.
108+
*/
109+
if (__arch_update_vdso_data())
110+
update_vdso_data(vdata, tk);
114111

115112
__arch_update_vsyscall(vdata, tk);
116113

0 commit comments

Comments
 (0)