[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <444ef6c4bbb47d55c700452d8cd23229@localhost>
Date: Tue, 23 Nov 2010 10:26:44 -0800
From: Kevin Cernekee <cernekee@...il.com>
To: Ralf Baechle <ralf@...ux-mips.org>
Cc: <linux-mips@...ux-mips.org>, <linux-kernel@...r.kernel.org>
Subject: [PATCH 6/7] MIPS: Fix CP0 COUNTER clockevent race
Consider the following test case:
write_c0_compare(read_c0_count());
Even if the counter doesn't increment during execution, this might not
generate an interrupt until the counter wraps around. The CPU may
perform the comparison each time CP0 COUNT increments, not when CP0
COMPARE is written.
If mips_next_event() is called with a very small delta, and CP0 COUNT
increments during the calculation of "cnt += delta", it is possible
that CP0 COMPARE will be written with the current value of CP0 COUNT.
If this is detected, the function should return -ETIME, to indicate
that the interrupt might not have actually gotten scheduled.
Signed-off-by: Kevin Cernekee <cernekee@...il.com>
---
arch/mips/kernel/cevt-r4k.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
index 2f4d7a9..98c5a97 100644
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -32,7 +32,7 @@ static int mips_next_event(unsigned long delta,
cnt = read_c0_count();
cnt += delta;
write_c0_compare(cnt);
- res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0;
+ res = ((int)(read_c0_count() - cnt) >= 0) ? -ETIME : 0;
return res;
}
--
1.7.0.4
--
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