[RFC PATCH v1 11/17] hw/virtio: force modern virtio for a CoVE guest

Baolong Duan <[email protected]> Fri, 31 Jul 2026 11:50:05 +0800
Newsgroups org.nongnu.qemu-riscv,org.nongnu.qemu-devel
Message-ID <[email protected]>
Devices have no direct access to the memory of a CoVE guest, so DMA has
to be bounced through buffers that the guest shares explicitly.  Offer
VIRTIO_F_ACCESS_PLATFORM unconditionally, together with
VIRTIO_F_VERSION_1 which Linux requires whenever ACCESS_PLATFORM is
offered.

Such a device therefore always negotiates in modern mode, so the legacy
IOMMU_PLATFORM check in virtio-pci does not apply to it either.

Signed-off-by: Baolong Duan <[email protected]>
---
 hw/virtio/virtio-bus.c | 12 ++++++++++++
 hw/virtio/virtio-pci.c |  9 ++++++++-
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
index 9b545acda3..2e2917236f 100644
--- a/hw/virtio/virtio-bus.c
+++ b/hw/virtio/virtio-bus.c
@@ -29,6 +29,7 @@
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/virtio.h"
 #include "system/address-spaces.h"
+#include "hw/riscv/cove.h"
 
 /* #define DEBUG_VIRTIO_BUS */
 
@@ -75,6 +76,17 @@ void virtio_bus_device_plugged(VirtIODevice *vdev, Error **errp)
         return;
     }
 
+    /*
+     * Devices cannot access the memory of a CoVE guest directly, so all DMA
+     * has to be bounced through buffers the guest shares explicitly: offer
+     * VIRTIO_F_ACCESS_PLATFORM unconditionally. VIRTIO_F_VERSION_1 has to be
+     * offered as well because Linux refuses ACCESS_PLATFORM without it.
+     */
+    if (riscv_cove_vm_active()) {
+        vdev->host_features |= 1ULL << VIRTIO_F_ACCESS_PLATFORM;
+        vdev->host_features |= 1ULL << VIRTIO_F_VERSION_1;
+    }
+
     if (klass->device_plugged != NULL) {
         klass->device_plugged(qbus->parent, &local_err);
     }
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 6f5db5fc42..b257d4a09f 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -34,6 +34,7 @@
 #include "hw/pci/msi.h"
 #include "hw/pci/msix.h"
 #include "hw/core/loader.h"
+#include "hw/riscv/cove.h"
 #include "system/accel-irq.h"
 #include "system/kvm.h"
 #include "hw/virtio/virtio-pci.h"
@@ -2048,7 +2049,13 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
                 return;
             }
         }
-        if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM)) {
+        /*
+         * A CoVE guest always negotiates in modern mode: ACCESS_PLATFORM,
+         * which shares its feature bit with IOMMU_PLATFORM, is forced
+         * together with VERSION_1, so this check does not apply.
+         */
+        if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM) &&
+            !riscv_cove_vm_active()) {
             error_setg(errp, "VIRTIO_F_IOMMU_PLATFORM was supported by"
                        " neither legacy nor transitional device");
             return;
-- 
2.34.1