From: Mohammadfaiz Bawa <[email protected]> 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]> Message-id: [email protected] Reviewed-by: Peter Maydell <[email protected]> Signed-off-by: Peter Maydell <[email protected]> --- 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 f8148b5dcf..fbe3ca9e12 100644 --- a/docs/system/arm/virt.rst +++ b/docs/system/arm/virt.rst @@ -226,6 +226,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 544004615d..719d2f994e 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -1154,7 +1154,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 50865e8115..81e700f516 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1208,7 +1208,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; @@ -1223,7 +1223,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; @@ -2826,6 +2826,36 @@ static void virt_set_its(Object *obj, bool value, Error **errp) } } +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_dtb_randomness(Object *obj, Error **errp) { VirtMachineState *vms = VIRT_MACHINE(obj); @@ -3535,6 +3565,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", @@ -3654,6 +3691,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 8069422769..dba8ac7f2f 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -172,6 +172,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.43.0
