mirror of https://github.com/xemu-project/xemu.git
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);
|
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 */
|
/* monitor info on PCI */
|
||||||
|
|
||||||
|
|
7
hw/pci.h
7
hw/pci.h
|
@ -182,6 +182,7 @@ typedef struct PCIDeviceClass {
|
||||||
const char *romfile;
|
const char *romfile;
|
||||||
} PCIDeviceClass;
|
} PCIDeviceClass;
|
||||||
|
|
||||||
|
typedef void (*PCIINTxRoutingNotifier)(PCIDevice *dev);
|
||||||
typedef int (*MSIVectorUseNotifier)(PCIDevice *dev, unsigned int vector,
|
typedef int (*MSIVectorUseNotifier)(PCIDevice *dev, unsigned int vector,
|
||||||
MSIMessage msg);
|
MSIMessage msg);
|
||||||
typedef void (*MSIVectorReleaseNotifier)(PCIDevice *dev, unsigned int vector);
|
typedef void (*MSIVectorReleaseNotifier)(PCIDevice *dev, unsigned int vector);
|
||||||
|
@ -259,6 +260,9 @@ struct PCIDevice {
|
||||||
MemoryRegion rom;
|
MemoryRegion rom;
|
||||||
uint32_t rom_bar;
|
uint32_t rom_bar;
|
||||||
|
|
||||||
|
/* INTx routing notifier */
|
||||||
|
PCIINTxRoutingNotifier intx_routing_notifier;
|
||||||
|
|
||||||
/* MSI-X notifiers */
|
/* MSI-X notifiers */
|
||||||
MSIVectorUseNotifier msix_vector_use_notifier;
|
MSIVectorUseNotifier msix_vector_use_notifier;
|
||||||
MSIVectorReleaseNotifier msix_vector_release_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);
|
uint8_t devfn_min, int nirq);
|
||||||
void pci_bus_set_route_irq_fn(PCIBus *, pci_route_irq_fn);
|
void pci_bus_set_route_irq_fn(PCIBus *, pci_route_irq_fn);
|
||||||
PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin);
|
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_device_reset(PCIDevice *dev);
|
||||||
void pci_bus_reset(PCIBus *bus);
|
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)) {
|
if (ranges_overlap(address, len, PIIX_PIRQC, 4)) {
|
||||||
PIIX3State *piix3 = DO_UPCAST(PIIX3State, dev, dev);
|
PIIX3State *piix3 = DO_UPCAST(PIIX3State, dev, dev);
|
||||||
int pic_irq;
|
int pic_irq;
|
||||||
|
|
||||||
|
pci_bus_fire_intx_routing_notifier(piix3->dev.bus);
|
||||||
piix3_update_irq_levels(piix3);
|
piix3_update_irq_levels(piix3);
|
||||||
for (pic_irq = 0; pic_irq < PIIX_NUM_PIC_IRQS; pic_irq++) {
|
for (pic_irq = 0; pic_irq < PIIX_NUM_PIC_IRQS; pic_irq++) {
|
||||||
piix3_set_irq_pic(piix3, pic_irq);
|
piix3_set_irq_pic(piix3, pic_irq);
|
||||||
|
|
Loading…
Reference in New Issue