aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2020-04-24 16:31:19 +0100
committerWill Deacon <will@kernel.org>2020-04-24 17:58:24 +0100
commite554aefd04bd38a8b6e9040022d494e5b7ae7a59 (patch)
treedffcad69eeacefe08795843f456e80223478bb01
parentbea6c33ca17c85c76e8455fb86e38036bdb2a928 (diff)
downloadkvmtool-e554aefd04bd38a8b6e9040022d494e5b7ae7a59.tar.gz
vfio: fix multi-MSI vector handling
A PCI device with a MSI capability enabling Multiple MSI messages (through the Multiple Message Enable field in the Message Control register[6:4]) is expected to drive the Message Data lower bits (number determined by the number of selected vectors) to generate the corresponding MSI messages writes on the PCI bus. Therefore, KVM expects the MSI data lower bits (a number of bits that depend on bits [6:4] of the Message Control register - which in turn control the number of vectors allocated) to be set-up by kvmtool while programming the MSI IRQ routing entries to make sure the MSI entries can actually be demultiplexed by KVM and IRQ routes set-up accordingly so that when an actual HW fires KVM can route it to the correct entry in the interrupt controller (and set-up a correct passthrough route for directly injected interrupt). Current kvmtool code does not set-up Message data entries correctly for multi-MSI vectors - the data field is left as programmed in the MSI capability by the guest for all vector entries, triggering IRQs misrouting. Fix it. Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Acked-by: Marc Zyngier <maz@kernel.org> Cc: Will Deacon <will@kernel.org> Cc: Julien Thierry <julien.thierry.kdev@gmail.com> Signed-off-by: Will Deacon <will@kernel.org>
-rw-r--r--vfio/pci.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/vfio/pci.c b/vfio/pci.c
index 4412c6d7..b09557de 100644
--- a/vfio/pci.c
+++ b/vfio/pci.c
@@ -434,6 +434,14 @@ static void vfio_pci_msi_cap_write(struct kvm *kvm, struct vfio_device *vdev,
for (i = 0; i < nr_vectors; i++) {
entry = &pdev->msi.entries[i];
+
+ /*
+ * Set the MSI data value as required by the PCI local
+ * bus specifications, MSI capability, "Message Data".
+ */
+ msg.data &= ~(nr_vectors - 1);
+ msg.data |= i;
+
entry->config.msg = msg;
vfio_pci_update_msi_entry(kvm, vdev, entry);
}