Windows ARM64 guests detect virtio-mmio devices declared in ACPI tables even when no backend is attached. This causes "Unknown devices" (ACPI\LNRO0005) to appear in Device Manager.
Until Windows fixes that by supporting, add a new machine property 'virtio-mmio-transports' to control the number of virtio-mmio transports instantiated. The default remains NUM_VIRTIO_TRANSPORTS (32) for backward compatibility. Setting it to 0 allows users to disable virtio-mmio entirely. Usage: -machine virt,virtio-mmio-transports=0 Signed-off-by: Mohammadfaiz Bawa <[email protected]> --- Changes in v2: - Renamed property from virtio-transports to virtio-mmio-transports - Added documentation in docs/system/arm/virt.rst docs/system/arm/virt.rst | 5 +++++ hw/arm/virt-acpi-build.c | 2 +- hw/arm/virt.c | 43 ++++++++++++++++++++++++++++++++++++++-- include/hw/arm/virt.h | 1 + 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst index e5570773ba..e037f2c269 100644 --- a/docs/system/arm/virt.rst +++ b/docs/system/arm/virt.rst @@ -212,6 +212,11 @@ dtb-randomness dtb-kaslr-seed A deprecated synonym for dtb-randomness. +virtio-mmio-transports + Set the number of virtio-mmio transports to create (between 0 and 32; + the default is 32). Unused transports are harmless, but you can + use this property to avoid exposing them to the guest if you wish. + x-oem-id Set string (up to 6 bytes) to override the default value of field OEMID in ACPI table header. diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index c145678185..27c007fd62 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -1150,7 +1150,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) fw_cfg_acpi_dsdt_add(scope, &memmap[VIRT_FW_CFG]); virtio_acpi_dsdt_add(scope, memmap[VIRT_MMIO].base, memmap[VIRT_MMIO].size, (irqmap[VIRT_MMIO] + ARM_SPI_BASE), - 0, NUM_VIRTIO_TRANSPORTS); + 0, vms->virtio_transports); acpi_dsdt_add_pci(scope, memmap, irqmap[VIRT_PCIE] + ARM_SPI_BASE, vms); if (vms->acpi_dev) { build_ged_aml(scope, "\\_SB."GED_DEVICE, diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 390845c503..b1e8ce9723 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1206,7 +1206,7 @@ static void create_virtio_devices(const VirtMachineState *vms) * between kernel versions). For reliable and stable identification * of disks users must use UUIDs or similar mechanisms. */ - for (i = 0; i < NUM_VIRTIO_TRANSPORTS; i++) { + for (i = 0; i < vms->virtio_transports; i++) { int irq = vms->irqmap[VIRT_MMIO] + i; hwaddr base = vms->memmap[VIRT_MMIO].base + i * size; @@ -1221,7 +1221,7 @@ static void create_virtio_devices(const VirtMachineState *vms) * loop influences virtio device to virtio transport assignment, whereas * this loop controls how virtio transports are laid out in the dtb. */ - for (i = NUM_VIRTIO_TRANSPORTS - 1; i >= 0; i--) { + for (i = vms->virtio_transports - 1; i >= 0; i--) { char *nodename; int irq = vms->irqmap[VIRT_MMIO] + i; hwaddr base = vms->memmap[VIRT_MMIO].base + i * size; @@ -2705,6 +2705,36 @@ static void virt_set_highmem_mmio_size(Object *obj, Visitor *v, extended_memmap[VIRT_HIGH_PCIE_MMIO].size = size; } +static void virt_get_virtio_transports(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + VirtMachineState *vms = VIRT_MACHINE(obj); + uint8_t transports = vms->virtio_transports; + + visit_type_uint8(v, name, &transports, errp); +} + +static void virt_set_virtio_transports(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + VirtMachineState *vms = VIRT_MACHINE(obj); + uint8_t transports; + + if (!visit_type_uint8(v, name, &transports, errp)) { + return; + } + + if (transports > NUM_VIRTIO_TRANSPORTS) { + error_setg(errp, "virtio-mmio-transports must not exceed %d", + NUM_VIRTIO_TRANSPORTS); + return; + } + + vms->virtio_transports = transports; +} + static bool virt_get_its(Object *obj, Error **errp) { VirtMachineState *vms = VIRT_MACHINE(obj); @@ -3427,6 +3457,13 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data) "Set the high memory region size " "for PCI MMIO"); + object_class_property_add(oc, "virtio-mmio-transports", "uint8", + virt_get_virtio_transports, + virt_set_virtio_transports, + NULL, NULL); + object_class_property_set_description(oc, "virtio-mmio-transports", + "Set the number of virtio-mmio transports to instantiate"); + object_class_property_add_str(oc, "gic-version", virt_get_gic_version, virt_set_gic_version); object_class_property_set_description(oc, "gic-version", @@ -3540,6 +3577,8 @@ static void virt_instance_init(Object *obj) vms->irqmap = a15irqmap; + vms->virtio_transports = NUM_VIRTIO_TRANSPORTS; + virt_flash_create(vms); vms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6); diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index 3b382bdf49..f898afaa6e 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -169,6 +169,7 @@ struct VirtMachineState { uint32_t msi_phandle; uint32_t iommu_phandle; int psci_conduit; + uint8_t virtio_transports; hwaddr highest_gpa; DeviceState *gic; DeviceState *acpi_dev; -- 2.53.0
