diff options
authorJunlian Bell <zhongjun@sangfor.com.cn>2016-09-26 20:41:01 +0800
committerPaolo Bonzini <pbonzini@redhat.com>2016-10-04 10:00:25 +0200
commit3cf294eebc98da6e2ff7976fcdf6a9b41984840e (patch)
parent1d5b128cbeeab638f772e88674f22e36b1b024e5 (diff)
MC146818 RTC: coordinate guest clock base to destination host after migration
qemu tracks guest time based on vector [base_rtc, last_update], in which last_update stands for a monotonic tick which is actually uptime of the host. according to rtc implementation codes of recent releases and upstream, after migration, the time base vector [base_rtc, last_update] isn't updated to coordinate with the destionation host, ie. qemu doesnt update last_update to uptime of the destination host. what problem have we got because of this bug? after migration, guest time may jump back to several days ago, that will make some critical business applications, such as lotus notes, malfunction. this patch is trying to fix the problem. first, when vmsave in progress, we rtc_update_time to refresh time stamp in cmos array, then during vmrestore, we rtc_set_time to update qemu base_rtc and last_update variable according to time stamp in cmos array. Signed-off-by: Junlian Bell <zhongjun@sangfor.com.cn> Message-Id: <20160926124101.2364-1-zhongjun@sangfor.com.cn> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 files changed, 9 insertions, 1 deletions
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index ea625f25ce..da209d02f0 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -717,11 +717,18 @@ static void rtc_set_date_from_host(ISADevice *dev)
rtc_set_cmos(s, &tm);
+static void rtc_pre_save(void *opaque)
+ RTCState *s = opaque;
+ rtc_update_time(s);
static int rtc_post_load(void *opaque, int version_id)
RTCState *s = opaque;
- if (version_id <= 2) {
+ if (version_id <= 2 || rtc_clock == QEMU_CLOCK_REALTIME) {
s->offset = 0;
@@ -764,6 +771,7 @@ static const VMStateDescription vmstate_rtc = {
.name = "mc146818rtc",
.version_id = 3,
.minimum_version_id = 1,
+ .pre_save = rtc_pre_save,
.post_load = rtc_post_load,
.fields = (VMStateField[]) {
VMSTATE_BUFFER(cmos_data, RTCState),