[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20060901203206.49ab445a.akpm@osdl.org>
Date: Fri, 1 Sep 2006 20:32:06 -0700
From: Andrew Morton <akpm@...l.org>
To: tglx@...utronix.de, Ingo Molnar <mingo@...e.hu>,
LKML <linux-kernel@...r.kernel.org>, Frank v Waveren <fvw@....cx>
Subject: Re: [PATCH] prevent timespec/timeval to ktime_t overflow
On Fri, 1 Sep 2006 20:13:05 -0700
Andrew Morton <akpm@...l.org> wrote:
> So I modified it to only trigger if current->mm!=NULL and:
Hey, that worked.
With this patch:
diff -puN include/linux/ktime.h~ktime-debug include/linux/ktime.h
--- a/include/linux/ktime.h~ktime-debug
+++ a/include/linux/ktime.h
@@ -57,6 +57,7 @@ typedef union {
} ktime_t;
#define KTIME_MAX (~((u64)1 << 63))
+#define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC)
/*
* ktime_t definitions when using the 64-bit scalar representation:
@@ -64,17 +65,7 @@ typedef union {
#if (BITS_PER_LONG == 64) || defined(CONFIG_KTIME_SCALAR)
-/**
- * ktime_set - Set a ktime_t variable from a seconds/nanoseconds value
- * @secs: seconds to set
- * @nsecs: nanoseconds to set
- *
- * Return the ktime_t representation of the value
- */
-static inline ktime_t ktime_set(const long secs, const unsigned long nsecs)
-{
- return (ktime_t) { .tv64 = (s64)secs * NSEC_PER_SEC + (s64)nsecs };
-}
+ktime_t ktime_set(const long secs, const unsigned long nsecs);
/* Subtract two ktime_t variables. rem = lhs -rhs: */
#define ktime_sub(lhs, rhs) \
diff -puN kernel/hrtimer.c~ktime-debug kernel/hrtimer.c
--- a/kernel/hrtimer.c~ktime-debug
+++ a/kernel/hrtimer.c
@@ -870,3 +870,32 @@ void __init hrtimers_init(void)
register_cpu_notifier(&hrtimers_nb);
}
+
+#if (BITS_PER_LONG == 64) || defined(CONFIG_KTIME_SCALAR)
+
+/**
+ * ktime_set - Set a ktime_t variable from a seconds/nanoseconds value
+ * @secs: seconds to set
+ * @nsecs: nanoseconds to set
+ *
+ * Return the ktime_t representation of the value
+ */
+ktime_t ktime_set(const long secs, const unsigned long nsecs)
+{
+#if (BITS_PER_LONG == 64)
+ static int no88bigabytes = 0;
+
+ if (current->mm && unlikely(secs >= KTIME_SEC_MAX)) {
+ if (!no88bigabytes) {
+ no88bigabytes = 1;
+ printk("ktime_set: %ld : %lu\n", secs, nsecs);
+ WARN_ON(1);
+ }
+ return (ktime_t){ .tv64 = KTIME_MAX };
+ }
+#endif
+ return (ktime_t) { .tv64 = (s64)secs * NSEC_PER_SEC + (s64)nsecs };
+}
+EXPORT_SYMBOL(ktime_set);
+
+#endif
_
It emits that interrupt-time warning and gets to a login prompt.
But with this patch, which is the same thing with the debug stuff removed:
diff -puN include/linux/ktime.h~ktime-debug include/linux/ktime.h
--- a/include/linux/ktime.h~ktime-debug
+++ a/include/linux/ktime.h
@@ -57,6 +57,7 @@ typedef union {
} ktime_t;
#define KTIME_MAX (~((u64)1 << 63))
+#define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC)
/*
* ktime_t definitions when using the 64-bit scalar representation:
@@ -64,17 +65,7 @@ typedef union {
#if (BITS_PER_LONG == 64) || defined(CONFIG_KTIME_SCALAR)
-/**
- * ktime_set - Set a ktime_t variable from a seconds/nanoseconds value
- * @secs: seconds to set
- * @nsecs: nanoseconds to set
- *
- * Return the ktime_t representation of the value
- */
-static inline ktime_t ktime_set(const long secs, const unsigned long nsecs)
-{
- return (ktime_t) { .tv64 = (s64)secs * NSEC_PER_SEC + (s64)nsecs };
-}
+ktime_t ktime_set(const long secs, const unsigned long nsecs);
/* Subtract two ktime_t variables. rem = lhs -rhs: */
#define ktime_sub(lhs, rhs) \
diff -puN kernel/hrtimer.c~ktime-debug kernel/hrtimer.c
--- a/kernel/hrtimer.c~ktime-debug
+++ a/kernel/hrtimer.c
@@ -870,3 +870,24 @@ void __init hrtimers_init(void)
register_cpu_notifier(&hrtimers_nb);
}
+
+#if (BITS_PER_LONG == 64) || defined(CONFIG_KTIME_SCALAR)
+
+/**
+ * ktime_set - Set a ktime_t variable from a seconds/nanoseconds value
+ * @secs: seconds to set
+ * @nsecs: nanoseconds to set
+ *
+ * Return the ktime_t representation of the value
+ */
+ktime_t ktime_set(const long secs, const unsigned long nsecs)
+{
+#if (BITS_PER_LONG == 64)
+ if (unlikely(secs >= KTIME_SEC_MAX))
+ return (ktime_t){ .tv64 = KTIME_MAX };
+#endif
+ return (ktime_t) { .tv64 = (s64)secs * NSEC_PER_SEC + (s64)nsecs };
+}
+EXPORT_SYMBOL(ktime_set);
+
+#endif
_
it hangs in udev startup.
How very unpleasant. gcc-4.0.2.
--
VGER BF report: H 0
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists