Resynchronize the guest RTC via vmmci(4) on host resume from zzz/ZZZ
authormlarkin <mlarkin@openbsd.org>
Tue, 2 May 2017 09:51:19 +0000 (09:51 +0000)
committermlarkin <mlarkin@openbsd.org>
Tue, 2 May 2017 09:51:19 +0000 (09:51 +0000)
(vmd part)

This feature is for OpenBSD guests only.

ok reyk, kettenis

usr.sbin/vmd/mc146818.c
usr.sbin/vmd/virtio.c
usr.sbin/vmd/virtio.h

index ba721d2..62601ad 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: mc146818.c,v 1.12 2017/03/27 00:28:04 deraadt Exp $ */
+/* $OpenBSD: mc146818.c,v 1.13 2017/05/02 09:51:19 mlarkin Exp $ */
 /*
  * Copyright (c) 2016 Mike Larkin <mlarkin@openbsd.org>
  *
 #include <string.h>
 #include <time.h>
 
+#include "vmd.h"
 #include "mc146818.h"
 #include "proc.h"
+#include "virtio.h"
 #include "vmm.h"
 
 #define MC_DIVIDER_MASK 0xe0
@@ -96,8 +98,16 @@ rtc_updateregs(void)
 static void
 rtc_fire1(int fd, short type, void *arg)
 {
-       rtc.now++;
+       time_t old = rtc.now;
+
+       time(&rtc.now);
+
        rtc_updateregs();
+       if (rtc.now - old > 5) {
+               log_debug("%s: RTC clock drift (%llds), requesting guest "
+                   "resync", __func__, (rtc.now - old));
+               vmmci_ctl(VMMCI_SYNCRTC);
+       }
        evtimer_add(&rtc.sec, &rtc.sec_tv);
 }
 
index f84110a..8b496c2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: virtio.c,v 1.43 2017/04/25 16:38:23 reyk Exp $        */
+/*     $OpenBSD: virtio.c,v 1.44 2017/05/02 09:51:19 mlarkin Exp $     */
 
 /*
  * Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -58,6 +58,7 @@ int nr_vionet;
 
 #define VMMCI_F_TIMESYNC       (1<<0)
 #define VMMCI_F_ACK            (1<<1)
+#define VMMCI_F_SYNCRTC                (1<<2)
 
 const char *
 vioblk_cmd_name(uint32_t type)
@@ -1453,6 +1454,18 @@ vmmci_ctl(unsigned int cmd)
                tv.tv_sec = VMMCI_TIMEOUT;
                evtimer_add(&vmmci.timeout, &tv);
                break;
+       case VMMCI_SYNCRTC:
+               if (vmmci.cfg.guest_feature & VMMCI_F_SYNCRTC) {
+                       /* RTC updated, request guest VM resync of its RTC */
+                       vmmci.cmd = cmd;
+
+                       vmmci.cfg.isr_status = VIRTIO_CONFIG_ISR_CONFIG_CHANGE;
+                       vcpu_assert_pic_irq(vmmci.vm_id, 0, vmmci.irq);
+               } else {
+                       log_debug("%s: RTC sync skipped (guest does not "
+                           "support RTC sync)\n", __func__);
+               }
+               break;
        default:
                fatalx("invalid vmmci command: %d", cmd);
        }
@@ -1499,6 +1512,11 @@ vmmci_ack(unsigned int cmd)
                        evtimer_add(&vmmci.timeout, &tv);
                }
                break;
+       case VMMCI_SYNCRTC:
+               log_debug("%s: vm %u acknowledged RTC sync request",
+                   __func__, vmmci.vm_id);
+               vmmci.cmd = VMMCI_NONE;
+               break;
        default:
                log_warnx("%s: illegal request %u", __func__, cmd);
                break;
@@ -1774,7 +1792,8 @@ virtio_init(struct vmd_vm *vm, int *child_disks, int *child_taps)
        }
 
        memset(&vmmci, 0, sizeof(vmmci));
-       vmmci.cfg.device_feature = VMMCI_F_TIMESYNC|VMMCI_F_ACK;
+       vmmci.cfg.device_feature = VMMCI_F_TIMESYNC | VMMCI_F_ACK |
+           VMMCI_F_SYNCRTC;
        vmmci.vm_id = vcp->vcp_id;
        vmmci.irq = pci_get_dev_irq(id);
 
index a830d17..05559fc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: virtio.h,v 1.15 2017/04/19 15:38:32 reyk Exp $        */
+/*     $OpenBSD: virtio.h,v 1.16 2017/05/02 09:51:19 mlarkin Exp $     */
 
 /*
  * Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -147,6 +147,7 @@ enum vmmci_cmd {
        VMMCI_NONE = 0,
        VMMCI_SHUTDOWN,
        VMMCI_REBOOT,
+       VMMCI_SYNCRTC,
 };
 
 struct vmmci_dev {