diff options
author | jhb <jhb@FreeBSD.org> | 2014-07-21 00:21:56 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2014-07-21 00:21:56 +0000 |
commit | cf1a2223269e3a031a511b90ce2035ffdf9f7420 (patch) | |
tree | 47f56b4d318aeb5e1020c53d57cb9963e35eeb27 | |
parent | 25b41d088263e9d1574521319b2e37df9842fd2f (diff) | |
download | FreeBSD-src-cf1a2223269e3a031a511b90ce2035ffdf9f7420.zip FreeBSD-src-cf1a2223269e3a031a511b90ce2035ffdf9f7420.tar.gz |
MFC 260847,264055,264867:
- Add a very simple virtio_random(4) driver for FreeBSD guests to harvest
entropy from hypervisors.
- Add support to bhyve for the virtio RNG entropy-source device to provide
entry to bhyve guests.
-rw-r--r-- | share/man/man4/Makefile | 2 | ||||
-rw-r--r-- | share/man/man4/virtio_random.4 | 61 | ||||
-rw-r--r-- | sys/amd64/conf/NOTES | 1 | ||||
-rw-r--r-- | sys/conf/files.amd64 | 1 | ||||
-rw-r--r-- | sys/conf/files.i386 | 1 | ||||
-rw-r--r-- | sys/dev/virtio/random/virtio_random.c | 231 | ||||
-rw-r--r-- | sys/i386/conf/NOTES | 1 | ||||
-rw-r--r-- | sys/modules/virtio/Makefile | 2 | ||||
-rw-r--r-- | sys/modules/virtio/random/Makefile | 36 | ||||
-rw-r--r-- | sys/sys/random.h | 1 | ||||
-rw-r--r-- | usr.sbin/bhyve/Makefile | 1 | ||||
-rw-r--r-- | usr.sbin/bhyve/bhyve.8 | 4 | ||||
-rw-r--r-- | usr.sbin/bhyve/pci_virtio_rnd.c | 189 | ||||
-rw-r--r-- | usr.sbin/bhyve/virtio.h | 1 |
14 files changed, 530 insertions, 2 deletions
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 92c8709..3a9af12 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -555,6 +555,7 @@ MAN= aac.4 \ ${_virtio.4} \ ${_virtio_balloon.4} \ ${_virtio_blk.4} \ + ${_virtio_random.4} \ ${_virtio_scsi.4} \ vkbd.4 \ vlan.4 \ @@ -804,6 +805,7 @@ _nxge.4= nxge.4 _virtio.4= virtio.4 _virtio_balloon.4=virtio_balloon.4 _virtio_blk.4= virtio_blk.4 +_virtio_random.4= virtio_random.4 _virtio_scsi.4= virtio_scsi.4 _vmx.4= vmx.4 _vtnet.4= vtnet.4 diff --git a/share/man/man4/virtio_random.4 b/share/man/man4/virtio_random.4 new file mode 100644 index 0000000..a20e868 --- /dev/null +++ b/share/man/man4/virtio_random.4 @@ -0,0 +1,61 @@ +.\" Copyright (c) 2013 Bryan Venteicher +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd December 28, 2013 +.Dt VIRTIO_RANDOM 4 +.Os +.Sh NAME +.Nm virtio_random +.Nd VirtIO Entropy driver +.Sh SYNOPSIS +To compile this driver into the kernel, +place the following lines in your +kernel configuration file: +.Bd -ragged -offset indent +.Cd "device virtio_random" +.Ed +.Pp +Alternatively, to load the driver as a +module at boot time, place the following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +virtio_random_load="YES" +.Ed +.Sh DESCRIPTION +The +.Nm +device driver provides support for VirtIO entropy devices. +.Pp +The entropy device supplies high-quality randomness from the +hypervisor to the guest. +.Sh SEE ALSO +.Xr random 4 +.Xr virtio 4 +.Sh HISTORY +The +.Nm +driver was written by +.An Bryan Venteicher Aq bryanv@FreeBSD.org . diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES index ffe7910..2986698 100644 --- a/sys/amd64/conf/NOTES +++ b/sys/amd64/conf/NOTES @@ -472,6 +472,7 @@ device vtnet # VirtIO Ethernet device device virtio_blk # VirtIO Block device device virtio_scsi # VirtIO SCSI device device virtio_balloon # VirtIO Memory Balloon device +device virtio_random # VirtIO Entropy device device hyperv # HyperV drivers diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index 84b6e6b..e569b91 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -448,6 +448,7 @@ dev/virtio/network/if_vtnet.c optional vtnet dev/virtio/block/virtio_blk.c optional virtio_blk dev/virtio/balloon/virtio_balloon.c optional virtio_balloon dev/virtio/scsi/virtio_scsi.c optional virtio_scsi +dev/virtio/random/virtio_random.c optional virtio_random isa/syscons_isa.c optional sc isa/vga_isa.c optional vga kern/imgact_binmisc.c optional imagact_binmisc diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 6e6098c..2c0ad75 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -413,6 +413,7 @@ dev/virtio/network/if_vtnet.c optional vtnet dev/virtio/block/virtio_blk.c optional virtio_blk dev/virtio/balloon/virtio_balloon.c optional virtio_balloon dev/virtio/scsi/virtio_scsi.c optional virtio_scsi +dev/virtio/random/virtio_random.c optional virtio_random i386/acpica/acpi_machdep.c optional acpi acpi_wakecode.o optional acpi \ dependency "$S/i386/acpica/acpi_wakecode.S assym.s" \ diff --git a/sys/dev/virtio/random/virtio_random.c b/sys/dev/virtio/random/virtio_random.c new file mode 100644 index 0000000..bd1f0df --- /dev/null +++ b/sys/dev/virtio/random/virtio_random.c @@ -0,0 +1,231 @@ +/*- + * Copyright (c) 2013, Bryan Venteicher <bryanv@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Driver for VirtIO entropy device. */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/module.h> +#include <sys/sglist.h> +#include <sys/callout.h> +#include <sys/random.h> + +#include <machine/bus.h> +#include <machine/resource.h> +#include <sys/bus.h> + +#include <dev/virtio/virtio.h> +#include <dev/virtio/virtqueue.h> + +struct vtrnd_softc { + device_t vtrnd_dev; + uint64_t vtrnd_features; + struct callout vtrnd_callout; + struct virtqueue *vtrnd_vq; +}; + +static int vtrnd_modevent(module_t, int, void *); + +static int vtrnd_probe(device_t); +static int vtrnd_attach(device_t); +static int vtrnd_detach(device_t); + +static void vtrnd_negotiate_features(struct vtrnd_softc *); +static int vtrnd_alloc_virtqueue(struct vtrnd_softc *); +static void vtrnd_harvest(struct vtrnd_softc *); +static void vtrnd_timer(void *); + +#define VTRND_FEATURES 0 + +static struct virtio_feature_desc vtrnd_feature_desc[] = { + { 0, NULL } +}; + +static device_method_t vtrnd_methods[] = { + /* Device methods. */ + DEVMETHOD(device_probe, vtrnd_probe), + DEVMETHOD(device_attach, vtrnd_attach), + DEVMETHOD(device_detach, vtrnd_detach), + + DEVMETHOD_END +}; + +static driver_t vtrnd_driver = { + "vtrnd", + vtrnd_methods, + sizeof(struct vtrnd_softc) +}; +static devclass_t vtrnd_devclass; + +DRIVER_MODULE(virtio_random, virtio_pci, vtrnd_driver, vtrnd_devclass, + vtrnd_modevent, 0); +MODULE_VERSION(virtio_random, 1); +MODULE_DEPEND(virtio_random, virtio, 1, 1, 1); + +static int +vtrnd_modevent(module_t mod, int type, void *unused) +{ + int error; + + switch (type) { + case MOD_LOAD: + case MOD_QUIESCE: + case MOD_UNLOAD: + case MOD_SHUTDOWN: + error = 0; + break; + default: + error = EOPNOTSUPP; + break; + } + + return (error); +} + +static int +vtrnd_probe(device_t dev) +{ + + if (virtio_get_device_type(dev) != VIRTIO_ID_ENTROPY) + return (ENXIO); + + device_set_desc(dev, "VirtIO Entropy Adapter"); + + return (BUS_PROBE_DEFAULT); +} + +static int +vtrnd_attach(device_t dev) +{ + struct vtrnd_softc *sc; + int error; + + sc = device_get_softc(dev); + sc->vtrnd_dev = dev; + + callout_init(&sc->vtrnd_callout, CALLOUT_MPSAFE); + + virtio_set_feature_desc(dev, vtrnd_feature_desc); + vtrnd_negotiate_features(sc); + + error = vtrnd_alloc_virtqueue(sc); + if (error) { + device_printf(dev, "cannot allocate virtqueue\n"); + goto fail; + } + + callout_reset(&sc->vtrnd_callout, 5 * hz, vtrnd_timer, sc); + +fail: + if (error) + vtrnd_detach(dev); + + return (error); +} + +static int +vtrnd_detach(device_t dev) +{ + struct vtrnd_softc *sc; + + sc = device_get_softc(dev); + + callout_drain(&sc->vtrnd_callout); + + return (0); +} + +static void +vtrnd_negotiate_features(struct vtrnd_softc *sc) +{ + device_t dev; + uint64_t features; + + dev = sc->vtrnd_dev; + features = VTRND_FEATURES; + + sc->vtrnd_features = virtio_negotiate_features(dev, features); +} + +static int +vtrnd_alloc_virtqueue(struct vtrnd_softc *sc) +{ + device_t dev; + struct vq_alloc_info vq_info; + + dev = sc->vtrnd_dev; + + VQ_ALLOC_INFO_INIT(&vq_info, 0, NULL, sc, &sc->vtrnd_vq, + "%s request", device_get_nameunit(dev)); + + return (virtio_alloc_virtqueues(dev, 0, 1, &vq_info)); +} + +static void +vtrnd_harvest(struct vtrnd_softc *sc) +{ + struct sglist_seg segs[1]; + struct sglist sg; + struct virtqueue *vq; + uint32_t value; + int error; + + vq = sc->vtrnd_vq; + + sglist_init(&sg, 1, segs); + error = sglist_append(&sg, &value, sizeof(value)); + KASSERT(error == 0 && sg.sg_nseg == 1, + ("%s: error %d adding buffer to sglist", __func__, error)); + + if (!virtqueue_empty(vq)) + return; + if (virtqueue_enqueue(vq, &value, &sg, 0, 1) != 0) + return; + + /* + * Poll for the response, but the command is likely already + * done when we return from the notify. + */ + virtqueue_notify(vq); + virtqueue_poll(vq, NULL); + + random_harvest(&value, sizeof(value), sizeof(value) * NBBY / 2, + RANDOM_PURE_VIRTIO); +} + +static void +vtrnd_timer(void *xsc) +{ + struct vtrnd_softc *sc; + + sc = xsc; + + vtrnd_harvest(sc); + callout_schedule(&sc->vtrnd_callout, 5 * hz); +} diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES index 8c4efea..d60d5db 100644 --- a/sys/i386/conf/NOTES +++ b/sys/i386/conf/NOTES @@ -800,6 +800,7 @@ device vtnet # VirtIO Ethernet device device virtio_blk # VirtIO Block device device virtio_scsi # VirtIO SCSI device device virtio_balloon # VirtIO Memory Balloon device +device virtio_random # VirtIO Entropy device device hyperv # HyperV drivers diff --git a/sys/modules/virtio/Makefile b/sys/modules/virtio/Makefile index 12846b2..ecf9441 100644 --- a/sys/modules/virtio/Makefile +++ b/sys/modules/virtio/Makefile @@ -23,6 +23,6 @@ # SUCH DAMAGE. # -SUBDIR= virtio pci network block balloon scsi +SUBDIR= virtio pci network block balloon scsi random .include <bsd.subdir.mk> diff --git a/sys/modules/virtio/random/Makefile b/sys/modules/virtio/random/Makefile new file mode 100644 index 0000000..fb5b9b0 --- /dev/null +++ b/sys/modules/virtio/random/Makefile @@ -0,0 +1,36 @@ +# +# $FreeBSD$ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +.PATH: ${.CURDIR}/../../../dev/virtio/random + +KMOD= virtio_random +SRCS= virtio_random.c +SRCS+= virtio_bus_if.h virtio_if.h +SRCS+= bus_if.h device_if.h + +MFILES= kern/bus_if.m kern/device_if.m \ + dev/virtio/virtio_bus_if.m dev/virtio/virtio_if.m + +.include <bsd.kmod.mk> diff --git a/sys/sys/random.h b/sys/sys/random.h index 0f26b8b..fe170ea 100644 --- a/sys/sys/random.h +++ b/sys/sys/random.h @@ -56,6 +56,7 @@ enum esource { RANDOM_PURE_RDRAND, RANDOM_PURE_NEHEMIAH, RANDOM_PURE_RNDTEST, + RANDOM_PURE_VIRTIO, ENTROPYSOURCE }; void random_harvest(void *, u_int, u_int, enum esource); diff --git a/usr.sbin/bhyve/Makefile b/usr.sbin/bhyve/Makefile index 116fb60..d6682fb 100644 --- a/usr.sbin/bhyve/Makefile +++ b/usr.sbin/bhyve/Makefile @@ -26,6 +26,7 @@ SRCS= \ pci_passthru.c \ pci_virtio_block.c \ pci_virtio_net.c \ + pci_virtio_rnd.c \ pci_uart.c \ pm.c \ pmtmr.c \ diff --git a/usr.sbin/bhyve/bhyve.8 b/usr.sbin/bhyve/bhyve.8 index 159ec08..2d2d396 100644 --- a/usr.sbin/bhyve/bhyve.8 +++ b/usr.sbin/bhyve/bhyve.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 27, 2014 +.Dd April 2, 2014 .Dt BHYVE 8 .Os .Sh NAME @@ -126,6 +126,8 @@ PCI pass-through device. Virtio network interface. .It Li virtio-blk Virtio block storage interface. +.It Li virtio-rnd +Virtio RNG interface. .It Li ahci-cd AHCI controller attached to an ATAPI CD/DVD. .It Li ahci-hd diff --git a/usr.sbin/bhyve/pci_virtio_rnd.c b/usr.sbin/bhyve/pci_virtio_rnd.c new file mode 100644 index 0000000..38459d2 --- /dev/null +++ b/usr.sbin/bhyve/pci_virtio_rnd.c @@ -0,0 +1,189 @@ +/*- + * Copyright (c) 2014 Nahanni Systems Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * virtio entropy device emulation. + * Randomness is sourced from /dev/random which does not block + * once it has been seeded at bootup. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/linker_set.h> +#include <sys/uio.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <assert.h> +#include <pthread.h> + +#include "bhyverun.h" +#include "pci_emul.h" +#include "virtio.h" + +#define VTRND_RINGSZ 64 + + +static int pci_vtrnd_debug; +#define DPRINTF(params) if (pci_vtrnd_debug) printf params +#define WPRINTF(params) printf params + +/* + * Per-device softc + */ +struct pci_vtrnd_softc { + struct virtio_softc vrsc_vs; + struct vqueue_info vrsc_vq; + pthread_mutex_t vrsc_mtx; + uint64_t vrsc_cfg; + int vrsc_fd; +}; + +static void pci_vtrnd_reset(void *); +static void pci_vtrnd_notify(void *, struct vqueue_info *); + +static struct virtio_consts vtrnd_vi_consts = { + "vtrnd", /* our name */ + 1, /* we support 1 virtqueue */ + 0, /* config reg size */ + pci_vtrnd_reset, /* reset */ + pci_vtrnd_notify, /* device-wide qnotify */ + NULL, /* read virtio config */ + NULL, /* write virtio config */ + 0, /* our capabilities */ +}; + + +static void +pci_vtrnd_reset(void *vsc) +{ + struct pci_vtrnd_softc *sc; + + sc = vsc; + + DPRINTF(("vtrnd: device reset requested !\n")); + vi_reset_dev(&sc->vrsc_vs); +} + + +static void +pci_vtrnd_notify(void *vsc, struct vqueue_info *vq) +{ + struct iovec iov; + struct pci_vtrnd_softc *sc; + int len; + + sc = vsc; + + vq_startchains(vq); + + if (sc->vrsc_fd < 0) { + vq_endchains(vq, 0); + return; + } + + while (vq_has_descs(vq)) { + vq_getchain(vq, &iov, 1, NULL); + + len = read(sc->vrsc_fd, iov.iov_base, iov.iov_len); + + DPRINTF(("vtrnd: vtrnd_notify(): %d\r\n", len)); + + /* Catastrophe if unable to read from /dev/random */ + assert(len > 0); + + /* + * Release this chain and handle more + */ + vq_relchain(vq, len); + } + vq_endchains(vq, 1); /* Generate interrupt if appropriate. */ +} + + +static int +pci_vtrnd_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + struct pci_vtrnd_softc *sc; + int fd; + int len; + uint8_t v; + + /* + * Should always be able to open /dev/random. + */ + fd = open("/dev/random", O_RDONLY | O_NONBLOCK); + + assert(fd >= 0); + + /* + * Check that device is seeded and non-blocking. + */ + len = read(fd, &v, sizeof(v)); + if (len <= 0) { + WPRINTF(("vtrnd: /dev/random not ready, read(): %d", len)); + return (1); + } + + sc = malloc(sizeof(struct pci_vtrnd_softc)); + memset(sc, 0, sizeof(struct pci_vtrnd_softc)); + + vi_softc_linkup(&sc->vrsc_vs, &vtrnd_vi_consts, sc, pi, &sc->vrsc_vq); + sc->vrsc_vs.vs_mtx = &sc->vrsc_mtx; + + sc->vrsc_vq.vq_qsize = VTRND_RINGSZ; + + /* keep /dev/random opened while emulating */ + sc->vrsc_fd = fd; + + /* initialize config space */ + pci_set_cfgdata16(pi, PCIR_DEVICE, VIRTIO_DEV_RANDOM); + pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR); + pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_CRYPTO); + pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_TYPE_ENTROPY); + + if (vi_intr_init(&sc->vrsc_vs, 1, fbsdrun_virtio_msix())) + return (1); + vi_set_io_bar(&sc->vrsc_vs, 0); + + return (0); +} + + +struct pci_devemu pci_de_vrnd = { + .pe_emu = "virtio-rnd", + .pe_init = pci_vtrnd_init, + .pe_barwrite = vi_pci_write, + .pe_barread = vi_pci_read +}; +PCI_EMUL_SET(pci_de_vrnd); diff --git a/usr.sbin/bhyve/virtio.h b/usr.sbin/bhyve/virtio.h index 51a654a..01b5f7b 100644 --- a/usr.sbin/bhyve/virtio.h +++ b/usr.sbin/bhyve/virtio.h @@ -209,6 +209,7 @@ struct vring_used { #define VIRTIO_VENDOR 0x1AF4 #define VIRTIO_DEV_NET 0x1000 #define VIRTIO_DEV_BLOCK 0x1001 +#define VIRTIO_DEV_RANDOM 0x1002 /* * PCI config space constants. |