aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Evans <kevans@FreeBSD.org>2026-11-05 21:53:30 +0000
committerColin Percival <cperciva@FreeBSD.org>2026-11-10 20:51:19 +0000
commit61b5fa09db8d95e38f795366135b5b13ebbd4f3b (patch)
tree13362c16a5b5ecba3334c7d26f2cf5230f928145
parent16edda206cc4972a9fbe1433fb5bb25907fc40cc (diff)
virtio_random: defer first enqueue until after DRIVER_OKreleng/15.2
According to the virtio spec: > The driver MUST NOT send any buffer available notifications to the > device before setting DRIVER_OK. DRIVER_OK isn't set until after attach completes, so defer the first enqueue. We haven't found any problems as a result of this to the best of my knowledge: q35 and other devices that we *have* been used with will apparently check when we go DRIVER_OK. Tested with q35 virtio-random, which still works. Approved by: re (cperciva) Reported by: llm-postcr Reviewed by: kfv, markj Fixes: f1c5a2e3a62505 ("virtio_random: Pipeline fetching the data") Sponsored by: Stormshield Sponsored by: Klara, Inc. (cherry picked from commit 12f90bbd3029fedea93e9bb0b1f02c3afafe237b) (cherry picked from commit 1a10bff4ce4772bb1611c286df8728cace5dfb65)
-rw-r--r--sys/dev/virtio/random/virtio_random.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/sys/dev/virtio/random/virtio_random.c b/sys/dev/virtio/random/virtio_random.c
index 3f30c8b68f4c..128e9c3937f0 100644
--- a/sys/dev/virtio/random/virtio_random.c
+++ b/sys/dev/virtio/random/virtio_random.c
@@ -47,6 +47,8 @@
#include <dev/virtio/virtio.h>
#include <dev/virtio/virtqueue.h>
+#include "virtio_if.h"
+
struct vtrnd_softc {
device_t vtrnd_dev;
uint64_t vtrnd_features;
@@ -69,6 +71,7 @@ static int vtrnd_setup_features(struct vtrnd_softc *);
static int vtrnd_alloc_virtqueue(struct vtrnd_softc *);
static int vtrnd_harvest(struct vtrnd_softc *, void *, size_t *);
static void vtrnd_enqueue(struct vtrnd_softc *sc);
+static int vtrnd_attach_completed(device_t);
static unsigned vtrnd_read(void *, unsigned);
#define VTRND_FEATURES 0
@@ -93,6 +96,9 @@ static device_method_t vtrnd_methods[] = {
DEVMETHOD(device_detach, vtrnd_detach),
DEVMETHOD(device_shutdown, vtrnd_shutdown),
+ /* Virtio methods. */
+ DEVMETHOD(virtio_attach_completed, vtrnd_attach_completed),
+
DEVMETHOD_END
};
@@ -181,8 +187,6 @@ vtrnd_attach(device_t dev)
sc->inactive = false;
random_source_register(&random_vtrnd);
- vtrnd_enqueue(sc);
-
fail:
if (error)
vtrnd_detach(dev);
@@ -327,3 +331,13 @@ vtrnd_read(void *buf, unsigned usz)
return (sz);
}
+
+static int
+vtrnd_attach_completed(device_t dev)
+{
+ struct vtrnd_softc *sc;
+
+ sc = device_get_softc(dev);
+ vtrnd_enqueue(sc);
+ return (0);
+}