mirror of https://gitee.com/openkylin/qemu.git
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;
|
||||
|
||||
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 */
|
||||
MSIMessage msg; /* cache the MSI message so we know when it changes */
|
||||
int virq; /* KVM irqchip route for QEMU bypass */
|
||||
int virq;
|
||||
bool use;
|
||||
} VFIOMSIVector;
|
||||
|
||||
|
@ -681,13 +689,24 @@ static int vfio_enable_vectors(VFIODevice *vdev, bool msix)
|
|||
fds = (int32_t *)&irq_set->data;
|
||||
|
||||
for (i = 0; i < vdev->nr_vectors; i++) {
|
||||
if (!vdev->msi_vectors[i].use) {
|
||||
fds[i] = -1;
|
||||
} else if (vdev->msi_vectors[i].virq >= 0) {
|
||||
fds[i] = event_notifier_get_fd(&vdev->msi_vectors[i].kvm_interrupt);
|
||||
} else {
|
||||
fds[i] = event_notifier_get_fd(&vdev->msi_vectors[i].interrupt);
|
||||
int fd = -1;
|
||||
|
||||
/*
|
||||
* MSI vs MSI-X - The guest has direct access to MSI mask and pending
|
||||
* bits, therefore we always use the KVM signaling path when setup.
|
||||
* 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);
|
||||
|
@ -724,7 +743,6 @@ static void vfio_add_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage *msg,
|
|||
return;
|
||||
}
|
||||
|
||||
vector->msg = *msg;
|
||||
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)
|
||||
{
|
||||
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,
|
||||
|
@ -919,6 +936,7 @@ retry:
|
|||
|
||||
for (i = 0; i < vdev->nr_vectors; i++) {
|
||||
VFIOMSIVector *vector = &vdev->msi_vectors[i];
|
||||
MSIMessage msg = msi_get_message(&vdev->pdev, i);
|
||||
|
||||
vector->vdev = vdev;
|
||||
vector->virq = -1;
|
||||
|
@ -931,13 +949,11 @@ retry:
|
|||
qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),
|
||||
vfio_msi_interrupt, NULL, vector);
|
||||
|
||||
vector->msg = msi_get_message(&vdev->pdev, i);
|
||||
|
||||
/*
|
||||
* Attempt to enable route through KVM irqchip,
|
||||
* 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 */
|
||||
|
|
Loading…
Reference in New Issue