diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2006-05-20 18:00:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-05-21 15:59:21 -0400 |
commit | 92f63cd000059366af18712367216d96180e0ec0 (patch) | |
tree | 4f88c3875afaa8183d6cfcff685e03ac7684d82d | |
parent | 0662b71322e211dba9a4bc0e6fbca7861a2b5a7d (diff) |
[PATCH] s390: next_timer_interrupt overflow in stop_hz_timer
The 32 bit unsigned substraction (next - jiffies) in stop_hz_timer can
overflow if jiffies gets advanced between next_timer_interrupt and the read
under the xtime lock. The cast to a u64 then results in a large value
which causes the cpu to wait too long. Fix this by casting next and
jiffies independently to u64 before subtracting them.
(Spotted by Zachary Amsden <zach@vmware.com>)
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | arch/s390/kernel/time.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 029f09901b85..ce19ad4e92ec 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c | |||
@@ -272,7 +272,7 @@ static inline void stop_hz_timer(void) | |||
272 | next = next_timer_interrupt(); | 272 | next = next_timer_interrupt(); |
273 | do { | 273 | do { |
274 | seq = read_seqbegin_irqsave(&xtime_lock, flags); | 274 | seq = read_seqbegin_irqsave(&xtime_lock, flags); |
275 | timer = (__u64)(next - jiffies) + jiffies_64; | 275 | timer = (__u64 next) - (__u64 jiffies) + jiffies_64; |
276 | } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); | 276 | } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); |
277 | todval = -1ULL; | 277 | todval = -1ULL; |
278 | /* Be careful about overflows. */ | 278 | /* Be careful about overflows. */ |