Skip to content

Commit 710eb8e

Browse files
elic307imstsirkin
authored andcommitted
vdpa/mlx5: Fix memory key MTT population
map_direct_mr() assumed that the number of scatter/gather entries returned by dma_map_sg_attrs() was equal to the number of segments in the sgl list. This led to wrong population of the mkey object. Fix this by properly referring to the returned value. The hardware expects each MTT entry to contain the DMA address of a contiguous block of memory of size (1 << mr->log_size) bytes. dma_map_sg_attrs() can coalesce several sg entries into a single scatter/gather entry of contiguous DMA range so we need to scan the list and refer to the size of each s/g entry. In addition, get rid of fill_sg() which effect is overwritten by populate_mtts(). Fixes: 94abbcc ("vdpa/mlx5: Add shared memory registration code") Signed-off-by: Eli Cohen <elic@nvidia.com> Link: https://lore.kernel.org/r/20210107071845.GA224876@mtl-vdi-166.wap.labs.mlnx Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Acked-by: Jason Wang <jasowang@redhat.com>
1 parent 19c329f commit 710eb8e

File tree

2 files changed

+13
-16
lines changed

2 files changed

+13
-16
lines changed

drivers/vdpa/mlx5/core/mlx5_vdpa.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ struct mlx5_vdpa_direct_mr {
1515
struct sg_table sg_head;
1616
int log_size;
1717
int nsg;
18+
int nent;
1819
struct list_head list;
1920
u64 offset;
2021
};

drivers/vdpa/mlx5/core/mr.c

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,6 @@ static int get_octo_len(u64 len, int page_shift)
2525
return (npages + 1) / 2;
2626
}
2727

28-
static void fill_sg(struct mlx5_vdpa_direct_mr *mr, void *in)
29-
{
30-
struct scatterlist *sg;
31-
__be64 *pas;
32-
int i;
33-
34-
pas = MLX5_ADDR_OF(create_mkey_in, in, klm_pas_mtt);
35-
for_each_sg(mr->sg_head.sgl, sg, mr->nsg, i)
36-
(*pas) = cpu_to_be64(sg_dma_address(sg));
37-
}
38-
3928
static void mlx5_set_access_mode(void *mkc, int mode)
4029
{
4130
MLX5_SET(mkc, mkc, access_mode_1_0, mode & 0x3);
@@ -45,10 +34,18 @@ static void mlx5_set_access_mode(void *mkc, int mode)
4534
static void populate_mtts(struct mlx5_vdpa_direct_mr *mr, __be64 *mtt)
4635
{
4736
struct scatterlist *sg;
37+
int nsg = mr->nsg;
38+
u64 dma_addr;
39+
u64 dma_len;
40+
int j = 0;
4841
int i;
4942

50-
for_each_sg(mr->sg_head.sgl, sg, mr->nsg, i)
51-
mtt[i] = cpu_to_be64(sg_dma_address(sg));
43+
for_each_sg(mr->sg_head.sgl, sg, mr->nent, i) {
44+
for (dma_addr = sg_dma_address(sg), dma_len = sg_dma_len(sg);
45+
nsg && dma_len;
46+
nsg--, dma_addr += BIT(mr->log_size), dma_len -= BIT(mr->log_size))
47+
mtt[j++] = cpu_to_be64(dma_addr);
48+
}
5249
}
5350

5451
static int create_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr *mr)
@@ -64,7 +61,6 @@ static int create_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct
6461
return -ENOMEM;
6562

6663
MLX5_SET(create_mkey_in, in, uid, mvdev->res.uid);
67-
fill_sg(mr, in);
6864
mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry);
6965
MLX5_SET(mkc, mkc, lw, !!(mr->perm & VHOST_MAP_WO));
7066
MLX5_SET(mkc, mkc, lr, !!(mr->perm & VHOST_MAP_RO));
@@ -276,8 +272,8 @@ static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr
276272
done:
277273
mr->log_size = log_entity_size;
278274
mr->nsg = nsg;
279-
err = dma_map_sg_attrs(dma, mr->sg_head.sgl, mr->nsg, DMA_BIDIRECTIONAL, 0);
280-
if (!err)
275+
mr->nent = dma_map_sg_attrs(dma, mr->sg_head.sgl, mr->nsg, DMA_BIDIRECTIONAL, 0);
276+
if (!mr->nent)
281277
goto err_map;
282278

283279
err = create_direct_mr(mvdev, mr);

0 commit comments

Comments
 (0)