This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 6f6fba96b6357d1c0a288513a113c44e7696489f Author: pengyiqiang <[email protected]> AuthorDate: Thu Oct 8 18:59:36 2026 +0800 drivers/virtio: reset the device only when it is not in power-on state Commit fee69a20461 dropped the RESET write at init because it hangs QEMU in virtio_gpu_reset() under icount + record/replay. Without it, a device left configured by an earlier boot keeps a stale queue and every probe fails with -ENOENT. Read the status first and write RESET only when it is not 0, which keeps the power-on case free of the hanging write. Signed-off-by: pengyiqiang <[email protected]> --- drivers/virtio/virtio-mmio.c | 10 +++++++++- drivers/virtio/virtio-pci.c | 11 +++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/virtio/virtio-mmio.c b/drivers/virtio/virtio-mmio.c index 8ef4cb3ccd5..46ea346dae2 100644 --- a/drivers/virtio/virtio-mmio.c +++ b/drivers/virtio/virtio-mmio.c @@ -854,7 +854,15 @@ static int virtio_mmio_init_device(FAR struct virtio_mmio_device_s *vmdev, vrtinfo("VIRTIO version: %"PRIu32" device: %"PRIu32" vendor: %"PRIx32"\n", vdev->id.version, vdev->id.device, vdev->id.vendor); - /* Reset the virtio device and set ACK */ + /* Reset the virtio device and set ACK. A device still in its power-on + * state (status 0) is already reset; skipping the write then avoids a + * QEMU hang in virtio_gpu_reset() under icount + record/replay. + */ + + if (virtio_mmio_get_status(vdev) != VIRTIO_CONFIG_STATUS_RESET) + { + virtio_mmio_set_status(vdev, VIRTIO_CONFIG_STATUS_RESET); + } virtio_mmio_set_status(vdev, VIRTIO_CONFIG_STATUS_ACK); return OK; diff --git a/drivers/virtio/virtio-pci.c b/drivers/virtio/virtio-pci.c index 79b6c56cf08..4b1bb40c513 100644 --- a/drivers/virtio/virtio-pci.c +++ b/drivers/virtio/virtio-pci.c @@ -174,6 +174,7 @@ static int virtio_pci_probe(FAR struct pci_device_s *dev) { FAR struct virtio_pci_device_s *vpdev; FAR struct virtio_device *vdev; + uint8_t status; int ret; /* We only own devices >= 0x1000 and <= 0x107f: leave the rest. */ @@ -255,6 +256,16 @@ static int virtio_pci_probe(FAR struct pci_device_s *dev) vrtinfo("Polling mode\n"); #endif + /* Only reset a device that is not already in its power-on state, see + * virtio_mmio_init_device(). + */ + + if (virtio_get_status(vdev, &status) != 0 || + status != VIRTIO_CONFIG_STATUS_RESET) + { + virtio_set_status(vdev, VIRTIO_CONFIG_STATUS_RESET); + } + virtio_set_status(vdev, VIRTIO_CONFIG_STATUS_ACK); ret = virtio_register_device(&vpdev->vdev);
