summaryrefslogtreecommitdiff
path: root/include/hw/pci
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2019-05-13 16:19:37 +1000
committerMichael S. Tsirkin <mst@redhat.com>2019-05-29 18:00:57 -0400
commit2f57db8a2781787a0a31d3a9ce4a286fc45a42b3 (patch)
tree918fc927c1a76bde7dfb73be3f2e0e91b0cdb703 /include/hw/pci
parente4610781635404d494120c19bade8dad6f00f0b3 (diff)
downloadqemu-2f57db8a2781787a0a31d3a9ce4a286fc45a42b3.zip
pcie: Simplify pci_adjust_config_limit()
Since c2077e2c "pci: Adjust PCI config limit based on bus topology", pci_adjust_config_limit() has been used in the config space read and write paths to only permit access to extended config space on buses which permit it. Specifically it prevents access on devices below a vanilla-PCI bus via some combination of bridges, even if both the host bridge and the device itself are PCI-E. It accomplishes this with a somewhat complex call up the chain of bridges to see if any of them prohibit extended config space access. This is overly complex, since we can always know if the bus will support such access at the point it is constructed. This patch simplifies the test by using a flag in the PCIBus instance indicating whether extended configuration space is accessible. It is false for vanilla PCI buses. For PCI-E buses, it is true for root buses and equal to the parent bus's's capability otherwise. For the special case of sPAPR's paravirtualized PCI root bus, which acts mostly like vanilla PCI, but does allow extended config space access, we override the default value of the flag from the host bridge code. This should cause no behavioural change. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Greg Kurz <groug@kaod.org> Message-Id: <20190513061939.3464-4-david@gibson.dropbear.id.au> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'include/hw/pci')
-rw-r--r--include/hw/pci/pci.h1
-rw-r--r--include/hw/pci/pci_bus.h8
2 files changed, 7 insertions, 2 deletions
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index edf44de21d..da20c915ef 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -395,7 +395,6 @@ typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int pin);
#define TYPE_PCIE_BUS "PCIE"
bool pci_bus_is_express(PCIBus *bus);
-bool pci_bus_allows_extended_config_space(PCIBus *bus);
void pci_root_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
const char *name,
diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
index aea98d5040..0714f578af 100644
--- a/include/hw/pci/pci_bus.h
+++ b/include/hw/pci/pci_bus.h
@@ -17,12 +17,13 @@ typedef struct PCIBusClass {
int (*bus_num)(PCIBus *bus);
uint16_t (*numa_node)(PCIBus *bus);
- bool (*allows_extended_config_space)(PCIBus *bus);
} PCIBusClass;
enum PCIBusFlags {
/* This bus is the root of a PCI domain */
PCI_BUS_IS_ROOT = 0x0001,
+ /* PCIe extended configuration space is accessible on this bus */
+ PCI_BUS_EXTENDED_CONFIG_SPACE = 0x0002,
};
struct PCIBus {
@@ -57,4 +58,9 @@ static inline bool pci_bus_is_root(PCIBus *bus)
return !!(bus->flags & PCI_BUS_IS_ROOT);
}
+static inline bool pci_bus_allows_extended_config_space(PCIBus *bus)
+{
+ return !!(bus->flags & PCI_BUS_EXTENDED_CONFIG_SPACE);
+}
+
#endif /* QEMU_PCI_BUS_H */