mirror of https://github.com/xemu-project/xemu.git
vfio/pci: Use kvm_irqchip_add_irqfd_notifier_gsi() for irqfds
VFIO is currently the only one left that is not using the generic function (kvm_irqchip_add_irqfd_notifier_gsi()) to register irqfds. Let VFIO use the common framework too. Follow up patches will introduce extra features for kvm irqfd, so that VFIO can easily leverage that after the switch. Reviewed-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Cornelia Huck <cohuck@redhat.com> Reviewed-by: Alex Williamson <alex.williamson@redhat.com> Acked-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Peter Xu <peterx@redhat.com> Message-Id: <20200318145204.74483-3-peterx@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
353f98c9ad
commit
97a3757616
|
@ -115,11 +115,7 @@ static void vfio_intx_eoi(VFIODevice *vbasedev)
|
|||
static void vfio_intx_enable_kvm(VFIOPCIDevice *vdev, Error **errp)
|
||||
{
|
||||
#ifdef CONFIG_KVM
|
||||
struct kvm_irqfd irqfd = {
|
||||
.fd = event_notifier_get_fd(&vdev->intx.interrupt),
|
||||
.gsi = vdev->intx.route.irq,
|
||||
.flags = KVM_IRQFD_FLAG_RESAMPLE,
|
||||
};
|
||||
int irq_fd = event_notifier_get_fd(&vdev->intx.interrupt);
|
||||
Error *err = NULL;
|
||||
|
||||
if (vdev->no_kvm_intx || !kvm_irqfds_enabled() ||
|
||||
|
@ -129,7 +125,7 @@ static void vfio_intx_enable_kvm(VFIOPCIDevice *vdev, Error **errp)
|
|||
}
|
||||
|
||||
/* Get to a known interrupt state */
|
||||
qemu_set_fd_handler(irqfd.fd, NULL, NULL, vdev);
|
||||
qemu_set_fd_handler(irq_fd, NULL, NULL, vdev);
|
||||
vfio_mask_single_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX);
|
||||
vdev->intx.pending = false;
|
||||
pci_irq_deassert(&vdev->pdev);
|
||||
|
@ -140,17 +136,18 @@ static void vfio_intx_enable_kvm(VFIOPCIDevice *vdev, Error **errp)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
/* KVM triggers it, VFIO listens for it */
|
||||
irqfd.resamplefd = event_notifier_get_fd(&vdev->intx.unmask);
|
||||
|
||||
if (kvm_vm_ioctl(kvm_state, KVM_IRQFD, &irqfd)) {
|
||||
if (kvm_irqchip_add_irqfd_notifier_gsi(kvm_state,
|
||||
&vdev->intx.interrupt,
|
||||
&vdev->intx.unmask,
|
||||
vdev->intx.route.irq)) {
|
||||
error_setg_errno(errp, errno, "failed to setup resample irqfd");
|
||||
goto fail_irqfd;
|
||||
}
|
||||
|
||||
if (vfio_set_irq_signaling(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX, 0,
|
||||
VFIO_IRQ_SET_ACTION_UNMASK,
|
||||
irqfd.resamplefd, &err)) {
|
||||
event_notifier_get_fd(&vdev->intx.unmask),
|
||||
&err)) {
|
||||
error_propagate(errp, err);
|
||||
goto fail_vfio;
|
||||
}
|
||||
|
@ -165,12 +162,12 @@ static void vfio_intx_enable_kvm(VFIOPCIDevice *vdev, Error **errp)
|
|||
return;
|
||||
|
||||
fail_vfio:
|
||||
irqfd.flags = KVM_IRQFD_FLAG_DEASSIGN;
|
||||
kvm_vm_ioctl(kvm_state, KVM_IRQFD, &irqfd);
|
||||
kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, &vdev->intx.interrupt,
|
||||
vdev->intx.route.irq);
|
||||
fail_irqfd:
|
||||
event_notifier_cleanup(&vdev->intx.unmask);
|
||||
fail:
|
||||
qemu_set_fd_handler(irqfd.fd, vfio_intx_interrupt, NULL, vdev);
|
||||
qemu_set_fd_handler(irq_fd, vfio_intx_interrupt, NULL, vdev);
|
||||
vfio_unmask_single_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX);
|
||||
#endif
|
||||
}
|
||||
|
@ -178,12 +175,6 @@ fail:
|
|||
static void vfio_intx_disable_kvm(VFIOPCIDevice *vdev)
|
||||
{
|
||||
#ifdef CONFIG_KVM
|
||||
struct kvm_irqfd irqfd = {
|
||||
.fd = event_notifier_get_fd(&vdev->intx.interrupt),
|
||||
.gsi = vdev->intx.route.irq,
|
||||
.flags = KVM_IRQFD_FLAG_DEASSIGN,
|
||||
};
|
||||
|
||||
if (!vdev->intx.kvm_accel) {
|
||||
return;
|
||||
}
|
||||
|
@ -197,7 +188,8 @@ static void vfio_intx_disable_kvm(VFIOPCIDevice *vdev)
|
|||
pci_irq_deassert(&vdev->pdev);
|
||||
|
||||
/* Tell KVM to stop listening for an INTx irqfd */
|
||||
if (kvm_vm_ioctl(kvm_state, KVM_IRQFD, &irqfd)) {
|
||||
if (kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, &vdev->intx.interrupt,
|
||||
vdev->intx.route.irq)) {
|
||||
error_report("vfio: Error: Failed to disable INTx irqfd: %m");
|
||||
}
|
||||
|
||||
|
@ -205,7 +197,8 @@ static void vfio_intx_disable_kvm(VFIOPCIDevice *vdev)
|
|||
event_notifier_cleanup(&vdev->intx.unmask);
|
||||
|
||||
/* QEMU starts listening for interrupt events. */
|
||||
qemu_set_fd_handler(irqfd.fd, vfio_intx_interrupt, NULL, vdev);
|
||||
qemu_set_fd_handler(event_notifier_get_fd(&vdev->intx.interrupt),
|
||||
vfio_intx_interrupt, NULL, vdev);
|
||||
|
||||
vdev->intx.kvm_accel = false;
|
||||
|
||||
|
|
Loading…
Reference in New Issue