-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
target/arm: Handle overflow in calculation of next timer tick
In commit edac4d8 back in 2015 when we added support for the virtual timer offset CNTVOFF_EL2, we didn't correctly update the timer-recalculation code that figures out when the timer interrupt is next going to change state. We got it wrong in two ways: * for the 0->1 transition, we didn't notice that gt->cval + offset can overflow a uint64_t * for the 1->0 transition, we didn't notice that the transition might now happen before the count rolls over, if offset > count In the former case, we end up trying to set the next interrupt for a time in the past, which results in QEMU hanging as the timer fires continuously. In the latter case, we would fail to update the interrupt status when we are supposed to. Fix the calculations in both cases. The test case is Alex Bennée's from the bug report, and tests the 0->1 transition overflow case. Fixes: edac4d8 ("target-arm: Add CNTVOFF_EL2") Cc: qemu-stable@nongnu.org Resolves: https://gitlab.com/qemu-project/qemu/-/issues/60 Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20231120173506.3729884-1-peter.maydell@linaro.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> (cherry picked from commit 8d37a14) Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
- Loading branch information
Showing
3 changed files
with
75 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* | ||
* Simple Virtual Timer Test | ||
* | ||
* Copyright (c) 2020 Linaro Ltd | ||
* | ||
* SPDX-License-Identifier: GPL-2.0-or-later | ||
*/ | ||
|
||
#include <inttypes.h> | ||
#include <minilib.h> | ||
|
||
/* grabbed from Linux */ | ||
#define __stringify_1(x...) #x | ||
#define __stringify(x...) __stringify_1(x) | ||
|
||
#define read_sysreg(r) ({ \ | ||
uint64_t __val; \ | ||
asm volatile("mrs %0, " __stringify(r) : "=r" (__val)); \ | ||
__val; \ | ||
}) | ||
|
||
#define write_sysreg(r, v) do { \ | ||
uint64_t __val = (uint64_t)(v); \ | ||
asm volatile("msr " __stringify(r) ", %x0" \ | ||
: : "rZ" (__val)); \ | ||
} while (0) | ||
|
||
int main(void) | ||
{ | ||
int i; | ||
|
||
ml_printf("VTimer Test\n"); | ||
|
||
write_sysreg(cntvoff_el2, 1); | ||
write_sysreg(cntv_cval_el0, -1); | ||
write_sysreg(cntv_ctl_el0, 1); | ||
|
||
ml_printf("cntvoff_el2=%lx\n", read_sysreg(cntvoff_el2)); | ||
ml_printf("cntv_cval_el0=%lx\n", read_sysreg(cntv_cval_el0)); | ||
ml_printf("cntv_ctl_el0=%lx\n", read_sysreg(cntv_ctl_el0)); | ||
|
||
/* Now read cval a few times */ | ||
for (i = 0; i < 10; i++) { | ||
ml_printf("%d: cntv_cval_el0=%lx\n", i, read_sysreg(cntv_cval_el0)); | ||
} | ||
|
||
return 0; | ||
} |