summaryrefslogtreecommitdiff
path: root/arch/arm64/kernel/vdso.c
diff options
context:
space:
mode:
authorVincenzo Frascino <vincenzo.frascino@arm.com>2019-04-16 17:14:30 +0100
committerWill Deacon <will.deacon@arm.com>2019-04-16 18:15:56 +0100
commit81fb8736dd81da3fe94f28968dac60f392ec6746 (patch)
tree10b8e1dc7cfa6a70d87a9dc72cf6bc724fe5c05e /arch/arm64/kernel/vdso.c
parent22e6c8087e175bc5c507b4e45d1ca588b2bcc61c (diff)
downloadlwn-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.c3
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;