diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2010-06-04 10:50:28 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2010-06-04 10:50:28 +0100 |
commit | dce5093c7b29e485ea9b7ada9328c531ed950844 (patch) | |
tree | d92fca7c99900e483fdc1dadf1766aed0fb7657d | |
parent | 3df3cadf077aae259ea3f195da6ec81dc221961c (diff) | |
download | xen-dce5093c7b29e485ea9b7ada9328c531ed950844.tar.gz xen-dce5093c7b29e485ea9b7ada9328c531ed950844.tar.bz2 xen-dce5093c7b29e485ea9b7ada9328c531ed950844.zip |
Add a safety valve to the HVM RTC model for big time jumps
If xen's time leaps forward by a large amount, the RTC will try to
model a tick for every second that it thinks has passed. This can
livelock a CPU with a series of timer requests each of which fires
immediately and requests the next one.
This patch treats a delay of more than a day between ticks as a
special case, abandoning the attempt to catch up. That should be good
enough to avoid livelock but doesn't fix the underlying time problem.
Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>
xen-unstable changeset: 21515:1b6c9732436b
xen-unstable date: Fri Jun 04 10:05:42 2010 +0100
-rw-r--r-- | xen/arch/x86/hvm/rtc.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/xen/arch/x86/hvm/rtc.c b/xen/arch/x86/hvm/rtc.c index 1eb4854276..256c3c660e 100644 --- a/xen/arch/x86/hvm/rtc.c +++ b/xen/arch/x86/hvm/rtc.c @@ -281,9 +281,22 @@ static void rtc_next_second(RTCState *s) static void rtc_update_second(void *opaque) { RTCState *s = opaque; + s_time_t now = NOW(); spin_lock(&s->lock); + /* If we somehow get way out of sync (say, Xen time leaps forward), + * don't livelock the system trying to emulate every second. Time + * is already in bad trouble, so just skip forward rather than + * trying to sync the RTC registers */ + if ( unlikely(now - s->next_second_time > SECONDS(86400)) ) + { + dprintk(XENLOG_WARNING, "HVM RTC: dom %u skipping %llu seconds\n", + vrtc_domain(s)->domain_id, + (now - s->next_second_time) / SYSTEM_TIME_HZ); + s->next_second_time = now; + } + /* if the oscillator is not in normal operation, we do not update */ if ( (s->hw.cmos_data[RTC_REG_A] & RTC_DIV_CTL) != RTC_REF_CLCK_32KHZ ) { |