qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-ppc] [RFC for-4.1 5/5] pcie: Simplify pci_adjust_config_limit(


From: David Gibson
Subject: Re: [Qemu-ppc] [RFC for-4.1 5/5] pcie: Simplify pci_adjust_config_limit()
Date: Wed, 3 Apr 2019 12:24:35 +1100
User-agent: Mutt/1.11.3 (2019-02-01)

On Tue, Apr 02, 2019 at 03:53:05PM +0200, Greg Kurz wrote:
> 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

Corrected, along with the block comment formatting.

> > +     * 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 ?

I thought I'd tried that earlier and run into include hell because of
the target vs. non-target distinction.  But I must have been mistaken
because I tried it again and it worked fine.

> >  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".

Ah, good point.

> >  };
> >  
> >  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 {
> 

-- 
David Gibson                    | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
                                | _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]