Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull timer fix from Thomas Gleixner:
"One more fix from the timer departement:

- Handle division of negative nanosecond values proper on 32bit.

A recent cleanup wrecked the sign handling of the dividend and
dropped the check for negative divisors"

* 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
ktime: Fix ktime_divns to do signed division

+29 -12
+21 -6
include/linux/ktime.h
··· 166 166 } 167 167 168 168 #if BITS_PER_LONG < 64 169 - extern u64 __ktime_divns(const ktime_t kt, s64 div); 170 - static inline u64 ktime_divns(const ktime_t kt, s64 div) 169 + extern s64 __ktime_divns(const ktime_t kt, s64 div); 170 + static inline s64 ktime_divns(const ktime_t kt, s64 div) 171 171 { 172 + /* 173 + * Negative divisors could cause an inf loop, 174 + * so bug out here. 175 + */ 176 + BUG_ON(div < 0); 172 177 if (__builtin_constant_p(div) && !(div >> 32)) { 173 - u64 ns = kt.tv64; 174 - do_div(ns, div); 175 - return ns; 178 + s64 ns = kt.tv64; 179 + u64 tmp = ns < 0 ? -ns : ns; 180 + 181 + do_div(tmp, div); 182 + return ns < 0 ? -tmp : tmp; 176 183 } else { 177 184 return __ktime_divns(kt, div); 178 185 } 179 186 } 180 187 #else /* BITS_PER_LONG < 64 */ 181 - # define ktime_divns(kt, div) (u64)((kt).tv64 / (div)) 188 + static inline s64 ktime_divns(const ktime_t kt, s64 div) 189 + { 190 + /* 191 + * 32-bit implementation cannot handle negative divisors, 192 + * so catch them on 64bit as well. 193 + */ 194 + WARN_ON(div < 0); 195 + return kt.tv64 / div; 196 + } 182 197 #endif 183 198 184 199 static inline s64 ktime_to_us(const ktime_t kt)
+8 -6
kernel/time/hrtimer.c
··· 266 266 /* 267 267 * Divide a ktime value by a nanosecond value 268 268 */ 269 - u64 __ktime_divns(const ktime_t kt, s64 div) 269 + s64 __ktime_divns(const ktime_t kt, s64 div) 270 270 { 271 - u64 dclc; 272 271 int sft = 0; 272 + s64 dclc; 273 + u64 tmp; 273 274 274 275 dclc = ktime_to_ns(kt); 276 + tmp = dclc < 0 ? -dclc : dclc; 277 + 275 278 /* Make sure the divisor is less than 2^32: */ 276 279 while (div >> 32) { 277 280 sft++; 278 281 div >>= 1; 279 282 } 280 - dclc >>= sft; 281 - do_div(dclc, (unsigned long) div); 282 - 283 - return dclc; 283 + tmp >>= sft; 284 + do_div(tmp, (unsigned long) div); 285 + return dclc < 0 ? -tmp : tmp; 284 286 } 285 287 EXPORT_SYMBOL_GPL(__ktime_divns); 286 288 #endif /* BITS_PER_LONG >= 64 */