diff options
author | Nathan Lynch <nathan_lynch@mentor.com> | 2015-08-07 22:03:23 -0400 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2015-08-10 10:37:45 -0400 |
commit | 878854a374620a3f5e8c0a3c418e82a429bc2cff (patch) | |
tree | edcf287f8f7829e25067bdda041cdcb53ef473ef | |
parent | f7644cbfcdf03528f0f450f3940c4985b2291f49 (diff) |
arm64: VDSO: fix coarse clock monotonicity regression
Since 906c55579a63 ("timekeeping: Copy the shadow-timekeeper over the
real timekeeper last") it has become possible on arm64 to:
- Obtain a CLOCK_MONOTONIC_COARSE or CLOCK_REALTIME_COARSE timestamp
via syscall.
- Subsequently obtain a timestamp for the same clock ID via VDSO which
predates the first timestamp (by one jiffy).
This is because arm64's update_vsyscall is deriving the coarse time
using the __current_kernel_time interface, when it should really be
using the timekeeper object provided to it by the timekeeping core.
It happened to work before only because __current_kernel_time would
access the same timekeeper object which had been passed to
update_vsyscall. This is no longer the case.
Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>
Acked-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
-rw-r--r-- | arch/arm64/kernel/vdso.c | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index ec37ab3f524f..97bc68f4c689 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c | |||
@@ -199,16 +199,15 @@ up_fail: | |||
199 | */ | 199 | */ |
200 | void update_vsyscall(struct timekeeper *tk) | 200 | void update_vsyscall(struct timekeeper *tk) |
201 | { | 201 | { |
202 | struct timespec xtime_coarse; | ||
203 | u32 use_syscall = strcmp(tk->tkr_mono.clock->name, "arch_sys_counter"); | 202 | u32 use_syscall = strcmp(tk->tkr_mono.clock->name, "arch_sys_counter"); |
204 | 203 | ||
205 | ++vdso_data->tb_seq_count; | 204 | ++vdso_data->tb_seq_count; |
206 | smp_wmb(); | 205 | smp_wmb(); |
207 | 206 | ||
208 | xtime_coarse = __current_kernel_time(); | ||
209 | vdso_data->use_syscall = use_syscall; | 207 | vdso_data->use_syscall = use_syscall; |
210 | vdso_data->xtime_coarse_sec = xtime_coarse.tv_sec; | 208 | vdso_data->xtime_coarse_sec = tk->xtime_sec; |
211 | vdso_data->xtime_coarse_nsec = xtime_coarse.tv_nsec; | 209 | vdso_data->xtime_coarse_nsec = tk->tkr_mono.xtime_nsec >> |
210 | tk->tkr_mono.shift; | ||
212 | vdso_data->wtm_clock_sec = tk->wall_to_monotonic.tv_sec; | 211 | vdso_data->wtm_clock_sec = tk->wall_to_monotonic.tv_sec; |
213 | vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec; | 212 | vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec; |
214 | 213 | ||