[v3.19] ktime: Fix ktime_divns to do signed division

Message ID 1430502405-13378-1-git-send-email-john.stultz@linaro.org
State New
Headers show

Commit Message

John Stultz May 1, 2015, 5:46 p.m.
It was noted that the 32bit implementation of ktime_divns
was doing unsgined division adn didn't properly handle
negative values.

This patch fixes the problem by checking and preserving
the sign bit, and then reapplying it if appropriate
after the division.

Reported-by: Trevor Cordes <trevor@tecnopolis.ca>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 kernel/time/hrtimer.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index d8c724c..aaf44a07 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -266,12 +266,17 @@  lock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags)
 /*
  * Divide a ktime value by a nanosecond value
  */
-u64 ktime_divns(const ktime_t kt, s64 div)
+s64 ktime_divns(const ktime_t kt, s64 div)
 {
-	u64 dclc;
+	s64 dclc;
 	int sft = 0;
+	int neg = 0;
 
 	dclc = ktime_to_ns(kt);
+	if (dclc < 0) {
+		neg = 1;
+		dclc = -dclc;
+	}
 	/* Make sure the divisor is less than 2^32: */
 	while (div >> 32) {
 		sft++;
@@ -280,6 +285,8 @@  u64 ktime_divns(const ktime_t kt, s64 div)
 	dclc >>= sft;
 	do_div(dclc, (unsigned long) div);
 
+	if (neg)
+		dclc = -dclc;
 	return dclc;
 }
 EXPORT_SYMBOL_GPL(ktime_divns);