diff options
author | Vincenzo Frascino <vincenzo.frascino@arm.com> | 2019-04-16 17:14:30 +0100 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2019-04-16 18:15:56 +0100 |
commit | 81fb8736dd81da3fe94f28968dac60f392ec6746 (patch) | |
tree | 10b8e1dc7cfa6a70d87a9dc72cf6bc724fe5c05e /arch/arm64/kernel/vdso.c | |
parent | 22e6c8087e175bc5c507b4e45d1ca588b2bcc61c (diff) | |
download | lwn-81fb8736dd81da3fe94f28968dac60f392ec6746.tar.gz lwn-81fb8736dd81da3fe94f28968dac60f392ec6746.zip |
arm64: vdso: Fix clock_getres() for CLOCK_REALTIME
clock_getres() in the vDSO library has to preserve the same behaviour
of posix_get_hrtimer_res().
In particular, posix_get_hrtimer_res() does:
sec = 0;
ns = hrtimer_resolution;
where 'hrtimer_resolution' depends on whether or not high resolution
timers are enabled, which is a runtime decision.
The vDSO incorrectly returns the constant CLOCK_REALTIME_RES. Fix this
by exposing 'hrtimer_resolution' in the vDSO datapage and returning that
instead.
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
[will: Use WRITE_ONCE(), move adr off COARSE path, renumber labels, use 'w' reg]
Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm64/kernel/vdso.c')
-rw-r--r-- | arch/arm64/kernel/vdso.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 9fb0c0c95a85..42b7082029e1 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -230,6 +230,9 @@ void update_vsyscall(struct timekeeper *tk) vdso_data->wtm_clock_sec = tk->wall_to_monotonic.tv_sec; vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec; + /* Read without the seqlock held by clock_getres() */ + WRITE_ONCE(vdso_data->hrtimer_res, hrtimer_resolution); + if (!use_syscall) { /* tkr_mono.cycle_last == tkr_raw.cycle_last */ vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last; |