[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 06/10] target/arm: Detect overflow when calculating next PMU i
From: |
Peter Maydell |
Subject: |
[PATCH v2 06/10] target/arm: Detect overflow when calculating next PMU interrupt |
Date: |
Mon, 22 Aug 2022 14:23:54 +0100 |
In pmccntr_op_finish() and pmevcntr_op_finish() we calculate the next
point at which we will get an overflow and need to fire the PMU
interrupt or set the overflow flag. We do this by calculating the
number of nanoseconds to the overflow event and then adding it to
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL). However, we don't check
whether that signed addition overflows, which can happen if the next
PMU interrupt would happen massively far in the future (250 years or
more).
Since QEMU assumes that "when the QEMU_CLOCK_VIRTUAL rolls over" is
"never", the sensible behaviour in this situation is simply to not
try to set the timer if it would be beyond that point. Detect the
overflow, and skip setting the timer in that case.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
v1->v2: fixed bogus indentation
---
target/arm/helper.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 7d4127a1573..94307a6c417 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1227,10 +1227,13 @@ static void pmccntr_op_finish(CPUARMState *env)
int64_t overflow_in = cycles_ns_per(remaining_cycles);
if (overflow_in > 0) {
- int64_t overflow_at = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
- overflow_in;
- ARMCPU *cpu = env_archcpu(env);
- timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at);
+ int64_t overflow_at;
+
+ if (!sadd64_overflow(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
+ overflow_in, &overflow_at)) {
+ ARMCPU *cpu = env_archcpu(env);
+ timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at);
+ }
}
#endif
@@ -1275,10 +1278,13 @@ static void pmevcntr_op_finish(CPUARMState *env,
uint8_t counter)
int64_t overflow_in = pm_events[event_idx].ns_per_count(delta);
if (overflow_in > 0) {
- int64_t overflow_at = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
- overflow_in;
- ARMCPU *cpu = env_archcpu(env);
- timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at);
+ int64_t overflow_at;
+
+ if (!sadd64_overflow(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
+ overflow_in, &overflow_at)) {
+ ARMCPU *cpu = env_archcpu(env);
+ timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at);
+ }
}
#endif
--
2.25.1
- [PATCH v2 00/10] target/arm: Implement FEAT_PMUv3p5, Peter Maydell, 2022/08/22
- [PATCH v2 02/10] target/arm: Correct value returned by pmu_counter_mask(), Peter Maydell, 2022/08/22
- [PATCH v2 01/10] target/arm: Don't corrupt high half of PMOVSR when cycle counter overflows, Peter Maydell, 2022/08/22
- [PATCH v2 03/10] target/arm: Don't mishandle count when enabling or disabling PMU counters, Peter Maydell, 2022/08/22
- [PATCH v2 04/10] target/arm: Ignore PMCR.D when PMCR.LC is set, Peter Maydell, 2022/08/22
- [PATCH v2 05/10] target/arm: Honour MDCR_EL2.HPMD in Secure EL2, Peter Maydell, 2022/08/22
- [PATCH v2 06/10] target/arm: Detect overflow when calculating next PMU interrupt,
Peter Maydell <=
- [PATCH v2 07/10] target/arm: Rename pmu_8_n feature test functions, Peter Maydell, 2022/08/22
- [PATCH v2 10/10] target/arm: Report FEAT_PMUv3p5 for TCG '-cpu max', Peter Maydell, 2022/08/22
- [PATCH v2 08/10] target/arm: Implement FEAT_PMUv3p5 cycle counter disable bits, Peter Maydell, 2022/08/22
- [PATCH v2 09/10] target/arm: Support 64-bit event counters for FEAT_PMUv3p5, Peter Maydell, 2022/08/22
- Re: [PATCH v2 00/10] target/arm: Implement FEAT_PMUv3p5, Richard Henderson, 2022/08/23