@@ -361,6 +361,11 @@ static struct device *vring_dma_dev(const struct vring_virtqueue *vq)
361
361
static int vring_map_one_sg (const struct vring_virtqueue * vq , struct scatterlist * sg ,
362
362
enum dma_data_direction direction , dma_addr_t * addr )
363
363
{
364
+ if (vq -> premapped ) {
365
+ * addr = sg_dma_address (sg );
366
+ return 0 ;
367
+ }
368
+
364
369
if (!vq -> use_dma_api ) {
365
370
/*
366
371
* If DMA is not used, KMSAN doesn't know that the scatterlist
@@ -639,8 +644,12 @@ static inline int virtqueue_add_split(struct virtqueue *_vq,
639
644
dma_addr_t addr = vring_map_single (
640
645
vq , desc , total_sg * sizeof (struct vring_desc ),
641
646
DMA_TO_DEVICE );
642
- if (vring_mapping_error (vq , addr ))
647
+ if (vring_mapping_error (vq , addr )) {
648
+ if (vq -> premapped )
649
+ goto free_indirect ;
650
+
643
651
goto unmap_release ;
652
+ }
644
653
645
654
virtqueue_add_desc_split (_vq , vq -> split .vring .desc ,
646
655
head , addr ,
@@ -706,6 +715,7 @@ static inline int virtqueue_add_split(struct virtqueue *_vq,
706
715
i = vring_unmap_one_split (vq , i );
707
716
}
708
717
718
+ free_indirect :
709
719
if (indirect )
710
720
kfree (desc );
711
721
@@ -1307,8 +1317,12 @@ static int virtqueue_add_indirect_packed(struct vring_virtqueue *vq,
1307
1317
addr = vring_map_single (vq , desc ,
1308
1318
total_sg * sizeof (struct vring_packed_desc ),
1309
1319
DMA_TO_DEVICE );
1310
- if (vring_mapping_error (vq , addr ))
1320
+ if (vring_mapping_error (vq , addr )) {
1321
+ if (vq -> premapped )
1322
+ goto free_desc ;
1323
+
1311
1324
goto unmap_release ;
1325
+ }
1312
1326
1313
1327
vq -> packed .vring .desc [head ].addr = cpu_to_le64 (addr );
1314
1328
vq -> packed .vring .desc [head ].len = cpu_to_le32 (total_sg *
@@ -1366,6 +1380,7 @@ static int virtqueue_add_indirect_packed(struct vring_virtqueue *vq,
1366
1380
for (i = 0 ; i < err_idx ; i ++ )
1367
1381
vring_unmap_desc_packed (vq , & desc [i ]);
1368
1382
1383
+ free_desc :
1369
1384
kfree (desc );
1370
1385
1371
1386
END_USE (vq );
0 commit comments