History

Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost

Pull virtio updates from Michael Tsirkin: "vhost,virtio,vdpa: features, fixes, cleanups. vdpa/mlx5: - VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK - new maintainer vdpa: - support for vq descriptor mappings - decouple reset of iotlb mapping from device reset and fixes, cleanups all over the place" * tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost: (34 commits) vdpa_sim: implement .reset_map support vdpa/mlx5: implement .reset_map driver op vhost-vdpa: clean iotlb map during reset for older userspace vdpa: introduce .compat_reset operation callback vhost-vdpa: introduce IOTLB_PERSIST backend feature bit vhost-vdpa: reset vendor specific mapping to initial state in .release vdpa: introduce .reset_map operation callback virtio_pci: add check for common cfg size virtio-blk: fix implicit overflow on virtio_max_dma_size virtio_pci: add build offset check for the new common cfg items virtio: add definition of VIRTIO_F_NOTIF_CONFIG_DATA feature bit vduse: make vduse_class constant vhost-scsi: Spelling s/preceeding/preceding/g virtio: kdoc for struct virtio_pci_modern_device vdpa: Update sysfs ABI documentation MAINTAINERS: Add myself as mlx5_vdpa driver virtio-balloon: correct the comment of virtballoon_migratepage() mlx5_vdpa: offer VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK vdpa/mlx5: Update cvq iotlb mapping on ASID change vdpa/mlx5: Make iotlb helper functions more generic ...

Linus Torvalds committed 3 years ago

Commit 77fa2fb2 parents 1cfb751 86f6c2222 files · +544 −184Browse files

Unified · Split

22 files
  1. Documentation/ABI/testing/sysfs-bus-vdpa +2 −2
  2. MAINTAINERS +6 −0
  3. drivers/block/virtio_blk.c +3 −1
  4. drivers/vdpa/mlx5/core/mlx5_vdpa.h +20 −12
  5. drivers/vdpa/mlx5/core/mr.c +126 −83
  6. drivers/vdpa/mlx5/core/resources.c +3 −3
  7. drivers/vdpa/mlx5/net/mlx5_vnet.c +106 −31
  8. drivers/vdpa/vdpa_sim/vdpa_sim.c +43 −9
  9. drivers/vdpa/vdpa_user/vduse_dev.c +21 −19
  10. drivers/vhost/scsi.c +1 −1
  11. drivers/vhost/vdpa.c +75 −4
  12. drivers/virtio/virtio_balloon.c +1 −1
  13. drivers/virtio/virtio_pci_modern.c +36 −0
  14. drivers/virtio/virtio_pci_modern_dev.c +5 −1
  15. drivers/virtio/virtio_vdpa.c +1 −1
  16. include/linux/mlx5/mlx5_ifc.h +7 −1
  17. include/linux/mlx5/mlx5_ifc_vdpa.h +6 −1
  18. include/linux/vdpa.h +39 −2
  19. include/linux/virtio_pci_modern.h +23 −12
  20. include/uapi/linux/vhost.h +8 −0
  21. include/uapi/linux/vhost_types.h +7 −0
  22. include/uapi/linux/virtio_config.h +5 −0
Documentation/ABI/testing/sysfs-bus-vdpa+2−2
@@ -1,4 +1,4 @@
1−What: /sys/bus/vdpa/driver_autoprobe
1+What: /sys/bus/vdpa/drivers_autoprobe
22 Date: March 2020
33 Contact: virtualization@lists.linux-foundation.org
44 Description:
@@ -17,7 +17,7 @@ Description: · 12 unmodified lines
1717 Writing a device name to this file will cause the kernel binds
1818 devices to a compatible driver.
1919
20− This can be useful when /sys/bus/vdpa/driver_autoprobe is
20+ This can be useful when /sys/bus/vdpa/drivers_autoprobe is
2121 disabled.
2222
2323 What: /sys/bus/vdpa/drivers/.../bind
MAINTAINERS+6−0
@@ -13790,6 +13790,12 @@ F: drivers/infiniband/hw/mlx5/ · 13789 unmodified lines
1379013790 F: include/linux/mlx5/
1379113791 F: include/uapi/rdma/mlx5-abi.h
1379213792
13793+MELLANOX MLX5 VDPA DRIVER
13794+M: Dragos Tatulea <dtatulea@nvidia.com>
13795+L: virtualization@lists.linux-foundation.org
13796+S: Supported
13797+F: drivers/vdpa/mlx5/
13798+
1379313799 MELLANOX MLXCPLD I2C AND MUX DRIVER
1379413800 M: Vadim Pasternak <vadimp@nvidia.com>
1379513801 M: Michael Shych <michaelsh@nvidia.com>
drivers/block/virtio_blk.c+3−1
@@ -1311,6 +1311,7 @@ static int virtblk_probe(struct virtio_device *vdev) · 1310 unmodified lines
13111311 u16 min_io_size;
13121312 u8 physical_block_exp, alignment_offset;
13131313 unsigned int queue_depth;
1314+ size_t max_dma_size;
13141315
13151316 if (!vdev->config->get) {
13161317 dev_err(&vdev->dev, "%s failure: config access disabled\n",
@@ -1409,7 +1410,8 @@ static int virtblk_probe(struct virtio_device *vdev) · 92 unmodified lines
14091410 /* No real sector limit. */
14101411 blk_queue_max_hw_sectors(q, UINT_MAX);
14111412
1412− max_size = virtio_max_dma_size(vdev);
1413+ max_dma_size = virtio_max_dma_size(vdev);
1414+ max_size = max_dma_size > U32_MAX ? U32_MAX : max_dma_size;
14131415
14141416 /* Host can optionally specify maximum segment size and number of
14151417 * segments. */
drivers/vdpa/mlx5/core/mlx5_vdpa.h+20−12
@@ -31,11 +31,9 @@ struct mlx5_vdpa_mr { · 30 unmodified lines
3131 struct list_head head;
3232 unsigned long num_directs;
3333 unsigned long num_klms;
34− /* state of dvq mr */
35− bool initialized;
3634
37− /* serialize mkey creation and destruction */
38− struct mutex mkey_mtx;
35+ struct vhost_iotlb *iotlb;
36+
3937 bool user_mr;
4038 };
4139
@@ -74,11 +72,12 @@ struct mlx5_vdpa_wq_ent { · 32 unmodified lines
7472 enum {
7573 MLX5_VDPA_DATAVQ_GROUP,
7674 MLX5_VDPA_CVQ_GROUP,
75+ MLX5_VDPA_DATAVQ_DESC_GROUP,
7776 MLX5_VDPA_NUMVQ_GROUPS
7877 };
7978
8079 enum {
81− MLX5_VDPA_NUM_AS = MLX5_VDPA_NUMVQ_GROUPS
80+ MLX5_VDPA_NUM_AS = 2
8281 };
8382
8483 struct mlx5_vdpa_dev {
@@ -93,7 +92,9 @@ struct mlx5_vdpa_dev { · 8 unmodified lines
9392 u16 max_idx;
9493 u32 generation;
9594
96− struct mlx5_vdpa_mr mr;
95+ struct mlx5_vdpa_mr *mr[MLX5_VDPA_NUM_AS];
96+ /* serialize mr access */
97+ struct mutex mr_mtx;
9798 struct mlx5_control_vq cvq;
9899 struct workqueue_struct *wq;
99100 unsigned int group2asid[MLX5_VDPA_NUMVQ_GROUPS];
@@ -114,12 +115,19 @@ void mlx5_vdpa_free_resources(struct mlx5_vdpa_dev *mvdev); · 14 unmodified lines
114115 int mlx5_vdpa_create_mkey(struct mlx5_vdpa_dev *mvdev, u32 *mkey, u32 *in,
115116 int inlen);
116117 int mlx5_vdpa_destroy_mkey(struct mlx5_vdpa_dev *mvdev, u32 mkey);
117−int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
118− bool *change_map, unsigned int asid);
119−int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
120− unsigned int asid);
121−void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev);
122−void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
118+struct mlx5_vdpa_mr *mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
119+ struct vhost_iotlb *iotlb);
120+void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev);
121+void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
122+ struct mlx5_vdpa_mr *mr);
123+void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
124+ struct mlx5_vdpa_mr *mr,
125+ unsigned int asid);
126+int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
127+ struct vhost_iotlb *iotlb,
128+ unsigned int asid);
129+int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev);
130+int mlx5_vdpa_reset_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
123131
124132 #define mlx5_vdpa_warn(__dev, format, ...) \
125133 dev_warn((__dev)->mdev->device, "%s:%d:(pid %d) warning: " format, __func__, __LINE__, \
drivers/vdpa/mlx5/core/mr.c+126−83
@@ -301,10 +301,13 @@ static void unmap_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct · 300 unmodified lines
301301 sg_free_table(&mr->sg_head);
302302 }
303303
304−static int add_direct_chain(struct mlx5_vdpa_dev *mvdev, u64 start, u64 size, u8 perm,
304+static int add_direct_chain(struct mlx5_vdpa_dev *mvdev,
305+ struct mlx5_vdpa_mr *mr,
306+ u64 start,
307+ u64 size,
308+ u8 perm,
305309 struct vhost_iotlb *iotlb)
306310 {
307− struct mlx5_vdpa_mr *mr = &mvdev->mr;
308311 struct mlx5_vdpa_direct_mr *dmr;
309312 struct mlx5_vdpa_direct_mr *n;
310313 LIST_HEAD(tmp);
@@ -354,9 +357,10 @@ err_alloc: · 43 unmodified lines
354357 * indirect memory key that provides access to the enitre address space given
355358 * by iotlb.
356359 */
357−static int create_user_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb)
360+static int create_user_mr(struct mlx5_vdpa_dev *mvdev,
361+ struct mlx5_vdpa_mr *mr,
362+ struct vhost_iotlb *iotlb)
358363 {
359− struct mlx5_vdpa_mr *mr = &mvdev->mr;
360364 struct mlx5_vdpa_direct_mr *dmr;
361365 struct mlx5_vdpa_direct_mr *n;
362366 struct vhost_iotlb_map *map;
@@ -384,7 +388,7 @@ static int create_user_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb · 21 unmodified lines
384388 LOG_MAX_KLM_SIZE);
385389 mr->num_klms += nnuls;
386390 }
387− err = add_direct_chain(mvdev, ps, pe - ps, pperm, iotlb);
391+ err = add_direct_chain(mvdev, mr, ps, pe - ps, pperm, iotlb);
388392 if (err)
389393 goto err_chain;
390394 }
@@ -393,7 +397,7 @@ static int create_user_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb · 2 unmodified lines
393397 pperm = map->perm;
394398 }
395399 }
396− err = add_direct_chain(mvdev, ps, pe - ps, pperm, iotlb);
400+ err = add_direct_chain(mvdev, mr, ps, pe - ps, pperm, iotlb);
397401 if (err)
398402 goto err_chain;
399403
@@ -450,20 +454,23 @@ static void destroy_dma_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr *mr) · 50 unmodified lines
450454 mlx5_vdpa_destroy_mkey(mvdev, mr->mkey);
451455 }
452456
453−static int dup_iotlb(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *src)
457+static int dup_iotlb(struct vhost_iotlb *dst, struct vhost_iotlb *src)
454458 {
455459 struct vhost_iotlb_map *map;
456460 u64 start = 0, last = ULLONG_MAX;
457461 int err;
458462
463+ if (dst == src)
464+ return -EINVAL;
465+
459466 if (!src) {
460− err = vhost_iotlb_add_range(mvdev->cvq.iotlb, start, last, start, VHOST_ACCESS_RW);
467+ err = vhost_iotlb_add_range(dst, start, last, start, VHOST_ACCESS_RW);
461468 return err;
462469 }
463470
464471 for (map = vhost_iotlb_itree_first(src, start, last); map;
465472 map = vhost_iotlb_itree_next(map, start, last)) {
466− err = vhost_iotlb_add_range(mvdev->cvq.iotlb, map->start, map->last,
473+ err = vhost_iotlb_add_range(dst, map->start, map->last,
467474 map->addr, map->perm);
468475 if (err)
469476 return err;
@@ -471,9 +478,9 @@ static int dup_iotlb(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *src) · 1 unmodified line
471478 return 0;
472479 }
473480
474−static void prune_iotlb(struct mlx5_vdpa_dev *mvdev)
481+static void prune_iotlb(struct vhost_iotlb *iotlb)
475482 {
476− vhost_iotlb_del_range(mvdev->cvq.iotlb, 0, ULLONG_MAX);
483+ vhost_iotlb_del_range(iotlb, 0, ULLONG_MAX);
477484 }
478485
479486 static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr *mr)
@@ -489,133 +496,169 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr *mr · 9 unmodified lines
489496 }
490497 }
491498
492−static void _mlx5_vdpa_destroy_cvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid)
499+static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr *mr)
493500 {
494− if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
495− return;
501+ if (mr->user_mr)
502+ destroy_user_mr(mvdev, mr);
503+ else
504+ destroy_dma_mr(mvdev, mr);
496505
497− prune_iotlb(mvdev);
506+ vhost_iotlb_free(mr->iotlb);
498507 }
499508
500−static void _mlx5_vdpa_destroy_dvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid)
509+void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
510+ struct mlx5_vdpa_mr *mr)
501511 {
502− struct mlx5_vdpa_mr *mr = &mvdev->mr;
503−
504− if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid)
512+ if (!mr)
505513 return;
506514
507− if (!mr->initialized)
508− return;
515+ mutex_lock(&mvdev->mr_mtx);
509516
510− if (mr->user_mr)
511− destroy_user_mr(mvdev, mr);
512− else
513− destroy_dma_mr(mvdev, mr);
517+ _mlx5_vdpa_destroy_mr(mvdev, mr);
518+
519+ for (int i = 0; i < MLX5_VDPA_NUM_AS; i++) {
520+ if (mvdev->mr[i] == mr)
521+ mvdev->mr[i] = NULL;
522+ }
514523
515− mr->initialized = false;
524+ mutex_unlock(&mvdev->mr_mtx);
525+
526+ kfree(mr);
516527 }
517528
518−void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid)
529+void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
530+ struct mlx5_vdpa_mr *new_mr,
531+ unsigned int asid)
519532 {
520− struct mlx5_vdpa_mr *mr = &mvdev->mr;
533+ struct mlx5_vdpa_mr *old_mr = mvdev->mr[asid];
521534
522− mutex_lock(&mr->mkey_mtx);
535+ mutex_lock(&mvdev->mr_mtx);
523536
524− _mlx5_vdpa_destroy_dvq_mr(mvdev, asid);
525− _mlx5_vdpa_destroy_cvq_mr(mvdev, asid);
537+ mvdev->mr[asid] = new_mr;
538+ if (old_mr) {
539+ _mlx5_vdpa_destroy_mr(mvdev, old_mr);
540+ kfree(old_mr);
541+ }
526542
527− mutex_unlock(&mr->mkey_mtx);
528−}
543+ mutex_unlock(&mvdev->mr_mtx);
529544
530−void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
531−{
532− mlx5_vdpa_destroy_mr_asid(mvdev, mvdev->group2asid[MLX5_VDPA_CVQ_GROUP]);
533− mlx5_vdpa_destroy_mr_asid(mvdev, mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]);
534545 }
535546
536−static int _mlx5_vdpa_create_cvq_mr(struct mlx5_vdpa_dev *mvdev,
537− struct vhost_iotlb *iotlb,
538− unsigned int asid)
547+void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev)
539548 {
540− if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
541− return 0;
549+ for (int i = 0; i < MLX5_VDPA_NUM_AS; i++)
550+ mlx5_vdpa_destroy_mr(mvdev, mvdev->mr[i]);
542551
543− return dup_iotlb(mvdev, iotlb);
552+ prune_iotlb(mvdev->cvq.iotlb);
544553 }
545554
546−static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev *mvdev,
547− struct vhost_iotlb *iotlb,
548− unsigned int asid)
555+static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
556+ struct mlx5_vdpa_mr *mr,
557+ struct vhost_iotlb *iotlb)
549558 {
550− struct mlx5_vdpa_mr *mr = &mvdev->mr;
551559 int err;
552560
553− if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid)
554− return 0;
555−
556− if (mr->initialized)
557− return 0;
558−
559561 if (iotlb)
560− err = create_user_mr(mvdev, iotlb);
562+ err = create_user_mr(mvdev, mr, iotlb);
561563 else
562564 err = create_dma_mr(mvdev, mr);
563565
564566 if (err)
565567 return err;
566568
567− mr->initialized = true;
569+ mr->iotlb = vhost_iotlb_alloc(0, 0);
570+ if (!mr->iotlb) {
571+ err = -ENOMEM;
572+ goto err_mr;
573+ }
574+
575+ err = dup_iotlb(mr->iotlb, iotlb);
576+ if (err)
577+ goto err_iotlb;
568578
569579 return 0;
580+
581+err_iotlb:
582+ vhost_iotlb_free(mr->iotlb);
583+
584+err_mr:
585+ if (iotlb)
586+ destroy_user_mr(mvdev, mr);
587+ else
588+ destroy_dma_mr(mvdev, mr);
589+
590+ return err;
570591 }
571592
572−static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
573− struct vhost_iotlb *iotlb, unsigned int asid)
593+struct mlx5_vdpa_mr *mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
594+ struct vhost_iotlb *iotlb)
574595 {
596+ struct mlx5_vdpa_mr *mr;
575597 int err;
576598
577− err = _mlx5_vdpa_create_dvq_mr(mvdev, iotlb, asid);
578− if (err)
579− return err;
599+ mr = kzalloc(sizeof(*mr), GFP_KERNEL);
600+ if (!mr)
601+ return ERR_PTR(-ENOMEM);
602+
603+ mutex_lock(&mvdev->mr_mtx);
604+ err = _mlx5_vdpa_create_mr(mvdev, mr, iotlb);
605+ mutex_unlock(&mvdev->mr_mtx);
580606
581− err = _mlx5_vdpa_create_cvq_mr(mvdev, iotlb, asid);
582607 if (err)
583608 goto out_err;
584609
585− return 0;
610+ return mr;
586611
587612 out_err:
588− _mlx5_vdpa_destroy_dvq_mr(mvdev, asid);
589−
590− return err;
613+ kfree(mr);
614+ return ERR_PTR(err);
591615 }
592616
593−int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
594− unsigned int asid)
617+int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
618+ struct vhost_iotlb *iotlb,
619+ unsigned int asid)
595620 {
596621 int err;
597622
598− mutex_lock(&mvdev->mr.mkey_mtx);
599− err = _mlx5_vdpa_create_mr(mvdev, iotlb, asid);
600− mutex_unlock(&mvdev->mr.mkey_mtx);
623+ if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
624+ return 0;
625+
626+ spin_lock(&mvdev->cvq.iommu_lock);
627+
628+ prune_iotlb(mvdev->cvq.iotlb);
629+ err = dup_iotlb(mvdev->cvq.iotlb, iotlb);
630+
631+ spin_unlock(&mvdev->cvq.iommu_lock);
632+
601633 return err;
602634 }
603635
604−int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
605− bool *change_map, unsigned int asid)
636+int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev)
606637 {
607− struct mlx5_vdpa_mr *mr = &mvdev->mr;
608− int err = 0;
638+ struct mlx5_vdpa_mr *mr;
639+
640+ mr = mlx5_vdpa_create_mr(mvdev, NULL);
641+ if (IS_ERR(mr))
642+ return PTR_ERR(mr);
609643
610− *change_map = false;
611− mutex_lock(&mr->mkey_mtx);
612− if (mr->initialized) {
613− mlx5_vdpa_info(mvdev, "memory map update\n");
614− *change_map = true;
644+ mlx5_vdpa_update_mr(mvdev, mr, 0);
645+
646+ return mlx5_vdpa_update_cvq_iotlb(mvdev, NULL, 0);
647+}
648+
649+int mlx5_vdpa_reset_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid)
650+{
651+ if (asid >= MLX5_VDPA_NUM_AS)
652+ return -EINVAL;
653+
654+ mlx5_vdpa_destroy_mr(mvdev, mvdev->mr[asid]);
655+
656+ if (asid == 0 && MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
657+ if (mlx5_vdpa_create_dma_mr(mvdev))
658+ mlx5_vdpa_warn(mvdev, "create DMA MR failed\n");
659+ } else {
660+ mlx5_vdpa_update_cvq_iotlb(mvdev, NULL, asid);
615661 }
616− if (!*change_map)
617− err = _mlx5_vdpa_create_mr(mvdev, iotlb, asid);
618− mutex_unlock(&mr->mkey_mtx);
619662
620− return err;
663+ return 0;
621664 }
drivers/vdpa/mlx5/core/resources.c+3−3
@@ -256,7 +256,7 @@ int mlx5_vdpa_alloc_resources(struct mlx5_vdpa_dev *mvdev) · 255 unmodified lines
256256 mlx5_vdpa_warn(mvdev, "resources already allocated\n");
257257 return -EINVAL;
258258 }
259− mutex_init(&mvdev->mr.mkey_mtx);
259+ mutex_init(&mvdev->mr_mtx);
260260 res->uar = mlx5_get_uars_page(mdev);
261261 if (IS_ERR(res->uar)) {
262262 err = PTR_ERR(res->uar);
@@ -301,7 +301,7 @@ err_pd: · 38 unmodified lines
301301 err_uctx:
302302 mlx5_put_uars_page(mdev, res->uar);
303303 err_uars:
304− mutex_destroy(&mvdev->mr.mkey_mtx);
304+ mutex_destroy(&mvdev->mr_mtx);
305305 return err;
306306 }
307307
@@ -318,6 +318,6 @@ void mlx5_vdpa_free_resources(struct mlx5_vdpa_dev *mvdev) · 10 unmodified lines
318318 dealloc_pd(mvdev, res->pdn, res->uid);
319319 destroy_uctx(mvdev, res->uid);
320320 mlx5_put_uars_page(mvdev->mdev, res->uar);
321− mutex_destroy(&mvdev->mr.mkey_mtx);
321+ mutex_destroy(&mvdev->mr_mtx);
322322 res->valid = false;
323323 }
drivers/vdpa/mlx5/net/mlx5_vnet.c+106−31
@@ -7,6 +7,7 @@ · 6 unmodified lines
77 #include <uapi/linux/virtio_net.h>
88 #include <uapi/linux/virtio_ids.h>
99 #include <uapi/linux/vdpa.h>
10+#include <uapi/linux/vhost_types.h>
1011 #include <linux/virtio_config.h>
1112 #include <linux/auxiliary_bus.h>
1213 #include <linux/mlx5/cq.h>
@@ -861,6 +862,9 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque · 848 unmodified lines
861862 {
862863 int inlen = MLX5_ST_SZ_BYTES(create_virtio_net_q_in);
863864 u32 out[MLX5_ST_SZ_DW(create_virtio_net_q_out)] = {};
865+ struct mlx5_vdpa_dev *mvdev = &ndev->mvdev;
866+ struct mlx5_vdpa_mr *vq_mr;
867+ struct mlx5_vdpa_mr *vq_desc_mr;
864868 void *obj_context;
865869 u16 mlx_features;
866870 void *cmd_hdr;
@@ -913,7 +917,14 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque · 46 unmodified lines
913917 MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr);
914918 MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr);
915919 MLX5_SET64(virtio_q, vq_ctx, available_addr, mvq->driver_addr);
916− MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, ndev->mvdev.mr.mkey);
920+ vq_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]];
921+ if (vq_mr)
922+ MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, vq_mr->mkey);
923+
924+ vq_desc_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_DESC_GROUP]];
925+ if (vq_desc_mr && MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, desc_group_mkey_supported))
926+ MLX5_SET(virtio_q, vq_ctx, desc_group_mkey, vq_desc_mr->mkey);
927+
917928 MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id);
918929 MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size);
919930 MLX5_SET(virtio_q, vq_ctx, umem_2_id, mvq->umem2.id);
@@ -2301,6 +2312,16 @@ static u32 mlx5_vdpa_get_vq_group(struct vdpa_device *vdev, u16 idx) · 1381 unmodified lines
23012312 return MLX5_VDPA_DATAVQ_GROUP;
23022313 }
23032314
2315+static u32 mlx5_vdpa_get_vq_desc_group(struct vdpa_device *vdev, u16 idx)
2316+{
2317+ struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
2318+
2319+ if (is_ctrl_vq_idx(mvdev, idx))
2320+ return MLX5_VDPA_CVQ_GROUP;
2321+
2322+ return MLX5_VDPA_DATAVQ_DESC_GROUP;
2323+}
2324+
23042325 static u64 mlx_to_vritio_features(u16 dev_features)
23052326 {
23062327 u64 result = 0;
@@ -2539,6 +2560,11 @@ static void unregister_link_notifier(struct mlx5_vdpa_net *ndev) · 232 unmodified lines
25392560 flush_workqueue(ndev->mvdev.wq);
25402561 }
25412562
2563+static u64 mlx5_vdpa_get_backend_features(const struct vdpa_device *vdpa)
2564+{
2565+ return BIT_ULL(VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK);
2566+}
2567+
25422568 static int mlx5_vdpa_set_driver_features(struct vdpa_device *vdev, u64 features)
25432569 {
25442570 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
@@ -2673,7 +2699,8 @@ static void restore_channels_info(struct mlx5_vdpa_net *ndev) · 128 unmodified lines
26732699 }
26742700
26752701 static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev,
2676− struct vhost_iotlb *iotlb, unsigned int asid)
2702+ struct mlx5_vdpa_mr *new_mr,
2703+ unsigned int asid)
26772704 {
26782705 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
26792706 int err;
@@ -2681,28 +2708,21 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev, · 1 unmodified line
26812708 suspend_vqs(ndev);
26822709 err = save_channels_info(ndev);
26832710 if (err)
2684− goto err_mr;
2711+ return err;
26852712
26862713 teardown_driver(ndev);
2687− mlx5_vdpa_destroy_mr_asid(mvdev, asid);
2688− err = mlx5_vdpa_create_mr(mvdev, iotlb, asid);
2689− if (err)
2690− goto err_mr;
2714+
2715+ mlx5_vdpa_update_mr(mvdev, new_mr, asid);
26912716
26922717 if (!(mvdev->status & VIRTIO_CONFIG_S_DRIVER_OK) || mvdev->suspended)
2693− goto err_mr;
2718+ return 0;
26942719
26952720 restore_channels_info(ndev);
26962721 err = setup_driver(mvdev);
26972722 if (err)
2698− goto err_setup;
2723+ return err;
26992724
27002725 return 0;
2701−
2702−err_setup:
2703− mlx5_vdpa_destroy_mr_asid(mvdev, asid);
2704−err_mr:
2705− return err;
27062726 }
27072727
27082728 /* reslock must be held for this function */
@@ -2841,7 +2861,7 @@ static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status) · 132 unmodified lines
28412861 err_driver:
28422862 unregister_link_notifier(ndev);
28432863 err_setup:
2844− mlx5_vdpa_destroy_mr(&ndev->mvdev);
2864+ mlx5_vdpa_destroy_mr_resources(&ndev->mvdev);
28452865 ndev->mvdev.status |= VIRTIO_CONFIG_S_FAILED;
28462866 err_clear:
28472867 up_write(&ndev->reslock);
@@ -2856,7 +2876,7 @@ static void init_group_to_asid_map(struct mlx5_vdpa_dev *mvdev) · 8 unmodified lines
28562876 mvdev->group2asid[i] = 0;
28572877 }
28582878
2859−static int mlx5_vdpa_reset(struct vdpa_device *vdev)
2879+static int mlx5_vdpa_compat_reset(struct vdpa_device *vdev, u32 flags)
28602880 {
28612881 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
28622882 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
@@ -2868,7 +2888,8 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev) · 5 unmodified lines
28682888 unregister_link_notifier(ndev);
28692889 teardown_driver(ndev);
28702890 clear_vqs_ready(ndev);
2871− mlx5_vdpa_destroy_mr(&ndev->mvdev);
2891+ if (flags & VDPA_RESET_F_CLEAN_MAP)
2892+ mlx5_vdpa_destroy_mr_resources(&ndev->mvdev);
28722893 ndev->mvdev.status = 0;
28732894 ndev->mvdev.suspended = false;
28742895 ndev->cur_num_vqs = 0;
@@ -2879,8 +2900,9 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev) · 4 unmodified lines
28792900 init_group_to_asid_map(mvdev);
28802901 ++mvdev->generation;
28812902
2882− if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
2883− if (mlx5_vdpa_create_mr(mvdev, NULL, 0))
2903+ if ((flags & VDPA_RESET_F_CLEAN_MAP) &&
2904+ MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
2905+ if (mlx5_vdpa_create_dma_mr(mvdev))
28842906 mlx5_vdpa_warn(mvdev, "create MR failed\n");
28852907 }
28862908 up_write(&ndev->reslock);
@@ -2888,6 +2910,11 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev) · 1 unmodified line
28882910 return 0;
28892911 }
28902912
2913+static int mlx5_vdpa_reset(struct vdpa_device *vdev)
2914+{
2915+ return mlx5_vdpa_compat_reset(vdev, 0);
2916+}
2917+
28912918 static size_t mlx5_vdpa_get_config_size(struct vdpa_device *vdev)
28922919 {
28932920 return sizeof(struct virtio_net_config);
@@ -2919,18 +2946,38 @@ static u32 mlx5_vdpa_get_generation(struct vdpa_device *vdev) · 25 unmodified lines
29192946 static int set_map_data(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
29202947 unsigned int asid)
29212948 {
2922− bool change_map;
2949+ struct mlx5_vdpa_mr *new_mr;
29232950 int err;
29242951
2925− err = mlx5_vdpa_handle_set_map(mvdev, iotlb, &change_map, asid);
2926− if (err) {
2927− mlx5_vdpa_warn(mvdev, "set map failed(%d)\n", err);
2928− return err;
2952+ if (asid >= MLX5_VDPA_NUM_AS)
2953+ return -EINVAL;
2954+
2955+ if (vhost_iotlb_itree_first(iotlb, 0, U64_MAX)) {
2956+ new_mr = mlx5_vdpa_create_mr(mvdev, iotlb);
2957+ if (IS_ERR(new_mr)) {
2958+ err = PTR_ERR(new_mr);
2959+ mlx5_vdpa_warn(mvdev, "create map failed(%d)\n", err);
2960+ return err;
2961+ }
2962+ } else {
2963+ /* Empty iotlbs don't have an mr but will clear the previous mr. */
2964+ new_mr = NULL;
2965+ }
2966+
2967+ if (!mvdev->mr[asid]) {
2968+ mlx5_vdpa_update_mr(mvdev, new_mr, asid);
2969+ } else {
2970+ err = mlx5_vdpa_change_map(mvdev, new_mr, asid);
2971+ if (err) {
2972+ mlx5_vdpa_warn(mvdev, "change map failed(%d)\n", err);
2973+ goto out_err;
2974+ }
29292975 }
29302976
2931− if (change_map)
2932− err = mlx5_vdpa_change_map(mvdev, iotlb, asid);
2977+ return mlx5_vdpa_update_cvq_iotlb(mvdev, iotlb, asid);
29332978
2979+out_err:
2980+ mlx5_vdpa_destroy_mr(mvdev, new_mr);
29342981 return err;
29352982 }
29362983
@@ -2947,6 +2994,18 @@ static int mlx5_vdpa_set_map(struct vdpa_device *vdev, unsigned int asid, · 10 unmodified lines
29472994 return err;
29482995 }
29492996
2997+static int mlx5_vdpa_reset_map(struct vdpa_device *vdev, unsigned int asid)
2998+{
2999+ struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
3000+ struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
3001+ int err;
3002+
3003+ down_write(&ndev->reslock);
3004+ err = mlx5_vdpa_reset_mr(mvdev, asid);
3005+ up_write(&ndev->reslock);
3006+ return err;
3007+}
3008+
29503009 static struct device *mlx5_get_vq_dma_dev(struct vdpa_device *vdev, u16 idx)
29513010 {
29523011 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
@@ -2985,7 +3044,7 @@ static void mlx5_vdpa_free(struct vdpa_device *vdev) · 32 unmodified lines
29853044 ndev = to_mlx5_vdpa_ndev(mvdev);
29863045
29873046 free_resources(ndev);
2988− mlx5_vdpa_destroy_mr(mvdev);
3047+ mlx5_vdpa_destroy_mr_resources(mvdev);
29893048 if (!is_zero_ether_addr(ndev->config.mac)) {
29903049 pfmdev = pci_get_drvdata(pci_physfn(mvdev->mdev->pdev));
29913050 mlx5_mpfs_del_mac(pfmdev, ndev->config.mac);
@@ -3169,12 +3228,19 @@ static int mlx5_set_group_asid(struct vdpa_device *vdev, u32 group, · 177 unmodified lines
31693228 unsigned int asid)
31703229 {
31713230 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
3231+ int err = 0;
31723232
31733233 if (group >= MLX5_VDPA_NUMVQ_GROUPS)
31743234 return -EINVAL;
31753235
31763236 mvdev->group2asid[group] = asid;
3177− return 0;
3237+
3238+ mutex_lock(&mvdev->mr_mtx);
3239+ if (group == MLX5_VDPA_CVQ_GROUP && mvdev->mr[asid])
3240+ err = mlx5_vdpa_update_cvq_iotlb(mvdev, mvdev->mr[asid]->iotlb, asid);
3241+ mutex_unlock(&mvdev->mr_mtx);
3242+
3243+ return err;
31783244 }
31793245
31803246 static const struct vdpa_config_ops mlx5_vdpa_ops = {
@@ -3191,7 +3257,9 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = { · 10 unmodified lines
31913257 .get_vq_irq = mlx5_get_vq_irq,
31923258 .get_vq_align = mlx5_vdpa_get_vq_align,
31933259 .get_vq_group = mlx5_vdpa_get_vq_group,
3260+ .get_vq_desc_group = mlx5_vdpa_get_vq_desc_group, /* Op disabled if not supported. */
31943261 .get_device_features = mlx5_vdpa_get_device_features,
3262+ .get_backend_features = mlx5_vdpa_get_backend_features,
31953263 .set_driver_features = mlx5_vdpa_set_driver_features,
31963264 .get_driver_features = mlx5_vdpa_get_driver_features,
31973265 .set_config_cb = mlx5_vdpa_set_config_cb,
@@ -3201,11 +3269,13 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = { · 3 unmodified lines
32013269 .get_status = mlx5_vdpa_get_status,
32023270 .set_status = mlx5_vdpa_set_status,
32033271 .reset = mlx5_vdpa_reset,
3272+ .compat_reset = mlx5_vdpa_compat_reset,
32043273 .get_config_size = mlx5_vdpa_get_config_size,
32053274 .get_config = mlx5_vdpa_get_config,
32063275 .set_config = mlx5_vdpa_set_config,
32073276 .get_generation = mlx5_vdpa_get_generation,
32083277 .set_map = mlx5_vdpa_set_map,
3278+ .reset_map = mlx5_vdpa_reset_map,
32093279 .set_group_asid = mlx5_set_group_asid,
32103280 .get_vq_dma_dev = mlx5_get_vq_dma_dev,
32113281 .free = mlx5_vdpa_free,
@@ -3289,6 +3359,7 @@ struct mlx5_vdpa_mgmtdev { · 77 unmodified lines
32893359 struct vdpa_mgmt_dev mgtdev;
32903360 struct mlx5_adev *madev;
32913361 struct mlx5_vdpa_net *ndev;
3362+ struct vdpa_config_ops vdpa_ops;
32923363 };
32933364
32943365 static int config_func_mtu(struct mlx5_core_dev *mdev, u16 mtu)
@@ -3402,7 +3473,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, · 107 unmodified lines
34023473 max_vqs = 2;
34033474 }
34043475
3405− ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mlx5_vdpa_ops,
3476+ ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mgtdev->vdpa_ops,
34063477 MLX5_VDPA_NUMVQ_GROUPS, MLX5_VDPA_NUM_AS, name, false);
34073478 if (IS_ERR(ndev))
34083479 return PTR_ERR(ndev);
@@ -3485,7 +3556,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, · 76 unmodified lines
34853556 goto err_mpfs;
34863557
34873558 if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
3488− err = mlx5_vdpa_create_mr(mvdev, NULL, 0);
3559+ err = mlx5_vdpa_create_dma_mr(mvdev);
34893560 if (err)
34903561 goto err_res;
34913562 }
@@ -3515,7 +3586,7 @@ err_reg: · 23 unmodified lines
35153586 err_res2:
35163587 free_resources(ndev);
35173588 err_mr:
3518− mlx5_vdpa_destroy_mr(mvdev);
3589+ mlx5_vdpa_destroy_mr_resources(mvdev);
35193590 err_res:
35203591 mlx5_vdpa_free_resources(&ndev->mvdev);
35213592 err_mpfs:
@@ -3575,6 +3646,10 @@ static int mlx5v_probe(struct auxiliary_device *adev, · 53 unmodified lines
35753646 MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues) + 1;
35763647 mgtdev->mgtdev.supported_features = get_supported_features(mdev);
35773648 mgtdev->madev = madev;
3649+ mgtdev->vdpa_ops = mlx5_vdpa_ops;
3650+
3651+ if (!MLX5_CAP_DEV_VDPA_EMULATION(mdev, desc_group_mkey_supported))
3652+ mgtdev->vdpa_ops.get_vq_desc_group = NULL;
35783653
35793654 err = vdpa_mgmtdev_register(&mgtdev->mgtdev);
35803655 if (err)
drivers/vdpa/vdpa_sim/vdpa_sim.c+43−9
@@ -139,7 +139,7 @@ static void vdpasim_vq_reset(struct vdpasim *vdpasim, · 138 unmodified lines
139139 vq->vring.notify = NULL;
140140 }
141141
142−static void vdpasim_do_reset(struct vdpasim *vdpasim)
142+static void vdpasim_do_reset(struct vdpasim *vdpasim, u32 flags)
143143 {
144144 int i;
145145
@@ -151,11 +151,13 @@ static void vdpasim_do_reset(struct vdpasim *vdpasim) · 5 unmodified lines
151151 &vdpasim->iommu_lock);
152152 }
153153
154− for (i = 0; i < vdpasim->dev_attr.nas; i++) {
155− vhost_iotlb_reset(&vdpasim->iommu[i]);
156− vhost_iotlb_add_range(&vdpasim->iommu[i], 0, ULONG_MAX,
157− 0, VHOST_MAP_RW);
158− vdpasim->iommu_pt[i] = true;
154+ if (flags & VDPA_RESET_F_CLEAN_MAP) {
155+ for (i = 0; i < vdpasim->dev_attr.nas; i++) {
156+ vhost_iotlb_reset(&vdpasim->iommu[i]);
157+ vhost_iotlb_add_range(&vdpasim->iommu[i], 0, ULONG_MAX,
158+ 0, VHOST_MAP_RW);
159+ vdpasim->iommu_pt[i] = true;
160+ }
159161 }
160162
161163 vdpasim->running = true;
@@ -259,8 +261,12 @@ struct vdpasim *vdpasim_create(struct vdpasim_dev_attr *dev_attr, · 97 unmodified lines
259261 if (!vdpasim->iommu_pt)
260262 goto err_iommu;
261263
262− for (i = 0; i < vdpasim->dev_attr.nas; i++)
264+ for (i = 0; i < vdpasim->dev_attr.nas; i++) {
263265 vhost_iotlb_init(&vdpasim->iommu[i], max_iotlb_entries, 0);
266+ vhost_iotlb_add_range(&vdpasim->iommu[i], 0, ULONG_MAX, 0,
267+ VHOST_MAP_RW);
268+ vdpasim->iommu_pt[i] = true;
269+ }
264270
265271 for (i = 0; i < dev_attr->nvqs; i++)
266272 vringh_set_iotlb(&vdpasim->vqs[i].vring, &vdpasim->iommu[0],
@@ -480,18 +486,23 @@ static void vdpasim_set_status(struct vdpa_device *vdpa, u8 status) · 213 unmodified lines
480486 mutex_unlock(&vdpasim->mutex);
481487 }
482488
483−static int vdpasim_reset(struct vdpa_device *vdpa)
489+static int vdpasim_compat_reset(struct vdpa_device *vdpa, u32 flags)
484490 {
485491 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
486492
487493 mutex_lock(&vdpasim->mutex);
488494 vdpasim->status = 0;
489− vdpasim_do_reset(vdpasim);
495+ vdpasim_do_reset(vdpasim, flags);
490496 mutex_unlock(&vdpasim->mutex);
491497
492498 return 0;
493499 }
494500
501+static int vdpasim_reset(struct vdpa_device *vdpa)
502+{
503+ return vdpasim_compat_reset(vdpa, 0);
504+}
505+
495506 static int vdpasim_suspend(struct vdpa_device *vdpa)
496507 {
497508 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
@@ -637,6 +648,25 @@ err: · 139 unmodified lines
637648 return ret;
638649 }
639650
651+static int vdpasim_reset_map(struct vdpa_device *vdpa, unsigned int asid)
652+{
653+ struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
654+
655+ if (asid >= vdpasim->dev_attr.nas)
656+ return -EINVAL;
657+
658+ spin_lock(&vdpasim->iommu_lock);
659+ if (vdpasim->iommu_pt[asid])
660+ goto out;
661+ vhost_iotlb_reset(&vdpasim->iommu[asid]);
662+ vhost_iotlb_add_range(&vdpasim->iommu[asid], 0, ULONG_MAX,
663+ 0, VHOST_MAP_RW);
664+ vdpasim->iommu_pt[asid] = true;
665+out:
666+ spin_unlock(&vdpasim->iommu_lock);
667+ return 0;
668+}
669+
640670 static int vdpasim_bind_mm(struct vdpa_device *vdpa, struct mm_struct *mm)
641671 {
642672 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
@@ -749,6 +779,7 @@ static const struct vdpa_config_ops vdpasim_config_ops = { · 106 unmodified lines
749779 .get_status = vdpasim_get_status,
750780 .set_status = vdpasim_set_status,
751781 .reset = vdpasim_reset,
782+ .compat_reset = vdpasim_compat_reset,
752783 .suspend = vdpasim_suspend,
753784 .resume = vdpasim_resume,
754785 .get_config_size = vdpasim_get_config_size,
@@ -759,6 +790,7 @@ static const struct vdpa_config_ops vdpasim_config_ops = { · 4 unmodified lines
759790 .set_group_asid = vdpasim_set_group_asid,
760791 .dma_map = vdpasim_dma_map,
761792 .dma_unmap = vdpasim_dma_unmap,
793+ .reset_map = vdpasim_reset_map,
762794 .bind_mm = vdpasim_bind_mm,
763795 .unbind_mm = vdpasim_unbind_mm,
764796 .free = vdpasim_free,
@@ -787,6 +819,7 @@ static const struct vdpa_config_ops vdpasim_batch_config_ops = { · 22 unmodified lines
787819 .get_status = vdpasim_get_status,
788820 .set_status = vdpasim_set_status,
789821 .reset = vdpasim_reset,
822+ .compat_reset = vdpasim_compat_reset,
790823 .suspend = vdpasim_suspend,
791824 .resume = vdpasim_resume,
792825 .get_config_size = vdpasim_get_config_size,
@@ -796,6 +829,7 @@ static const struct vdpa_config_ops vdpasim_batch_config_ops = { · 3 unmodified lines
796829 .get_iova_range = vdpasim_get_iova_range,
797830 .set_group_asid = vdpasim_set_group_asid,
798831 .set_map = vdpasim_set_map,
832+ .reset_map = vdpasim_reset_map,
799833 .bind_mm = vdpasim_bind_mm,
800834 .unbind_mm = vdpasim_unbind_mm,
801835 .free = vdpasim_free,
drivers/vdpa/vdpa_user/vduse_dev.c+21−19
@@ -134,7 +134,6 @@ static DEFINE_MUTEX(vduse_lock); · 133 unmodified lines
134134 static DEFINE_IDR(vduse_idr);
135135
136136 static dev_t vduse_major;
137−static struct class *vduse_class;
138137 static struct cdev vduse_ctrl_cdev;
139138 static struct cdev vduse_cdev;
140139 static struct workqueue_struct *vduse_irq_wq;
@@ -1528,6 +1527,16 @@ static const struct kobj_type vq_type = { · 1387 unmodified lines
15281527 .default_groups = vq_groups,
15291528 };
15301529
1530+static char *vduse_devnode(const struct device *dev, umode_t *mode)
1531+{
1532+ return kasprintf(GFP_KERNEL, "vduse/%s", dev_name(dev));
1533+}
1534+
1535+static const struct class vduse_class = {
1536+ .name = "vduse",
1537+ .devnode = vduse_devnode,
1538+};
1539+
15311540 static void vduse_dev_deinit_vqs(struct vduse_dev *dev)
15321541 {
15331542 int i;
@@ -1638,7 +1647,7 @@ static int vduse_destroy_dev(char *name) · 104 unmodified lines
16381647 mutex_unlock(&dev->lock);
16391648
16401649 vduse_dev_reset(dev);
1641− device_destroy(vduse_class, MKDEV(MAJOR(vduse_major), dev->minor));
1650+ device_destroy(&vduse_class, MKDEV(MAJOR(vduse_major), dev->minor));
16421651 idr_remove(&vduse_idr, dev->minor);
16431652 kvfree(dev->config);
16441653 vduse_dev_deinit_vqs(dev);
@@ -1805,7 +1814,7 @@ static int vduse_create_dev(struct vduse_dev_config *config, · 160 unmodified lines
18051814
18061815 dev->minor = ret;
18071816 dev->msg_timeout = VDUSE_MSG_DEFAULT_TIMEOUT;
1808− dev->dev = device_create_with_groups(vduse_class, NULL,
1817+ dev->dev = device_create_with_groups(&vduse_class, NULL,
18091818 MKDEV(MAJOR(vduse_major), dev->minor),
18101819 dev, vduse_dev_groups, "%s", config->name);
18111820 if (IS_ERR(dev->dev)) {
@@ -1821,7 +1830,7 @@ static int vduse_create_dev(struct vduse_dev_config *config, · 9 unmodified lines
18211830
18221831 return 0;
18231832 err_vqs:
1824− device_destroy(vduse_class, MKDEV(MAJOR(vduse_major), dev->minor));
1833+ device_destroy(&vduse_class, MKDEV(MAJOR(vduse_major), dev->minor));
18251834 err_dev:
18261835 idr_remove(&vduse_idr, dev->minor);
18271836 err_idr:
@@ -1934,11 +1943,6 @@ static const struct file_operations vduse_ctrl_fops = { · 106 unmodified lines
19341943 .llseek = noop_llseek,
19351944 };
19361945
1937−static char *vduse_devnode(const struct device *dev, umode_t *mode)
1938−{
1939− return kasprintf(GFP_KERNEL, "vduse/%s", dev_name(dev));
1940−}
1941−
19421946 struct vduse_mgmt_dev {
19431947 struct vdpa_mgmt_dev mgmt_dev;
19441948 struct device dev;
@@ -2082,11 +2086,9 @@ static int vduse_init(void) · 137 unmodified lines
20822086 int ret;
20832087 struct device *dev;
20842088
2085− vduse_class = class_create("vduse");
2086− if (IS_ERR(vduse_class))
2087− return PTR_ERR(vduse_class);
2088−
2089− vduse_class->devnode = vduse_devnode;
2089+ ret = class_register(&vduse_class);
2090+ if (ret)
2091+ return ret;
20902092
20912093 ret = alloc_chrdev_region(&vduse_major, 0, VDUSE_DEV_MAX, "vduse");
20922094 if (ret)
@@ -2099,7 +2101,7 @@ static int vduse_init(void) · 6 unmodified lines
20992101 if (ret)
21002102 goto err_ctrl_cdev;
21012103
2102− dev = device_create(vduse_class, NULL, vduse_major, NULL, "control");
2104+ dev = device_create(&vduse_class, NULL, vduse_major, NULL, "control");
21032105 if (IS_ERR(dev)) {
21042106 ret = PTR_ERR(dev);
21052107 goto err_device;
@@ -2141,13 +2143,13 @@ err_bound_wq: · 35 unmodified lines
21412143 err_wq:
21422144 cdev_del(&vduse_cdev);
21432145 err_cdev:
2144− device_destroy(vduse_class, vduse_major);
2146+ device_destroy(&vduse_class, vduse_major);
21452147 err_device:
21462148 cdev_del(&vduse_ctrl_cdev);
21472149 err_ctrl_cdev:
21482150 unregister_chrdev_region(vduse_major, VDUSE_DEV_MAX);
21492151 err_chardev_region:
2150− class_destroy(vduse_class);
2152+ class_unregister(&vduse_class);
21512153 return ret;
21522154 }
21532155 module_init(vduse_init);
@@ -2159,10 +2161,10 @@ static void vduse_exit(void) · 5 unmodified lines
21592161 destroy_workqueue(vduse_irq_bound_wq);
21602162 destroy_workqueue(vduse_irq_wq);
21612163 cdev_del(&vduse_cdev);
2162− device_destroy(vduse_class, vduse_major);
2164+ device_destroy(&vduse_class, vduse_major);
21632165 cdev_del(&vduse_ctrl_cdev);
21642166 unregister_chrdev_region(vduse_major, VDUSE_DEV_MAX);
2165− class_destroy(vduse_class);
2167+ class_unregister(&vduse_class);
21662168 }
21672169 module_exit(vduse_exit);
21682170
drivers/vhost/scsi.c+1−1
@@ -1158,7 +1158,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq) · 1157 unmodified lines
11581158 /*
11591159 * Set prot_iter to data_iter and truncate it to
11601160 * prot_bytes, and advance data_iter past any
1161− * preceeding prot_bytes that may be present.
1161+ * preceding prot_bytes that may be present.
11621162 *
11631163 * Also fix up the exp_data_len to reflect only the
11641164 * actual data payload length.
drivers/vhost/vdpa.c+75−4
@@ -131,6 +131,15 @@ static struct vhost_vdpa_as *vhost_vdpa_find_alloc_as(struct vhost_vdpa *v, · 130 unmodified lines
131131 return vhost_vdpa_alloc_as(v, asid);
132132 }
133133
134+static void vhost_vdpa_reset_map(struct vhost_vdpa *v, u32 asid)
135+{
136+ struct vdpa_device *vdpa = v->vdpa;
137+ const struct vdpa_config_ops *ops = vdpa->config;
138+
139+ if (ops->reset_map)
140+ ops->reset_map(vdpa, asid);
141+}
142+
134143 static int vhost_vdpa_remove_as(struct vhost_vdpa *v, u32 asid)
135144 {
136145 struct vhost_vdpa_as *as = asid_to_as(v, asid);
@@ -140,6 +149,14 @@ static int vhost_vdpa_remove_as(struct vhost_vdpa *v, u32 asid) · 3 unmodified lines
140149
141150 hlist_del(&as->hash_link);
142151 vhost_vdpa_iotlb_unmap(v, &as->iotlb, 0ULL, 0ULL - 1, asid);
152+ /*
153+ * Devices with vendor specific IOMMU may need to restore
154+ * iotlb to the initial or default state, which cannot be
155+ * cleaned up in the all range unmap call above. Give them
156+ * a chance to clean up or reset the map to the desired
157+ * state.
158+ */
159+ vhost_vdpa_reset_map(v, asid);
143160 kfree(as);
144161
145162 return 0;
@@ -210,13 +227,24 @@ static void vhost_vdpa_unsetup_vq_irq(struct vhost_vdpa *v, u16 qid) · 64 unmodified lines
210227 irq_bypass_unregister_producer(&vq->call_ctx.producer);
211228 }
212229
213−static int vhost_vdpa_reset(struct vhost_vdpa *v)
230+static int _compat_vdpa_reset(struct vhost_vdpa *v)
214231 {
215232 struct vdpa_device *vdpa = v->vdpa;
233+ u32 flags = 0;
216234
217− v->in_batch = 0;
235+ if (v->vdev.vqs) {
236+ flags |= !vhost_backend_has_feature(v->vdev.vqs[0],
237+ VHOST_BACKEND_F_IOTLB_PERSIST) ?
238+ VDPA_RESET_F_CLEAN_MAP : 0;
239+ }
218240
219− return vdpa_reset(vdpa);
241+ return vdpa_reset(vdpa, flags);
242+}
243+
244+static int vhost_vdpa_reset(struct vhost_vdpa *v)
245+{
246+ v->in_batch = 0;
247+ return _compat_vdpa_reset(v);
220248 }
221249
222250 static long vhost_vdpa_bind_mm(struct vhost_vdpa *v)
@@ -295,7 +323,7 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp) · 72 unmodified lines
295323 vhost_vdpa_unsetup_vq_irq(v, i);
296324
297325 if (status == 0) {
298− ret = vdpa_reset(vdpa);
326+ ret = _compat_vdpa_reset(v);
299327 if (ret)
300328 return ret;
301329 } else
@@ -389,6 +417,14 @@ static bool vhost_vdpa_can_resume(const struct vhost_vdpa *v) · 87 unmodified lines
389417 return ops->resume;
390418 }
391419
420+static bool vhost_vdpa_has_desc_group(const struct vhost_vdpa *v)
421+{
422+ struct vdpa_device *vdpa = v->vdpa;
423+ const struct vdpa_config_ops *ops = vdpa->config;
424+
425+ return ops->get_vq_desc_group;
426+}
427+
392428 static long vhost_vdpa_get_features(struct vhost_vdpa *v, u64 __user *featurep)
393429 {
394430 struct vdpa_device *vdpa = v->vdpa;
@@ -414,6 +450,15 @@ static u64 vhost_vdpa_get_backend_features(const struct vhost_vdpa *v) · 19 unmodified lines
414450 return ops->get_backend_features(vdpa);
415451 }
416452
453+static bool vhost_vdpa_has_persistent_map(const struct vhost_vdpa *v)
454+{
455+ struct vdpa_device *vdpa = v->vdpa;
456+ const struct vdpa_config_ops *ops = vdpa->config;
457+
458+ return (!ops->set_map && !ops->dma_map) || ops->reset_map ||
459+ vhost_vdpa_get_backend_features(v) & BIT_ULL(VHOST_BACKEND_F_IOTLB_PERSIST);
460+}
461+
417462 static long vhost_vdpa_set_features(struct vhost_vdpa *v, u64 __user *featurep)
418463 {
419464 struct vdpa_device *vdpa = v->vdpa;
@@ -605,6 +650,16 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd, · 185 unmodified lines
605650 else if (copy_to_user(argp, &s, sizeof(s)))
606651 return -EFAULT;
607652 return 0;
653+ case VHOST_VDPA_GET_VRING_DESC_GROUP:
654+ if (!vhost_vdpa_has_desc_group(v))
655+ return -EOPNOTSUPP;
656+ s.index = idx;
657+ s.num = ops->get_vq_desc_group(vdpa, idx);
658+ if (s.num >= vdpa->ngroups)
659+ return -EIO;
660+ else if (copy_to_user(argp, &s, sizeof(s)))
661+ return -EFAULT;
662+ return 0;
608663 case VHOST_VDPA_SET_GROUP_ASID:
609664 if (copy_from_user(&s, argp, sizeof(s)))
610665 return -EFAULT;
@@ -690,6 +745,8 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep, · 79 unmodified lines
690745 if (copy_from_user(&features, featurep, sizeof(features)))
691746 return -EFAULT;
692747 if (features & ~(VHOST_VDPA_BACKEND_FEATURES |
748+ BIT_ULL(VHOST_BACKEND_F_DESC_ASID) |
749+ BIT_ULL(VHOST_BACKEND_F_IOTLB_PERSIST) |
693750 BIT_ULL(VHOST_BACKEND_F_SUSPEND) |
694751 BIT_ULL(VHOST_BACKEND_F_RESUME) |
695752 BIT_ULL(VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK)))
@@ -700,6 +757,15 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep, · 4 unmodified lines
700757 if ((features & BIT_ULL(VHOST_BACKEND_F_RESUME)) &&
701758 !vhost_vdpa_can_resume(v))
702759 return -EOPNOTSUPP;
760+ if ((features & BIT_ULL(VHOST_BACKEND_F_DESC_ASID)) &&
761+ !(features & BIT_ULL(VHOST_BACKEND_F_IOTLB_ASID)))
762+ return -EINVAL;
763+ if ((features & BIT_ULL(VHOST_BACKEND_F_DESC_ASID)) &&
764+ !vhost_vdpa_has_desc_group(v))
765+ return -EOPNOTSUPP;
766+ if ((features & BIT_ULL(VHOST_BACKEND_F_IOTLB_PERSIST)) &&
767+ !vhost_vdpa_has_persistent_map(v))
768+ return -EOPNOTSUPP;
703769 vhost_set_backend_features(&v->vdev, features);
704770 return 0;
705771 }
@@ -753,6 +819,10 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep, · 47 unmodified lines
753819 features |= BIT_ULL(VHOST_BACKEND_F_SUSPEND);
754820 if (vhost_vdpa_can_resume(v))
755821 features |= BIT_ULL(VHOST_BACKEND_F_RESUME);
822+ if (vhost_vdpa_has_desc_group(v))
823+ features |= BIT_ULL(VHOST_BACKEND_F_DESC_ASID);
824+ if (vhost_vdpa_has_persistent_map(v))
825+ features |= BIT_ULL(VHOST_BACKEND_F_IOTLB_PERSIST);
756826 features |= vhost_vdpa_get_backend_features(v);
757827 if (copy_to_user(featurep, &features, sizeof(features)))
758828 r = -EFAULT;
@@ -1285,6 +1355,7 @@ static void vhost_vdpa_cleanup(struct vhost_vdpa *v) · 526 unmodified lines
12851355 vhost_vdpa_free_domain(v);
12861356 vhost_dev_cleanup(&v->vdev);
12871357 kfree(v->vdev.vqs);
1358+ v->vdev.vqs = NULL;
12881359 }
12891360
12901361 static int vhost_vdpa_open(struct inode *inode, struct file *filep)
drivers/virtio/virtio_balloon.c+1−1
@@ -745,7 +745,7 @@ static void report_free_page_func(struct work_struct *work) · 744 unmodified lines
745745 * 2) update the host about the old page removed from vb->pages list;
746746 *
747747 * This function preforms the balloon page migration task.
748− * Called through balloon_mapping->a_ops->migratepage
748+ * Called through movable_operations->migrate_page
749749 */
750750 static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info,
751751 struct page *newpage, struct page *page, enum migrate_mode mode)
drivers/virtio/virtio_pci_modern.c+36−0
@@ -39,6 +39,39 @@ static void vp_transport_features(struct virtio_device *vdev, u64 features) · 38 unmodified lines
3939 __virtio_set_bit(vdev, VIRTIO_F_RING_RESET);
4040 }
4141
42+static int __vp_check_common_size_one_feature(struct virtio_device *vdev, u32 fbit,
43+ u32 offset, const char *fname)
44+{
45+ struct virtio_pci_device *vp_dev = to_vp_device(vdev);
46+
47+ if (!__virtio_test_bit(vdev, fbit))
48+ return 0;
49+
50+ if (likely(vp_dev->mdev.common_len >= offset))
51+ return 0;
52+
53+ dev_err(&vdev->dev,
54+ "virtio: common cfg size(%zu) does not match the feature %s\n",
55+ vp_dev->mdev.common_len, fname);
56+
57+ return -EINVAL;
58+}
59+
60+#define vp_check_common_size_one_feature(vdev, fbit, field) \
61+ __vp_check_common_size_one_feature(vdev, fbit, \
62+ offsetofend(struct virtio_pci_modern_common_cfg, field), #fbit)
63+
64+static int vp_check_common_size(struct virtio_device *vdev)
65+{
66+ if (vp_check_common_size_one_feature(vdev, VIRTIO_F_NOTIF_CONFIG_DATA, queue_notify_data))
67+ return -EINVAL;
68+
69+ if (vp_check_common_size_one_feature(vdev, VIRTIO_F_RING_RESET, queue_reset))
70+ return -EINVAL;
71+
72+ return 0;
73+}
74+
4275 /* virtio config->finalize_features() implementation */
4376 static int vp_finalize_features(struct virtio_device *vdev)
4477 {
@@ -57,6 +90,9 @@ static int vp_finalize_features(struct virtio_device *vdev) · 12 unmodified lines
5790 return -EINVAL;
5891 }
5992
93+ if (vp_check_common_size(vdev))
94+ return -EINVAL;
95+
6096 vp_modern_set_features(&vp_dev->mdev, vdev->features);
6197
6298 return 0;
drivers/virtio/virtio_pci_modern_dev.c+5−1
@@ -203,6 +203,10 @@ static inline void check_offsets(void) · 202 unmodified lines
203203 offsetof(struct virtio_pci_common_cfg, queue_used_lo));
204204 BUILD_BUG_ON(VIRTIO_PCI_COMMON_Q_USEDHI !=
205205 offsetof(struct virtio_pci_common_cfg, queue_used_hi));
206+ BUILD_BUG_ON(VIRTIO_PCI_COMMON_Q_NDATA !=
207+ offsetof(struct virtio_pci_modern_common_cfg, queue_notify_data));
208+ BUILD_BUG_ON(VIRTIO_PCI_COMMON_Q_RESET !=
209+ offsetof(struct virtio_pci_modern_common_cfg, queue_reset));
206210 }
207211
208212 /*
@@ -292,7 +296,7 @@ int vp_modern_probe(struct virtio_pci_modern_device *mdev) · 83 unmodified lines
292296 mdev->common = vp_modern_map_capability(mdev, common,
293297 sizeof(struct virtio_pci_common_cfg), 4,
294298 0, sizeof(struct virtio_pci_modern_common_cfg),
295− NULL, NULL);
299+ &mdev->common_len, NULL);
296300 if (!mdev->common)
297301 goto err_map_common;
298302 mdev->isr = vp_modern_map_capability(mdev, isr, sizeof(u8), 1,
drivers/virtio/virtio_vdpa.c+1−1
@@ -100,7 +100,7 @@ static void virtio_vdpa_reset(struct virtio_device *vdev) · 99 unmodified lines
100100 {
101101 struct vdpa_device *vdpa = vd_get_vdpa(vdev);
102102
103− vdpa_reset(vdpa);
103+ vdpa_reset(vdpa, 0);
104104 }
105105
106106 static bool virtio_vdpa_notify(struct virtqueue *vq)
include/linux/mlx5/mlx5_ifc.h+7−1
@@ -1232,7 +1232,13 @@ struct mlx5_ifc_virtio_emulation_cap_bits { · 1231 unmodified lines
12321232 u8 max_emulated_devices[0x8];
12331233 u8 max_num_virtio_queues[0x18];
12341234
1235− u8 reserved_at_a0[0x60];
1235+ u8 reserved_at_a0[0x20];
1236+
1237+ u8 reserved_at_c0[0x13];
1238+ u8 desc_group_mkey_supported[0x1];
1239+ u8 reserved_at_d4[0xc];
1240+
1241+ u8 reserved_at_e0[0x20];
12361242
12371243 u8 umem_1_buffer_param_a[0x20];
12381244
include/linux/mlx5/mlx5_ifc_vdpa.h+6−1
@@ -74,7 +74,11 @@ struct mlx5_ifc_virtio_q_bits { · 73 unmodified lines
7474 u8 reserved_at_320[0x8];
7575 u8 pd[0x18];
7676
77− u8 reserved_at_340[0xc0];
77+ u8 reserved_at_340[0x20];
78+
79+ u8 desc_group_mkey[0x20];
80+
81+ u8 reserved_at_380[0x80];
7882 };
7983
8084 struct mlx5_ifc_virtio_net_q_object_bits {
@@ -141,6 +145,7 @@ enum { · 60 unmodified lines
141145 MLX5_VIRTQ_MODIFY_MASK_STATE = (u64)1 << 0,
142146 MLX5_VIRTQ_MODIFY_MASK_DIRTY_BITMAP_PARAMS = (u64)1 << 3,
143147 MLX5_VIRTQ_MODIFY_MASK_DIRTY_BITMAP_DUMP_ENABLE = (u64)1 << 4,
148+ MLX5_VIRTQ_MODIFY_MASK_DESC_GROUP_MKEY = (u64)1 << 14,
144149 };
145150
146151 enum {
include/linux/vdpa.h+39−2
@@ -204,6 +204,16 @@ struct vdpa_map_file { · 203 unmodified lines
204204 * @vdev: vdpa device
205205 * @idx: virtqueue index
206206 * Returns u32: group id for this virtqueue
207+ * @get_vq_desc_group: Get the group id for the descriptor table of
208+ * a specific virtqueue (optional)
209+ * @vdev: vdpa device
210+ * @idx: virtqueue index
211+ * Returns u32: group id for the descriptor table
212+ * portion of this virtqueue. Could be different
213+ * than the one from @get_vq_group, in which case
214+ * the access to the descriptor table can be
215+ * confined to a separate asid, isolating from
216+ * the virtqueue's buffer address access.
207217 * @get_device_features: Get virtio features supported by the device
208218 * @vdev: vdpa device
209219 * Returns the virtio features support by the
@@ -242,6 +252,17 @@ struct vdpa_map_file { · 32 unmodified lines
242252 * @reset: Reset device
243253 * @vdev: vdpa device
244254 * Returns integer: success (0) or error (< 0)
255+ * @compat_reset: Reset device with compatibility quirks to
256+ * accommodate older userspace. Only needed by
257+ * parent driver which used to have bogus reset
258+ * behaviour, and has to maintain such behaviour
259+ * for compatibility with older userspace.
260+ * Historically compliant driver only has to
261+ * implement .reset, Historically non-compliant
262+ * driver should implement both.
263+ * @vdev: vdpa device
264+ * @flags: compatibility quirks for reset
265+ * Returns integer: success (0) or error (< 0)
245266 * @suspend: Suspend the device (optional)
246267 * @vdev: vdpa device
247268 * Returns integer: success (0) or error (< 0)
@@ -317,6 +338,15 @@ struct vdpa_map_file { · 69 unmodified lines
317338 * @iova: iova to be unmapped
318339 * @size: size of the area
319340 * Returns integer: success (0) or error (< 0)
341+ * @reset_map: Reset device memory mapping to the default
342+ * state (optional)
343+ * Needed for devices that are using device
344+ * specific DMA translation and prefer mapping
345+ * to be decoupled from the virtio life cycle,
346+ * i.e. device .reset op does not reset mapping
347+ * @vdev: vdpa device
348+ * @asid: address space identifier
349+ * Returns integer: success (0) or error (< 0)
320350 * @get_vq_dma_dev: Get the dma device for a specific
321351 * virtqueue (optional)
322352 * @vdev: vdpa device
@@ -360,6 +390,7 @@ struct vdpa_config_ops { · 37 unmodified lines
360390 /* Device ops */
361391 u32 (*get_vq_align)(struct vdpa_device *vdev);
362392 u32 (*get_vq_group)(struct vdpa_device *vdev, u16 idx);
393+ u32 (*get_vq_desc_group)(struct vdpa_device *vdev, u16 idx);
363394 u64 (*get_device_features)(struct vdpa_device *vdev);
364395 u64 (*get_backend_features)(const struct vdpa_device *vdev);
365396 int (*set_driver_features)(struct vdpa_device *vdev, u64 features);
@@ -373,6 +404,8 @@ struct vdpa_config_ops { · 7 unmodified lines
373404 u8 (*get_status)(struct vdpa_device *vdev);
374405 void (*set_status)(struct vdpa_device *vdev, u8 status);
375406 int (*reset)(struct vdpa_device *vdev);
407+ int (*compat_reset)(struct vdpa_device *vdev, u32 flags);
408+#define VDPA_RESET_F_CLEAN_MAP 1
376409 int (*suspend)(struct vdpa_device *vdev);
377410 int (*resume)(struct vdpa_device *vdev);
378411 size_t (*get_config_size)(struct vdpa_device *vdev);
@@ -394,6 +427,7 @@ struct vdpa_config_ops { · 15 unmodified lines
394427 u64 iova, u64 size, u64 pa, u32 perm, void *opaque);
395428 int (*dma_unmap)(struct vdpa_device *vdev, unsigned int asid,
396429 u64 iova, u64 size);
430+ int (*reset_map)(struct vdpa_device *vdev, unsigned int asid);
397431 int (*set_group_asid)(struct vdpa_device *vdev, unsigned int group,
398432 unsigned int asid);
399433 struct device *(*get_vq_dma_dev)(struct vdpa_device *vdev, u16 idx);
@@ -485,14 +519,17 @@ static inline struct device *vdpa_get_dma_dev(struct vdpa_device *vdev) · 85 unmodified lines
485519 return vdev->dma_dev;
486520 }
487521
488−static inline int vdpa_reset(struct vdpa_device *vdev)
522+static inline int vdpa_reset(struct vdpa_device *vdev, u32 flags)
489523 {
490524 const struct vdpa_config_ops *ops = vdev->config;
491525 int ret;
492526
493527 down_write(&vdev->cf_lock);
494528 vdev->features_valid = false;
495− ret = ops->reset(vdev);
529+ if (ops->compat_reset && flags)
530+ ret = ops->compat_reset(vdev, flags);
531+ else
532+ ret = ops->reset(vdev);
496533 up_write(&vdev->cf_lock);
497534 return ret;
498535 }
include/linux/virtio_pci_modern.h+23−12
@@ -12,37 +12,48 @@ struct virtio_pci_modern_common_cfg { · 11 unmodified lines
1212 __le16 queue_reset; /* read-write */
1313 };
1414
15+/**
16+ * struct virtio_pci_modern_device - info for modern PCI virtio
17+ * @pci_dev: Ptr to the PCI device struct
18+ * @common: Position of the common capability in the PCI config
19+ * @device: Device-specific data (non-legacy mode)
20+ * @notify_base: Base of vq notifications (non-legacy mode)
21+ * @notify_pa: Physical base of vq notifications
22+ * @isr: Where to read and clear interrupt
23+ * @notify_len: So we can sanity-check accesses
24+ * @device_len: So we can sanity-check accesses
25+ * @notify_map_cap: Capability for when we need to map notifications per-vq
26+ * @notify_offset_multiplier: Multiply queue_notify_off by this value
27+ * (non-legacy mode).
28+ * @modern_bars: Bitmask of BARs
29+ * @id: Device and vendor id
30+ * @device_id_check: Callback defined before vp_modern_probe() to be used to
31+ * verify the PCI device is a vendor's expected device rather
32+ * than the standard virtio PCI device
33+ * Returns the found device id or ERRNO
34+ * @dma_mask: Optional mask instead of the traditional DMA_BIT_MASK(64),
35+ * for vendor devices with DMA space address limitations
36+ */
1537 struct virtio_pci_modern_device {
1638 struct pci_dev *pci_dev;
1739
1840 struct virtio_pci_common_cfg __iomem *common;
19− /* Device-specific data (non-legacy mode) */
2041 void __iomem *device;
21− /* Base of vq notifications (non-legacy mode). */
2242 void __iomem *notify_base;
23− /* Physical base of vq notifications */
2443 resource_size_t notify_pa;
25− /* Where to read and clear interrupt */
2644 u8 __iomem *isr;
2745
28− /* So we can sanity-check accesses. */
2946 size_t notify_len;
3047 size_t device_len;
48+ size_t common_len;
3149
32− /* Capability for when we need to map notifications per-vq. */
3350 int notify_map_cap;
3451
35− /* Multiply queue_notify_off by this value. (non-legacy mode). */
3652 u32 notify_offset_multiplier;
37−
3853 int modern_bars;
39−
4054 struct virtio_device_id id;
4155
42− /* optional check for vendor virtio device, returns dev_id or -ERRNO */
4356 int (*device_id_check)(struct pci_dev *pdev);
44−
45− /* optional mask for devices with limited DMA space */
4657 u64 dma_mask;
4758 };
4859
include/uapi/linux/vhost.h+8−0
@@ -219,4 +219,12 @@ · 218 unmodified lines
219219 */
220220 #define VHOST_VDPA_RESUME _IO(VHOST_VIRTIO, 0x7E)
221221
222+/* Get the group for the descriptor table including driver & device areas
223+ * of a virtqueue: read index, write group in num.
224+ * The virtqueue index is stored in the index field of vhost_vring_state.
225+ * The group ID of the descriptor table for this specific virtqueue
226+ * is returned via num field of vhost_vring_state.
227+ */
228+#define VHOST_VDPA_GET_VRING_DESC_GROUP _IOWR(VHOST_VIRTIO, 0x7F, \
229+ struct vhost_vring_state)
222230 #endif
include/uapi/linux/vhost_types.h+7−0
@@ -185,5 +185,12 @@ struct vhost_vdpa_iova_range { · 184 unmodified lines
185185 * DRIVER_OK
186186 */
187187 #define VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK 0x6
188+/* Device may expose the virtqueue's descriptor area, driver area and
189+ * device area to a different group for ASID binding than where its
190+ * buffers may reside. Requires VHOST_BACKEND_F_IOTLB_ASID.
191+ */
192+#define VHOST_BACKEND_F_DESC_ASID 0x7
193+/* IOTLB don't flush memory mapping across device reset */
194+#define VHOST_BACKEND_F_IOTLB_PERSIST 0x8
188195
189196 #endif
include/uapi/linux/virtio_config.h+5−0
@@ -105,6 +105,11 @@ · 104 unmodified lines
105105 */
106106 #define VIRTIO_F_NOTIFICATION_DATA 38
107107
108+/* This feature indicates that the driver uses the data provided by the device
109+ * as a virtqueue identifier in available buffer notifications.
110+ */
111+#define VIRTIO_F_NOTIF_CONFIG_DATA 39
112+
108113 /*
109114 * This feature indicates that the driver can reset a queue individually.
110115 */