hw/rtc/mc146818rtc.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
Under situation where virtual machine is running in a deployment where
the system time is unstable, there is a chance that legacy OpenStack
Windows machines without stimer enabled will crash if system time moves
backwards and diftfix=slew is enabled. This primarily caused by the fact
the system time moves faster than NTP server and after synchronization,
system time flows backwards.
Signed-off-by: shenjiatong <yshxxsjt715@163.com>
---
hw/rtc/mc146818rtc.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c
index 8ccee9a385..fa5d7915b1 100644
--- a/hw/rtc/mc146818rtc.c
+++ b/hw/rtc/mc146818rtc.c
@@ -180,7 +180,6 @@ static void periodic_timer_update(MC146818RtcState *s, int64_t current_time,
RTC_CLOCK_RATE, NANOSECONDS_PER_SECOND);
last_periodic_clock = next_periodic_clock - old_period;
lost_clock = cur_clock - last_periodic_clock;
- assert(lost_clock >= 0);
}
/*
@@ -199,10 +198,15 @@ static void periodic_timer_update(MC146818RtcState *s, int64_t current_time,
*/
if (s->lost_tick_policy == LOST_TICK_POLICY_SLEW) {
uint32_t old_irq_coalesced = s->irq_coalesced;
+ if (lost_clock >= 0) {
+ lost_clock += old_irq_coalesced * old_period;
+ s->irq_coalesced = lost_clock / s->period;
+ lost_clock %= s->period;
+ } else {
+ s->irq_coalesced = 0;
+ lost_clock = 0;
+ }
- lost_clock += old_irq_coalesced * old_period;
- s->irq_coalesced = lost_clock / s->period;
- lost_clock %= s->period;
if (old_irq_coalesced != s->irq_coalesced ||
old_period != s->period) {
DPRINTF_C("cmos: coalesced irqs scaled from %d to %d, "
@@ -215,6 +219,7 @@ static void periodic_timer_update(MC146818RtcState *s, int64_t current_time,
* no way to compensate the interrupt if LOST_TICK_POLICY_SLEW
* is not used, we should make the time progress anyway.
*/
+ lost_clock = MAX(0, lost_clock);
lost_clock = MIN(lost_clock, period);
}
--
2.43.0
© 2016 - 2024 Red Hat, Inc.