2014-03-17 23:22:01 +01:00
/*
* Copyright ( C ) 2001 Andrea Arcangeli < andrea @ suse . de > SuSE
* Copyright 2003 Andi Kleen , SuSE Labs .
*
* Modified for x86 32 bit architecture by
* Stefani Seibold < stefani @ seibold . net >
2014-03-17 23:22:10 +01:00
* sponsored by Rohde & Schwarz GmbH & Co . KG Munich / Germany
2014-03-17 23:22:01 +01:00
*
* Thanks to hpa @ transmeta . com for some useful hint .
* Special thanks to Ingo Molnar for his early experience with
* a different vsyscall implementation for Linux / IA32 and for the name .
*
*/
# include <linux/timekeeper_internal.h>
# include <asm/vgtod.h>
2014-03-17 23:22:10 +01:00
# include <asm/vvar.h>
2014-03-17 23:22:01 +01:00
DEFINE_VVAR ( struct vsyscall_gtod_data , vsyscall_gtod_data ) ;
void update_vsyscall_tz ( void )
{
2014-03-17 23:22:10 +01:00
vsyscall_gtod_data . tz_minuteswest = sys_tz . tz_minuteswest ;
vsyscall_gtod_data . tz_dsttime = sys_tz . tz_dsttime ;
2014-03-17 23:22:01 +01:00
}
void update_vsyscall ( struct timekeeper * tk )
{
struct vsyscall_gtod_data * vdata = & vsyscall_gtod_data ;
2014-03-17 23:22:10 +01:00
gtod_write_begin ( vdata ) ;
2014-03-17 23:22:01 +01:00
/* copy vsyscall data */
2014-03-17 23:22:10 +01:00
vdata - > vclock_mode = tk - > clock - > archdata . vclock_mode ;
vdata - > cycle_last = tk - > clock - > cycle_last ;
vdata - > mask = tk - > clock - > mask ;
vdata - > mult = tk - > mult ;
vdata - > shift = tk - > shift ;
2014-03-17 23:22:01 +01:00
vdata - > wall_time_sec = tk - > xtime_sec ;
vdata - > wall_time_snsec = tk - > xtime_nsec ;
vdata - > monotonic_time_sec = tk - > xtime_sec
+ tk - > wall_to_monotonic . tv_sec ;
vdata - > monotonic_time_snsec = tk - > xtime_nsec
2014-05-09 11:11:27 -04:00
+ ( ( u64 ) tk - > wall_to_monotonic . tv_nsec
2014-03-17 23:22:01 +01:00
< < tk - > shift ) ;
while ( vdata - > monotonic_time_snsec > =
( ( ( u64 ) NSEC_PER_SEC ) < < tk - > shift ) ) {
vdata - > monotonic_time_snsec - =
( ( u64 ) NSEC_PER_SEC ) < < tk - > shift ;
vdata - > monotonic_time_sec + + ;
}
2014-03-17 23:22:10 +01:00
vdata - > wall_time_coarse_sec = tk - > xtime_sec ;
vdata - > wall_time_coarse_nsec = ( long ) ( tk - > xtime_nsec > > tk - > shift ) ;
2014-03-17 23:22:01 +01:00
2014-03-17 23:22:10 +01:00
vdata - > monotonic_time_coarse_sec =
vdata - > wall_time_coarse_sec + tk - > wall_to_monotonic . tv_sec ;
vdata - > monotonic_time_coarse_nsec =
vdata - > wall_time_coarse_nsec + tk - > wall_to_monotonic . tv_nsec ;
2014-03-17 23:22:01 +01:00
2014-03-17 23:22:10 +01:00
while ( vdata - > monotonic_time_coarse_nsec > = NSEC_PER_SEC ) {
vdata - > monotonic_time_coarse_nsec - = NSEC_PER_SEC ;
vdata - > monotonic_time_coarse_sec + + ;
}
gtod_write_end ( vdata ) ;
2014-03-17 23:22:01 +01:00
}