summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'tags/2.6.21-1/20961_linux-2.6-xen-backwards-time.patch')
-rw-r--r--tags/2.6.21-1/20961_linux-2.6-xen-backwards-time.patch63
1 files changed, 63 insertions, 0 deletions
diff --git a/tags/2.6.21-1/20961_linux-2.6-xen-backwards-time.patch b/tags/2.6.21-1/20961_linux-2.6-xen-backwards-time.patch
new file mode 100644
index 0000000..f15994e
--- /dev/null
+++ b/tags/2.6.21-1/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();