在 2021/7/6 下午3:20, Cindy Lu 写道:
use the virtio_pci_get_notifier function to
get the notifer, the input of the function
will is the idx, the output is notifier and
vector


You need to describe why such decoupling is needed.



Signed-off-by: Cindy Lu <l...@redhat.com>


I think we need move this patch as patch 3.


---
  hw/virtio/virtio-pci.c | 45 ++++++++++++++++++++++++++++++++----------
  1 file changed, 35 insertions(+), 10 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 2fe5b1f5aa..fe06847b62 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -710,6 +710,28 @@ static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy 
*proxy,
      ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, irqfd->virq);
      assert(ret == 0);
  }
+static int virtio_pci_get_notifier(VirtIOPCIProxy *proxy, int queue_no,
+                                      EventNotifier **n, unsigned int *vector)
+{
+    PCIDevice *dev = &proxy->pci_dev;
+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+    VirtQueue *vq;
+
+    if (queue_no == VIRTIO_CONFIG_IRQ_IDX) {
+        return -1;
+    } else {
+        if (!virtio_queue_get_num(vdev, queue_no)) {
+            return -1;
+        }
+        *vector = virtio_queue_vector(vdev, queue_no);
+        vq = virtio_get_queue(vdev, queue_no);
+        *n = virtio_queue_get_guest_notifier(vq);
+    }
+    if (*vector >= msix_nr_vectors_allocated(dev)) {
+        return -1;
+    }
+    return 0;
+}
static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
  {
@@ -718,13 +740,15 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy 
*proxy, int nvqs)
      VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
      unsigned int vector;
      int ret, queue_no;
-    VirtQueue *vq;
      EventNotifier *n;
      for (queue_no = 0; queue_no < nvqs; queue_no++) {
          if (!virtio_queue_get_num(vdev, queue_no)) {
              break;
          }
-        vector = virtio_queue_vector(vdev, queue_no);
+        ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector);
+        if (ret < 0) {
+            break;


So this suppresses the check below? (you had a similar check that is done in virtio_pci_get_notifier).

Thanks


+        }
          if (vector >= msix_nr_vectors_allocated(dev)) {
              continue;
          }
@@ -736,8 +760,6 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, 
int nvqs)
           * Otherwise, delay until unmasked in the frontend.
           */
          if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
-            vq = virtio_get_queue(vdev, queue_no);
-            n = virtio_queue_get_guest_notifier(vq);
              ret = kvm_virtio_pci_irqfd_use(proxy, n, vector);
              if (ret < 0) {
                  kvm_virtio_pci_vq_vector_release(proxy, vector);
@@ -754,8 +776,10 @@ undo:
              continue;
          }
          if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
-            vq = virtio_get_queue(vdev, queue_no);
-            n = virtio_queue_get_guest_notifier(vq);
+            ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector);
+            if (ret < 0) {
+                break;
+            }
              kvm_virtio_pci_irqfd_release(proxy, n, vector);
          }
          kvm_virtio_pci_vq_vector_release(proxy, vector);
@@ -770,13 +794,16 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy 
*proxy, int nvqs)
      unsigned int vector;
      int queue_no;
      VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
-    VirtQueue *vq;
      EventNotifier *n;
+    int ret ;
      for (queue_no = 0; queue_no < nvqs; queue_no++) {
          if (!virtio_queue_get_num(vdev, queue_no)) {
              break;
          }
-        vector = virtio_queue_vector(vdev, queue_no);
+        ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector);
+        if (ret < 0) {
+            break;
+        }
          if (vector >= msix_nr_vectors_allocated(dev)) {
              continue;
          }
@@ -784,8 +811,6 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy 
*proxy, int nvqs)
           * Otherwise, it was cleaned when masked in the frontend.
           */
          if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
-            vq = virtio_get_queue(vdev, queue_no);
-            n = virtio_queue_get_guest_notifier(vq);
              kvm_virtio_pci_irqfd_release(proxy, n, vector);
          }
          kvm_virtio_pci_vq_vector_release(proxy, vector);


Reply via email to