On 08/19/2013 05:35 PM, Michael S. Tsirkin wrote: > On Wed, Aug 07, 2013 at 06:51:32PM +1000, Alexey Kardashevskiy wrote: >> On PPC64 systems MSI Messages are translated to system IRQ in a PCI >> host bridge. This is already supported for emulated MSI/MSIX but >> not for irqfd where the current QEMU allocates IRQ numbers from >> irqchip and maps MSIMessages to those IRQ in the host kernel. >> >> The patch extends irqfd support in order to avoid unnecessary >> mapping and reuse the one which already exists in a PCI host bridge. >> >> Specifically, a map_msi callback is added to PCIBus and pci_bus_map_msi() >> to PCI API. The latter tries a bus specific map_msi and falls back to >> the default kvm_irqchip_add_msi_route() if none set. >> >> Signed-off-by: Alexey Kardashevskiy <a...@ozlabs.ru> > > The mapping (irq # within data) is really KVM on PPC64 specific, > isn't it? > > So why not implement > kvm_irqchip_add_msi_route(kvm_state, msg); > to simply return msg.data on PPC64?
How exactly? Please give some details. kvm_irqchip_add_msi_route() is implemented in kvm-all.c once for all platforms so hack it right there? I thought we discussed all of this already and decided that this thing should go to PCI host bridge and by default PHB's map_msi() callback should just call kvm_irqchip_add_msi_route(). This is why I touched i386. Things have changed since then? > Then you won't have to change all the rest of the code. > >> --- >> Changes: >> 2013/08/07 v5: >> * pci_bus_map_msi now has default behaviour which is to call >> kvm_irqchip_add_msi_route >> * kvm_irqchip_release_virq fixed not crash when there is no routes >> --- >> hw/i386/kvm/pci-assign.c | 4 ++-- >> hw/misc/vfio.c | 4 ++-- >> hw/pci/pci.c | 9 +++++++++ >> hw/virtio/virtio-pci.c | 2 +- >> include/hw/pci/pci.h | 2 ++ >> include/hw/pci/pci_bus.h | 1 + >> kvm-all.c | 3 +++ >> 7 files changed, 20 insertions(+), 5 deletions(-) >> >> diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c >> index 5618173..fb59982 100644 >> --- a/hw/i386/kvm/pci-assign.c >> +++ b/hw/i386/kvm/pci-assign.c >> @@ -1008,9 +1008,9 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev) >> MSIMessage msg = msi_get_message(pci_dev, 0); >> int virq; >> >> - virq = kvm_irqchip_add_msi_route(kvm_state, msg); >> + virq = pci_bus_map_msi(kvm_state, pci_dev->bus, msg); >> if (virq < 0) { >> - perror("assigned_dev_update_msi: kvm_irqchip_add_msi_route"); >> + perror("assigned_dev_update_msi: pci_bus_map_msi"); >> return; >> } >> > > This really confuses me. Why are you changing i386 code? > > >> diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c >> index 017e693..adcd23d 100644 >> --- a/hw/misc/vfio.c >> +++ b/hw/misc/vfio.c >> @@ -643,7 +643,7 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, >> unsigned int nr, >> * Attempt to enable route through KVM irqchip, >> * default to userspace handling if unavailable. >> */ >> - vector->virq = msg ? kvm_irqchip_add_msi_route(kvm_state, *msg) : -1; >> + vector->virq = msg ? pci_bus_map_msi(kvm_state, vdev->pdev.bus, *msg) : >> -1; >> if (vector->virq < 0 || >> kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt, >> vector->virq) < 0) { >> @@ -811,7 +811,7 @@ retry: >> * Attempt to enable route through KVM irqchip, >> * default to userspace handling if unavailable. >> */ >> - vector->virq = kvm_irqchip_add_msi_route(kvm_state, msg); >> + vector->virq = pci_bus_map_msi(kvm_state, vdev->pdev.bus, msg); >> if (vector->virq < 0 || >> kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt, >> vector->virq) < 0) { >> diff --git a/hw/pci/pci.c b/hw/pci/pci.c >> index 4c004f5..4bce3e7 100644 >> --- a/hw/pci/pci.c >> +++ b/hw/pci/pci.c >> @@ -1249,6 +1249,15 @@ void pci_device_set_intx_routing_notifier(PCIDevice >> *dev, >> dev->intx_routing_notifier = notifier; >> } >> >> +int pci_bus_map_msi(KVMState *s, PCIBus *bus, MSIMessage msg) >> +{ >> + if (bus->map_msi) { >> + return bus->map_msi(s, bus, msg); >> + } >> + >> + return kvm_irqchip_add_msi_route(s, msg); >> +} >> + >> /* >> * PCI-to-PCI bridge specification >> * 9.1: Interrupt routing. Table 9-1 >> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c >> index d37037e..21180d2 100644 >> --- a/hw/virtio/virtio-pci.c >> +++ b/hw/virtio/virtio-pci.c >> @@ -481,7 +481,7 @@ static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy >> *proxy, >> int ret; >> >> if (irqfd->users == 0) { >> - ret = kvm_irqchip_add_msi_route(kvm_state, msg); >> + ret = pci_bus_map_msi(kvm_state, proxy->pci_dev.bus, msg); >> if (ret < 0) { >> return ret; >> } >> diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h >> index ccec2ba..b6ad9e4 100644 >> --- a/include/hw/pci/pci.h >> +++ b/include/hw/pci/pci.h >> @@ -332,6 +332,7 @@ MemoryRegion *pci_address_space_io(PCIDevice *dev); >> typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level); >> typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num); >> typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int pin); >> +typedef int (*pci_map_msi_fn)(KVMState *s, PCIBus *bus, MSIMessage msg); >> >> typedef enum { >> PCI_HOTPLUG_DISABLED, >> @@ -375,6 +376,7 @@ bool pci_intx_route_changed(PCIINTxRoute *old, >> PCIINTxRoute *new); >> void pci_bus_fire_intx_routing_notifier(PCIBus *bus); >> void pci_device_set_intx_routing_notifier(PCIDevice *dev, >> PCIINTxRoutingNotifier notifier); >> +int pci_bus_map_msi(KVMState *s, PCIBus *bus, MSIMessage msg); >> void pci_device_reset(PCIDevice *dev); >> void pci_bus_reset(PCIBus *bus); >> >> diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h >> index 9df1788..5bf7994 100644 >> --- a/include/hw/pci/pci_bus.h >> +++ b/include/hw/pci/pci_bus.h >> @@ -16,6 +16,7 @@ struct PCIBus { >> pci_set_irq_fn set_irq; >> pci_map_irq_fn map_irq; >> pci_route_irq_fn route_intx_to_irq; >> + pci_map_msi_fn map_msi; >> pci_hotplug_fn hotplug; >> DeviceState *hotplug_qdev; >> void *irq_opaque; >> diff --git a/kvm-all.c b/kvm-all.c >> index 716860f..3ae5274 100644 >> --- a/kvm-all.c >> +++ b/kvm-all.c >> @@ -1069,6 +1069,9 @@ void kvm_irqchip_release_virq(KVMState *s, int virq) >> struct kvm_irq_routing_entry *e; >> int i; >> >> + if (!s->irq_routes) { >> + return; >> + } >> for (i = 0; i < s->irq_routes->nr; i++) { >> e = &s->irq_routes->entries[i]; >> if (e->gsi == virq) { >> -- >> 1.8.3.2 -- Alexey