diff options
author | Vaporeon | 2017-12-22 22:43:37 +1300 |
---|---|---|
committer | Vaporeon | 2017-12-22 22:43:37 +1300 |
commit | b35bbf5374538b5bfec90956553a0eab36e526a9 (patch) | |
tree | 23d085b3bfa5de5fdfc929b74b12cf05775f4fca | |
parent | 371dcabe713623310b257fde9bc92b5ceb32a033 (diff) | |
download | aur-b35bbf5374538b5bfec90956553a0eab36e526a9.tar.gz |
merge this to one patch
-rw-r--r-- | .SRCINFO | 12 | ||||
-rw-r--r-- | PKGBUILD | 15 | ||||
-rw-r--r-- | v4_ivshmem.patch | 331 | ||||
-rw-r--r-- | v4_ivshmem_1.patch | 78 | ||||
-rw-r--r-- | v4_ivshmem_2.patch | 104 | ||||
-rw-r--r-- | v4_ivshmem_3.patch | 100 | ||||
-rw-r--r-- | v4_ivshmem_4.patch | 49 |
7 files changed, 337 insertions, 352 deletions
@@ -1,5 +1,5 @@ # Generated by mksrcinfo v8 -# Thu Dec 14 04:42:33 UTC 2017 +# Fri Dec 22 09:36:02 UTC 2017 pkgbase = qemu-patched pkgdesc = A generic and open source machine emulator and virtualizer - Patched for extra functionality pkgver = 2.11.0 @@ -41,10 +41,7 @@ pkgbase = qemu-patched source = cpu-pinning.patch source = audio-improvements.patch source = v2_qemu_zen_smt_cache.patch - source = v4_ivshmem_1.patch - source = v4_ivshmem_2.patch - source = v4_ivshmem_3.patch - source = v4_ivshmem_4.patch + source = v4_ivshmem.patch sha256sums = c4f034c7665a84a1c3be72c8da37f3c31ec063475699df062ab646d8b2e17fcb sha256sums = SKIP sha256sums = c39bcde4a09165e64419fd2033b3532378bba84d509d39e2d51694d44c1f8d88 @@ -53,10 +50,7 @@ pkgbase = qemu-patched sha256sums = 8d4a7e35ab1a0a465f737cf60fc0392afc430e22354a40a89505f8766a3a3ee8 sha256sums = 23338655345d0ee535f34acc124f1ddd75e5ad4483e2bd87294b7ac4fe3fa859 sha256sums = adf3f389849e92c5ea4c4cee0abf1ac5df61a176d296e9263ac773194ba86e57 - sha256sums = 2626aa6c13ad0596a02501e7b31800c7536c629d89297c4b7ba11e311e4cd4e8 - sha256sums = 87dcd51a3500382c2b0e1462eb99c21ec355ab0d2b41705f7e0a356827accceb - sha256sums = fd619e15797dd38bdfe822d36b3d41064b5585e0961a7cde0cf88c21c9dcd466 - sha256sums = e5f81c6df9f8344b78f70023bafa87fe2e950c0302ab234da08309e45c9f1be6 + sha256sums = 4acbbd8834dc5782feb86795748f37e1b1aa4f61b54303234ea4f13bd4c0e068 pkgname = qemu-patched optdepends = qemu-patched-arch-extra: extra architectures support @@ -23,10 +23,7 @@ source=("$url/download/${_pkgname}-${pkgver}.tar.bz2"{,.sig} cpu-pinning.patch audio-improvements.patch v2_qemu_zen_smt_cache.patch - v4_ivshmem_1.patch - v4_ivshmem_2.patch - v4_ivshmem_3.patch - v4_ivshmem_4.patch) + v4_ivshmem.patch) sha256sums=('c4f034c7665a84a1c3be72c8da37f3c31ec063475699df062ab646d8b2e17fcb' 'SKIP' 'c39bcde4a09165e64419fd2033b3532378bba84d509d39e2d51694d44c1f8d88' @@ -35,10 +32,7 @@ sha256sums=('c4f034c7665a84a1c3be72c8da37f3c31ec063475699df062ab646d8b2e17fcb' '8d4a7e35ab1a0a465f737cf60fc0392afc430e22354a40a89505f8766a3a3ee8' '23338655345d0ee535f34acc124f1ddd75e5ad4483e2bd87294b7ac4fe3fa859' 'adf3f389849e92c5ea4c4cee0abf1ac5df61a176d296e9263ac773194ba86e57' - '2626aa6c13ad0596a02501e7b31800c7536c629d89297c4b7ba11e311e4cd4e8' - '87dcd51a3500382c2b0e1462eb99c21ec355ab0d2b41705f7e0a356827accceb' - 'fd619e15797dd38bdfe822d36b3d41064b5585e0961a7cde0cf88c21c9dcd466' - 'e5f81c6df9f8344b78f70023bafa87fe2e950c0302ab234da08309e45c9f1be6') + '4acbbd8834dc5782feb86795748f37e1b1aa4f61b54303234ea4f13bd4c0e068') validpgpkeys=('CEACC9E15534EBABB82D3FA03353C9CEF108B584') case $CARCH in @@ -57,10 +51,7 @@ prepare() { patch -p1 < ../cpu-pinning.patch patch -p0 < ../audio-improvements.patch patch -p1 < ../v2_qemu_zen_smt_cache.patch - patch -p1 < ../v4_ivshmem_1.patch - patch -p1 < ../v4_ivshmem_2.patch - patch -p1 < ../v4_ivshmem_3.patch - patch -p1 < ../v4_ivshmem_4.patch + patch -p1 < ../v4_ivshmem.patch } build() { diff --git a/v4_ivshmem.patch b/v4_ivshmem.patch new file mode 100644 index 000000000000..65065b6807a2 --- /dev/null +++ b/v4_ivshmem.patch @@ -0,0 +1,331 @@ +As of commit 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications"), +QEMU crashes with: + + kvm_irqchip_commit_routes: Assertion `ret == 0' failed. + +if the ivshmem device is configured with more vectors than what the server +supports. This is caused by the ivshmem_vector_unmask() being called on +vectors that have not been initialized by ivshmem_add_kvm_msi_virq(). + +This commit fixes it by adding a simple check to the mask and unmask +callbacks. + +Note that the opposite mismatch, if the server supplies more vectors than +what the device is configured for, is already handled and leads to output +like: + + Too many eventfd received, device has 1 vectors + +To reproduce the assert, run: + + ivshmem-server -n 0 + +and QEMU with: + + -device ivshmem-doorbell,chardev=iv + -chardev socket,path=/tmp/ivshmem_socket,id=iv + +then load the Windows driver, at the time of writing available at: + +https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem + +The issue is believed to have been masked by other guest drivers, notably +Linux ones, not enabling MSI-X on the device. + +Fixes: 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications") +Signed-off-by: Ladi Prosek <address@hidden> +Reviewed-by: Marc-André Lureau <address@hidden> +Reviewed-by: Markus Armbruster <address@hidden> +--- + hw/misc/ivshmem.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c +index a5a46827fe..6e46669744 100644 +--- a/hw/misc/ivshmem.c ++++ b/hw/misc/ivshmem.c +@@ -317,6 +317,10 @@ static int ivshmem_vector_unmask(PCIDevice *dev, unsigned vector, + int ret; + + IVSHMEM_DPRINTF("vector unmask %p %d\n", dev, vector); ++ if (!v->pdev) { ++ error_report("ivshmem: vector %d route does not exist", vector); ++ return -EINVAL; ++ } + + ret = kvm_irqchip_update_msi_route(kvm_state, v->virq, msg, dev); + if (ret < 0) { +@@ -331,12 +335,16 @@ static void ivshmem_vector_mask(PCIDevice *dev, unsigned vector) + { + IVShmemState *s = IVSHMEM_COMMON(dev); + EventNotifier *n = &s->peers[s->vm_id].eventfds[vector]; ++ MSIVector *v = &s->msi_vectors[vector]; + int ret; + + IVSHMEM_DPRINTF("vector mask %p %d\n", dev, vector); ++ if (!v->pdev) { ++ error_report("ivshmem: vector %d route does not exist", vector); ++ return; ++ } + +- ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, +- s->msi_vectors[vector].virq); ++ ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, v->virq); + if (ret != 0) { + error_report("remove_irqfd_notifier_gsi failed"); + } +-- +2.13.6 +As of commit 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications"), +QEMU crashes with: + +ivshmem: msix_set_vector_notifiers failed +msix_unset_vector_notifiers: Assertion `dev->msix_vector_use_notifier && +dev->msix_vector_release_notifier' failed. + +if MSI-X is repeatedly enabled and disabled on the ivshmem device, for example +by loading and unloading the Windows ivshmem driver. This is because +msix_unset_vector_notifiers() doesn't call any of the release notifier callbacks +since MSI-X is already disabled at that point (msix_enabled() returning false +is how this transition is detected in the first place). Thus +ivshmem_vector_mask() +doesn't run and when MSI-X is subsequently enabled again ivshmem_vector_unmask() +fails. + +This is fixed by keeping track of unmasked vectors and making sure that +ivshmem_vector_mask() always runs on MSI-X disable. + +Fixes: 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications") +Signed-off-by: Ladi Prosek <address@hidden> +Reviewed-by: Markus Armbruster <address@hidden> +--- + hw/misc/ivshmem.c | 32 ++++++++++++++++++++++++++------ + 1 file changed, 26 insertions(+), 6 deletions(-) + +diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c +index 6e46669744..91364d8364 100644 +--- a/hw/misc/ivshmem.c ++++ b/hw/misc/ivshmem.c +@@ -77,6 +77,7 @@ typedef struct Peer { + typedef struct MSIVector { + PCIDevice *pdev; + int virq; ++ bool unmasked; + } MSIVector; + + typedef struct IVShmemState { +@@ -321,6 +322,7 @@ static int ivshmem_vector_unmask(PCIDevice *dev, unsigned vector, + error_report("ivshmem: vector %d route does not exist", vector); + return -EINVAL; + } ++ assert(!v->unmasked); + + ret = kvm_irqchip_update_msi_route(kvm_state, v->virq, msg, dev); + if (ret < 0) { +@@ -328,7 +330,13 @@ static int ivshmem_vector_unmask(PCIDevice *dev, unsigned vector, + } + kvm_irqchip_commit_routes(kvm_state); + +- return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, v->virq); ++ ret = kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, v->virq); ++ if (ret < 0) { ++ return ret; ++ } ++ v->unmasked = true; ++ ++ return 0; + } + + static void ivshmem_vector_mask(PCIDevice *dev, unsigned vector) +@@ -343,11 +351,14 @@ static void ivshmem_vector_mask(PCIDevice *dev, unsigned vector) + error_report("ivshmem: vector %d route does not exist", vector); + return; + } ++ assert(v->unmasked); + + ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, v->virq); +- if (ret != 0) { ++ if (ret < 0) { + error_report("remove_irqfd_notifier_gsi failed"); ++ return; + } ++ v->unmasked = false; + } + + static void ivshmem_vector_poll(PCIDevice *dev, +@@ -817,11 +828,20 @@ static void ivshmem_disable_irqfd(IVShmemState *s) + PCIDevice *pdev = PCI_DEVICE(s); + int i; + +- for (i = 0; i < s->peers[s->vm_id].nb_eventfds; i++) { +- ivshmem_remove_kvm_msi_virq(s, i); +- } +- + msix_unset_vector_notifiers(pdev); ++ ++ for (i = 0; i < s->peers[s->vm_id].nb_eventfds; i++) { ++ /* ++ * MSI-X is already disabled here so msix_unset_vector_notifiers() ++ * didn't call our release notifier. Do it now to keep our masks and ++ * unmasks balanced. ++ */ ++ if (s->msi_vectors[i].unmasked) { ++ ivshmem_vector_mask(pdev, i); ++ } ++ ivshmem_remove_kvm_msi_virq(s, i); ++ } ++ + } + + static void ivshmem_write_config(PCIDevice *pdev, uint32_t address, +-- +2.13.6 +Adds a rollback path to ivshmem_enable_irqfd() and fixes +ivshmem_disable_irqfd() to bail if irqfd has not been enabled. + +To reproduce, run: + + ivshmem-server -n 0 + +and QEMU with: + + -device ivshmem-doorbell,chardev=iv + -chardev socket,path=/tmp/ivshmem_socket,id=iv + +then load, unload, and load again the Windows driver, at the time of writing +available at: + +https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem + +The issue is believed to have been masked by other guest drivers, notably +Linux ones, not enabling MSI-X on the device. + +Signed-off-by: Ladi Prosek <address@hidden> +Reviewed-by: Markus Armbruster <address@hidden> +--- + hw/misc/ivshmem.c | 37 ++++++++++++++++++++++++------------- + 1 file changed, 24 insertions(+), 13 deletions(-) + +diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c +index 91364d8364..d1bb246d12 100644 +--- a/hw/misc/ivshmem.c ++++ b/hw/misc/ivshmem.c +@@ -786,6 +786,20 @@ static int ivshmem_setup_interrupts(IVShmemState *s, Error **errp) + return 0; + } + ++static void ivshmem_remove_kvm_msi_virq(IVShmemState *s, int vector) ++{ ++ IVSHMEM_DPRINTF("ivshmem_remove_kvm_msi_virq vector:%d\n", vector); ++ ++ if (s->msi_vectors[vector].pdev == NULL) { ++ return; ++ } ++ ++ /* it was cleaned when masked in the frontend. */ ++ kvm_irqchip_release_virq(kvm_state, s->msi_vectors[vector].virq); ++ ++ s->msi_vectors[vector].pdev = NULL; ++} ++ + static void ivshmem_enable_irqfd(IVShmemState *s) + { + PCIDevice *pdev = PCI_DEVICE(s); +@@ -797,7 +811,7 @@ static void ivshmem_enable_irqfd(IVShmemState *s) + ivshmem_add_kvm_msi_virq(s, i, &err); + if (err) { + error_report_err(err); +- /* TODO do we need to handle the error? */ ++ goto undo; + } + } + +@@ -806,21 +820,14 @@ static void ivshmem_enable_irqfd(IVShmemState *s) + ivshmem_vector_mask, + ivshmem_vector_poll)) { + error_report("ivshmem: msix_set_vector_notifiers failed"); ++ goto undo; + } +-} ++ return; + +-static void ivshmem_remove_kvm_msi_virq(IVShmemState *s, int vector) +-{ +- IVSHMEM_DPRINTF("ivshmem_remove_kvm_msi_virq vector:%d\n", vector); +- +- if (s->msi_vectors[vector].pdev == NULL) { +- return; ++undo: ++ while (--i >= 0) { ++ ivshmem_remove_kvm_msi_virq(s, i); + } +- +- /* it was cleaned when masked in the frontend. */ +- kvm_irqchip_release_virq(kvm_state, s->msi_vectors[vector].virq); +- +- s->msi_vectors[vector].pdev = NULL; + } + + static void ivshmem_disable_irqfd(IVShmemState *s) +@@ -828,6 +835,10 @@ static void ivshmem_disable_irqfd(IVShmemState *s) + PCIDevice *pdev = PCI_DEVICE(s); + int i; + ++ if (!pdev->msix_vector_use_notifier) { ++ return; ++ } ++ + msix_unset_vector_notifiers(pdev); + + for (i = 0; i < s->peers[s->vm_id].nb_eventfds; i++) { +-- +2.13.6 +The effects of ivshmem_enable_irqfd() was not undone on device reset. + +This manifested as: +ivshmem_add_kvm_msi_virq: Assertion `!s->msi_vectors[vector].pdev' failed. + +when irqfd was enabled before reset and then enabled again after reset, making +ivshmem_enable_irqfd() run for the second time. + +To reproduce, run: + + ivshmem-server + +and QEMU with: + + -device ivshmem-doorbell,chardev=iv + -chardev socket,path=/tmp/ivshmem_socket,id=iv + +then install the Windows driver, at the time of writing available at: + +https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem + +and crash-reboot the guest by inducing a BSOD. + +Signed-off-by: Ladi Prosek <address@hidden> +--- + hw/misc/ivshmem.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c +index d1bb246d12..9c7e74ef12 100644 +--- a/hw/misc/ivshmem.c ++++ b/hw/misc/ivshmem.c +@@ -758,10 +758,14 @@ static void ivshmem_msix_vector_use(IVShmemState *s) + } + } + ++static void ivshmem_disable_irqfd(IVShmemState *s); ++ + static void ivshmem_reset(DeviceState *d) + { + IVShmemState *s = IVSHMEM_COMMON(d); + ++ ivshmem_disable_irqfd(s); ++ + s->intrstatus = 0; + s->intrmask = 0; + if (ivshmem_has_feature(s, IVSHMEM_MSI)) { +-- +2.13.6 diff --git a/v4_ivshmem_1.patch b/v4_ivshmem_1.patch deleted file mode 100644 index 70d71ce976b7..000000000000 --- a/v4_ivshmem_1.patch +++ /dev/null @@ -1,78 +0,0 @@ -As of commit 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications"), -QEMU crashes with: - - kvm_irqchip_commit_routes: Assertion `ret == 0' failed. - -if the ivshmem device is configured with more vectors than what the server -supports. This is caused by the ivshmem_vector_unmask() being called on -vectors that have not been initialized by ivshmem_add_kvm_msi_virq(). - -This commit fixes it by adding a simple check to the mask and unmask -callbacks. - -Note that the opposite mismatch, if the server supplies more vectors than -what the device is configured for, is already handled and leads to output -like: - - Too many eventfd received, device has 1 vectors - -To reproduce the assert, run: - - ivshmem-server -n 0 - -and QEMU with: - - -device ivshmem-doorbell,chardev=iv - -chardev socket,path=/tmp/ivshmem_socket,id=iv - -then load the Windows driver, at the time of writing available at: - -https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem - -The issue is believed to have been masked by other guest drivers, notably -Linux ones, not enabling MSI-X on the device. - -Fixes: 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications") -Signed-off-by: Ladi Prosek <address@hidden> -Reviewed-by: Marc-André Lureau <address@hidden> -Reviewed-by: Markus Armbruster <address@hidden> ---- - hw/misc/ivshmem.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c -index a5a46827fe..6e46669744 100644 ---- a/hw/misc/ivshmem.c -+++ b/hw/misc/ivshmem.c -@@ -317,6 +317,10 @@ static int ivshmem_vector_unmask(PCIDevice *dev, unsigned vector, - int ret; - - IVSHMEM_DPRINTF("vector unmask %p %d\n", dev, vector); -+ if (!v->pdev) { -+ error_report("ivshmem: vector %d route does not exist", vector); -+ return -EINVAL; -+ } - - ret = kvm_irqchip_update_msi_route(kvm_state, v->virq, msg, dev); - if (ret < 0) { -@@ -331,12 +335,16 @@ static void ivshmem_vector_mask(PCIDevice *dev, unsigned vector) - { - IVShmemState *s = IVSHMEM_COMMON(dev); - EventNotifier *n = &s->peers[s->vm_id].eventfds[vector]; -+ MSIVector *v = &s->msi_vectors[vector]; - int ret; - - IVSHMEM_DPRINTF("vector mask %p %d\n", dev, vector); -+ if (!v->pdev) { -+ error_report("ivshmem: vector %d route does not exist", vector); -+ return; -+ } - -- ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, -- s->msi_vectors[vector].virq); -+ ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, v->virq); - if (ret != 0) { - error_report("remove_irqfd_notifier_gsi failed"); - } --- -2.13.6 diff --git a/v4_ivshmem_2.patch b/v4_ivshmem_2.patch deleted file mode 100644 index 4df27de7ba96..000000000000 --- a/v4_ivshmem_2.patch +++ /dev/null @@ -1,104 +0,0 @@ -As of commit 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications"), -QEMU crashes with: - -ivshmem: msix_set_vector_notifiers failed -msix_unset_vector_notifiers: Assertion `dev->msix_vector_use_notifier && -dev->msix_vector_release_notifier' failed. - -if MSI-X is repeatedly enabled and disabled on the ivshmem device, for example -by loading and unloading the Windows ivshmem driver. This is because -msix_unset_vector_notifiers() doesn't call any of the release notifier callbacks -since MSI-X is already disabled at that point (msix_enabled() returning false -is how this transition is detected in the first place). Thus -ivshmem_vector_mask() -doesn't run and when MSI-X is subsequently enabled again ivshmem_vector_unmask() -fails. - -This is fixed by keeping track of unmasked vectors and making sure that -ivshmem_vector_mask() always runs on MSI-X disable. - -Fixes: 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications") -Signed-off-by: Ladi Prosek <address@hidden> -Reviewed-by: Markus Armbruster <address@hidden> ---- - hw/misc/ivshmem.c | 32 ++++++++++++++++++++++++++------ - 1 file changed, 26 insertions(+), 6 deletions(-) - -diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c -index 6e46669744..91364d8364 100644 ---- a/hw/misc/ivshmem.c -+++ b/hw/misc/ivshmem.c -@@ -77,6 +77,7 @@ typedef struct Peer { - typedef struct MSIVector { - PCIDevice *pdev; - int virq; -+ bool unmasked; - } MSIVector; - - typedef struct IVShmemState { -@@ -321,6 +322,7 @@ static int ivshmem_vector_unmask(PCIDevice *dev, unsigned vector, - error_report("ivshmem: vector %d route does not exist", vector); - return -EINVAL; - } -+ assert(!v->unmasked); - - ret = kvm_irqchip_update_msi_route(kvm_state, v->virq, msg, dev); - if (ret < 0) { -@@ -328,7 +330,13 @@ static int ivshmem_vector_unmask(PCIDevice *dev, unsigned vector, - } - kvm_irqchip_commit_routes(kvm_state); - -- return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, v->virq); -+ ret = kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, v->virq); -+ if (ret < 0) { -+ return ret; -+ } -+ v->unmasked = true; -+ -+ return 0; - } - - static void ivshmem_vector_mask(PCIDevice *dev, unsigned vector) -@@ -343,11 +351,14 @@ static void ivshmem_vector_mask(PCIDevice *dev, unsigned vector) - error_report("ivshmem: vector %d route does not exist", vector); - return; - } -+ assert(v->unmasked); - - ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, v->virq); -- if (ret != 0) { -+ if (ret < 0) { - error_report("remove_irqfd_notifier_gsi failed"); -+ return; - } -+ v->unmasked = false; - } - - static void ivshmem_vector_poll(PCIDevice *dev, -@@ -817,11 +828,20 @@ static void ivshmem_disable_irqfd(IVShmemState *s) - PCIDevice *pdev = PCI_DEVICE(s); - int i; - -- for (i = 0; i < s->peers[s->vm_id].nb_eventfds; i++) { -- ivshmem_remove_kvm_msi_virq(s, i); -- } -- - msix_unset_vector_notifiers(pdev); -+ -+ for (i = 0; i < s->peers[s->vm_id].nb_eventfds; i++) { -+ /* -+ * MSI-X is already disabled here so msix_unset_vector_notifiers() -+ * didn't call our release notifier. Do it now to keep our masks and -+ * unmasks balanced. -+ */ -+ if (s->msi_vectors[i].unmasked) { -+ ivshmem_vector_mask(pdev, i); -+ } -+ ivshmem_remove_kvm_msi_virq(s, i); -+ } -+ - } - - static void ivshmem_write_config(PCIDevice *pdev, uint32_t address, --- -2.13.6 diff --git a/v4_ivshmem_3.patch b/v4_ivshmem_3.patch deleted file mode 100644 index 205da550b901..000000000000 --- a/v4_ivshmem_3.patch +++ /dev/null @@ -1,100 +0,0 @@ -Adds a rollback path to ivshmem_enable_irqfd() and fixes -ivshmem_disable_irqfd() to bail if irqfd has not been enabled. - -To reproduce, run: - - ivshmem-server -n 0 - -and QEMU with: - - -device ivshmem-doorbell,chardev=iv - -chardev socket,path=/tmp/ivshmem_socket,id=iv - -then load, unload, and load again the Windows driver, at the time of writing -available at: - -https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem - -The issue is believed to have been masked by other guest drivers, notably -Linux ones, not enabling MSI-X on the device. - -Signed-off-by: Ladi Prosek <address@hidden> -Reviewed-by: Markus Armbruster <address@hidden> ---- - hw/misc/ivshmem.c | 37 ++++++++++++++++++++++++------------- - 1 file changed, 24 insertions(+), 13 deletions(-) - -diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c -index 91364d8364..d1bb246d12 100644 ---- a/hw/misc/ivshmem.c -+++ b/hw/misc/ivshmem.c -@@ -786,6 +786,20 @@ static int ivshmem_setup_interrupts(IVShmemState *s, Error **errp) - return 0; - } - -+static void ivshmem_remove_kvm_msi_virq(IVShmemState *s, int vector) -+{ -+ IVSHMEM_DPRINTF("ivshmem_remove_kvm_msi_virq vector:%d\n", vector); -+ -+ if (s->msi_vectors[vector].pdev == NULL) { -+ return; -+ } -+ -+ /* it was cleaned when masked in the frontend. */ -+ kvm_irqchip_release_virq(kvm_state, s->msi_vectors[vector].virq); -+ -+ s->msi_vectors[vector].pdev = NULL; -+} -+ - static void ivshmem_enable_irqfd(IVShmemState *s) - { - PCIDevice *pdev = PCI_DEVICE(s); -@@ -797,7 +811,7 @@ static void ivshmem_enable_irqfd(IVShmemState *s) - ivshmem_add_kvm_msi_virq(s, i, &err); - if (err) { - error_report_err(err); -- /* TODO do we need to handle the error? */ -+ goto undo; - } - } - -@@ -806,21 +820,14 @@ static void ivshmem_enable_irqfd(IVShmemState *s) - ivshmem_vector_mask, - ivshmem_vector_poll)) { - error_report("ivshmem: msix_set_vector_notifiers failed"); -+ goto undo; - } --} -+ return; - --static void ivshmem_remove_kvm_msi_virq(IVShmemState *s, int vector) --{ -- IVSHMEM_DPRINTF("ivshmem_remove_kvm_msi_virq vector:%d\n", vector); -- -- if (s->msi_vectors[vector].pdev == NULL) { -- return; -+undo: -+ while (--i >= 0) { -+ ivshmem_remove_kvm_msi_virq(s, i); - } -- -- /* it was cleaned when masked in the frontend. */ -- kvm_irqchip_release_virq(kvm_state, s->msi_vectors[vector].virq); -- -- s->msi_vectors[vector].pdev = NULL; - } - - static void ivshmem_disable_irqfd(IVShmemState *s) -@@ -828,6 +835,10 @@ static void ivshmem_disable_irqfd(IVShmemState *s) - PCIDevice *pdev = PCI_DEVICE(s); - int i; - -+ if (!pdev->msix_vector_use_notifier) { -+ return; -+ } -+ - msix_unset_vector_notifiers(pdev); - - for (i = 0; i < s->peers[s->vm_id].nb_eventfds; i++) { --- -2.13.6 diff --git a/v4_ivshmem_4.patch b/v4_ivshmem_4.patch deleted file mode 100644 index 46824c62a5d9..000000000000 --- a/v4_ivshmem_4.patch +++ /dev/null @@ -1,49 +0,0 @@ -The effects of ivshmem_enable_irqfd() was not undone on device reset. - -This manifested as: -ivshmem_add_kvm_msi_virq: Assertion `!s->msi_vectors[vector].pdev' failed. - -when irqfd was enabled before reset and then enabled again after reset, making -ivshmem_enable_irqfd() run for the second time. - -To reproduce, run: - - ivshmem-server - -and QEMU with: - - -device ivshmem-doorbell,chardev=iv - -chardev socket,path=/tmp/ivshmem_socket,id=iv - -then install the Windows driver, at the time of writing available at: - -https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem - -and crash-reboot the guest by inducing a BSOD. - -Signed-off-by: Ladi Prosek <address@hidden> ---- - hw/misc/ivshmem.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c -index d1bb246d12..9c7e74ef12 100644 ---- a/hw/misc/ivshmem.c -+++ b/hw/misc/ivshmem.c -@@ -758,10 +758,14 @@ static void ivshmem_msix_vector_use(IVShmemState *s) - } - } - -+static void ivshmem_disable_irqfd(IVShmemState *s); -+ - static void ivshmem_reset(DeviceState *d) - { - IVShmemState *s = IVSHMEM_COMMON(d); - -+ ivshmem_disable_irqfd(s); -+ - s->intrstatus = 0; - s->intrmask = 0; - if (ivshmem_has_feature(s, IVSHMEM_MSI)) { --- -2.13.6 |