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);

Reply via email to