[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [RFC for-4.1 5/5] pcie: Simplify pci_adjust_config_limi
From: |
Greg Kurz |
Subject: |
Re: [Qemu-devel] [RFC for-4.1 5/5] pcie: Simplify pci_adjust_config_limit() |
Date: |
Tue, 2 Apr 2019 15:53:05 +0200 |
On Tue, 2 Apr 2019 16:40:28 +1100
David Gibson <address@hidden> wrote:
> 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 wither extended configuration space is accessible. It is always
> 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.
>
> This should cause no behavioural change.
>
> Signed-off-by: David Gibson <address@hidden>
> ---
LGTM. Some remarks below.
> hw/pci/pci.c | 36 ++++++++++++++++++++++--------------
> hw/pci/pci_host.c | 13 +++----------
> hw/ppc/spapr_pci.c | 24 +++++++++---------------
> include/hw/pci/pci_bus.h | 3 ++-
> 4 files changed, 36 insertions(+), 40 deletions(-)
>
> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> index ea5941fb22..420496571e 100644
> --- a/hw/pci/pci.c
> +++ b/hw/pci/pci.c
> @@ -120,6 +120,25 @@ static void pci_bus_realize(BusState *qbus, Error **errp)
> vmstate_register(NULL, -1, &vmstate_pcibus, bus);
> }
>
> +static void pcie_bus_realize(BusState *qbus, Error **errp)
> +{
> + PCIBus *bus = PCI_BUS(qbus);
> +
> + pci_bus_realize(qbus, errp);
> +
> + /* a PCI-E bus can supported extended config space if it's the
s/supported/support
> + * root bus, or if the bus/bridge above it does as well */
> + if (pci_bus_is_root(bus)) {
> + bus->flags |= PCI_BUS_EXTENDED_CONFIG_SPACE;
> + } else {
> + PCIBus *parent_bus = pci_get_bus(bus->parent_dev);
> +
> + if (pci_bus_allows_extended_config_space(parent_bus)) {
> + bus->flags |= PCI_BUS_EXTENDED_CONFIG_SPACE;
> + }
> + }
> +}
> +
> static void pci_bus_unrealize(BusState *qbus, Error **errp)
> {
> PCIBus *bus = PCI_BUS(qbus);
> @@ -142,11 +161,6 @@ static uint16_t pcibus_numa_node(PCIBus *bus)
> return NUMA_NODE_UNASSIGNED;
> }
>
> -static bool pcibus_allows_extended_config_space(PCIBus *bus)
> -{
> - return false;
> -}
> -
> static void pci_bus_class_init(ObjectClass *klass, void *data)
> {
> BusClass *k = BUS_CLASS(klass);
> @@ -161,7 +175,6 @@ static void pci_bus_class_init(ObjectClass *klass, void
> *data)
>
> pbc->bus_num = pcibus_num;
> pbc->numa_node = pcibus_numa_node;
> - pbc->allows_extended_config_space = pcibus_allows_extended_config_space;
> }
>
> static const TypeInfo pci_bus_info = {
> @@ -182,16 +195,11 @@ static const TypeInfo conventional_pci_interface_info =
> {
> .parent = TYPE_INTERFACE,
> };
>
> -static bool pciebus_allows_extended_config_space(PCIBus *bus)
> -{
> - return true;
> -}
> -
> static void pcie_bus_class_init(ObjectClass *klass, void *data)
> {
> - PCIBusClass *pbc = PCI_BUS_CLASS(klass);
> + BusClass *k = BUS_CLASS(klass);
>
> - pbc->allows_extended_config_space = pciebus_allows_extended_config_space;
> + k->realize = pcie_bus_realize;
> }
>
> static const TypeInfo pcie_bus_info = {
> @@ -412,7 +420,7 @@ bool pci_bus_is_express(PCIBus *bus)
>
> bool pci_bus_allows_extended_config_space(PCIBus *bus)
> {
> - return PCI_BUS_GET_CLASS(bus)->allows_extended_config_space(bus);
> + return !!(bus->flags & PCI_BUS_EXTENDED_CONFIG_SPACE);
> }
>
Maybe make this a static inline in pci_bus.h like you already did with
pci_bus_is_root() in the previous patch ?
> void pci_root_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState
> *parent,
> diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
> index 9d64b2e12f..5f3497256c 100644
> --- a/hw/pci/pci_host.c
> +++ b/hw/pci/pci_host.c
> @@ -53,16 +53,9 @@ static inline PCIDevice *pci_dev_find_by_addr(PCIBus *bus,
> uint32_t addr)
>
> static void pci_adjust_config_limit(PCIBus *bus, uint32_t *limit)
> {
> - if (*limit > PCI_CONFIG_SPACE_SIZE) {
> - if (!pci_bus_allows_extended_config_space(bus)) {
> - *limit = PCI_CONFIG_SPACE_SIZE;
> - return;
> - }
> -
> - if (!pci_bus_is_root(bus)) {
> - PCIDevice *bridge = pci_bridge_get_device(bus);
> - pci_adjust_config_limit(pci_get_bus(bridge), limit);
> - }
> + if ((*limit > PCI_CONFIG_SPACE_SIZE) &&
parenthesitis ? ;-)
> + !pci_bus_allows_extended_config_space(bus)) {
> + *limit = PCI_CONFIG_SPACE_SIZE;
> }
> }
>
> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
> index 2e76d8cbd8..23d70ca6fe 100644
> --- a/hw/ppc/spapr_pci.c
> +++ b/hw/ppc/spapr_pci.c
> @@ -1638,26 +1638,11 @@ static void spapr_phb_unrealize(DeviceState *dev,
> Error **errp)
> memory_region_del_subregion(get_system_memory(), &sphb->mem32window);
> }
>
> -static bool spapr_phb_allows_extended_config_space(PCIBus *bus)
> -{
> - SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(BUS(bus)->parent);
> -
> - return sphb->pcie_ecs;
> -}
> -
> -static void spapr_phb_root_bus_class_init(ObjectClass *klass, void *data)
> -{
> - PCIBusClass *pbc = PCI_BUS_CLASS(klass);
> -
> - pbc->allows_extended_config_space =
> spapr_phb_allows_extended_config_space;
> -}
> -
> #define TYPE_SPAPR_PHB_ROOT_BUS "spapr-pci-host-bridge-root-bus"
>
> static const TypeInfo spapr_phb_root_bus_info = {
> .name = TYPE_SPAPR_PHB_ROOT_BUS,
> .parent = TYPE_PCI_BUS,
> - .class_init = spapr_phb_root_bus_class_init,
The type is quite useless now, it should be dropped I guess, ie.
git revert of "spapr_pci: Fix extended config space accesses".
> };
>
> static void spapr_phb_realize(DeviceState *dev, Error **errp)
> @@ -1766,6 +1751,15 @@ static void spapr_phb_realize(DeviceState *dev, Error
> **errp)
> &sphb->memspace, &sphb->iospace,
> PCI_DEVFN(0, 0), PCI_NUM_PINS,
> TYPE_SPAPR_PHB_ROOT_BUS);
> +
> + /*
> + * Despite resembling a vanilla PCI bus in most ways, the PAPR
> + * para-virtualized PCI bus *does* permit PCI-E extended config
> + * space access
> + */
> + if (sphb->pcie_ecs) {
> + bus->flags |= PCI_BUS_EXTENDED_CONFIG_SPACE;
> + }
> phb->bus = bus;
> qbus_set_hotplug_handler(BUS(phb->bus), OBJECT(sphb), NULL);
>
> diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
> index aea98d5040..3c0be4c420 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 {
- [Qemu-devel] [RFC for-4.1 0/5] Simplify some not-really-necessary PCI bus callbacks, David Gibson, 2019/04/02
- [Qemu-devel] [RFC for-4.1 3/5] pcie: Remove redundant test in pcie_mmcfg_data_read(), David Gibson, 2019/04/02
- [Qemu-devel] [RFC for-4.1 4/5] pci: Simplify pci_bus_is_root(), David Gibson, 2019/04/02
- [Qemu-devel] [RFC for-4.1 2/5] spapr_pci: Fix extended config space accesses, David Gibson, 2019/04/02
- [Qemu-devel] [RFC for-4.1 1/5] pci: Allow PCI bus subtypes to support extended config space accesses, David Gibson, 2019/04/02
- [Qemu-devel] [RFC for-4.1 5/5] pcie: Simplify pci_adjust_config_limit(), David Gibson, 2019/04/02
- Re: [Qemu-devel] [RFC for-4.1 5/5] pcie: Simplify pci_adjust_config_limit(),
Greg Kurz <=