aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeo Yan <leo.yan@linaro.org>2019-04-08 09:27:18 +0800
committerWill Deacon <will.deacon@arm.com>2019-04-26 14:49:11 +0100
commit12bd7a16811bc250fee97f106a874720abd2346d (patch)
tree7e765f733549820c7244b2baf140f4300ebccc09
parenta1ff6f87aa420da3afaec475f9bd405228e04189 (diff)
downloadkvmtool-12bd7a16811bc250fee97f106a874720abd2346d.tar.gz
vfio-pci: Add new function for INTx one-time initialisation
To support INTx enabling for multiple times, we need firstly to extract one-time initialisation and move the related code into a new function vfio_pci_init_intx(); if later disable and re-enable the INTx, we can skip these one-time operations. This patch move below three main operations for INTx one-time initialisation from function vfio_pci_enable_intx() into function vfio_pci_init_intx(): - Reserve 2 FDs for INTx; - Sanity check with ioctl VFIO_DEVICE_GET_IRQ_INFO; - Setup pdev->intx_gsi. Suggested-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com> Signed-off-by: Leo Yan <leo.yan@linaro.org> Reviewed-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--vfio/pci.c67
1 files changed, 40 insertions, 27 deletions
diff --git a/vfio/pci.c b/vfio/pci.c
index 5224fee3..3c39844b 100644
--- a/vfio/pci.c
+++ b/vfio/pci.c
@@ -1018,30 +1018,7 @@ static int vfio_pci_enable_intx(struct kvm *kvm, struct vfio_device *vdev)
struct vfio_irq_eventfd trigger;
struct vfio_irq_eventfd unmask;
struct vfio_pci_device *pdev = &vdev->pci;
- int gsi = pdev->hdr.irq_line - KVM_IRQ_OFFSET;
-
- struct vfio_irq_info irq_info = {
- .argsz = sizeof(irq_info),
- .index = VFIO_PCI_INTX_IRQ_INDEX,
- };
-
- vfio_pci_reserve_irq_fds(2);
-
- ret = ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info);
- if (ret || irq_info.count == 0) {
- vfio_dev_err(vdev, "no INTx reported by VFIO");
- return -ENODEV;
- }
-
- if (!(irq_info.flags & VFIO_IRQ_INFO_EVENTFD)) {
- vfio_dev_err(vdev, "interrupt not eventfd capable");
- return -EINVAL;
- }
-
- if (!(irq_info.flags & VFIO_IRQ_INFO_AUTOMASKED)) {
- vfio_dev_err(vdev, "INTx interrupt not AUTOMASKED");
- return -EINVAL;
- }
+ int gsi = pdev->intx_gsi;
/*
* PCI IRQ is level-triggered, so we use two eventfds. trigger_fd
@@ -1097,8 +1074,6 @@ static int vfio_pci_enable_intx(struct kvm *kvm, struct vfio_device *vdev)
pdev->intx_fd = trigger_fd;
pdev->unmask_fd = unmask_fd;
- /* Guest is going to ovewrite our irq_line... */
- pdev->intx_gsi = gsi;
return 0;
@@ -1117,6 +1092,39 @@ err_close:
return ret;
}
+static int vfio_pci_init_intx(struct kvm *kvm, struct vfio_device *vdev)
+{
+ int ret;
+ struct vfio_pci_device *pdev = &vdev->pci;
+ struct vfio_irq_info irq_info = {
+ .argsz = sizeof(irq_info),
+ .index = VFIO_PCI_INTX_IRQ_INDEX,
+ };
+
+ vfio_pci_reserve_irq_fds(2);
+
+ ret = ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info);
+ if (ret || irq_info.count == 0) {
+ vfio_dev_err(vdev, "no INTx reported by VFIO");
+ return -ENODEV;
+ }
+
+ if (!(irq_info.flags & VFIO_IRQ_INFO_EVENTFD)) {
+ vfio_dev_err(vdev, "interrupt not eventfd capable");
+ return -EINVAL;
+ }
+
+ if (!(irq_info.flags & VFIO_IRQ_INFO_AUTOMASKED)) {
+ vfio_dev_err(vdev, "INTx interrupt not AUTOMASKED");
+ return -EINVAL;
+ }
+
+ /* Guest is going to ovewrite our irq_line... */
+ pdev->intx_gsi = pdev->hdr.irq_line - KVM_IRQ_OFFSET;
+
+ return 0;
+}
+
static int vfio_pci_configure_dev_irqs(struct kvm *kvm, struct vfio_device *vdev)
{
int ret = 0;
@@ -1142,8 +1150,13 @@ static int vfio_pci_configure_dev_irqs(struct kvm *kvm, struct vfio_device *vdev
return ret;
}
- if (pdev->irq_modes & VFIO_PCI_IRQ_MODE_INTX)
+ if (pdev->irq_modes & VFIO_PCI_IRQ_MODE_INTX) {
+ ret = vfio_pci_init_intx(kvm, vdev);
+ if (ret)
+ return ret;
+
ret = vfio_pci_enable_intx(kvm, vdev);
+ }
return ret;
}