diff options
author | 2017-01-19 10:16:22 +0000 | |
---|---|---|
committer | 2017-01-19 10:16:22 +0000 | |
commit | 981cad086d71d00694ff5abcfdf6b6652a57f89e (patch) | |
tree | 0a25d77094bb504d5b46108279d5f50771c0cf06 | |
parent | make error handling a function, and use it in a few places (diff) | |
download | wireguard-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.c | 68 | ||||
-rw-r--r-- | usr.sbin/vmd/virtio.c | 22 | ||||
-rw-r--r-- | usr.sbin/vmd/virtio.h | 3 |
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; |