qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: Artem Pisarenko <artem.k.pisarenko@gmail.com>
Subject: [Qemu-devel] [PULL 18/48] Fixes RTC bug with base datetime shifts in clock=vm
Date: Thu, 18 Oct 2018 22:31:45 +0200	[thread overview]
Message-ID: <1539894735-14232-19-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1539894735-14232-1-git-send-email-pbonzini@redhat.com>

From: Artem Pisarenko <artem.k.pisarenko@gmail.com>

This makes all current "-rtc" option parameters combinations produce
fixed/unambiguous RTC timedate reference for hardware emulation
frontends.
It restores determinism of guest execution when used with clock=vm and
specified base <datetime> value.

Buglink: https://bugs.launchpad.net/qemu/+bug/1797033
Signed-off-by: Artem Pisarenko <artem.k.pisarenko@gmail.com>
Message-Id: <1d963c3e013dfedafa1f6edb9fb219b7e49e39da.1539846575.git.artem.k.pisarenko@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 vl.c | 62 +++++++++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 39 insertions(+), 23 deletions(-)

diff --git a/vl.c b/vl.c
index d15e086..5bb53f7 100644
--- a/vl.c
+++ b/vl.c
@@ -152,8 +152,10 @@ static enum {
     RTC_BASE_LOCALTIME,
     RTC_BASE_DATETIME,
 } rtc_base_type = RTC_BASE_UTC;
-static int rtc_host_datetime_offset = -1; /* valid only for host rtc_clock and
-                                             rtc_base_type=RTC_BASE_DATETIME */
+static time_t rtc_ref_start_datetime;
+static int rtc_realtime_clock_offset; /* used only with QEMU_CLOCK_REALTIME */
+static int rtc_host_datetime_offset = -1; /* valid & used only with
+                                             RTC_BASE_DATETIME */
 QEMUClockType rtc_clock;
 int vga_interface_type = VGA_NONE;
 static DisplayOptions dpy;
@@ -247,6 +249,7 @@ static struct {
 static QemuOptsList qemu_rtc_opts = {
     .name = "rtc",
     .head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_opts.head),
+    .merge_lists = true,
     .desc = {
         {
             .name = "base",
@@ -785,32 +788,42 @@ void qemu_system_vmstop_request(RunState state)
 }
 
 /***********************************************************/
-/* real time host monotonic timer */
-
-static time_t qemu_timedate(void)
+/* RTC reference time/date access */
+static time_t qemu_ref_timedate(void)
 {
-    return qemu_clock_get_ms(QEMU_CLOCK_HOST) / 1000;
+    time_t value = qemu_clock_get_ms(rtc_clock) / 1000;
+    switch (rtc_clock) {
+    case QEMU_CLOCK_REALTIME:
+        value -= rtc_realtime_clock_offset;
+        /* no break */
+    case QEMU_CLOCK_VIRTUAL:
+        value += rtc_ref_start_datetime;
+        break;
+    case QEMU_CLOCK_HOST:
+        if (rtc_base_type == RTC_BASE_DATETIME) {
+            value -= rtc_host_datetime_offset;
+        }
+        break;
+    default:
+        assert(0);
+    }
+    return value;
 }
 
-/***********************************************************/
-/* RTC reference time/date access */
 void qemu_get_timedate(struct tm *tm, int offset)
 {
-    time_t ti = qemu_timedate();
+    time_t ti = qemu_ref_timedate();
 
     ti += offset;
 
     switch (rtc_base_type) {
+    case RTC_BASE_DATETIME:
     case RTC_BASE_UTC:
         gmtime_r(&ti, tm);
         break;
     case RTC_BASE_LOCALTIME:
         localtime_r(&ti, tm);
         break;
-    case RTC_BASE_DATETIME:
-        ti -= rtc_host_datetime_offset;
-        gmtime_r(&ti, tm);
-        break;
     }
 }
 
@@ -819,6 +832,7 @@ int qemu_timedate_diff(struct tm *tm)
     time_t seconds;
 
     switch (rtc_base_type) {
+    case RTC_BASE_DATETIME:
     case RTC_BASE_UTC:
         seconds = mktimegm(tm);
         break;
@@ -829,17 +843,14 @@ int qemu_timedate_diff(struct tm *tm)
         seconds = mktime(&tmp);
         break;
     }
-    case RTC_BASE_DATETIME:
-        seconds = mktimegm(tm) + rtc_host_datetime_offset;
-        break;
     default:
         abort();
     }
 
-    return seconds - qemu_timedate();
+    return seconds - qemu_ref_timedate();
 }
 
-static void configure_rtc_host_datetime_offset(const char *startdate)
+static void configure_rtc_base_datetime(const char *startdate)
 {
     time_t rtc_start_datetime;
     struct tm tm;
@@ -865,14 +876,19 @@ static void configure_rtc_host_datetime_offset(const char *startdate)
                      "'2006-06-17T16:01:21' or '2006-06-17'\n");
         exit(1);
     }
-    rtc_host_datetime_offset = (qemu_clock_get_ms(QEMU_CLOCK_HOST) / 1000)
-                               - rtc_start_datetime;
+    rtc_host_datetime_offset = rtc_ref_start_datetime - rtc_start_datetime;
+    rtc_ref_start_datetime = rtc_start_datetime;
 }
 
 static void configure_rtc(QemuOpts *opts)
 {
     const char *value;
 
+    /* Set defaults */
+    rtc_clock = QEMU_CLOCK_HOST;
+    rtc_ref_start_datetime = qemu_clock_get_ms(QEMU_CLOCK_HOST) / 1000;
+    rtc_realtime_clock_offset = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) / 1000;
+
     value = qemu_opt_get(opts, "base");
     if (value) {
         if (!strcmp(value, "utc")) {
@@ -885,7 +901,7 @@ static void configure_rtc(QemuOpts *opts)
             replay_add_blocker(blocker);
         } else {
             rtc_base_type = RTC_BASE_DATETIME;
-            configure_rtc_host_datetime_offset(value);
+            configure_rtc_base_datetime(value);
         }
     }
     value = qemu_opt_get(opts, "clock");
@@ -3035,7 +3051,6 @@ int main(int argc, char **argv, char **envp)
         error_reportf_err(err, "cannot initialize crypto: ");
         exit(1);
     }
-    rtc_clock = QEMU_CLOCK_HOST;
 
     QLIST_INIT (&vm_change_state_head);
     os_setup_early_signal_handling();
@@ -3755,7 +3770,6 @@ int main(int argc, char **argv, char **envp)
                 if (!opts) {
                     exit(1);
                 }
-                configure_rtc(opts);
                 break;
             case QEMU_OPTION_tb_size:
 #ifndef CONFIG_TCG
@@ -3973,6 +3987,8 @@ int main(int argc, char **argv, char **envp)
         exit(EXIT_FAILURE);
     }
 
+    configure_rtc(qemu_find_opts_singleton("rtc"));
+
     machine_class = select_machine();
 
     set_memory_options(&ram_slots, &maxram_size, machine_class);
-- 
1.8.3.1

  parent reply	other threads:[~2018-10-18 20:32 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-18 20:31 [Qemu-devel] [PULL 00/48] Miscellaneous patches for 2018-10-18 Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 01/48] es1370: more fixes for ADC_FRAMEADR and ADC_FRAMECNT Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 02/48] Revert some patches from recent [PATCH v6] "Fixing record/replay and adding reverse debugging" Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 03/48] qemu-timer: introduce timer attributes Paolo Bonzini
2018-11-05 23:16   ` Eric Blake
2018-11-06  5:01     ` Artem Pisarenko
2018-11-06  9:45     ` Paolo Bonzini
2018-11-07 20:21       ` Eric Blake
2018-11-08  9:37         ` Peter Maydell
2018-10-18 20:31 ` [Qemu-devel] [PULL 04/48] qemu-timer: avoid checkpoints for virtual clock timers in external subsystems Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 05/48] qemu-timer: optimize record/replay checkpointing for all clocks Paolo Bonzini
2018-10-19  6:59   ` Artem Pisarenko
2018-10-18 20:31 ` [Qemu-devel] [PULL 06/48] target-i386: kvm: do not initialize padding fields Paolo Bonzini
2018-10-19  9:03   ` Peter Maydell
2018-10-19 11:44     ` Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 07/48] linux-headers: update to 4.20-rc1 Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 08/48] target-i386 : add coalesced_pio API Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 09/48] target-i386: add rtc 0x70 port as coalesced_pio Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 10/48] target-i386: add i440fx 0xcf8 " Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 11/48] target-i386: add q35 " Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 12/48] replay: don't process events at virtual clock checkpoint Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 13/48] i386/kvm: add support for Hyper-V IPI send Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 14/48] i386: hvf: Fix register refs if REX is present Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 15/48] i386: hvf: Remove hvf_disabled Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 16/48] vl: improve/fix documentation related to RTC function Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 17/48] vl: refactor -rtc option references Paolo Bonzini
2018-10-18 20:31 ` Paolo Bonzini [this message]
2018-10-18 20:31 ` [Qemu-devel] [PULL 19/48] vl, qapi: offset calculation in RTC_CHANGE event reverted Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 20/48] call HotplugHandler->plug() as the last step in device realization Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 21/48] hw: edu: drop DO_UPCAST Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 22/48] scsi-disk: fix double completion of failing passthrough requests Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 23/48] scsi-disk: fix rerror/werror=ignore Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 24/48] hyperv_testdev: refactor for better maintainability Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 25/48] hyperv_testdev: drop unnecessary includes Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 26/48] hyperv: cosmetic: g_malloc -> g_new Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 27/48] hyperv: synic: only setup ack notifier if there's a callback Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 28/48] hyperv: allow passing arbitrary data to sint ack callback Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 29/48] hyperv: address HvSintRoute by X86CPU pointer Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 30/48] hyperv: make HvSintRoute reference-counted Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 31/48] hyperv: rename kvm_hv_sint_route_set_sint Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 32/48] hyperv: split hyperv-proto.h into x86 and arch-independent parts Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 33/48] hyperv: make hyperv_vp_index inline Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 34/48] hyperv: factor out arch-independent API into hw/hyperv Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 35/48] default-configs: collect CONFIG_HYPERV* in hyperv.mak Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 36/48] i386: add hyperv-stub for CONFIG_HYPERV=n Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 37/48] hyperv:synic: split capability testing and setting Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 39/48] hyperv: only add SynIC in compatible configurations Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 40/48] hyperv: make overlay pages for SynIC Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 41/48] hyperv: add synic message delivery Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 42/48] hyperv: add synic event flag signaling Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 43/48] hyperv: process SIGNAL_EVENT hypercall Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 44/48] hyperv: add support for KVM_HYPERV_EVENTFD Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 45/48] hyperv: process POST_MESSAGE hypercall Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 46/48] hyperv_testdev: add SynIC message and event testmodes Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 47/48] target/i386: kvm: just return after migrate_add_blocker failed Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 48/48] replay: pass raw icount value to replay_save_clock Paolo Bonzini
2018-10-19  7:32 ` [Qemu-devel] [PULL 00/48] Miscellaneous patches for 2018-10-18 Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1539894735-14232-19-git-send-email-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=artem.k.pisarenko@gmail.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).