diff options
author | Andre Przywara <andre.przywara@arm.com> | 2017-04-25 15:39:23 +0100 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2017-06-09 11:16:47 +0100 |
commit | 928ab7ac093eebd979a1043c216218e1fb74e523 (patch) | |
tree | 982cd24fbcc983fed5d892e19925c35966444a5a | |
parent | b960f243c593dfcfcc9359f30558a8ae6a6ff535 (diff) | |
download | kvmtool-928ab7ac093eebd979a1043c216218e1fb74e523.tar.gz |
PCI: Only allocate IRQ routing entry when available
If we need to inject an MSI into the guest, we rely at the moment on a
working GSI MSI routing functionality. However we can get away without
IRQ routing, if the host supports MSI injection via the KVM_SIGNAL_MSI
ioctl.
So we try the GSI routing first, but if that fails due to a missing
IRQ routing functionality, we fall back to KVM_SIGNAL_MSI (if that is
supported).
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r-- | virtio/pci.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/virtio/pci.c b/virtio/pci.c index e9f36c7d..04176c1d 100644 --- a/virtio/pci.c +++ b/virtio/pci.c @@ -193,8 +193,20 @@ static bool virtio_pci__specific_io_out(struct kvm *kvm, struct virtio_device *v gsi = irq__add_msix_route(kvm, &vpci->msix_table[vec].msg); - if (gsi >= 0) - vpci->config_gsi = gsi; + /* + * We don't need IRQ routing if we can use + * MSI injection via the KVM_SIGNAL_MSI ioctl. + */ + if (gsi == -ENXIO && + vpci->features & VIRTIO_PCI_F_SIGNAL_MSI) + break; + + if (gsi < 0) { + die("failed to configure MSIs"); + break; + } + + vpci->config_gsi = gsi; break; case VIRTIO_MSI_QUEUE_VECTOR: vec = ioport__read16(data); @@ -205,8 +217,19 @@ static bool virtio_pci__specific_io_out(struct kvm *kvm, struct virtio_device *v gsi = irq__add_msix_route(kvm, &vpci->msix_table[vec].msg); - if (gsi < 0) + /* + * We don't need IRQ routing if we can use + * MSI injection via the KVM_SIGNAL_MSI ioctl. + */ + if (gsi == -ENXIO && + vpci->features & VIRTIO_PCI_F_SIGNAL_MSI) break; + + if (gsi < 0) { + die("failed to configure MSIs"); + break; + } + vpci->gsis[vpci->queue_selector] = gsi; if (vdev->ops->notify_vq_gsi) vdev->ops->notify_vq_gsi(kvm, vpci->dev, |