pci: Add INTx routing notifier
This per-device notifier shall be triggered by any interrupt router along the path of a device's legacy interrupt signal on routing changes. For simplicity reasons and as this is a slow path anyway, no further details on the routing changes are provided. Instead, the callback is expected to use pci_device_route_intx_to_irq to check the effect of the change. Will be used by KVM PCI device assignment and VFIO. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
3afa9bb488
commit
0ae1625177
23
hw/pci.c
23
hw/pci.c
@ -1086,6 +1086,29 @@ PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)
|
||||
return bus->route_intx_to_irq(bus->irq_opaque, pin);
|
||||
}
|
||||
|
||||
void pci_bus_fire_intx_routing_notifier(PCIBus *bus)
|
||||
{
|
||||
PCIDevice *dev;
|
||||
PCIBus *sec;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
|
||||
dev = bus->devices[i];
|
||||
if (dev && dev->intx_routing_notifier) {
|
||||
dev->intx_routing_notifier(dev);
|
||||
}
|
||||
QLIST_FOREACH(sec, &bus->child, sibling) {
|
||||
pci_bus_fire_intx_routing_notifier(sec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pci_device_set_intx_routing_notifier(PCIDevice *dev,
|
||||
PCIINTxRoutingNotifier notifier)
|
||||
{
|
||||
dev->intx_routing_notifier = notifier;
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
/* monitor info on PCI */
|
||||
|
||||
|
7
hw/pci.h
7
hw/pci.h
@ -182,6 +182,7 @@ typedef struct PCIDeviceClass {
|
||||
const char *romfile;
|
||||
} PCIDeviceClass;
|
||||
|
||||
typedef void (*PCIINTxRoutingNotifier)(PCIDevice *dev);
|
||||
typedef int (*MSIVectorUseNotifier)(PCIDevice *dev, unsigned int vector,
|
||||
MSIMessage msg);
|
||||
typedef void (*MSIVectorReleaseNotifier)(PCIDevice *dev, unsigned int vector);
|
||||
@ -259,6 +260,9 @@ struct PCIDevice {
|
||||
MemoryRegion rom;
|
||||
uint32_t rom_bar;
|
||||
|
||||
/* INTx routing notifier */
|
||||
PCIINTxRoutingNotifier intx_routing_notifier;
|
||||
|
||||
/* MSI-X notifiers */
|
||||
MSIVectorUseNotifier msix_vector_use_notifier;
|
||||
MSIVectorReleaseNotifier msix_vector_release_notifier;
|
||||
@ -318,6 +322,9 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,
|
||||
uint8_t devfn_min, int nirq);
|
||||
void pci_bus_set_route_irq_fn(PCIBus *, pci_route_irq_fn);
|
||||
PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin);
|
||||
void pci_bus_fire_intx_routing_notifier(PCIBus *bus);
|
||||
void pci_device_set_intx_routing_notifier(PCIDevice *dev,
|
||||
PCIINTxRoutingNotifier notifier);
|
||||
void pci_device_reset(PCIDevice *dev);
|
||||
void pci_bus_reset(PCIBus *bus);
|
||||
|
||||
|
@ -423,6 +423,8 @@ static void piix3_write_config(PCIDevice *dev,
|
||||
if (ranges_overlap(address, len, PIIX_PIRQC, 4)) {
|
||||
PIIX3State *piix3 = DO_UPCAST(PIIX3State, dev, dev);
|
||||
int pic_irq;
|
||||
|
||||
pci_bus_fire_intx_routing_notifier(piix3->dev.bus);
|
||||
piix3_update_irq_levels(piix3);
|
||||
for (pic_irq = 0; pic_irq < PIIX_NUM_PIC_IRQS; pic_irq++) {
|
||||
piix3_set_irq_pic(piix3, pic_irq);
|
||||
|
Loading…
x
Reference in New Issue
Block a user