>
>Reported-by: Zhiyuan Yuan <yuanzhiy...@chinatelecom.cn>
>Signed-off-by: Jidong Xia <xi...@chinatelecom.cn>
>Signed-off-by: Huaitong Han <han...@chinatelecom.cn>
>---
> hw/pci/pci.c | 2 +-
> hw/s390x/virtio-ccw.c | 9 ++++++---
> hw/virtio/vhost.c | 5 ++---
> hw/virtio/virtio-pci.c | 15 ++++++++++-----
> include/hw/pci/pci.h | 1 +
> include/hw/virtio/virtio-bus.h | 2 +-
> 6 files changed, 21 insertions(+), 13 deletions(-)
>
>diff --git a/hw/pci/pci.c b/hw/pci/pci.c
>index 2844ec5556..503a897528 100644
>--- a/hw/pci/pci.c
>+++ b/hw/pci/pci.c
>@@ -1719,7 +1719,7 @@ static void pci_update_mappings(PCIDevice *d)
> pci_update_vga(d);
> }
>
>-static inline int pci_irq_disabled(PCIDevice *d)
>+int pci_irq_disabled(PCIDevice *d)
> {
> return pci_get_word(d->config + PCI_COMMAND) & PCI_COMMAND_INTX_DISABLE;
> }
>diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
>index 43f3b162c8..af482a22cd 100644
>--- a/hw/s390x/virtio-ccw.c
>+++ b/hw/s390x/virtio-ccw.c
>@@ -936,11 +936,14 @@ static void virtio_ccw_vmstate_change(DeviceState *d,
bool running)
> }
> }
>
>-static bool virtio_ccw_query_guest_notifiers(DeviceState *d)
>+static bool virtio_ccw_query_guest_notifiers_used(DeviceState *d, int n)
> {
> CcwDevice *dev = CCW_DEVICE(d);
>+ VirtioCcwDevice *vdev = VIRTIO_CCW_DEVICE(d);
>+ VirtIODevice *virtio_dev = virtio_bus_get_device(&vdev->bus);
>
>- return !!(dev->sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ENA);
>+ return !!(dev->sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ENA)
>+ && virtio_queue_vector(virtio_dev, n) != VIRTIO_NO_VECTOR;
> }
>
> static int virtio_ccw_get_mappings(VirtioCcwDevice *dev)
>@@ -1270,7 +1273,7 @@ static void virtio_ccw_bus_class_init(ObjectClass
*klass, void *data)
> bus_class->max_dev = 1;
> k->notify = virtio_ccw_notify;
> k->vmstate_change = virtio_ccw_vmstate_change;
>- k->query_guest_notifiers = virtio_ccw_query_guest_notifiers;
>+ k->query_guest_notifiers_used = virtio_ccw_query_guest_notifiers_used;
> k->set_guest_notifiers = virtio_ccw_set_guest_notifiers;
> k->save_queue = virtio_ccw_save_queue;
> k->load_queue = virtio_ccw_load_queue;
>diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
>index 6aa72fd434..32634da836 100644
>--- a/hw/virtio/vhost.c
>+++ b/hw/virtio/vhost.c
>@@ -1341,9 +1341,8 @@ int vhost_virtqueue_start(struct vhost_dev *dev,
> vhost_virtqueue_mask(dev, vdev, idx, false);
> }
>
>- if (k->query_guest_notifiers &&
>- k->query_guest_notifiers(qbus->parent) &&
>- virtio_queue_vector(vdev, idx) == VIRTIO_NO_VECTOR) {
>+ if (k->query_guest_notifiers_used &&
>+ !k->query_guest_notifiers_used(qbus->parent, idx)) {
> file.fd = -1;
> r = dev->vhost_ops->vhost_set_vring_call(dev, &file);
> if (r) {
>diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
>index 3ca3f849d3..25ff869618 100644
>--- a/hw/virtio/virtio-pci.c
>+++ b/hw/virtio/virtio-pci.c
>@@ -30,6 +30,7 @@
> #include "qemu/error-report.h"
> #include "qemu/log.h"
> #include "qemu/module.h"
>+#include "hw/pci/pci.h"
> #include "hw/pci/msi.h"
> #include "hw/pci/msix.h"
> #include "hw/loader.h"
>@@ -1031,7 +1032,7 @@ static void virtio_pci_one_vector_mask(VirtIOPCIProxy
*proxy,
>
> /* If guest supports masking, keep irqfd but mask it.
> * Otherwise, clean it up now.
>- */
>+ */
Unrelated change.
> if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
> k->guest_notifier_mask(vdev, queue_no, true);
> } else {
>@@ -1212,10 +1213,15 @@ static int virtio_pci_set_guest_notifier(DeviceState
*d, int n, bool assign,
> return 0;
> }
>
>-static bool virtio_pci_query_guest_notifiers(DeviceState *d)
>+static bool virtio_pci_query_guest_notifiers_used(DeviceState *d, int n)
> {
> VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
>- return msix_enabled(&proxy->pci_dev);
>+ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
>+
>+ if (msix_enabled(&proxy->pci_dev))
>+ return virtio_queue_vector(vdev, n) != VIRTIO_NO_VECTOR;
>+ else
>+ return !pci_irq_disabled(&proxy->pci_dev);
> }
>
> static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool
assign)
>@@ -2599,7 +2605,7 @@ static void virtio_pci_bus_class_init(ObjectClass
*klass, void *data)
> k->save_extra_state = virtio_pci_save_extra_state;
> k->load_extra_state = virtio_pci_load_extra_state;
> k->has_extra_state = virtio_pci_has_extra_state;
>- k->query_guest_notifiers = virtio_pci_query_guest_notifiers;
>+ k->query_guest_notifiers_used = virtio_pci_query_guest_notifiers_used;
> k->set_guest_notifiers = virtio_pci_set_guest_notifiers;
> k->set_host_notifier_mr = virtio_pci_set_host_notifier_mr;
> k->vmstate_change = virtio_pci_vmstate_change;
>@@ -2630,4 +2636,3 @@ static void virtio_pci_register_types(void)
> }
>
> type_init(virtio_pci_register_types)
>-
>diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
>index 822fbacdf0..de4ab28046 100644
>--- a/include/hw/pci/pci.h
>+++ b/include/hw/pci/pci.h
>@@ -256,6 +256,7 @@ void pci_del_capability(PCIDevice *pci_dev, uint8_t
cap_id, uint8_t cap_size);
>
> uint8_t pci_find_capability(PCIDevice *pci_dev, uint8_t cap_id);
>
>+int pci_irq_disabled(PCIDevice *d);
>
> uint32_t pci_default_read_config(PCIDevice *d,
> uint32_t address, int len);
>diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
>index 7ab8c9dab0..de75a44895 100644
>--- a/include/hw/virtio/virtio-bus.h
>+++ b/include/hw/virtio/virtio-bus.h
>@@ -48,7 +48,7 @@ struct VirtioBusClass {
> int (*load_done)(DeviceState *d, QEMUFile *f);
> int (*load_extra_state)(DeviceState *d, QEMUFile *f);
> bool (*has_extra_state)(DeviceState *d);
>- bool (*query_guest_notifiers)(DeviceState *d);
>+ bool (*query_guest_notifiers_used)(DeviceState *d, int n);
> int (*set_guest_notifiers)(DeviceState *d, int nvqs, bool assign);
> int (*set_host_notifier_mr)(DeviceState *d, int n,
> MemoryRegion *mr, bool assign);
>--
>2.43.5
>