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/seqlock.h> 11 #include <linux/time.h> 12 #include <linux/timekeeper_internal.h> 13 14 #include <asm/vvar.h> 15 16 void update_vsyscall_tz(void) 17 { 18 if (unlikely(vvar_data == NULL)) 19 return; 20 21 vvar_data->tz_minuteswest = sys_tz.tz_minuteswest; 22 vvar_data->tz_dsttime = sys_tz.tz_dsttime; 23 } 24 25 void update_vsyscall(struct timekeeper *tk) 26 { 27 struct vvar_data *vdata = vvar_data; 28 29 if (unlikely(vdata == NULL)) 30 return; 31 32 vvar_write_begin(vdata); 33 vdata->vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode; 34 vdata->clock.cycle_last = tk->tkr_mono.cycle_last; 35 vdata->clock.mask = tk->tkr_mono.mask; 36 vdata->clock.mult = tk->tkr_mono.mult; 37 vdata->clock.shift = tk->tkr_mono.shift; 38 39 vdata->wall_time_sec = tk->xtime_sec; 40 vdata->wall_time_snsec = tk->tkr_mono.xtime_nsec; 41 42 vdata->monotonic_time_sec = tk->xtime_sec + 43 tk->wall_to_monotonic.tv_sec; 44 vdata->monotonic_time_snsec = tk->tkr_mono.xtime_nsec + 45 (tk->wall_to_monotonic.tv_nsec << 46 tk->tkr_mono.shift); 47 48 while (vdata->monotonic_time_snsec >= 49 (((u64)NSEC_PER_SEC) << tk->tkr_mono.shift)) { 50 vdata->monotonic_time_snsec -= 51 ((u64)NSEC_PER_SEC) << tk->tkr_mono.shift; 52 vdata->monotonic_time_sec++; 53 } 54 55 vdata->wall_time_coarse_sec = tk->xtime_sec; 56 vdata->wall_time_coarse_nsec = 57 (long)(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift); 58 59 vdata->monotonic_time_coarse_sec = 60 vdata->wall_time_coarse_sec + tk->wall_to_monotonic.tv_sec; 61 vdata->monotonic_time_coarse_nsec = 62 vdata->wall_time_coarse_nsec + tk->wall_to_monotonic.tv_nsec; 63 64 while (vdata->monotonic_time_coarse_nsec >= NSEC_PER_SEC) { 65 vdata->monotonic_time_coarse_nsec -= NSEC_PER_SEC; 66 vdata->monotonic_time_coarse_sec++; 67 } 68 69 vvar_write_end(vdata); 70 } 71