|
|
9ae3a8 |
From 6f572c45ff2c2376a16cd15882067d7fdcd74a83 Mon Sep 17 00:00:00 2001
|
|
|
9ae3a8 |
From: Alex Williamson <alex.williamson@redhat.com>
|
|
|
9ae3a8 |
Date: Tue, 5 Nov 2013 15:30:40 +0100
|
|
|
9ae3a8 |
Subject: [PATCH 12/25] vfio-pci: Add support for MSI affinity
|
|
|
9ae3a8 |
MIME-Version: 1.0
|
|
|
9ae3a8 |
Content-Type: text/plain; charset=UTF-8
|
|
|
9ae3a8 |
Content-Transfer-Encoding: 8bit
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
RH-Author: Alex Williamson <alex.williamson@redhat.com>
|
|
|
9ae3a8 |
Message-id: <20131105153040.15749.78283.stgit@bling.home>
|
|
|
9ae3a8 |
Patchwork-id: 55413
|
|
|
9ae3a8 |
O-Subject: [RHEL7 qemu-kvm PATCH v2 2/2] vfio-pci: Add support for MSI affinity
|
|
|
9ae3a8 |
Bugzilla: 1025477
|
|
|
9ae3a8 |
RH-Acked-by: Bandan Das <bsd@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Bugzilla: 1025477
|
|
|
9ae3a8 |
Upstream commit: c7679d450ee021eb0826be65e4e018884443643a
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
When MSI is accelerated through KVM the vectors are only programmed
|
|
|
9ae3a8 |
when the guest first enables MSI support. Subsequent writes to the
|
|
|
9ae3a8 |
vector address or data fields are ignored. Unfortunately that means
|
|
|
9ae3a8 |
we're ignore updates done to adjust SMP affinity of the vectors.
|
|
|
9ae3a8 |
MSI SMP affinity already works in non-KVM mode because the address
|
|
|
9ae3a8 |
and data fields are read from their backing store on each interrupt.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
This patch stores the MSIMessage programmed into KVM so that we can
|
|
|
9ae3a8 |
determine when changes are made and update the routes.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
hw/misc/vfio.c | 47 ++++++++++++++++++++++++++++++++++++++++-------
|
|
|
9ae3a8 |
1 file changed, 40 insertions(+), 7 deletions(-)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
hw/misc/vfio.c | 47 ++++++++++++++++++++++++++++++++++++++++-------
|
|
|
9ae3a8 |
1 files changed, 40 insertions(+), 7 deletions(-)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
|
|
|
9ae3a8 |
index a072fd9..286dad1 100644
|
|
|
9ae3a8 |
--- a/hw/misc/vfio.c
|
|
|
9ae3a8 |
+++ b/hw/misc/vfio.c
|
|
|
9ae3a8 |
@@ -119,6 +119,7 @@ typedef struct VFIOINTx {
|
|
|
9ae3a8 |
typedef struct VFIOMSIVector {
|
|
|
9ae3a8 |
EventNotifier interrupt; /* eventfd triggered on interrupt */
|
|
|
9ae3a8 |
struct VFIODevice *vdev; /* back pointer to device */
|
|
|
9ae3a8 |
+ MSIMessage msg; /* cache the MSI message so we know when it changes */
|
|
|
9ae3a8 |
int virq; /* KVM irqchip route for QEMU bypass */
|
|
|
9ae3a8 |
bool use;
|
|
|
9ae3a8 |
} VFIOMSIVector;
|
|
|
9ae3a8 |
@@ -795,7 +796,6 @@ retry:
|
|
|
9ae3a8 |
vdev->msi_vectors = g_malloc0(vdev->nr_vectors * sizeof(VFIOMSIVector));
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
for (i = 0; i < vdev->nr_vectors; i++) {
|
|
|
9ae3a8 |
- MSIMessage msg;
|
|
|
9ae3a8 |
VFIOMSIVector *vector = &vdev->msi_vectors[i];
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
vector->vdev = vdev;
|
|
|
9ae3a8 |
@@ -805,13 +805,13 @@ retry:
|
|
|
9ae3a8 |
error_report("vfio: Error: event_notifier_init failed");
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- msg = msi_get_message(&vdev->pdev, i);
|
|
|
9ae3a8 |
+ vector->msg = msi_get_message(&vdev->pdev, i);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
/*
|
|
|
9ae3a8 |
* Attempt to enable route through KVM irqchip,
|
|
|
9ae3a8 |
* default to userspace handling if unavailable.
|
|
|
9ae3a8 |
*/
|
|
|
9ae3a8 |
- vector->virq = kvm_irqchip_add_msi_route(kvm_state, msg);
|
|
|
9ae3a8 |
+ vector->virq = kvm_irqchip_add_msi_route(kvm_state, vector->msg);
|
|
|
9ae3a8 |
if (vector->virq < 0 ||
|
|
|
9ae3a8 |
kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt,
|
|
|
9ae3a8 |
vector->virq) < 0) {
|
|
|
9ae3a8 |
@@ -917,6 +917,33 @@ static void vfio_disable_msi(VFIODevice *vdev)
|
|
|
9ae3a8 |
vdev->host.bus, vdev->host.slot, vdev->host.function);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+static void vfio_update_msi(VFIODevice *vdev)
|
|
|
9ae3a8 |
+{
|
|
|
9ae3a8 |
+ int i;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ for (i = 0; i < vdev->nr_vectors; i++) {
|
|
|
9ae3a8 |
+ VFIOMSIVector *vector = &vdev->msi_vectors[i];
|
|
|
9ae3a8 |
+ MSIMessage msg;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ if (!vector->use || vector->virq < 0) {
|
|
|
9ae3a8 |
+ continue;
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ msg = msi_get_message(&vdev->pdev, i);
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ if (msg.address != vector->msg.address ||
|
|
|
9ae3a8 |
+ msg.data != vector->msg.data) {
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ DPRINTF("%s(%04x:%02x:%02x.%x) MSI vector %d changed\n",
|
|
|
9ae3a8 |
+ __func__, vdev->host.domain, vdev->host.bus,
|
|
|
9ae3a8 |
+ vdev->host.slot, vdev->host.function, i);
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ kvm_irqchip_update_msi_route(kvm_state, vector->virq, msg);
|
|
|
9ae3a8 |
+ vector->msg = msg;
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+}
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
/*
|
|
|
9ae3a8 |
* IO Port/MMIO - Beware of the endians, VFIO is always little endian
|
|
|
9ae3a8 |
*/
|
|
|
9ae3a8 |
@@ -1834,10 +1861,16 @@ static void vfio_pci_write_config(PCIDevice *pdev, uint32_t addr,
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
is_enabled = msi_enabled(pdev);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- if (!was_enabled && is_enabled) {
|
|
|
9ae3a8 |
- vfio_enable_msi(vdev);
|
|
|
9ae3a8 |
- } else if (was_enabled && !is_enabled) {
|
|
|
9ae3a8 |
- vfio_disable_msi(vdev);
|
|
|
9ae3a8 |
+ if (!was_enabled) {
|
|
|
9ae3a8 |
+ if (is_enabled) {
|
|
|
9ae3a8 |
+ vfio_enable_msi(vdev);
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+ } else {
|
|
|
9ae3a8 |
+ if (!is_enabled) {
|
|
|
9ae3a8 |
+ vfio_disable_msi(vdev);
|
|
|
9ae3a8 |
+ } else {
|
|
|
9ae3a8 |
+ vfio_update_msi(vdev);
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
} else if (pdev->cap_present & QEMU_PCI_CAP_MSIX &&
|
|
|
9ae3a8 |
ranges_overlap(addr, len, pdev->msix_cap, MSIX_CAP_LENGTH)) {
|
|
|
9ae3a8 |
--
|
|
|
9ae3a8 |
1.7.1
|
|
|
9ae3a8 |
|