On 20/09/2016 09:19, [email protected] wrote:
> 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.
But last_update is not a monotonic tick, it's basically gettimeofday
unless you're using the "-rtc clock=..." option.
> +static void rtc_flush_time(RTCState *s)
> +{
> + struct tm ret;
> + time_t guest_sec;
> + int64_t guest_nsec;
> + uint64_t guest_clock = qemu_clock_get_ns(rtc_clock);
> +
> + guest_nsec = s->base_rtc * NANOSECONDS_PER_SECOND
> + + guest_clock - s->last_update;
> + guest_sec = (guest_nsec + NANOSECONDS_PER_SECOND/2)/
> NANOSECONDS_PER_SECOND;
> + gmtime_r(&guest_sec, &ret);
> +
> + rtc_set_cmos(s, &ret);
This should be just rtc_update_time(s).
Similarly:
>
> + rtc_get_time(s, &tm);
> + diff = mktimegm(&tm) - s->base_rtc;
> + assert(diff >= 0);
> + s->last_update = qemu_clock_get_ns(rtc_clock)
> + - diff * NANOSECONDS_PER_SECOND;
This should be rtc_set_time.
However, there are two problems with this approach. First, if you
migrate old QEMU to new QEMU, the new QEMU expects to have an up-to-date
s->base_rtc, while old QEMU provided an old QEMU. Second, every
migration will delay the RTC by a few tenths of a second. So the call
to rtc_set_time should be conditional on rtc_clock == QEMU_CLOCK_REALTIME.
Paolo