[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 1/2] Add PCI bus listener interface
On Mon, Oct 13, 2014 at 01:52:46PM +0100, Paul Durrant wrote: > The Xen ioreq-server API, introduced in Xen 4.5, requires that PCI device > models explicitly register with Xen for config space accesses. This patch > adds a PCI bus listener interface which can be used by the Xen interface > code to monitor PCI buses for arrival and departure of devices. > > Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> > Cc: Michael S. Tsirkin <mst@xxxxxxxxxx> > Cc: Paolo Bonzini <pbonzini@xxxxxxxxxx> > Cc: Andreas Faerber <afaerber@xxxxxxx> > Cc: Thomas Huth <thuth@xxxxxxxxxxxxxxxxxx> > Cc: Peter Crosthwaite <peter.crosthwaite@xxxxxxxxxx> > Cc: Christian Borntraeger <borntraeger@xxxxxxxxxx> Do you really need multiple notifiers? In any case, I think such a mechanism makes more sense on QOM level: we have APIs to find objects of a given class and/or at a given path, why not a mechanism to get notified when said objects are added/removed. > --- > hw/pci/pci.c | 65 > +++++++++++++++++++++++++++++++++++++++++++++++ > include/hw/pci/pci.h | 9 +++++++ > include/qemu/typedefs.h | 1 + > 3 files changed, 75 insertions(+) > > diff --git a/hw/pci/pci.c b/hw/pci/pci.c > index 6ce75aa..53c955d 100644 > --- a/hw/pci/pci.c > +++ b/hw/pci/pci.c > @@ -122,6 +122,66 @@ static uint16_t pci_default_sub_device_id = > PCI_SUBDEVICE_ID_QEMU; > > static QLIST_HEAD(, PCIHostState) pci_host_bridges; > > +static QTAILQ_HEAD(pci_listeners, PCIListener) pci_listeners > + = QTAILQ_HEAD_INITIALIZER(pci_listeners); > + > +enum ListenerDirection { Forward, Reverse }; > + > +#define PCI_LISTENER_CALL(_callback, _direction, _args...) \ > + do { \ > + PCIListener *_listener; \ > + \ > + switch (_direction) { \ > + case Forward: \ > + QTAILQ_FOREACH(_listener, &pci_listeners, link) { \ > + if (_listener->_callback) { \ > + _listener->_callback(_listener, ##_args); \ > + } \ > + } \ > + break; \ > + case Reverse: \ > + QTAILQ_FOREACH_REVERSE(_listener, &pci_listeners, \ > + pci_listeners, link) { \ > + if (_listener->_callback) { \ > + _listener->_callback(_listener, ##_args); \ > + } \ > + } \ > + break; \ > + default: \ > + abort(); \ > + } \ > + } while (0) > + > +static int pci_listener_add(DeviceState *dev, void *opaque) > +{ > + if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { > + PCIDevice *pci_dev = PCI_DEVICE(dev); > + > + PCI_LISTENER_CALL(device_add, Forward, pci_dev); > + } > + > + return 0; > +} > + > +void pci_listener_register(PCIListener *listener) > +{ > + PCIHostState *host; > + > + QTAILQ_INSERT_TAIL(&pci_listeners, listener, link); > + > + QLIST_FOREACH(host, &pci_host_bridges, next) { > + PCIBus *bus = host->bus; > + > + qbus_walk_children(&bus->qbus, NULL, NULL, pci_listener_add, > + NULL, NULL); > + } > +} > + > +void pci_listener_unregister(PCIListener *listener) > +{ > + QTAILQ_REMOVE(&pci_listeners, listener, link); > +} > + > static int pci_bar(PCIDevice *d, int reg) > { > uint8_t type; > @@ -795,6 +855,8 @@ static void pci_config_free(PCIDevice *pci_dev) > > static void do_pci_unregister_device(PCIDevice *pci_dev) > { > + PCI_LISTENER_CALL(device_del, Reverse, pci_dev); > + > pci_dev->bus->devices[pci_dev->devfn] = NULL; > pci_config_free(pci_dev); > > @@ -878,6 +940,9 @@ static PCIDevice *do_pci_register_device(PCIDevice > *pci_dev, PCIBus *bus, > pci_dev->config_write = config_write; > bus->devices[devfn] = pci_dev; > pci_dev->version_id = 2; /* Current pci device vmstate version */ > + > + PCI_LISTENER_CALL(device_add, Forward, pci_dev); > + > return pci_dev; > } > > diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h > index c352c7b..6c21b37 100644 > --- a/include/hw/pci/pci.h > +++ b/include/hw/pci/pci.h > @@ -303,6 +303,15 @@ struct PCIDevice { > MSIVectorPollNotifier msix_vector_poll_notifier; > }; > > +struct PCIListener { > + void (*device_add)(PCIListener *listener, PCIDevice *pci_dev); > + void (*device_del)(PCIListener *listener, PCIDevice *pci_dev); > + QTAILQ_ENTRY(PCIListener) link; > +}; > + > +void pci_listener_register(PCIListener *listener); > +void pci_listener_unregister(PCIListener *listener); > + > void pci_register_bar(PCIDevice *pci_dev, int region_num, > uint8_t attr, MemoryRegion *memory); > void pci_register_vga(PCIDevice *pci_dev, MemoryRegion *mem, > diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h > index 04df51b..2b974c6 100644 > --- a/include/qemu/typedefs.h > +++ b/include/qemu/typedefs.h > @@ -54,6 +54,7 @@ typedef struct PCIHostState PCIHostState; > typedef struct PCIExpressHost PCIExpressHost; > typedef struct PCIBus PCIBus; > typedef struct PCIDevice PCIDevice; > +typedef struct PCIListener PCIListener; > typedef struct PCIExpressDevice PCIExpressDevice; > typedef struct PCIBridge PCIBridge; > typedef struct PCIEAERMsg PCIEAERMsg; > -- > 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |