In preparation to support VIRTIO_F_DMB, locate a device's Device Memory Buffer once feature negotiation is complete. The shared memory id that locates the region may only be read after the device has confirmed FEATURES_OK, and finalize_features() runs before that.
virtio_features_ok() is the one place in the core that has just read FEATURES_OK back, so locate the region from there, and release it from virtio_dev_remove() and from the error paths of probe and restore. Restore and reset completion reach it too, where virtio_dmb_init() keeps the state of a device reporting the region it had. Suspend and reset need no handling of their own. Neither virtio_device_freeze() nor virtio_reset_device() deletes a virtqueue, and a live virtqueue holds addresses inside the region, so we keep it across both. Link: https://lore.kernel.org/virtio-comment/[email protected]/ Assisted-by: Kiro:claude-opus-5 checkpatch sparse Signed-off-by: Alexander Graf <[email protected]> --- drivers/virtio/virtio.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index 299fa83be1d5..6f112593566c 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c @@ -8,6 +8,8 @@ #include <linux/of.h> #include <uapi/linux/virtio_ids.h> +#include "virtio_dmb.h" + /* Unique numbering for virtio devices. */ static DEFINE_IDA(virtio_index_ida); @@ -231,7 +233,14 @@ static int virtio_features_ok(struct virtio_device *dev) status); return -ENODEV; } - return 0; + + /* + * Negotiation is complete, so a Device Memory Buffer may now be + * located. Reached from probe, from resume and from reset + * completion, all of which have to end with the state matching what + * the device reports now. + */ + return virtio_dmb_init(dev); } /** @@ -361,6 +370,7 @@ static int virtio_dev_probe(struct device *_d) err: virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED); + virtio_dmb_destroy(dev); return err; } @@ -377,6 +387,8 @@ static void virtio_dev_remove(struct device *_d) /* Driver should have reset device. */ WARN_ON_ONCE(dev->config->get_status(dev)); + virtio_dmb_destroy(dev); + /* Acknowledge the device's existence again. */ virtio_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE); @@ -650,6 +662,7 @@ static int virtio_device_restore_priv(struct virtio_device *dev, bool restore) err: virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED); + virtio_dmb_destroy(dev); return ret; }

