This patch moves the notification sanity check to
vp_modern_probe(). This can make sure the logic could be reused by
modules other than virtio-pci.

Signed-off-by: Jason Wang <[email protected]>
---
 drivers/virtio/virtio_pci_modern.c | 34 +++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/drivers/virtio/virtio_pci_modern.c 
b/drivers/virtio/virtio_pci_modern.c
index 02688c3b3fbd..d001c74beefe 100644
--- a/drivers/virtio/virtio_pci_modern.c
+++ b/drivers/virtio/virtio_pci_modern.c
@@ -384,17 +384,6 @@ static struct virtqueue *setup_vq(struct virtio_pci_device 
*vp_dev,
        vp_iowrite64_twopart(virtqueue_get_used_addr(vq),
                             &cfg->queue_used_lo, &cfg->queue_used_hi);
 
-       /* offset should not wrap */
-       if ((u64)off * mdev->notify_offset_multiplier + 2
-               > mdev->notify_len) {
-               dev_warn(&vp_dev->pci_dev->dev,
-                        "bad notification offset %u (x %u) "
-                        "for queue %u > %zd",
-                        off, mdev->notify_offset_multiplier,
-                        index, mdev->notify_len);
-               err = -EINVAL;
-               goto err_map_notify;
-       }
        vq->priv = (void __force *)mdev->notify_base +
                off * mdev->notify_offset_multiplier;
 
@@ -695,9 +684,11 @@ static inline void check_offsets(void)
 static int vp_modern_probe(struct virtio_pci_modern_device *mdev)
 {
        struct pci_dev *pci_dev = mdev->pci_dev;
-       int err, common, isr, notify, device;
+       int err, common, isr, notify, device, i;
+       unsigned int num_queues;
        u32 notify_length;
        u32 notify_offset;
+       u16 off;
 
        /* We only own devices >= 0x1000 and <= 0x107f: leave the rest. */
        if (pci_dev->device < 0x1000 || pci_dev->device > 0x107f)
@@ -796,6 +787,25 @@ static int vp_modern_probe(struct virtio_pci_modern_device 
*mdev)
        if (!mdev->notify_base)
                goto err;
 
+       num_queues = vp_ioread16(&mdev->common->num_queues);
+
+       /* offset should not wrap */
+       for (i = 0; i < num_queues; i++) {
+               vp_iowrite16(i, &mdev->common->queue_select);
+               off = vp_ioread16(&mdev->common->queue_notify_off);
+
+               if ((u64)off * mdev->notify_offset_multiplier + 2
+                       > mdev->notify_len) {
+                       dev_warn(&pci_dev->dev,
+                        "bad notification offset %u (x %u) "
+                        "for queue %u > %zd",
+                        off, mdev->notify_offset_multiplier,
+                        i, mdev->notify_len);
+                       err = -EINVAL;
+                       goto err;
+               }
+       }
+
        /* We don't know how much we should map, but PAGE_SIZE
         * is more than enough for all existing devices.
         */
-- 
2.25.1

Reply via email to