Commit 5878fc93 authored by Kevin Cernekee's avatar Kevin Cernekee Committed by Ralf Baechle

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: default avatarKevin Cernekee <cernekee@gmail.com>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/1836/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 190fca3e
...@@ -32,7 +32,7 @@ static int mips_next_event(unsigned long delta, ...@@ -32,7 +32,7 @@ static int mips_next_event(unsigned long delta,
cnt = read_c0_count(); cnt = read_c0_count();
cnt += delta; cnt += delta;
write_c0_compare(cnt); write_c0_compare(cnt);
res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0; res = ((int)(read_c0_count() - cnt) >= 0) ? -ETIME : 0;
return res; return res;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment