Export fixed BAR metadata through the "etc/fixed-bars" fw_cfg file
and set pci_fixed_bar_supported to allow the fixed-bar-N properties
on the virt machine.

Fixed BAR placement requires the guest to preserve the PCI resource
configuration established by firmware, preventing the fixed BAR
addresses from being reassigned during guest boot. ACPI provides
this through the PCI boot configuration preservation mechanism
(_DSM function 5).

Reject fixed BAR configuration if firmware is not loaded or ACPI
is disabled, since PCI boot configuration preservation cannot
otherwise be guaranteed.

Signed-off-by: Tushar Dave <[email protected]>
---
 hw/arm/virt.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 3ab3ad8c3b..4bacb57770 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -94,6 +94,7 @@
 #include "hw/cxl/cxl_host.h"
 #include "qemu/guest-random.h"
 #include "hw/watchdog/sbsa_gwdt.h"
+#include "hw/pci/pci-fixed-bar.h"
 
 static GlobalProperty arm_virt_compat_defaults[] = {
     { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "48" },
@@ -2435,6 +2436,23 @@ void virt_machine_done(Notifier *notifier, void *data)
                                        vms->memmap[VIRT_PLATFORM_BUS].size,
                                        vms->irqmap[VIRT_PLATFORM_BUS]);
     }
+    if (fixed_bars_write_blob(vms->fw_cfg,
+                              vms->memmap[VIRT_PCIE_MMIO].base,
+                              vms->memmap[VIRT_PCIE_MMIO].size,
+                              vms->memmap[VIRT_HIGH_PCIE_MMIO].base,
+                              vms->highmem_mmio ?
+                              vms->memmap[VIRT_HIGH_PCIE_MMIO].size : 0,
+                              &error_fatal)) {
+        if (!(vms->bootinfo.firmware_loaded && virt_is_acpi_enabled(vms))) {
+            error_report("fixed-bar: fixed BAR placement requires firmware "
+                         "and ACPI to preserve the PCI boot configuration, "
+                         "otherwise these BAR assignments could be "
+                         "reassigned later with no protection");
+            exit(1);
+        }
+        vms->pci_preserve_config = true;
+    }
+
     if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as, ms, cpu) < 0) 
{
         exit(1);
     }
@@ -4192,6 +4210,7 @@ static void virt_machine_class_init(ObjectClass *oc, 
const void *data)
     hc->unplug_request = virt_machine_device_unplug_request_cb;
     hc->unplug = virt_machine_device_unplug_cb;
     mc->nvdimm_supported = true;
+    mc->pci_fixed_bar_supported = true;
     mc->smp_props.clusters_supported = true;
 
     /* Supported caches */
-- 
2.34.1


Reply via email to