Now that viewport memory regions are created on demand, the PCIDevice of the
configuration memory can be determined once upon creation of the memory region
rather than dynamically resolving it upon each access. This is both more
efficient at runtime and resolves an attribute. Furthermore, if an invalid PCI
device is configured, a guest error is now logged since the error is now
direclty related to a guest action.

Signed-off-by: Bernhard Beschow <shen...@gmail.com>
---
 include/hw/pci-host/designware.h |  1 -
 hw/pci-host/designware.c         | 54 +++++++++++++++++---------------
 2 files changed, 28 insertions(+), 27 deletions(-)

diff --git a/include/hw/pci-host/designware.h b/include/hw/pci-host/designware.h
index 7dc8af049d..34beee1285 100644
--- a/include/hw/pci-host/designware.h
+++ b/include/hw/pci-host/designware.h
@@ -39,7 +39,6 @@ struct DesignwarePCIERootBus {
 };
 
 typedef struct DesignwarePCIEViewport {
-    DesignwarePCIERoot *root;
     const char *name;
     MemoryRegion mem;
 
diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
index 7d47d8228f..2a676c65a2 100644
--- a/hw/pci-host/designware.c
+++ b/hw/pci-host/designware.c
@@ -222,26 +222,18 @@ designware_pcie_root_config_read(PCIDevice *d, uint32_t 
address, int len)
 static uint64_t designware_pcie_root_data_access(void *opaque, hwaddr addr,
                                                  uint64_t *val, unsigned len)
 {
-    DesignwarePCIEViewport *viewport = opaque;
-    DesignwarePCIERoot *root = viewport->root;
-
-    const uint8_t busnum = DESIGNWARE_PCIE_ATU_BUS(viewport->target);
-    const uint8_t devfn  = DESIGNWARE_PCIE_ATU_DEVFN(viewport->target);
-    PCIBus    *pcibus    = pci_get_bus(PCI_DEVICE(root));
-    PCIDevice *pcidev    = pci_find_device(pcibus, busnum, devfn);
-
-    if (pcidev) {
-        addr &= pci_config_size(pcidev) - 1;
-
-        if (val) {
-            pci_host_config_write_common(pcidev, addr,
-                                         pci_config_size(pcidev),
-                                         *val, len);
-        } else {
-            return pci_host_config_read_common(pcidev, addr,
-                                               pci_config_size(pcidev),
-                                               len);
-        }
+    PCIDevice *pcidev = opaque;
+
+    addr &= pci_config_size(pcidev) - 1;
+
+    if (val) {
+        pci_host_config_write_common(pcidev, addr,
+                                     pci_config_size(pcidev),
+                                     *val, len);
+    } else {
+        return pci_host_config_read_common(pcidev, addr,
+                                           pci_config_size(pcidev),
+                                           len);
     }
 
     return UINT64_MAX;
@@ -312,11 +304,22 @@ static void 
designware_pcie_update_viewport(DesignwarePCIERoot *root,
                  * Configure MemoryRegion implementing access to configuration
                  * space
                  */
-                memory_region_init_io(&viewport->mem, OBJECT(root),
-                                      &designware_pci_host_conf_ops,
-                                      viewport, viewport->name, size);
-                memory_region_add_subregion(get_system_memory(), base,
-                                            &viewport->mem);
+                const uint8_t busnum = 
DESIGNWARE_PCIE_ATU_BUS(viewport->target);
+                const uint8_t devfn = 
DESIGNWARE_PCIE_ATU_DEVFN(viewport->target);
+                PCIBus *pcibus = pci_get_bus(PCI_DEVICE(root));
+                PCIDevice *pcidev = pci_find_device(pcibus, busnum, devfn);
+
+                if (pcidev) {
+                    memory_region_init_io(&viewport->mem, OBJECT(root),
+                                          &designware_pci_host_conf_ops,
+                                          pcidev, viewport->name, size);
+                    memory_region_add_subregion(get_system_memory(), base,
+                                                &viewport->mem);
+                } else {
+                    qemu_log_mask(LOG_GUEST_ERROR, "%s: No PCI device attached"
+                                  " under busnum: %d, devfn: %d\n", __func__,
+                                  (int)busnum, (int)devfn);
+                }
             }
         }
     }
@@ -444,7 +447,6 @@ static void designware_pcie_root_realize(PCIDevice *dev, 
Error **errp)
 
         for (size_t j = 0; j < DESIGNWARE_PCIE_NUM_VIEWPORTS; j++) {
             DesignwarePCIEViewport *viewport = &root->viewports[i][j];
-            viewport->root    = root;
             viewport->name    = names[i][j];
             viewport->inbound = i == DESIGNWARE_PCIE_VIEWPORT_INBOUND;
             viewport->base    = 0x0000000000000000ULL;
-- 
2.50.1


Reply via email to