diff options
Diffstat (limited to 'trunk/2.6.21/20961_linux-2.6-xen-backwards-time.patch')
-rw-r--r-- | trunk/2.6.21/20961_linux-2.6-xen-backwards-time.patch | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/trunk/2.6.21/20961_linux-2.6-xen-backwards-time.patch b/trunk/2.6.21/20961_linux-2.6-xen-backwards-time.patch new file mode 100644 index 0000000..f15994e --- /dev/null +++ b/trunk/2.6.21/20961_linux-2.6-xen-backwards-time.patch @@ -0,0 +1,63 @@ + +# HG changeset patch +# User kfraser@localhost.localdomain +# Date 1182263776 -3600 +# Node ID 87bb8705768a66ceabb15a419c5f86580bffb6bf +# Parent a413dd61e7e5e1bba11bab447184cf5e6b43513a +x86 time: Ensure gettimeofday() is monotonically increasing. +Signed-off-by: Atsushi SAKAI <sakaia@jp.fujitsu.com> + +Index: linux-2.6.21.i386/arch/i386/kernel/time-xen.c +=================================================================== +--- linux-2.6.21.i386.orig/arch/i386/kernel/time-xen.c ++++ linux-2.6.21.i386/arch/i386/kernel/time-xen.c +@@ -107,6 +107,9 @@ static DEFINE_PER_CPU(struct shadow_time + static struct timespec shadow_tv; + static u32 shadow_tv_version; + ++static struct timeval monotonic_tv; ++static spinlock_t monotonic_lock = SPIN_LOCK_UNLOCKED; ++ + /* Keep track of last time we did processing/updating of jiffies and xtime. */ + static u64 processed_system_time; /* System time (ns) at last processing. */ + static DEFINE_PER_CPU(u64, processed_system_time); +@@ -322,6 +325,7 @@ void do_gettimeofday(struct timeval *tv) + unsigned long seq; + unsigned long usec, sec; + unsigned long max_ntp_tick; ++ unsigned long flags; + s64 nsec; + unsigned int cpu; + struct shadow_time_info *shadow; +@@ -374,6 +378,18 @@ void do_gettimeofday(struct timeval *tv) + sec++; + } + ++ spin_lock_irqsave(&monotonic_lock, flags); ++ if ((sec > monotonic_tv.tv_sec) || ++ ((sec == monotonic_tv.tv_sec) && (usec > monotonic_tv.tv_usec))) ++ { ++ monotonic_tv.tv_sec = sec; ++ monotonic_tv.tv_usec = usec; ++ } else { ++ sec = monotonic_tv.tv_sec; ++ usec = monotonic_tv.tv_usec; ++ } ++ spin_unlock_irqrestore(&monotonic_lock, flags); ++ + tv->tv_sec = sec; + tv->tv_usec = usec; + } +@@ -423,6 +439,12 @@ int do_settimeofday(struct timespec *tv) + __update_wallclock(sec, nsec); + } + ++ /* Reset monotonic gettimeofday() timeval. */ ++ spin_lock(&monotonic_lock); ++ monotonic_tv.tv_sec = 0; ++ monotonic_tv.tv_usec = 0; ++ spin_unlock(&monotonic_lock); ++ + write_sequnlock_irq(&xtime_lock); + + put_cpu(); |