[RFC PATCH v1 08/17] hw/riscv/virt: use MSIs only for a CoVE guest

Baolong Duan <[email protected]> Fri, 31 Jul 2026 11:50:02 +0800
Newsgroups org.nongnu.qemu-riscv,org.nongnu.qemu-devel
Message-ID <[email protected]>
Interrupts of a CoVE guest can only be delivered as MSIs, so an IMSIC is
mandatory: without one PCIe devices have no interrupt source at all and
their drivers fail to probe.  Select aia=aplic-imsic when no AIA mode has
been requested.

Also stop creating the virtio-mmio transports, which a CoVE guest cannot
use; its devices are attached to the PCIe host bridge instead.

Signed-off-by: Baolong Duan <[email protected]>
---
 hw/riscv/virt.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 777859baa2..dbb82bbd21 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1373,6 +1373,16 @@ static void virt_machine_init(MachineState *machine)
         exit(1);
     }
 
+    /*
+     * A CoVE guest can only receive MSIs, so an IMSIC is mandatory: without
+     * it PCIe devices have no interrupt source at all and their drivers fail
+     * to probe.
+     */
+    if (s->cove_vm && s->aia_type == VIRT_AIA_TYPE_NONE) {
+        s->aia_type = VIRT_AIA_TYPE_APLIC_IMSIC;
+        warn_report("CoVE VM: forcing aia=aplic-imsic");
+    }
+
     /* Initialize sockets */
     mmio_irqchip = virtio_irqchip = pcie_irqchip = NULL;
     for (i = 0; i < socket_count; i++) {
@@ -1524,10 +1534,13 @@ static void virt_machine_init(MachineState *machine)
     sifive_test_create(s->memmap[VIRT_TEST].base);
 
     /* VirtIO MMIO devices */
-    for (i = 0; i < VIRTIO_COUNT; i++) {
-        sysbus_create_simple("virtio-mmio",
-            s->memmap[VIRT_VIRTIO].base + i * s->memmap[VIRT_VIRTIO].size,
-            qdev_get_gpio_in(virtio_irqchip, VIRTIO_IRQ + i));
+    /* A CoVE guest has no virtio-mmio transport, see create_fdt_virtio(). */
+    if (!s->cove_vm) {
+        for (i = 0; i < VIRTIO_COUNT; i++) {
+            sysbus_create_simple("virtio-mmio",
+                s->memmap[VIRT_VIRTIO].base + i * s->memmap[VIRT_VIRTIO].size,
+                qdev_get_gpio_in(virtio_irqchip, VIRTIO_IRQ + i));
+        }
     }
 
     gpex_pcie_init(system_memory, pcie_irqchip, s);
-- 
2.34.1