-/* $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
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);
}
-/* $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>
#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)
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);
}
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;
}
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);