Skip to content

Commit 38fc462

Browse files
elic307imstsirkin
authored andcommitted
vdpa/mlx5: Avoid overwriting CVQ iotlb
When qemu uses different address spaces for data and control virtqueues, the current code would overwrite the control virtqueue iotlb through the dup_iotlb call. Fix this by referring to the address space identifier and the group to asid mapping to determine which mapping needs to be updated. We also move the address space logic from mlx5 net to core directory. Reported-by: Eugenio Pérez <[email protected]> Signed-off-by: Eli Cohen <[email protected]> Message-Id: <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]> Acked-by: Jason Wang <[email protected]> Acked-by: Eugenio Pérez <[email protected]>
1 parent 0dbc1b4 commit 38fc462

File tree

3 files changed

+39
-59
lines changed

3 files changed

+39
-59
lines changed

drivers/vdpa/mlx5/core/mlx5_vdpa.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,9 @@ int mlx5_vdpa_create_mkey(struct mlx5_vdpa_dev *mvdev, u32 *mkey, u32 *in,
116116
int inlen);
117117
int mlx5_vdpa_destroy_mkey(struct mlx5_vdpa_dev *mvdev, u32 mkey);
118118
int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
119-
bool *change_map);
120-
int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb);
119+
bool *change_map, unsigned int asid);
120+
int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
121+
unsigned int asid);
121122
void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev);
122123

123124
#define mlx5_vdpa_warn(__dev, format, ...) \

drivers/vdpa/mlx5/core/mr.c

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -511,50 +511,58 @@ void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
511511
mutex_unlock(&mr->mkey_mtx);
512512
}
513513

514-
static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb)
514+
static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
515+
struct vhost_iotlb *iotlb, unsigned int asid)
515516
{
516517
struct mlx5_vdpa_mr *mr = &mvdev->mr;
517518
int err;
518519

519520
if (mr->initialized)
520521
return 0;
521522

522-
if (iotlb)
523-
err = create_user_mr(mvdev, iotlb);
524-
else
525-
err = create_dma_mr(mvdev, mr);
523+
if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] == asid) {
524+
if (iotlb)
525+
err = create_user_mr(mvdev, iotlb);
526+
else
527+
err = create_dma_mr(mvdev, mr);
526528

527-
if (err)
528-
return err;
529+
if (err)
530+
return err;
531+
}
529532

530-
err = dup_iotlb(mvdev, iotlb);
531-
if (err)
532-
goto out_err;
533+
if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] == asid) {
534+
err = dup_iotlb(mvdev, iotlb);
535+
if (err)
536+
goto out_err;
537+
}
533538

534539
mr->initialized = true;
535540
return 0;
536541

537542
out_err:
538-
if (iotlb)
539-
destroy_user_mr(mvdev, mr);
540-
else
541-
destroy_dma_mr(mvdev, mr);
543+
if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] == asid) {
544+
if (iotlb)
545+
destroy_user_mr(mvdev, mr);
546+
else
547+
destroy_dma_mr(mvdev, mr);
548+
}
542549

543550
return err;
544551
}
545552

546-
int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb)
553+
int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
554+
unsigned int asid)
547555
{
548556
int err;
549557

550558
mutex_lock(&mvdev->mr.mkey_mtx);
551-
err = _mlx5_vdpa_create_mr(mvdev, iotlb);
559+
err = _mlx5_vdpa_create_mr(mvdev, iotlb, asid);
552560
mutex_unlock(&mvdev->mr.mkey_mtx);
553561
return err;
554562
}
555563

556564
int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
557-
bool *change_map)
565+
bool *change_map, unsigned int asid)
558566
{
559567
struct mlx5_vdpa_mr *mr = &mvdev->mr;
560568
int err = 0;
@@ -566,7 +574,7 @@ int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *io
566574
*change_map = true;
567575
}
568576
if (!*change_map)
569-
err = _mlx5_vdpa_create_mr(mvdev, iotlb);
577+
err = _mlx5_vdpa_create_mr(mvdev, iotlb, asid);
570578
mutex_unlock(&mr->mkey_mtx);
571579

572580
return err;

drivers/vdpa/mlx5/net/mlx5_vnet.c

Lines changed: 10 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,7 +2394,8 @@ static void restore_channels_info(struct mlx5_vdpa_net *ndev)
23942394
}
23952395
}
23962396

2397-
static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb)
2397+
static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev,
2398+
struct vhost_iotlb *iotlb, unsigned int asid)
23982399
{
23992400
struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
24002401
int err;
@@ -2406,7 +2407,7 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb
24062407

24072408
teardown_driver(ndev);
24082409
mlx5_vdpa_destroy_mr(mvdev);
2409-
err = mlx5_vdpa_create_mr(mvdev, iotlb);
2410+
err = mlx5_vdpa_create_mr(mvdev, iotlb, asid);
24102411
if (err)
24112412
goto err_mr;
24122413

@@ -2587,7 +2588,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev)
25872588
++mvdev->generation;
25882589

25892590
if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
2590-
if (mlx5_vdpa_create_mr(mvdev, NULL))
2591+
if (mlx5_vdpa_create_mr(mvdev, NULL, 0))
25912592
mlx5_vdpa_warn(mvdev, "create MR failed\n");
25922593
}
25932594
up_write(&ndev->reslock);
@@ -2623,41 +2624,20 @@ static u32 mlx5_vdpa_get_generation(struct vdpa_device *vdev)
26232624
return mvdev->generation;
26242625
}
26252626

2626-
static int set_map_control(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb)
2627-
{
2628-
u64 start = 0ULL, last = 0ULL - 1;
2629-
struct vhost_iotlb_map *map;
2630-
int err = 0;
2631-
2632-
spin_lock(&mvdev->cvq.iommu_lock);
2633-
vhost_iotlb_reset(mvdev->cvq.iotlb);
2634-
2635-
for (map = vhost_iotlb_itree_first(iotlb, start, last); map;
2636-
map = vhost_iotlb_itree_next(map, start, last)) {
2637-
err = vhost_iotlb_add_range(mvdev->cvq.iotlb, map->start,
2638-
map->last, map->addr, map->perm);
2639-
if (err)
2640-
goto out;
2641-
}
2642-
2643-
out:
2644-
spin_unlock(&mvdev->cvq.iommu_lock);
2645-
return err;
2646-
}
2647-
2648-
static int set_map_data(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb)
2627+
static int set_map_data(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
2628+
unsigned int asid)
26492629
{
26502630
bool change_map;
26512631
int err;
26522632

2653-
err = mlx5_vdpa_handle_set_map(mvdev, iotlb, &change_map);
2633+
err = mlx5_vdpa_handle_set_map(mvdev, iotlb, &change_map, asid);
26542634
if (err) {
26552635
mlx5_vdpa_warn(mvdev, "set map failed(%d)\n", err);
26562636
return err;
26572637
}
26582638

26592639
if (change_map)
2660-
err = mlx5_vdpa_change_map(mvdev, iotlb);
2640+
err = mlx5_vdpa_change_map(mvdev, iotlb, asid);
26612641

26622642
return err;
26632643
}
@@ -2670,16 +2650,7 @@ static int mlx5_vdpa_set_map(struct vdpa_device *vdev, unsigned int asid,
26702650
int err = -EINVAL;
26712651

26722652
down_write(&ndev->reslock);
2673-
if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] == asid) {
2674-
err = set_map_data(mvdev, iotlb);
2675-
if (err)
2676-
goto out;
2677-
}
2678-
2679-
if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] == asid)
2680-
err = set_map_control(mvdev, iotlb);
2681-
2682-
out:
2653+
err = set_map_data(mvdev, iotlb, asid);
26832654
up_write(&ndev->reslock);
26842655
return err;
26852656
}
@@ -3182,7 +3153,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name,
31823153
goto err_mpfs;
31833154

31843155
if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
3185-
err = mlx5_vdpa_create_mr(mvdev, NULL);
3156+
err = mlx5_vdpa_create_mr(mvdev, NULL, 0);
31863157
if (err)
31873158
goto err_res;
31883159
}

0 commit comments

Comments
 (0)