If the vq is the premapped mode, use the sg_dma_address() directly.

Signed-off-by: Xuan Zhuo <xuanz...@linux.alibaba.com>
---
 drivers/virtio/virtio_ring.c | 36 ++++++++++++++++++++++++++----------
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 18212c3e056b..dc109fbc05a5 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -1299,9 +1299,13 @@ static int virtqueue_add_indirect_packed(struct 
vring_virtqueue *vq,
 
        for (n = 0; n < out_sgs + in_sgs; n++) {
                for (sg = sgs[n]; sg; sg = sg_next(sg)) {
-                       if (vring_map_one_sg(vq, sg, n < out_sgs ?
-                                            DMA_TO_DEVICE : DMA_FROM_DEVICE, 
&addr))
-                               goto unmap_release;
+                       if (vq->premapped) {
+                               addr = sg_dma_address(sg);
+                       } else {
+                               if (vring_map_one_sg(vq, sg, n < out_sgs ?
+                                                    DMA_TO_DEVICE : 
DMA_FROM_DEVICE, &addr))
+                                       goto unmap_release;
+                       }
 
                        desc[i].flags = cpu_to_le16(n < out_sgs ?
                                                0 : VRING_DESC_F_WRITE);
@@ -1369,10 +1373,12 @@ static int virtqueue_add_indirect_packed(struct 
vring_virtqueue *vq,
        return 0;
 
 unmap_release:
-       err_idx = i;
+       if (!vq->premapped) {
+               err_idx = i;
 
-       for (i = 0; i < err_idx; i++)
-               vring_unmap_desc_packed(vq, &desc[i]);
+               for (i = 0; i < err_idx; i++)
+                       vring_unmap_desc_packed(vq, &desc[i]);
+       }
 
        kfree(desc);
 
@@ -1447,9 +1453,13 @@ static inline int virtqueue_add_packed(struct virtqueue 
*_vq,
                for (sg = sgs[n]; sg; sg = sg_next(sg)) {
                        dma_addr_t addr;
 
-                       if (vring_map_one_sg(vq, sg, n < out_sgs ?
-                                            DMA_TO_DEVICE : DMA_FROM_DEVICE, 
&addr))
-                               goto unmap_release;
+                       if (vq->premapped) {
+                               addr = sg_dma_address(sg);
+                       } else {
+                               if (vring_map_one_sg(vq, sg, n < out_sgs ?
+                                                    DMA_TO_DEVICE : 
DMA_FROM_DEVICE, &addr))
+                                       goto unmap_release;
+                       }
 
                        flags = cpu_to_le16(vq->packed.avail_used_flags |
                                    (++c == total_sg ? 0 : VRING_DESC_F_NEXT) |
@@ -1512,11 +1522,17 @@ static inline int virtqueue_add_packed(struct virtqueue 
*_vq,
        return 0;
 
 unmap_release:
+       vq->packed.avail_used_flags = avail_used_flags;
+
+       if (vq->premapped) {
+               END_USE(vq);
+               return -EIO;
+       }
+
        err_idx = i;
        i = head;
        curr = vq->free_head;
 
-       vq->packed.avail_used_flags = avail_used_flags;
 
        for (n = 0; n < total_sg; n++) {
                if (i == err_idx)
-- 
2.32.0.3.g01195cf9f

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Reply via email to