1 | /* |
---|---|
2 | * Copyright (C) 2001 Andrea Arcangeli <andrea@suse.de> SuSE |
3 | * Copyright 2003 Andi Kleen, SuSE Labs. |
4 | * |
5 | * Thanks to hpa@transmeta.com for some useful hint. |
6 | * Special thanks to Ingo Molnar for his early experience with |
7 | * a different vsyscall implementation for Linux/IA32 and for the name. |
8 | */ |
9 | |
10 | #include <linux/time.h> |
11 | #include <linux/timekeeper_internal.h> |
12 | |
13 | #include <asm/vvar.h> |
14 | |
15 | void update_vsyscall_tz(void) |
16 | { |
17 | if (unlikely(vvar_data == NULL)) |
18 | return; |
19 | |
20 | vvar_data->tz_minuteswest = sys_tz.tz_minuteswest; |
21 | vvar_data->tz_dsttime = sys_tz.tz_dsttime; |
22 | } |
23 | |
24 | void update_vsyscall(struct timekeeper *tk) |
25 | { |
26 | struct vvar_data *vdata = vvar_data; |
27 | |
28 | if (unlikely(vdata == NULL)) |
29 | return; |
30 | |
31 | vvar_write_begin(vdata); |
32 | vdata->vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode; |
33 | vdata->clock.cycle_last = tk->tkr_mono.cycle_last; |
34 | vdata->clock.mask = tk->tkr_mono.mask; |
35 | vdata->clock.mult = tk->tkr_mono.mult; |
36 | vdata->clock.shift = tk->tkr_mono.shift; |
37 | |
38 | vdata->wall_time_sec = tk->xtime_sec; |
39 | vdata->wall_time_snsec = tk->tkr_mono.xtime_nsec; |
40 | |
41 | vdata->monotonic_time_sec = tk->xtime_sec + |
42 | tk->wall_to_monotonic.tv_sec; |
43 | vdata->monotonic_time_snsec = tk->tkr_mono.xtime_nsec + |
44 | (tk->wall_to_monotonic.tv_nsec << |
45 | tk->tkr_mono.shift); |
46 | |
47 | while (vdata->monotonic_time_snsec >= |
48 | (((u64)NSEC_PER_SEC) << tk->tkr_mono.shift)) { |
49 | vdata->monotonic_time_snsec -= |
50 | ((u64)NSEC_PER_SEC) << tk->tkr_mono.shift; |
51 | vdata->monotonic_time_sec++; |
52 | } |
53 | |
54 | vdata->wall_time_coarse_sec = tk->xtime_sec; |
55 | vdata->wall_time_coarse_nsec = |
56 | (long)(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift); |
57 | |
58 | vdata->monotonic_time_coarse_sec = |
59 | vdata->wall_time_coarse_sec + tk->wall_to_monotonic.tv_sec; |
60 | vdata->monotonic_time_coarse_nsec = |
61 | vdata->wall_time_coarse_nsec + tk->wall_to_monotonic.tv_nsec; |
62 | |
63 | while (vdata->monotonic_time_coarse_nsec >= NSEC_PER_SEC) { |
64 | vdata->monotonic_time_coarse_nsec -= NSEC_PER_SEC; |
65 | vdata->monotonic_time_coarse_sec++; |
66 | } |
67 | |
68 | vvar_write_end(vdata); |
69 | } |
70 |