diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 98cfc90cab1d4916e9664fa01cca00bb41801662..2bb84214e5f1384f2208b47f637a644aa94e747e 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -371,6 +371,11 @@ ia64_setup_printk_clock(void) ia64_printk_clock = ia64_itc_printk_clock; } +/* IA64 doesn't cache the timezone */ +void update_vsyscall_tz(void) +{ +} + void update_vsyscall(struct timespec *wall, struct clocksource *c) { unsigned long flags; diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index 8a67e282cb5e69837a9fbba529428de8f78201e0..f24e8acdec9160742d4913fef6fa5a694e6a0ce7 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c @@ -64,6 +64,16 @@ struct vsyscall_gtod_data __vsyscall_gtod_data __section_vsyscall_gtod_data = .sysctl_enabled = 1, }; +void update_vsyscall_tz(void) +{ + unsigned long flags; + + write_seqlock_irqsave(&vsyscall_gtod_data.lock, flags); + /* sys_tz has changed */ + vsyscall_gtod_data.sys_tz = sys_tz; + write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags); +} + void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) { unsigned long flags; @@ -77,7 +87,6 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) vsyscall_gtod_data.clock.shift = clock->shift; vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec; vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec; - vsyscall_gtod_data.sys_tz = sys_tz; vsyscall_gtod_data.wall_to_monotonic = wall_to_monotonic; write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags); } diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 16ea3374dddf7a543501fca71718c5d72b885e07..107787aacb647c95c37f53bf94d2660486d687a3 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -221,10 +221,15 @@ extern void clocksource_resume(void); #ifdef CONFIG_GENERIC_TIME_VSYSCALL extern void update_vsyscall(struct timespec *ts, struct clocksource *c); +extern void update_vsyscall_tz(void); #else static inline void update_vsyscall(struct timespec *ts, struct clocksource *c) { } + +static inline void update_vsyscall_tz(void) +{ +} #endif #endif /* _LINUX_CLOCKSOURCE_H */ diff --git a/kernel/time.c b/kernel/time.c index 2d5b6a682138d12af18eb2b93caeca9c4443c56f..d9725bdcd04558457a61aba188371acdbfabe402 100644 --- a/kernel/time.c +++ b/kernel/time.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -158,6 +159,7 @@ int do_sys_settimeofday(struct timespec *tv, struct timezone *tz) if (tz) { /* SMP safe, global irq locking makes it work. */ sys_tz = *tz; + update_vsyscall_tz(); if (firsttime) { firsttime = 0; if (!tv)