From e82d5294934c4546a225fe4ca515799a323e432e Mon Sep 17 00:00:00 2001 From: mlarkin Date: Tue, 2 May 2017 09:51:19 +0000 Subject: [PATCH] Resynchronize the guest RTC via vmmci(4) on host resume from zzz/ZZZ (vmd part) This feature is for OpenBSD guests only. ok reyk, kettenis --- usr.sbin/vmd/mc146818.c | 14 ++++++++++++-- usr.sbin/vmd/virtio.c | 23 +++++++++++++++++++++-- usr.sbin/vmd/virtio.h | 3 ++- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/usr.sbin/vmd/mc146818.c b/usr.sbin/vmd/mc146818.c index ba721d27106..62601adbac3 100644 --- a/usr.sbin/vmd/mc146818.c +++ b/usr.sbin/vmd/mc146818.c @@ -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 * @@ -27,8 +27,10 @@ #include #include +#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); } diff --git a/usr.sbin/vmd/virtio.c b/usr.sbin/vmd/virtio.c index f84110a5301..8b496c20cd4 100644 --- a/usr.sbin/vmd/virtio.c +++ b/usr.sbin/vmd/virtio.c @@ -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 @@ -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); diff --git a/usr.sbin/vmd/virtio.h b/usr.sbin/vmd/virtio.h index a830d1738d0..05559fc7342 100644 --- a/usr.sbin/vmd/virtio.h +++ b/usr.sbin/vmd/virtio.h @@ -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 @@ -147,6 +147,7 @@ enum vmmci_cmd { VMMCI_NONE = 0, VMMCI_SHUTDOWN, VMMCI_REBOOT, + VMMCI_SYNCRTC, }; struct vmmci_dev { -- 2.20.1