Forward remote device's interrupts to the guest Signed-off-by: Elena Ufimtseva <elena.ufimts...@oracle.com> Signed-off-by: John G Johnson <john.g.john...@oracle.com> Signed-off-by: Jagannathan Raman <jag.ra...@oracle.com> --- include/hw/remote/iohub.h | 2 ++ hw/remote/iohub.c | 6 ++++++ hw/remote/vfio-user-obj.c | 30 ++++++++++++++++++++++++++++++ hw/remote/trace-events | 1 + 4 files changed, 39 insertions(+)
diff --git a/include/hw/remote/iohub.h b/include/hw/remote/iohub.h index 0bf98e0..132f496 100644 --- a/include/hw/remote/iohub.h +++ b/include/hw/remote/iohub.h @@ -15,6 +15,7 @@ #include "qemu/event_notifier.h" #include "qemu/thread-posix.h" #include "hw/remote/mpqemu-link.h" +#include "libvfio-user/include/libvfio-user.h" #define REMOTE_IOHUB_NB_PIRQS PCI_DEVFN_MAX @@ -30,6 +31,7 @@ typedef struct RemoteIOHubState { unsigned int irq_level[REMOTE_IOHUB_NB_PIRQS]; ResampleToken token[REMOTE_IOHUB_NB_PIRQS]; QemuMutex irq_level_lock[REMOTE_IOHUB_NB_PIRQS]; + vfu_ctx_t *vfu_ctx[REMOTE_IOHUB_NB_PIRQS]; } RemoteIOHubState; int remote_iohub_map_irq(PCIDevice *pci_dev, int intx); diff --git a/hw/remote/iohub.c b/hw/remote/iohub.c index 547d597..241c8d7 100644 --- a/hw/remote/iohub.c +++ b/hw/remote/iohub.c @@ -18,6 +18,8 @@ #include "hw/remote/machine.h" #include "hw/remote/iohub.h" #include "qemu/main-loop.h" +#include "libvfio-user/include/libvfio-user.h" +#include "trace.h" void remote_iohub_init(RemoteIOHubState *iohub) { @@ -62,6 +64,10 @@ void remote_iohub_set_irq(void *opaque, int pirq, int level) QEMU_LOCK_GUARD(&iohub->irq_level_lock[pirq]); if (level) { + if (iohub->vfu_ctx[pirq]) { + trace_vfu_interrupt(pirq); + vfu_irq_trigger(iohub->vfu_ctx[pirq], 0); + } if (++iohub->irq_level[pirq] == 1) { event_notifier_set(&iohub->irqfds[pirq]); } diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c index 9853feb..d2a2e51 100644 --- a/hw/remote/vfio-user-obj.c +++ b/hw/remote/vfio-user-obj.c @@ -41,6 +41,9 @@ #include "sysemu/sysemu.h" #include "hw/qdev-core.h" #include "hw/pci/pci.h" +#include "hw/boards.h" +#include "hw/remote/iohub.h" +#include "hw/remote/machine.h" #include "libvfio-user/include/libvfio-user.h" @@ -305,6 +308,26 @@ static void vfu_object_register_bars(vfu_ctx_t *vfu_ctx, PCIDevice *pdev) } } +static int vfu_object_setup_irqs(vfu_ctx_t *vfu_ctx, PCIDevice *pci_dev) +{ + RemoteMachineState *machine = REMOTE_MACHINE(current_machine); + RemoteIOHubState *iohub = &machine->iohub; + int pirq, intx, ret; + + ret = vfu_setup_device_nr_irqs(vfu_ctx, VFU_DEV_INTX_IRQ, 1); + if (ret < 0) { + return ret; + } + + intx = pci_get_byte(pci_dev->config + PCI_INTERRUPT_PIN) - 1; + + pirq = remote_iohub_map_irq(pci_dev, intx); + + iohub->vfu_ctx[pirq] = vfu_ctx; + + return 0; +} + static void vfu_object_machine_done(Notifier *notifier, void *data) { VfuObject *o = container_of(notifier, VfuObject, machine_done); @@ -361,6 +384,13 @@ static void vfu_object_machine_done(Notifier *notifier, void *data) vfu_object_register_bars(o->vfu_ctx, o->pci_dev); + ret = vfu_object_setup_irqs(o->vfu_ctx, o->pci_dev); + if (ret < 0) { + error_setg(&error_abort, "vfu: Failed to setup interrupts for %s", + o->devid); + return; + } + qemu_thread_create(&o->vfu_ctx_thread, "VFU ctx runner", vfu_object_ctx_run, o, QEMU_THREAD_JOINABLE); } diff --git a/hw/remote/trace-events b/hw/remote/trace-events index f3f65e2..b419d6f 100644 --- a/hw/remote/trace-events +++ b/hw/remote/trace-events @@ -11,3 +11,4 @@ vfu_dma_register(uint64_t gpa, size_t len) "vfu: registering GPA 0x%"PRIx64", %z vfu_dma_unregister(uint64_t gpa) "vfu: unregistering GPA 0x%"PRIx64"" vfu_bar_rw_enter(const char *op, uint64_t addr) "vfu: %s request for BAR address 0x%"PRIx64"" vfu_bar_rw_exit(const char *op, uint64_t addr) "vfu: Finished %s of BAR address 0x%"PRIx64"" +vfu_interrupt(int pirq) "vfu: sending interrupt to device - PIRQ %d" -- 1.8.3.1