summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorreyk <reyk@openbsd.org>2017-01-19 10:16:22 +0000
committerreyk <reyk@openbsd.org>2017-01-19 10:16:22 +0000
commit981cad086d71d00694ff5abcfdf6b6652a57f89e (patch)
tree0a25d77094bb504d5b46108279d5f50771c0cf06
parentmake error handling a function, and use it in a few places (diff)
downloadwireguard-openbsd-981cad086d71d00694ff5abcfdf6b6652a57f89e.tar.xz
wireguard-openbsd-981cad086d71d00694ff5abcfdf6b6652a57f89e.zip
Export the host time to the guest, add it as a timedelta sensor in vmmci(4)
OK kettenis@ mlarkin@
-rw-r--r--sys/dev/pci/vmmci.c68
-rw-r--r--usr.sbin/vmd/virtio.c22
-rw-r--r--usr.sbin/vmd/virtio.h3
3 files changed, 87 insertions, 6 deletions
diff --git a/sys/dev/pci/vmmci.c b/sys/dev/pci/vmmci.c
index 23f86c5e4ea..7d79fca958e 100644
--- a/sys/dev/pci/vmmci.c
+++ b/sys/dev/pci/vmmci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmmci.c,v 1.1 2017/01/13 14:37:32 reyk Exp $ */
+/* $OpenBSD: vmmci.c,v 1.2 2017/01/19 10:16:22 reyk Exp $ */
/*
* Copyright (c) 2017 Reyk Floeter <reyk@openbsd.org>
@@ -44,6 +44,8 @@ struct vmmci_softc {
struct virtio_softc *sc_virtio;
enum vmmci_cmd sc_cmd;
unsigned int sc_interval;
+ struct ksensordev sc_sensordev;
+ struct ksensor sc_sensor;
struct timeout sc_tick;
};
@@ -51,6 +53,8 @@ int vmmci_match(struct device *, void *, void *);
void vmmci_attach(struct device *, struct device *, void *);
int vmmci_config_change(struct virtio_softc *);
+void vmmci_tick(void *);
+void vmmci_tick_hook(struct device *);
struct cfattach vmmci_ca = {
sizeof(struct vmmci_softc),
@@ -59,6 +63,14 @@ struct cfattach vmmci_ca = {
NULL
};
+/* Configuration registers */
+#define VMMCI_CONFIG_COMMAND 0
+#define VMMCI_CONFIG_TIME_SEC 4
+#define VMMCI_CONFIG_TIME_USEC 12
+
+/* Feature bits */
+#define VMMCI_F_TIMESYNC (1<<0)
+
struct cfdriver vmmci_cd = {
NULL, "vmmci", DV_DULL
};
@@ -77,6 +89,7 @@ vmmci_attach(struct device *parent, struct device *self, void *aux)
{
struct vmmci_softc *sc = (struct vmmci_softc *)self;
struct virtio_softc *vsc = (struct virtio_softc *)parent;
+ uint32_t features;
if (vsc->sc_child != NULL)
panic("already attached to something else");
@@ -87,7 +100,19 @@ vmmci_attach(struct device *parent, struct device *self, void *aux)
vsc->sc_ipl = IPL_NET;
sc->sc_virtio = vsc;
- virtio_negotiate_features(vsc, 0, NULL);
+ features = VMMCI_F_TIMESYNC;
+ features = virtio_negotiate_features(vsc, features, NULL);
+
+ if (features & VMMCI_F_TIMESYNC) {
+ strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
+ sizeof(sc->sc_sensordev.xname));
+ sc->sc_sensor.type = SENSOR_TIMEDELTA;
+ sc->sc_sensor.status = SENSOR_S_UNKNOWN;
+ sensor_attach(&sc->sc_sensordev, &sc->sc_sensor);
+ sensordev_install(&sc->sc_sensordev);
+
+ config_mountroot(self, vmmci_tick_hook);
+ }
printf("\n");
}
@@ -96,8 +121,10 @@ int
vmmci_config_change(struct virtio_softc *vsc)
{
struct vmmci_softc *sc = (struct vmmci_softc *)vsc->sc_child;
- int cmd = virtio_read_device_config_1(vsc, 0);
+ int cmd;
+ /* Check for command */
+ cmd = virtio_read_device_config_1(vsc, VMMCI_CONFIG_COMMAND);
if (cmd == sc->sc_cmd)
return (0);
sc->sc_cmd = cmd;
@@ -119,3 +146,38 @@ vmmci_config_change(struct virtio_softc *vsc)
return (1);
}
+
+void
+vmmci_tick(void *arg)
+{
+ struct vmmci_softc *sc = arg;
+ struct virtio_softc *vsc = sc->sc_virtio;
+ struct timeval *guest = &sc->sc_sensor.tv;
+ struct timeval host, diff;
+
+ microtime(guest);
+
+ /* Update time delta sensor */
+ host.tv_sec = virtio_read_device_config_8(vsc, VMMCI_CONFIG_TIME_SEC);
+ host.tv_usec = virtio_read_device_config_8(vsc, VMMCI_CONFIG_TIME_USEC);
+
+ if (host.tv_usec > 0) {
+ timersub(guest, &host, &diff);
+
+ sc->sc_sensor.value = (uint64_t)diff.tv_sec * 1000000000LL +
+ (uint64_t)diff.tv_usec * 1000LL;
+ sc->sc_sensor.status = SENSOR_S_OK;
+ } else
+ sc->sc_sensor.status = SENSOR_S_UNKNOWN;
+
+ timeout_add_sec(&sc->sc_tick, 15);
+}
+
+void
+vmmci_tick_hook(struct device *self)
+{
+ struct vmmci_softc *sc = (struct vmmci_softc *)self;
+
+ timeout_set(&sc->sc_tick, vmmci_tick, sc);
+ vmmci_tick(sc);
+}
diff --git a/usr.sbin/vmd/virtio.c b/usr.sbin/vmd/virtio.c
index 0bd6fb3374d..f85c06452db 100644
--- a/usr.sbin/vmd/virtio.c
+++ b/usr.sbin/vmd/virtio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: virtio.c,v 1.29 2017/01/17 21:51:01 krw Exp $ */
+/* $OpenBSD: virtio.c,v 1.30 2017/01/19 10:16:22 reyk Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -56,6 +56,8 @@ int nr_vionet;
#define VIRTIO_NET_F_MAC (1<<5)
+#define VMMCI_F_TIMESYNC (1<<0)
+
const char *
vioblk_cmd_name(uint32_t type)
{
@@ -110,6 +112,8 @@ virtio_reg_name(uint8_t reg)
case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI: return "device config 0";
case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 4: return "device config 1";
case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 8: return "device config 2";
+ case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 12: return "device config 3";
+ case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 16: return "device config 4";
default: return "unknown";
}
}
@@ -1243,6 +1247,20 @@ vmmci_io(int dir, uint16_t reg, uint32_t *data, uint8_t *intr,
case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI:
*data = vmmci.cmd;
break;
+ case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 4:
+ /* Update time once when reading the first register */
+ gettimeofday(&vmmci.time, NULL);
+ *data = (uint64_t)vmmci.time.tv_sec;
+ break;
+ case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 8:
+ *data = (uint64_t)vmmci.time.tv_sec << 32;
+ break;
+ case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 12:
+ *data = (uint64_t)vmmci.time.tv_usec;
+ break;
+ case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 16:
+ *data = (uint64_t)vmmci.time.tv_usec << 32;
+ break;
case VIRTIO_CONFIG_DEVICE_FEATURES:
*data = vmmci.cfg.device_feature;
break;
@@ -1458,7 +1476,7 @@ virtio_init(struct vm_create_params *vcp, int *child_disks, int *child_taps)
return;
}
- vmmci.cfg.device_feature = 0;
+ vmmci.cfg.device_feature = VMMCI_F_TIMESYNC;
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 99cb1f8c767..a7ff7343747 100644
--- a/usr.sbin/vmd/virtio.h
+++ b/usr.sbin/vmd/virtio.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: virtio.h,v 1.7 2017/01/13 14:50:56 reyk Exp $ */
+/* $OpenBSD: virtio.h,v 1.8 2017/01/19 10:16:22 reyk Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -144,6 +144,7 @@ enum vmmci_cmd {
struct vmmci_dev {
struct virtio_io_cfg cfg;
+ struct timeval time;
enum vmmci_cmd cmd;
uint32_t vm_id;
int irq;