mirror of
https://github.com/qemu/qemu.git
synced 2025-08-10 03:59:16 +00:00
VFIO patches: Fix MSI-X vector expansion, remove MSI/X message caching
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJT4S/FAAoJECObm247sIsij0gQAJ7DeNQjhmVyRsqP1zGTiedE /P+fOIO1bXaYdZwjYG53r/zeqeYRJQ6lFndW7sR6vgDh+TdGEzlpHv8B7QQ2fkFU kIkSI3sIVVUZqS+bhJPnQzuOvWMePb9CqzIOO8E/kj/UqJirJ2boVdkr69uUEjzj r3UHMZmxWOnAiqGihUUmgMckGIrMaAMlsco247o0pHtZwwMH0Q9OP+WnWiVS64PG nT9wyGwNfXxJLpSMNsWneFEjRsmv/5IuhGc8tw5Xwwsf8ufHuTtsriIB01R47MV0 ljoXAwOh38gkMggOspgrWfxLqwZtoW4U2dl/0ojxysC/5jA6yCOf1xK5rDs5BvRc djV0jjlcjDWBcWWp26TvnYoL/KC0WfMxnH2PaoplmpEWEyl8OsMOWCGlGyjakISw DSrx668bivM9ywmHC7qN401LKbJRtSka8hb1ZEkyYql1llTErv585NCkwYSKiMmN sesqidhB2RkTI816zV2/MBp/P78sfXTgHEIR5QP+yZ6rOwH/YwYL/0u5yN1UY/uN j7zkaVZLU3Pzf6k3E9WNwyTG8Gzln8FZyck3SS6xiGGton3BuM2gb51pp3plmVHY w82cxstAVujLwjl/Vg/OMI1oW5fVLfS6FhG4dkh+RQqBvgwe/0Wd2wLvHeGwcfcn kKwfhZDXVQ7H7cKgdYLb =MOBq -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/awilliam/tags/vfio-pci-for-qemu-20140805.0' into staging VFIO patches: Fix MSI-X vector expansion, remove MSI/X message caching # gpg: Signature made Tue 05 Aug 2014 20:25:57 BST using RSA key ID 3BB08B22 # gpg: Can't check signature: public key not found * remotes/awilliam/tags/vfio-pci-for-qemu-20140805.0: vfio: Don't cache MSIMessage vfio: Fix MSI-X vector expansion Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
9d8bb35574
@ -120,11 +120,19 @@ typedef struct VFIOINTx {
|
|||||||
} VFIOINTx;
|
} VFIOINTx;
|
||||||
|
|
||||||
typedef struct VFIOMSIVector {
|
typedef struct VFIOMSIVector {
|
||||||
EventNotifier interrupt; /* eventfd triggered on interrupt */
|
/*
|
||||||
EventNotifier kvm_interrupt; /* eventfd triggered for KVM irqfd bypass */
|
* Two interrupt paths are configured per vector. The first, is only used
|
||||||
|
* for interrupts injected via QEMU. This is typically the non-accel path,
|
||||||
|
* but may also be used when we want QEMU to handle masking and pending
|
||||||
|
* bits. The KVM path bypasses QEMU and is therefore higher performance,
|
||||||
|
* but requires masking at the device. virq is used to track the MSI route
|
||||||
|
* through KVM, thus kvm_interrupt is only available when virq is set to a
|
||||||
|
* valid (>= 0) value.
|
||||||
|
*/
|
||||||
|
EventNotifier interrupt;
|
||||||
|
EventNotifier kvm_interrupt;
|
||||||
struct VFIODevice *vdev; /* back pointer to device */
|
struct VFIODevice *vdev; /* back pointer to device */
|
||||||
MSIMessage msg; /* cache the MSI message so we know when it changes */
|
int virq;
|
||||||
int virq; /* KVM irqchip route for QEMU bypass */
|
|
||||||
bool use;
|
bool use;
|
||||||
} VFIOMSIVector;
|
} VFIOMSIVector;
|
||||||
|
|
||||||
@ -681,13 +689,24 @@ static int vfio_enable_vectors(VFIODevice *vdev, bool msix)
|
|||||||
fds = (int32_t *)&irq_set->data;
|
fds = (int32_t *)&irq_set->data;
|
||||||
|
|
||||||
for (i = 0; i < vdev->nr_vectors; i++) {
|
for (i = 0; i < vdev->nr_vectors; i++) {
|
||||||
if (!vdev->msi_vectors[i].use) {
|
int fd = -1;
|
||||||
fds[i] = -1;
|
|
||||||
} else if (vdev->msi_vectors[i].virq >= 0) {
|
/*
|
||||||
fds[i] = event_notifier_get_fd(&vdev->msi_vectors[i].kvm_interrupt);
|
* MSI vs MSI-X - The guest has direct access to MSI mask and pending
|
||||||
} else {
|
* bits, therefore we always use the KVM signaling path when setup.
|
||||||
fds[i] = event_notifier_get_fd(&vdev->msi_vectors[i].interrupt);
|
* MSI-X mask and pending bits are emulated, so we want to use the
|
||||||
|
* KVM signaling path only when configured and unmasked.
|
||||||
|
*/
|
||||||
|
if (vdev->msi_vectors[i].use) {
|
||||||
|
if (vdev->msi_vectors[i].virq < 0 ||
|
||||||
|
(msix && msix_is_masked(&vdev->pdev, i))) {
|
||||||
|
fd = event_notifier_get_fd(&vdev->msi_vectors[i].interrupt);
|
||||||
|
} else {
|
||||||
|
fd = event_notifier_get_fd(&vdev->msi_vectors[i].kvm_interrupt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fds[i] = fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
|
ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
|
||||||
@ -724,7 +743,6 @@ static void vfio_add_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage *msg,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector->msg = *msg;
|
|
||||||
vector->virq = virq;
|
vector->virq = virq;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -740,7 +758,6 @@ static void vfio_remove_kvm_msi_virq(VFIOMSIVector *vector)
|
|||||||
static void vfio_update_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage msg)
|
static void vfio_update_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage msg)
|
||||||
{
|
{
|
||||||
kvm_irqchip_update_msi_route(kvm_state, vector->virq, msg);
|
kvm_irqchip_update_msi_route(kvm_state, vector->virq, msg);
|
||||||
vector->msg = msg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
|
static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
|
||||||
@ -919,6 +936,7 @@ retry:
|
|||||||
|
|
||||||
for (i = 0; i < vdev->nr_vectors; i++) {
|
for (i = 0; i < vdev->nr_vectors; i++) {
|
||||||
VFIOMSIVector *vector = &vdev->msi_vectors[i];
|
VFIOMSIVector *vector = &vdev->msi_vectors[i];
|
||||||
|
MSIMessage msg = msi_get_message(&vdev->pdev, i);
|
||||||
|
|
||||||
vector->vdev = vdev;
|
vector->vdev = vdev;
|
||||||
vector->virq = -1;
|
vector->virq = -1;
|
||||||
@ -931,13 +949,11 @@ retry:
|
|||||||
qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),
|
qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),
|
||||||
vfio_msi_interrupt, NULL, vector);
|
vfio_msi_interrupt, NULL, vector);
|
||||||
|
|
||||||
vector->msg = msi_get_message(&vdev->pdev, i);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Attempt to enable route through KVM irqchip,
|
* Attempt to enable route through KVM irqchip,
|
||||||
* default to userspace handling if unavailable.
|
* default to userspace handling if unavailable.
|
||||||
*/
|
*/
|
||||||
vfio_add_kvm_msi_virq(vector, &vector->msg, false);
|
vfio_add_kvm_msi_virq(vector, &msg, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set interrupt type prior to possible interrupts */
|
/* Set interrupt type prior to possible interrupts */
|
||||||
|
Loading…
Reference in New Issue
Block a user