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 @@
1What: /sys/bus/vdpa/driver_autoprobe1What: /sys/bus/vdpa/drivers_autoprobe
2Date: March 20202Date: March 2020
3Contact: virtualization@lists.linux-foundation.org3Contact: virtualization@lists.linux-foundation.org
4Description:4Description:
@@ -17,7 +17,7 @@ Description: · 12 unmodified lines
17 Writing a device name to this file will cause the kernel binds17 Writing a device name to this file will cause the kernel binds
18 devices to a compatible driver.18 devices to a compatible driver.
19 19
20 This can be useful when /sys/bus/vdpa/driver_autoprobe is20 This can be useful when /sys/bus/vdpa/drivers_autoprobe is
21 disabled.21 disabled.
22 22
23What: /sys/bus/vdpa/drivers/.../bind23What: /sys/bus/vdpa/drivers/.../bind
MAINTAINERS+6−0
@@ -13790,6 +13790,12 @@ F: drivers/infiniband/hw/mlx5/ · 13789 unmodified lines
13790F: include/linux/mlx5/13790F: include/linux/mlx5/
13791F: include/uapi/rdma/mlx5-abi.h13791F: include/uapi/rdma/mlx5-abi.h
13792 13792
13793MELLANOX MLX5 VDPA DRIVER
13794M: Dragos Tatulea <dtatulea@nvidia.com>
13795L: virtualization@lists.linux-foundation.org
13796S: Supported
13797F: drivers/vdpa/mlx5/
13798
13793MELLANOX MLXCPLD I2C AND MUX DRIVER13799MELLANOX MLXCPLD I2C AND MUX DRIVER
13794M: Vadim Pasternak <vadimp@nvidia.com>13800M: Vadim Pasternak <vadimp@nvidia.com>
13795M: Michael Shych <michaelsh@nvidia.com>13801M: 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
1311 u16 min_io_size;1311 u16 min_io_size;
1312 u8 physical_block_exp, alignment_offset;1312 u8 physical_block_exp, alignment_offset;
1313 unsigned int queue_depth;1313 unsigned int queue_depth;
1314 size_t max_dma_size;
1314 1315
1315 if (!vdev->config->get) {1316 if (!vdev->config->get) {
1316 dev_err(&vdev->dev, "%s failure: config access disabled\n",1317 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
1409 /* No real sector limit. */1410 /* No real sector limit. */
1410 blk_queue_max_hw_sectors(q, UINT_MAX);1411 blk_queue_max_hw_sectors(q, UINT_MAX);
1411 1412
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;
1413 1415
1414 /* Host can optionally specify maximum segment size and number of1416 /* Host can optionally specify maximum segment size and number of
1415 * segments. */1417 * segments. */
drivers/vdpa/mlx5/core/mlx5_vdpa.h+20−12
@@ -31,11 +31,9 @@ struct mlx5_vdpa_mr { · 30 unmodified lines
31 struct list_head head;31 struct list_head head;
32 unsigned long num_directs;32 unsigned long num_directs;
33 unsigned long num_klms;33 unsigned long num_klms;
34 /* state of dvq mr */
35 bool initialized;
36 34
37 /* serialize mkey creation and destruction */35 struct vhost_iotlb *iotlb;
38 struct mutex mkey_mtx;36
39 bool user_mr;37 bool user_mr;
40};38};
41 39
@@ -74,11 +72,12 @@ struct mlx5_vdpa_wq_ent { · 32 unmodified lines
74enum {72enum {
75 MLX5_VDPA_DATAVQ_GROUP,73 MLX5_VDPA_DATAVQ_GROUP,
76 MLX5_VDPA_CVQ_GROUP,74 MLX5_VDPA_CVQ_GROUP,
75 MLX5_VDPA_DATAVQ_DESC_GROUP,
77 MLX5_VDPA_NUMVQ_GROUPS76 MLX5_VDPA_NUMVQ_GROUPS
78};77};
79 78
80enum {79enum {
81 MLX5_VDPA_NUM_AS = MLX5_VDPA_NUMVQ_GROUPS80 MLX5_VDPA_NUM_AS = 2
82};81};
83 82
84struct mlx5_vdpa_dev {83struct mlx5_vdpa_dev {
@@ -93,7 +92,9 @@ struct mlx5_vdpa_dev { · 8 unmodified lines
93 u16 max_idx;92 u16 max_idx;
94 u32 generation;93 u32 generation;
95 94
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;
97 struct mlx5_control_vq cvq;98 struct mlx5_control_vq cvq;
98 struct workqueue_struct *wq;99 struct workqueue_struct *wq;
99 unsigned int group2asid[MLX5_VDPA_NUMVQ_GROUPS];100 unsigned int group2asid[MLX5_VDPA_NUMVQ_GROUPS];
@@ -114,12 +115,19 @@ void mlx5_vdpa_free_resources(struct mlx5_vdpa_dev *mvdev); · 14 unmodified lines
114int mlx5_vdpa_create_mkey(struct mlx5_vdpa_dev *mvdev, u32 *mkey, u32 *in,115int mlx5_vdpa_create_mkey(struct mlx5_vdpa_dev *mvdev, u32 *mkey, u32 *in,
115 int inlen);116 int inlen);
116int mlx5_vdpa_destroy_mkey(struct mlx5_vdpa_dev *mvdev, u32 mkey);117int mlx5_vdpa_destroy_mkey(struct mlx5_vdpa_dev *mvdev, u32 mkey);
117int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,118struct mlx5_vdpa_mr *mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
118 bool *change_map, unsigned int asid);119 struct vhost_iotlb *iotlb);
119int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,120void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev);
120 unsigned int asid);121void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
121void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev);122 struct mlx5_vdpa_mr *mr);
122void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid);123void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
124 struct mlx5_vdpa_mr *mr,
125 unsigned int asid);
126int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
127 struct vhost_iotlb *iotlb,
128 unsigned int asid);
129int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev);
130int mlx5_vdpa_reset_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
123 131
124#define mlx5_vdpa_warn(__dev, format, ...) \132#define mlx5_vdpa_warn(__dev, format, ...) \
125 dev_warn((__dev)->mdev->device, "%s:%d:(pid %d) warning: " format, __func__, __LINE__, \133 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
301 sg_free_table(&mr->sg_head);301 sg_free_table(&mr->sg_head);
302}302}
303 303
304static int add_direct_chain(struct mlx5_vdpa_dev *mvdev, u64 start, u64 size, u8 perm,304static int add_direct_chain(struct mlx5_vdpa_dev *mvdev,
305 struct mlx5_vdpa_mr *mr,
306 u64 start,
307 u64 size,
308 u8 perm,
305 struct vhost_iotlb *iotlb)309 struct vhost_iotlb *iotlb)
306{310{
307 struct mlx5_vdpa_mr *mr = &mvdev->mr;
308 struct mlx5_vdpa_direct_mr *dmr;311 struct mlx5_vdpa_direct_mr *dmr;
309 struct mlx5_vdpa_direct_mr *n;312 struct mlx5_vdpa_direct_mr *n;
310 LIST_HEAD(tmp);313 LIST_HEAD(tmp);
@@ -354,9 +357,10 @@ err_alloc: · 43 unmodified lines
354 * indirect memory key that provides access to the enitre address space given357 * indirect memory key that provides access to the enitre address space given
355 * by iotlb.358 * by iotlb.
356 */359 */
357static int create_user_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb)360static int create_user_mr(struct mlx5_vdpa_dev *mvdev,
361 struct mlx5_vdpa_mr *mr,
362 struct vhost_iotlb *iotlb)
358{363{
359 struct mlx5_vdpa_mr *mr = &mvdev->mr;
360 struct mlx5_vdpa_direct_mr *dmr;364 struct mlx5_vdpa_direct_mr *dmr;
361 struct mlx5_vdpa_direct_mr *n;365 struct mlx5_vdpa_direct_mr *n;
362 struct vhost_iotlb_map *map;366 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
384 LOG_MAX_KLM_SIZE);388 LOG_MAX_KLM_SIZE);
385 mr->num_klms += nnuls;389 mr->num_klms += nnuls;
386 }390 }
387 err = add_direct_chain(mvdev, ps, pe - ps, pperm, iotlb);391 err = add_direct_chain(mvdev, mr, ps, pe - ps, pperm, iotlb);
388 if (err)392 if (err)
389 goto err_chain;393 goto err_chain;
390 }394 }
@@ -393,7 +397,7 @@ static int create_user_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb · 2 unmodified lines
393 pperm = map->perm;397 pperm = map->perm;
394 }398 }
395 }399 }
396 err = add_direct_chain(mvdev, ps, pe - ps, pperm, iotlb);400 err = add_direct_chain(mvdev, mr, ps, pe - ps, pperm, iotlb);
397 if (err)401 if (err)
398 goto err_chain;402 goto err_chain;
399 403
@@ -450,20 +454,23 @@ static void destroy_dma_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr *mr) · 50 unmodified lines
450 mlx5_vdpa_destroy_mkey(mvdev, mr->mkey);454 mlx5_vdpa_destroy_mkey(mvdev, mr->mkey);
451}455}
452 456
453static int dup_iotlb(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *src)457static int dup_iotlb(struct vhost_iotlb *dst, struct vhost_iotlb *src)
454{458{
455 struct vhost_iotlb_map *map;459 struct vhost_iotlb_map *map;
456 u64 start = 0, last = ULLONG_MAX;460 u64 start = 0, last = ULLONG_MAX;
457 int err;461 int err;
458 462
463 if (dst == src)
464 return -EINVAL;
465
459 if (!src) {466 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);
461 return err;468 return err;
462 }469 }
463 470
464 for (map = vhost_iotlb_itree_first(src, start, last); map;471 for (map = vhost_iotlb_itree_first(src, start, last); map;
465 map = vhost_iotlb_itree_next(map, start, last)) {472 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,
467 map->addr, map->perm);474 map->addr, map->perm);
468 if (err)475 if (err)
469 return err;476 return err;
@@ -471,9 +478,9 @@ static int dup_iotlb(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *src) · 1 unmodified line
471 return 0;478 return 0;
472}479}
473 480
474static void prune_iotlb(struct mlx5_vdpa_dev *mvdev)481static void prune_iotlb(struct vhost_iotlb *iotlb)
475{482{
476 vhost_iotlb_del_range(mvdev->cvq.iotlb, 0, ULLONG_MAX);483 vhost_iotlb_del_range(iotlb, 0, ULLONG_MAX);
477}484}
478 485
479static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr *mr)486static 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
489 }496 }
490}497}
491 498
492static void _mlx5_vdpa_destroy_cvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid)499static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr *mr)
493{500{
494 if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)501 if (mr->user_mr)
495 return;502 destroy_user_mr(mvdev, mr);
503 else
504 destroy_dma_mr(mvdev, mr);
496 505
497 prune_iotlb(mvdev);506 vhost_iotlb_free(mr->iotlb);
498}507}
499 508
500static void _mlx5_vdpa_destroy_dvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid)509void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
510 struct mlx5_vdpa_mr *mr)
501{511{
502 struct mlx5_vdpa_mr *mr = &mvdev->mr;512 if (!mr)
503
504 if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid)
505 return;513 return;
506 514
507 if (!mr->initialized)515 mutex_lock(&mvdev->mr_mtx);
508 return;
509 516
510 if (mr->user_mr)517 _mlx5_vdpa_destroy_mr(mvdev, mr);
511 destroy_user_mr(mvdev, mr);518
512 else519 for (int i = 0; i < MLX5_VDPA_NUM_AS; i++) {
513 destroy_dma_mr(mvdev, mr);520 if (mvdev->mr[i] == mr)
521 mvdev->mr[i] = NULL;
522 }
514 523
515 mr->initialized = false;524 mutex_unlock(&mvdev->mr_mtx);
525
526 kfree(mr);
516}527}
517 528
518void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid)529void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
530 struct mlx5_vdpa_mr *new_mr,
531 unsigned int asid)
519{532{
520 struct mlx5_vdpa_mr *mr = &mvdev->mr;533 struct mlx5_vdpa_mr *old_mr = mvdev->mr[asid];
521 534
522 mutex_lock(&mr->mkey_mtx);535 mutex_lock(&mvdev->mr_mtx);
523 536
524 _mlx5_vdpa_destroy_dvq_mr(mvdev, asid);537 mvdev->mr[asid] = new_mr;
525 _mlx5_vdpa_destroy_cvq_mr(mvdev, asid);538 if (old_mr) {
539 _mlx5_vdpa_destroy_mr(mvdev, old_mr);
540 kfree(old_mr);
541 }
526 542
527 mutex_unlock(&mr->mkey_mtx);543 mutex_unlock(&mvdev->mr_mtx);
528}
529 544
530void 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]);
534}545}
535 546
536static int _mlx5_vdpa_create_cvq_mr(struct mlx5_vdpa_dev *mvdev,547void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev)
537 struct vhost_iotlb *iotlb,
538 unsigned int asid)
539{548{
540 if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)549 for (int i = 0; i < MLX5_VDPA_NUM_AS; i++)
541 return 0;550 mlx5_vdpa_destroy_mr(mvdev, mvdev->mr[i]);
542 551
543 return dup_iotlb(mvdev, iotlb);552 prune_iotlb(mvdev->cvq.iotlb);
544}553}
545 554
546static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev *mvdev,555static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
547 struct vhost_iotlb *iotlb,556 struct mlx5_vdpa_mr *mr,
548 unsigned int asid)557 struct vhost_iotlb *iotlb)
549{558{
550 struct mlx5_vdpa_mr *mr = &mvdev->mr;
551 int err;559 int err;
552 560
553 if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid)
554 return 0;
555
556 if (mr->initialized)
557 return 0;
558
559 if (iotlb)561 if (iotlb)
560 err = create_user_mr(mvdev, iotlb);562 err = create_user_mr(mvdev, mr, iotlb);
561 else563 else
562 err = create_dma_mr(mvdev, mr);564 err = create_dma_mr(mvdev, mr);
563 565
564 if (err)566 if (err)
565 return err;567 return err;
566 568
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;
568 578
569 return 0;579 return 0;
580
581err_iotlb:
582 vhost_iotlb_free(mr->iotlb);
583
584err_mr:
585 if (iotlb)
586 destroy_user_mr(mvdev, mr);
587 else
588 destroy_dma_mr(mvdev, mr);
589
590 return err;
570}591}
571 592
572static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,593struct mlx5_vdpa_mr *mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
573 struct vhost_iotlb *iotlb, unsigned int asid)594 struct vhost_iotlb *iotlb)
574{595{
596 struct mlx5_vdpa_mr *mr;
575 int err;597 int err;
576 598
577 err = _mlx5_vdpa_create_dvq_mr(mvdev, iotlb, asid);599 mr = kzalloc(sizeof(*mr), GFP_KERNEL);
578 if (err)600 if (!mr)
579 return err;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);
580 606
581 err = _mlx5_vdpa_create_cvq_mr(mvdev, iotlb, asid);
582 if (err)607 if (err)
583 goto out_err;608 goto out_err;
584 609
585 return 0;610 return mr;
586 611
587out_err:612out_err:
588 _mlx5_vdpa_destroy_dvq_mr(mvdev, asid);613 kfree(mr);
589 614 return ERR_PTR(err);
590 return err;
591}615}
592 616
593int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,617int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
594 unsigned int asid)618 struct vhost_iotlb *iotlb,
619 unsigned int asid)
595{620{
596 int err;621 int err;
597 622
598 mutex_lock(&mvdev->mr.mkey_mtx);623 if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
599 err = _mlx5_vdpa_create_mr(mvdev, iotlb, asid);624 return 0;
600 mutex_unlock(&mvdev->mr.mkey_mtx);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
601 return err;633 return err;
602}634}
603 635
604int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,636int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev)
605 bool *change_map, unsigned int asid)
606{637{
607 struct mlx5_vdpa_mr *mr = &mvdev->mr;638 struct mlx5_vdpa_mr *mr;
608 int err = 0;639
640 mr = mlx5_vdpa_create_mr(mvdev, NULL);
641 if (IS_ERR(mr))
642 return PTR_ERR(mr);
609 643
610 *change_map = false;644 mlx5_vdpa_update_mr(mvdev, mr, 0);
611 mutex_lock(&mr->mkey_mtx);645
612 if (mr->initialized) {646 return mlx5_vdpa_update_cvq_iotlb(mvdev, NULL, 0);
613 mlx5_vdpa_info(mvdev, "memory map update\n");647}
614 *change_map = true;648
649int 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);
615 }661 }
616 if (!*change_map)
617 err = _mlx5_vdpa_create_mr(mvdev, iotlb, asid);
618 mutex_unlock(&mr->mkey_mtx);
619 662
620 return err;663 return 0;
621}664}
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
256 mlx5_vdpa_warn(mvdev, "resources already allocated\n");256 mlx5_vdpa_warn(mvdev, "resources already allocated\n");
257 return -EINVAL;257 return -EINVAL;
258 }258 }
259 mutex_init(&mvdev->mr.mkey_mtx);259 mutex_init(&mvdev->mr_mtx);
260 res->uar = mlx5_get_uars_page(mdev);260 res->uar = mlx5_get_uars_page(mdev);
261 if (IS_ERR(res->uar)) {261 if (IS_ERR(res->uar)) {
262 err = PTR_ERR(res->uar);262 err = PTR_ERR(res->uar);
@@ -301,7 +301,7 @@ err_pd: · 38 unmodified lines
301err_uctx:301err_uctx:
302 mlx5_put_uars_page(mdev, res->uar);302 mlx5_put_uars_page(mdev, res->uar);
303err_uars:303err_uars:
304 mutex_destroy(&mvdev->mr.mkey_mtx);304 mutex_destroy(&mvdev->mr_mtx);
305 return err;305 return err;
306}306}
307 307
@@ -318,6 +318,6 @@ void mlx5_vdpa_free_resources(struct mlx5_vdpa_dev *mvdev) · 10 unmodified lines
318 dealloc_pd(mvdev, res->pdn, res->uid);318 dealloc_pd(mvdev, res->pdn, res->uid);
319 destroy_uctx(mvdev, res->uid);319 destroy_uctx(mvdev, res->uid);
320 mlx5_put_uars_page(mvdev->mdev, res->uar);320 mlx5_put_uars_page(mvdev->mdev, res->uar);
321 mutex_destroy(&mvdev->mr.mkey_mtx);321 mutex_destroy(&mvdev->mr_mtx);
322 res->valid = false;322 res->valid = false;
323}323}
drivers/vdpa/mlx5/net/mlx5_vnet.c+106−31
@@ -7,6 +7,7 @@ · 6 unmodified lines
7#include <uapi/linux/virtio_net.h>7#include <uapi/linux/virtio_net.h>
8#include <uapi/linux/virtio_ids.h>8#include <uapi/linux/virtio_ids.h>
9#include <uapi/linux/vdpa.h>9#include <uapi/linux/vdpa.h>
10#include <uapi/linux/vhost_types.h>
10#include <linux/virtio_config.h>11#include <linux/virtio_config.h>
11#include <linux/auxiliary_bus.h>12#include <linux/auxiliary_bus.h>
12#include <linux/mlx5/cq.h>13#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
861{862{
862 int inlen = MLX5_ST_SZ_BYTES(create_virtio_net_q_in);863 int inlen = MLX5_ST_SZ_BYTES(create_virtio_net_q_in);
863 u32 out[MLX5_ST_SZ_DW(create_virtio_net_q_out)] = {};864 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;
864 void *obj_context;868 void *obj_context;
865 u16 mlx_features;869 u16 mlx_features;
866 void *cmd_hdr;870 void *cmd_hdr;
@@ -913,7 +917,14 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque · 46 unmodified lines
913 MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr);917 MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr);
914 MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr);918 MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr);
915 MLX5_SET64(virtio_q, vq_ctx, available_addr, mvq->driver_addr);919 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
917 MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id);928 MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id);
918 MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size);929 MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size);
919 MLX5_SET(virtio_q, vq_ctx, umem_2_id, mvq->umem2.id);930 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
2301 return MLX5_VDPA_DATAVQ_GROUP;2312 return MLX5_VDPA_DATAVQ_GROUP;
2302}2313}
2303 2314
2315static 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
2304static u64 mlx_to_vritio_features(u16 dev_features)2325static u64 mlx_to_vritio_features(u16 dev_features)
2305{2326{
2306 u64 result = 0;2327 u64 result = 0;
@@ -2539,6 +2560,11 @@ static void unregister_link_notifier(struct mlx5_vdpa_net *ndev) · 232 unmodified lines
2539 flush_workqueue(ndev->mvdev.wq);2560 flush_workqueue(ndev->mvdev.wq);
2540}2561}
2541 2562
2563static 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
2542static int mlx5_vdpa_set_driver_features(struct vdpa_device *vdev, u64 features)2568static int mlx5_vdpa_set_driver_features(struct vdpa_device *vdev, u64 features)
2543{2569{
2544 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);2570 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
2673}2699}
2674 2700
2675static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev,2701static 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)
2677{2704{
2678 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);2705 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
2679 int err;2706 int err;
@@ -2681,28 +2708,21 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev, · 1 unmodified line
2681 suspend_vqs(ndev);2708 suspend_vqs(ndev);
2682 err = save_channels_info(ndev);2709 err = save_channels_info(ndev);
2683 if (err)2710 if (err)
2684 goto err_mr;2711 return err;
2685 2712
2686 teardown_driver(ndev);2713 teardown_driver(ndev);
2687 mlx5_vdpa_destroy_mr_asid(mvdev, asid);2714
2688 err = mlx5_vdpa_create_mr(mvdev, iotlb, asid);2715 mlx5_vdpa_update_mr(mvdev, new_mr, asid);
2689 if (err)
2690 goto err_mr;
2691 2716
2692 if (!(mvdev->status & VIRTIO_CONFIG_S_DRIVER_OK) || mvdev->suspended)2717 if (!(mvdev->status & VIRTIO_CONFIG_S_DRIVER_OK) || mvdev->suspended)
2693 goto err_mr;2718 return 0;
2694 2719
2695 restore_channels_info(ndev);2720 restore_channels_info(ndev);
2696 err = setup_driver(mvdev);2721 err = setup_driver(mvdev);
2697 if (err)2722 if (err)
2698 goto err_setup;2723 return err;
2699 2724
2700 return 0;2725 return 0;
2701
2702err_setup:
2703 mlx5_vdpa_destroy_mr_asid(mvdev, asid);
2704err_mr:
2705 return err;
2706}2726}
2707 2727
2708/* reslock must be held for this function */2728/* 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
2841err_driver:2861err_driver:
2842 unregister_link_notifier(ndev);2862 unregister_link_notifier(ndev);
2843err_setup:2863err_setup:
2844 mlx5_vdpa_destroy_mr(&ndev->mvdev);2864 mlx5_vdpa_destroy_mr_resources(&ndev->mvdev);
2845 ndev->mvdev.status |= VIRTIO_CONFIG_S_FAILED;2865 ndev->mvdev.status |= VIRTIO_CONFIG_S_FAILED;
2846err_clear:2866err_clear:
2847 up_write(&ndev->reslock);2867 up_write(&ndev->reslock);
@@ -2856,7 +2876,7 @@ static void init_group_to_asid_map(struct mlx5_vdpa_dev *mvdev) · 8 unmodified lines
2856 mvdev->group2asid[i] = 0;2876 mvdev->group2asid[i] = 0;
2857}2877}
2858 2878
2859static int mlx5_vdpa_reset(struct vdpa_device *vdev)2879static int mlx5_vdpa_compat_reset(struct vdpa_device *vdev, u32 flags)
2860{2880{
2861 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);2881 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
2862 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);2882 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
2868 unregister_link_notifier(ndev);2888 unregister_link_notifier(ndev);
2869 teardown_driver(ndev);2889 teardown_driver(ndev);
2870 clear_vqs_ready(ndev);2890 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);
2872 ndev->mvdev.status = 0;2893 ndev->mvdev.status = 0;
2873 ndev->mvdev.suspended = false;2894 ndev->mvdev.suspended = false;
2874 ndev->cur_num_vqs = 0;2895 ndev->cur_num_vqs = 0;
@@ -2879,8 +2900,9 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev) · 4 unmodified lines
2879 init_group_to_asid_map(mvdev);2900 init_group_to_asid_map(mvdev);
2880 ++mvdev->generation;2901 ++mvdev->generation;
2881 2902
2882 if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {2903 if ((flags & VDPA_RESET_F_CLEAN_MAP) &&
2883 if (mlx5_vdpa_create_mr(mvdev, NULL, 0))2904 MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
2905 if (mlx5_vdpa_create_dma_mr(mvdev))
2884 mlx5_vdpa_warn(mvdev, "create MR failed\n");2906 mlx5_vdpa_warn(mvdev, "create MR failed\n");
2885 }2907 }
2886 up_write(&ndev->reslock);2908 up_write(&ndev->reslock);
@@ -2888,6 +2910,11 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev) · 1 unmodified line
2888 return 0;2910 return 0;
2889}2911}
2890 2912
2913static int mlx5_vdpa_reset(struct vdpa_device *vdev)
2914{
2915 return mlx5_vdpa_compat_reset(vdev, 0);
2916}
2917
2891static size_t mlx5_vdpa_get_config_size(struct vdpa_device *vdev)2918static size_t mlx5_vdpa_get_config_size(struct vdpa_device *vdev)
2892{2919{
2893 return sizeof(struct virtio_net_config);2920 return sizeof(struct virtio_net_config);
@@ -2919,18 +2946,38 @@ static u32 mlx5_vdpa_get_generation(struct vdpa_device *vdev) · 25 unmodified lines
2919static int set_map_data(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,2946static int set_map_data(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
2920 unsigned int asid)2947 unsigned int asid)
2921{2948{
2922 bool change_map;2949 struct mlx5_vdpa_mr *new_mr;
2923 int err;2950 int err;
2924 2951
2925 err = mlx5_vdpa_handle_set_map(mvdev, iotlb, &change_map, asid);2952 if (asid >= MLX5_VDPA_NUM_AS)
2926 if (err) {2953 return -EINVAL;
2927 mlx5_vdpa_warn(mvdev, "set map failed(%d)\n", err);2954
2928 return err;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 }
2929 }2975 }
2930 2976
2931 if (change_map)2977 return mlx5_vdpa_update_cvq_iotlb(mvdev, iotlb, asid);
2932 err = mlx5_vdpa_change_map(mvdev, iotlb, asid);
2933 2978
2979out_err:
2980 mlx5_vdpa_destroy_mr(mvdev, new_mr);
2934 return err;2981 return err;
2935}2982}
2936 2983
@@ -2947,6 +2994,18 @@ static int mlx5_vdpa_set_map(struct vdpa_device *vdev, unsigned int asid, · 10 unmodified lines
2947 return err;2994 return err;
2948}2995}
2949 2996
2997static 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
2950static struct device *mlx5_get_vq_dma_dev(struct vdpa_device *vdev, u16 idx)3009static struct device *mlx5_get_vq_dma_dev(struct vdpa_device *vdev, u16 idx)
2951{3010{
2952 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);3011 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
@@ -2985,7 +3044,7 @@ static void mlx5_vdpa_free(struct vdpa_device *vdev) · 32 unmodified lines
2985 ndev = to_mlx5_vdpa_ndev(mvdev);3044 ndev = to_mlx5_vdpa_ndev(mvdev);
2986 3045
2987 free_resources(ndev);3046 free_resources(ndev);
2988 mlx5_vdpa_destroy_mr(mvdev);3047 mlx5_vdpa_destroy_mr_resources(mvdev);
2989 if (!is_zero_ether_addr(ndev->config.mac)) {3048 if (!is_zero_ether_addr(ndev->config.mac)) {
2990 pfmdev = pci_get_drvdata(pci_physfn(mvdev->mdev->pdev));3049 pfmdev = pci_get_drvdata(pci_physfn(mvdev->mdev->pdev));
2991 mlx5_mpfs_del_mac(pfmdev, ndev->config.mac);3050 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
3169 unsigned int asid)3228 unsigned int asid)
3170{3229{
3171 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);3230 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
3231 int err = 0;
3172 3232
3173 if (group >= MLX5_VDPA_NUMVQ_GROUPS)3233 if (group >= MLX5_VDPA_NUMVQ_GROUPS)
3174 return -EINVAL;3234 return -EINVAL;
3175 3235
3176 mvdev->group2asid[group] = asid;3236 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;
3178}3244}
3179 3245
3180static const struct vdpa_config_ops mlx5_vdpa_ops = {3246static const struct vdpa_config_ops mlx5_vdpa_ops = {
@@ -3191,7 +3257,9 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = { · 10 unmodified lines
3191 .get_vq_irq = mlx5_get_vq_irq,3257 .get_vq_irq = mlx5_get_vq_irq,
3192 .get_vq_align = mlx5_vdpa_get_vq_align,3258 .get_vq_align = mlx5_vdpa_get_vq_align,
3193 .get_vq_group = mlx5_vdpa_get_vq_group,3259 .get_vq_group = mlx5_vdpa_get_vq_group,
3260 .get_vq_desc_group = mlx5_vdpa_get_vq_desc_group, /* Op disabled if not supported. */
3194 .get_device_features = mlx5_vdpa_get_device_features,3261 .get_device_features = mlx5_vdpa_get_device_features,
3262 .get_backend_features = mlx5_vdpa_get_backend_features,
3195 .set_driver_features = mlx5_vdpa_set_driver_features,3263 .set_driver_features = mlx5_vdpa_set_driver_features,
3196 .get_driver_features = mlx5_vdpa_get_driver_features,3264 .get_driver_features = mlx5_vdpa_get_driver_features,
3197 .set_config_cb = mlx5_vdpa_set_config_cb,3265 .set_config_cb = mlx5_vdpa_set_config_cb,
@@ -3201,11 +3269,13 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = { · 3 unmodified lines
3201 .get_status = mlx5_vdpa_get_status,3269 .get_status = mlx5_vdpa_get_status,
3202 .set_status = mlx5_vdpa_set_status,3270 .set_status = mlx5_vdpa_set_status,
3203 .reset = mlx5_vdpa_reset,3271 .reset = mlx5_vdpa_reset,
3272 .compat_reset = mlx5_vdpa_compat_reset,
3204 .get_config_size = mlx5_vdpa_get_config_size,3273 .get_config_size = mlx5_vdpa_get_config_size,
3205 .get_config = mlx5_vdpa_get_config,3274 .get_config = mlx5_vdpa_get_config,
3206 .set_config = mlx5_vdpa_set_config,3275 .set_config = mlx5_vdpa_set_config,
3207 .get_generation = mlx5_vdpa_get_generation,3276 .get_generation = mlx5_vdpa_get_generation,
3208 .set_map = mlx5_vdpa_set_map,3277 .set_map = mlx5_vdpa_set_map,
3278 .reset_map = mlx5_vdpa_reset_map,
3209 .set_group_asid = mlx5_set_group_asid,3279 .set_group_asid = mlx5_set_group_asid,
3210 .get_vq_dma_dev = mlx5_get_vq_dma_dev,3280 .get_vq_dma_dev = mlx5_get_vq_dma_dev,
3211 .free = mlx5_vdpa_free,3281 .free = mlx5_vdpa_free,
@@ -3289,6 +3359,7 @@ struct mlx5_vdpa_mgmtdev { · 77 unmodified lines
3289 struct vdpa_mgmt_dev mgtdev;3359 struct vdpa_mgmt_dev mgtdev;
3290 struct mlx5_adev *madev;3360 struct mlx5_adev *madev;
3291 struct mlx5_vdpa_net *ndev;3361 struct mlx5_vdpa_net *ndev;
3362 struct vdpa_config_ops vdpa_ops;
3292};3363};
3293 3364
3294static int config_func_mtu(struct mlx5_core_dev *mdev, u16 mtu)3365static 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
3402 max_vqs = 2;3473 max_vqs = 2;
3403 }3474 }
3404 3475
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,
3406 MLX5_VDPA_NUMVQ_GROUPS, MLX5_VDPA_NUM_AS, name, false);3477 MLX5_VDPA_NUMVQ_GROUPS, MLX5_VDPA_NUM_AS, name, false);
3407 if (IS_ERR(ndev))3478 if (IS_ERR(ndev))
3408 return PTR_ERR(ndev);3479 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
3485 goto err_mpfs;3556 goto err_mpfs;
3486 3557
3487 if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {3558 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);
3489 if (err)3560 if (err)
3490 goto err_res;3561 goto err_res;
3491 }3562 }
@@ -3515,7 +3586,7 @@ err_reg: · 23 unmodified lines
3515err_res2:3586err_res2:
3516 free_resources(ndev);3587 free_resources(ndev);
3517err_mr:3588err_mr:
3518 mlx5_vdpa_destroy_mr(mvdev);3589 mlx5_vdpa_destroy_mr_resources(mvdev);
3519err_res:3590err_res:
3520 mlx5_vdpa_free_resources(&ndev->mvdev);3591 mlx5_vdpa_free_resources(&ndev->mvdev);
3521err_mpfs:3592err_mpfs:
@@ -3575,6 +3646,10 @@ static int mlx5v_probe(struct auxiliary_device *adev, · 53 unmodified lines
3575 MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues) + 1;3646 MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues) + 1;
3576 mgtdev->mgtdev.supported_features = get_supported_features(mdev);3647 mgtdev->mgtdev.supported_features = get_supported_features(mdev);
3577 mgtdev->madev = madev;3648 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;
3578 3653
3579 err = vdpa_mgmtdev_register(&mgtdev->mgtdev);3654 err = vdpa_mgmtdev_register(&mgtdev->mgtdev);
3580 if (err)3655 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
139 vq->vring.notify = NULL;139 vq->vring.notify = NULL;
140}140}
141 141
142static void vdpasim_do_reset(struct vdpasim *vdpasim)142static void vdpasim_do_reset(struct vdpasim *vdpasim, u32 flags)
143{143{
144 int i;144 int i;
145 145
@@ -151,11 +151,13 @@ static void vdpasim_do_reset(struct vdpasim *vdpasim) · 5 unmodified lines
151 &vdpasim->iommu_lock);151 &vdpasim->iommu_lock);
152 }152 }
153 153
154 for (i = 0; i < vdpasim->dev_attr.nas; i++) {154 if (flags & VDPA_RESET_F_CLEAN_MAP) {
155 vhost_iotlb_reset(&vdpasim->iommu[i]);155 for (i = 0; i < vdpasim->dev_attr.nas; i++) {
156 vhost_iotlb_add_range(&vdpasim->iommu[i], 0, ULONG_MAX,156 vhost_iotlb_reset(&vdpasim->iommu[i]);
157 0, VHOST_MAP_RW);157 vhost_iotlb_add_range(&vdpasim->iommu[i], 0, ULONG_MAX,
158 vdpasim->iommu_pt[i] = true;158 0, VHOST_MAP_RW);
159 vdpasim->iommu_pt[i] = true;
160 }
159 }161 }
160 162
161 vdpasim->running = true;163 vdpasim->running = true;
@@ -259,8 +261,12 @@ struct vdpasim *vdpasim_create(struct vdpasim_dev_attr *dev_attr, · 97 unmodified lines
259 if (!vdpasim->iommu_pt)261 if (!vdpasim->iommu_pt)
260 goto err_iommu;262 goto err_iommu;
261 263
262 for (i = 0; i < vdpasim->dev_attr.nas; i++)264 for (i = 0; i < vdpasim->dev_attr.nas; i++) {
263 vhost_iotlb_init(&vdpasim->iommu[i], max_iotlb_entries, 0);265 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 }
264 270
265 for (i = 0; i < dev_attr->nvqs; i++)271 for (i = 0; i < dev_attr->nvqs; i++)
266 vringh_set_iotlb(&vdpasim->vqs[i].vring, &vdpasim->iommu[0],272 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
480 mutex_unlock(&vdpasim->mutex);486 mutex_unlock(&vdpasim->mutex);
481}487}
482 488
483static int vdpasim_reset(struct vdpa_device *vdpa)489static int vdpasim_compat_reset(struct vdpa_device *vdpa, u32 flags)
484{490{
485 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);491 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
486 492
487 mutex_lock(&vdpasim->mutex);493 mutex_lock(&vdpasim->mutex);
488 vdpasim->status = 0;494 vdpasim->status = 0;
489 vdpasim_do_reset(vdpasim);495 vdpasim_do_reset(vdpasim, flags);
490 mutex_unlock(&vdpasim->mutex);496 mutex_unlock(&vdpasim->mutex);
491 497
492 return 0;498 return 0;
493}499}
494 500
501static int vdpasim_reset(struct vdpa_device *vdpa)
502{
503 return vdpasim_compat_reset(vdpa, 0);
504}
505
495static int vdpasim_suspend(struct vdpa_device *vdpa)506static int vdpasim_suspend(struct vdpa_device *vdpa)
496{507{
497 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);508 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
@@ -637,6 +648,25 @@ err: · 139 unmodified lines
637 return ret;648 return ret;
638}649}
639 650
651static 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;
665out:
666 spin_unlock(&vdpasim->iommu_lock);
667 return 0;
668}
669
640static int vdpasim_bind_mm(struct vdpa_device *vdpa, struct mm_struct *mm)670static int vdpasim_bind_mm(struct vdpa_device *vdpa, struct mm_struct *mm)
641{671{
642 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);672 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
@@ -749,6 +779,7 @@ static const struct vdpa_config_ops vdpasim_config_ops = { · 106 unmodified lines
749 .get_status = vdpasim_get_status,779 .get_status = vdpasim_get_status,
750 .set_status = vdpasim_set_status,780 .set_status = vdpasim_set_status,
751 .reset = vdpasim_reset,781 .reset = vdpasim_reset,
782 .compat_reset = vdpasim_compat_reset,
752 .suspend = vdpasim_suspend,783 .suspend = vdpasim_suspend,
753 .resume = vdpasim_resume,784 .resume = vdpasim_resume,
754 .get_config_size = vdpasim_get_config_size,785 .get_config_size = vdpasim_get_config_size,
@@ -759,6 +790,7 @@ static const struct vdpa_config_ops vdpasim_config_ops = { · 4 unmodified lines
759 .set_group_asid = vdpasim_set_group_asid,790 .set_group_asid = vdpasim_set_group_asid,
760 .dma_map = vdpasim_dma_map,791 .dma_map = vdpasim_dma_map,
761 .dma_unmap = vdpasim_dma_unmap,792 .dma_unmap = vdpasim_dma_unmap,
793 .reset_map = vdpasim_reset_map,
762 .bind_mm = vdpasim_bind_mm,794 .bind_mm = vdpasim_bind_mm,
763 .unbind_mm = vdpasim_unbind_mm,795 .unbind_mm = vdpasim_unbind_mm,
764 .free = vdpasim_free,796 .free = vdpasim_free,
@@ -787,6 +819,7 @@ static const struct vdpa_config_ops vdpasim_batch_config_ops = { · 22 unmodified lines
787 .get_status = vdpasim_get_status,819 .get_status = vdpasim_get_status,
788 .set_status = vdpasim_set_status,820 .set_status = vdpasim_set_status,
789 .reset = vdpasim_reset,821 .reset = vdpasim_reset,
822 .compat_reset = vdpasim_compat_reset,
790 .suspend = vdpasim_suspend,823 .suspend = vdpasim_suspend,
791 .resume = vdpasim_resume,824 .resume = vdpasim_resume,
792 .get_config_size = vdpasim_get_config_size,825 .get_config_size = vdpasim_get_config_size,
@@ -796,6 +829,7 @@ static const struct vdpa_config_ops vdpasim_batch_config_ops = { · 3 unmodified lines
796 .get_iova_range = vdpasim_get_iova_range,829 .get_iova_range = vdpasim_get_iova_range,
797 .set_group_asid = vdpasim_set_group_asid,830 .set_group_asid = vdpasim_set_group_asid,
798 .set_map = vdpasim_set_map,831 .set_map = vdpasim_set_map,
832 .reset_map = vdpasim_reset_map,
799 .bind_mm = vdpasim_bind_mm,833 .bind_mm = vdpasim_bind_mm,
800 .unbind_mm = vdpasim_unbind_mm,834 .unbind_mm = vdpasim_unbind_mm,
801 .free = vdpasim_free,835 .free = vdpasim_free,
drivers/vdpa/vdpa_user/vduse_dev.c+21−19
@@ -134,7 +134,6 @@ static DEFINE_MUTEX(vduse_lock); · 133 unmodified lines
134static DEFINE_IDR(vduse_idr);134static DEFINE_IDR(vduse_idr);
135 135
136static dev_t vduse_major;136static dev_t vduse_major;
137static struct class *vduse_class;
138static struct cdev vduse_ctrl_cdev;137static struct cdev vduse_ctrl_cdev;
139static struct cdev vduse_cdev;138static struct cdev vduse_cdev;
140static struct workqueue_struct *vduse_irq_wq;139static struct workqueue_struct *vduse_irq_wq;
@@ -1528,6 +1527,16 @@ static const struct kobj_type vq_type = { · 1387 unmodified lines
1528 .default_groups = vq_groups,1527 .default_groups = vq_groups,
1529};1528};
1530 1529
1530static char *vduse_devnode(const struct device *dev, umode_t *mode)
1531{
1532 return kasprintf(GFP_KERNEL, "vduse/%s", dev_name(dev));
1533}
1534
1535static const struct class vduse_class = {
1536 .name = "vduse",
1537 .devnode = vduse_devnode,
1538};
1539
1531static void vduse_dev_deinit_vqs(struct vduse_dev *dev)1540static void vduse_dev_deinit_vqs(struct vduse_dev *dev)
1532{1541{
1533 int i;1542 int i;
@@ -1638,7 +1647,7 @@ static int vduse_destroy_dev(char *name) · 104 unmodified lines
1638 mutex_unlock(&dev->lock);1647 mutex_unlock(&dev->lock);
1639 1648
1640 vduse_dev_reset(dev);1649 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));
1642 idr_remove(&vduse_idr, dev->minor);1651 idr_remove(&vduse_idr, dev->minor);
1643 kvfree(dev->config);1652 kvfree(dev->config);
1644 vduse_dev_deinit_vqs(dev);1653 vduse_dev_deinit_vqs(dev);
@@ -1805,7 +1814,7 @@ static int vduse_create_dev(struct vduse_dev_config *config, · 160 unmodified lines
1805 1814
1806 dev->minor = ret;1815 dev->minor = ret;
1807 dev->msg_timeout = VDUSE_MSG_DEFAULT_TIMEOUT;1816 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,
1809 MKDEV(MAJOR(vduse_major), dev->minor),1818 MKDEV(MAJOR(vduse_major), dev->minor),
1810 dev, vduse_dev_groups, "%s", config->name);1819 dev, vduse_dev_groups, "%s", config->name);
1811 if (IS_ERR(dev->dev)) {1820 if (IS_ERR(dev->dev)) {
@@ -1821,7 +1830,7 @@ static int vduse_create_dev(struct vduse_dev_config *config, · 9 unmodified lines
1821 1830
1822 return 0;1831 return 0;
1823err_vqs:1832err_vqs:
1824 device_destroy(vduse_class, MKDEV(MAJOR(vduse_major), dev->minor));1833 device_destroy(&vduse_class, MKDEV(MAJOR(vduse_major), dev->minor));
1825err_dev:1834err_dev:
1826 idr_remove(&vduse_idr, dev->minor);1835 idr_remove(&vduse_idr, dev->minor);
1827err_idr:1836err_idr:
@@ -1934,11 +1943,6 @@ static const struct file_operations vduse_ctrl_fops = { · 106 unmodified lines
1934 .llseek = noop_llseek,1943 .llseek = noop_llseek,
1935};1944};
1936 1945
1937static char *vduse_devnode(const struct device *dev, umode_t *mode)
1938{
1939 return kasprintf(GFP_KERNEL, "vduse/%s", dev_name(dev));
1940}
1941
1942struct vduse_mgmt_dev {1946struct vduse_mgmt_dev {
1943 struct vdpa_mgmt_dev mgmt_dev;1947 struct vdpa_mgmt_dev mgmt_dev;
1944 struct device dev;1948 struct device dev;
@@ -2082,11 +2086,9 @@ static int vduse_init(void) · 137 unmodified lines
2082 int ret;2086 int ret;
2083 struct device *dev;2087 struct device *dev;
2084 2088
2085 vduse_class = class_create("vduse");2089 ret = class_register(&vduse_class);
2086 if (IS_ERR(vduse_class))2090 if (ret)
2087 return PTR_ERR(vduse_class);2091 return ret;
2088
2089 vduse_class->devnode = vduse_devnode;
2090 2092
2091 ret = alloc_chrdev_region(&vduse_major, 0, VDUSE_DEV_MAX, "vduse");2093 ret = alloc_chrdev_region(&vduse_major, 0, VDUSE_DEV_MAX, "vduse");
2092 if (ret)2094 if (ret)
@@ -2099,7 +2101,7 @@ static int vduse_init(void) · 6 unmodified lines
2099 if (ret)2101 if (ret)
2100 goto err_ctrl_cdev;2102 goto err_ctrl_cdev;
2101 2103
2102 dev = device_create(vduse_class, NULL, vduse_major, NULL, "control");2104 dev = device_create(&vduse_class, NULL, vduse_major, NULL, "control");
2103 if (IS_ERR(dev)) {2105 if (IS_ERR(dev)) {
2104 ret = PTR_ERR(dev);2106 ret = PTR_ERR(dev);
2105 goto err_device;2107 goto err_device;
@@ -2141,13 +2143,13 @@ err_bound_wq: · 35 unmodified lines
2141err_wq:2143err_wq:
2142 cdev_del(&vduse_cdev);2144 cdev_del(&vduse_cdev);
2143err_cdev:2145err_cdev:
2144 device_destroy(vduse_class, vduse_major);2146 device_destroy(&vduse_class, vduse_major);
2145err_device:2147err_device:
2146 cdev_del(&vduse_ctrl_cdev);2148 cdev_del(&vduse_ctrl_cdev);
2147err_ctrl_cdev:2149err_ctrl_cdev:
2148 unregister_chrdev_region(vduse_major, VDUSE_DEV_MAX);2150 unregister_chrdev_region(vduse_major, VDUSE_DEV_MAX);
2149err_chardev_region:2151err_chardev_region:
2150 class_destroy(vduse_class);2152 class_unregister(&vduse_class);
2151 return ret;2153 return ret;
2152}2154}
2153module_init(vduse_init);2155module_init(vduse_init);
@@ -2159,10 +2161,10 @@ static void vduse_exit(void) · 5 unmodified lines
2159 destroy_workqueue(vduse_irq_bound_wq);2161 destroy_workqueue(vduse_irq_bound_wq);
2160 destroy_workqueue(vduse_irq_wq);2162 destroy_workqueue(vduse_irq_wq);
2161 cdev_del(&vduse_cdev);2163 cdev_del(&vduse_cdev);
2162 device_destroy(vduse_class, vduse_major);2164 device_destroy(&vduse_class, vduse_major);
2163 cdev_del(&vduse_ctrl_cdev);2165 cdev_del(&vduse_ctrl_cdev);
2164 unregister_chrdev_region(vduse_major, VDUSE_DEV_MAX);2166 unregister_chrdev_region(vduse_major, VDUSE_DEV_MAX);
2165 class_destroy(vduse_class);2167 class_unregister(&vduse_class);
2166}2168}
2167module_exit(vduse_exit);2169module_exit(vduse_exit);
2168 2170
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
1158 /*1158 /*
1159 * Set prot_iter to data_iter and truncate it to1159 * Set prot_iter to data_iter and truncate it to
1160 * prot_bytes, and advance data_iter past any1160 * prot_bytes, and advance data_iter past any
1161 * preceeding prot_bytes that may be present.1161 * preceding prot_bytes that may be present.
1162 *1162 *
1163 * Also fix up the exp_data_len to reflect only the1163 * Also fix up the exp_data_len to reflect only the
1164 * actual data payload length.1164 * 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
131 return vhost_vdpa_alloc_as(v, asid);131 return vhost_vdpa_alloc_as(v, asid);
132}132}
133 133
134static 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
134static int vhost_vdpa_remove_as(struct vhost_vdpa *v, u32 asid)143static int vhost_vdpa_remove_as(struct vhost_vdpa *v, u32 asid)
135{144{
136 struct vhost_vdpa_as *as = asid_to_as(v, asid);145 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
140 149
141 hlist_del(&as->hash_link);150 hlist_del(&as->hash_link);
142 vhost_vdpa_iotlb_unmap(v, &as->iotlb, 0ULL, 0ULL - 1, asid);151 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);
143 kfree(as);160 kfree(as);
144 161
145 return 0;162 return 0;
@@ -210,13 +227,24 @@ static void vhost_vdpa_unsetup_vq_irq(struct vhost_vdpa *v, u16 qid) · 64 unmodified lines
210 irq_bypass_unregister_producer(&vq->call_ctx.producer);227 irq_bypass_unregister_producer(&vq->call_ctx.producer);
211}228}
212 229
213static int vhost_vdpa_reset(struct vhost_vdpa *v)230static int _compat_vdpa_reset(struct vhost_vdpa *v)
214{231{
215 struct vdpa_device *vdpa = v->vdpa;232 struct vdpa_device *vdpa = v->vdpa;
233 u32 flags = 0;
216 234
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 }
218 240
219 return vdpa_reset(vdpa);241 return vdpa_reset(vdpa, flags);
242}
243
244static int vhost_vdpa_reset(struct vhost_vdpa *v)
245{
246 v->in_batch = 0;
247 return _compat_vdpa_reset(v);
220}248}
221 249
222static long vhost_vdpa_bind_mm(struct vhost_vdpa *v)250static 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
295 vhost_vdpa_unsetup_vq_irq(v, i);323 vhost_vdpa_unsetup_vq_irq(v, i);
296 324
297 if (status == 0) {325 if (status == 0) {
298 ret = vdpa_reset(vdpa);326 ret = _compat_vdpa_reset(v);
299 if (ret)327 if (ret)
300 return ret;328 return ret;
301 } else329 } else
@@ -389,6 +417,14 @@ static bool vhost_vdpa_can_resume(const struct vhost_vdpa *v) · 87 unmodified lines
389 return ops->resume;417 return ops->resume;
390}418}
391 419
420static 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
392static long vhost_vdpa_get_features(struct vhost_vdpa *v, u64 __user *featurep)428static long vhost_vdpa_get_features(struct vhost_vdpa *v, u64 __user *featurep)
393{429{
394 struct vdpa_device *vdpa = v->vdpa;430 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
414 return ops->get_backend_features(vdpa);450 return ops->get_backend_features(vdpa);
415}451}
416 452
453static 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
417static long vhost_vdpa_set_features(struct vhost_vdpa *v, u64 __user *featurep)462static long vhost_vdpa_set_features(struct vhost_vdpa *v, u64 __user *featurep)
418{463{
419 struct vdpa_device *vdpa = v->vdpa;464 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
605 else if (copy_to_user(argp, &s, sizeof(s)))650 else if (copy_to_user(argp, &s, sizeof(s)))
606 return -EFAULT;651 return -EFAULT;
607 return 0;652 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;
608 case VHOST_VDPA_SET_GROUP_ASID:663 case VHOST_VDPA_SET_GROUP_ASID:
609 if (copy_from_user(&s, argp, sizeof(s)))664 if (copy_from_user(&s, argp, sizeof(s)))
610 return -EFAULT;665 return -EFAULT;
@@ -690,6 +745,8 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep, · 79 unmodified lines
690 if (copy_from_user(&features, featurep, sizeof(features)))745 if (copy_from_user(&features, featurep, sizeof(features)))
691 return -EFAULT;746 return -EFAULT;
692 if (features & ~(VHOST_VDPA_BACKEND_FEATURES |747 if (features & ~(VHOST_VDPA_BACKEND_FEATURES |
748 BIT_ULL(VHOST_BACKEND_F_DESC_ASID) |
749 BIT_ULL(VHOST_BACKEND_F_IOTLB_PERSIST) |
693 BIT_ULL(VHOST_BACKEND_F_SUSPEND) |750 BIT_ULL(VHOST_BACKEND_F_SUSPEND) |
694 BIT_ULL(VHOST_BACKEND_F_RESUME) |751 BIT_ULL(VHOST_BACKEND_F_RESUME) |
695 BIT_ULL(VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK)))752 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
700 if ((features & BIT_ULL(VHOST_BACKEND_F_RESUME)) &&757 if ((features & BIT_ULL(VHOST_BACKEND_F_RESUME)) &&
701 !vhost_vdpa_can_resume(v))758 !vhost_vdpa_can_resume(v))
702 return -EOPNOTSUPP;759 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;
703 vhost_set_backend_features(&v->vdev, features);769 vhost_set_backend_features(&v->vdev, features);
704 return 0;770 return 0;
705 }771 }
@@ -753,6 +819,10 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep, · 47 unmodified lines
753 features |= BIT_ULL(VHOST_BACKEND_F_SUSPEND);819 features |= BIT_ULL(VHOST_BACKEND_F_SUSPEND);
754 if (vhost_vdpa_can_resume(v))820 if (vhost_vdpa_can_resume(v))
755 features |= BIT_ULL(VHOST_BACKEND_F_RESUME);821 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);
756 features |= vhost_vdpa_get_backend_features(v);826 features |= vhost_vdpa_get_backend_features(v);
757 if (copy_to_user(featurep, &features, sizeof(features)))827 if (copy_to_user(featurep, &features, sizeof(features)))
758 r = -EFAULT;828 r = -EFAULT;
@@ -1285,6 +1355,7 @@ static void vhost_vdpa_cleanup(struct vhost_vdpa *v) · 526 unmodified lines
1285 vhost_vdpa_free_domain(v);1355 vhost_vdpa_free_domain(v);
1286 vhost_dev_cleanup(&v->vdev);1356 vhost_dev_cleanup(&v->vdev);
1287 kfree(v->vdev.vqs);1357 kfree(v->vdev.vqs);
1358 v->vdev.vqs = NULL;
1288}1359}
1289 1360
1290static int vhost_vdpa_open(struct inode *inode, struct file *filep)1361static 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
745 * 2) update the host about the old page removed from vb->pages list;745 * 2) update the host about the old page removed from vb->pages list;
746 *746 *
747 * This function preforms the balloon page migration task.747 * This function preforms the balloon page migration task.
748 * Called through balloon_mapping->a_ops->migratepage748 * Called through movable_operations->migrate_page
749 */749 */
750static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info,750static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info,
751 struct page *newpage, struct page *page, enum migrate_mode mode)751 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
39 __virtio_set_bit(vdev, VIRTIO_F_RING_RESET);39 __virtio_set_bit(vdev, VIRTIO_F_RING_RESET);
40}40}
41 41
42static 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
64static 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
42/* virtio config->finalize_features() implementation */75/* virtio config->finalize_features() implementation */
43static int vp_finalize_features(struct virtio_device *vdev)76static int vp_finalize_features(struct virtio_device *vdev)
44{77{
@@ -57,6 +90,9 @@ static int vp_finalize_features(struct virtio_device *vdev) · 12 unmodified lines
57 return -EINVAL;90 return -EINVAL;
58 }91 }
59 92
93 if (vp_check_common_size(vdev))
94 return -EINVAL;
95
60 vp_modern_set_features(&vp_dev->mdev, vdev->features);96 vp_modern_set_features(&vp_dev->mdev, vdev->features);
61 97
62 return 0;98 return 0;
drivers/virtio/virtio_pci_modern_dev.c+5−1
@@ -203,6 +203,10 @@ static inline void check_offsets(void) · 202 unmodified lines
203 offsetof(struct virtio_pci_common_cfg, queue_used_lo));203 offsetof(struct virtio_pci_common_cfg, queue_used_lo));
204 BUILD_BUG_ON(VIRTIO_PCI_COMMON_Q_USEDHI !=204 BUILD_BUG_ON(VIRTIO_PCI_COMMON_Q_USEDHI !=
205 offsetof(struct virtio_pci_common_cfg, queue_used_hi));205 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));
206}210}
207 211
208/*212/*
@@ -292,7 +296,7 @@ int vp_modern_probe(struct virtio_pci_modern_device *mdev) · 83 unmodified lines
292 mdev->common = vp_modern_map_capability(mdev, common,296 mdev->common = vp_modern_map_capability(mdev, common,
293 sizeof(struct virtio_pci_common_cfg), 4,297 sizeof(struct virtio_pci_common_cfg), 4,
294 0, sizeof(struct virtio_pci_modern_common_cfg),298 0, sizeof(struct virtio_pci_modern_common_cfg),
295 NULL, NULL);299 &mdev->common_len, NULL);
296 if (!mdev->common)300 if (!mdev->common)
297 goto err_map_common;301 goto err_map_common;
298 mdev->isr = vp_modern_map_capability(mdev, isr, sizeof(u8), 1,302 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
100{100{
101 struct vdpa_device *vdpa = vd_get_vdpa(vdev);101 struct vdpa_device *vdpa = vd_get_vdpa(vdev);
102 102
103 vdpa_reset(vdpa);103 vdpa_reset(vdpa, 0);
104}104}
105 105
106static bool virtio_vdpa_notify(struct virtqueue *vq)106static 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
1232 u8 max_emulated_devices[0x8];1232 u8 max_emulated_devices[0x8];
1233 u8 max_num_virtio_queues[0x18];1233 u8 max_num_virtio_queues[0x18];
1234 1234
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];
1236 1242
1237 u8 umem_1_buffer_param_a[0x20];1243 u8 umem_1_buffer_param_a[0x20];
1238 1244
include/linux/mlx5/mlx5_ifc_vdpa.h+6−1
@@ -74,7 +74,11 @@ struct mlx5_ifc_virtio_q_bits { · 73 unmodified lines
74 u8 reserved_at_320[0x8];74 u8 reserved_at_320[0x8];
75 u8 pd[0x18];75 u8 pd[0x18];
76 76
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];
78};82};
79 83
80struct mlx5_ifc_virtio_net_q_object_bits {84struct mlx5_ifc_virtio_net_q_object_bits {
@@ -141,6 +145,7 @@ enum { · 60 unmodified lines
141 MLX5_VIRTQ_MODIFY_MASK_STATE = (u64)1 << 0,145 MLX5_VIRTQ_MODIFY_MASK_STATE = (u64)1 << 0,
142 MLX5_VIRTQ_MODIFY_MASK_DIRTY_BITMAP_PARAMS = (u64)1 << 3,146 MLX5_VIRTQ_MODIFY_MASK_DIRTY_BITMAP_PARAMS = (u64)1 << 3,
143 MLX5_VIRTQ_MODIFY_MASK_DIRTY_BITMAP_DUMP_ENABLE = (u64)1 << 4,147 MLX5_VIRTQ_MODIFY_MASK_DIRTY_BITMAP_DUMP_ENABLE = (u64)1 << 4,
148 MLX5_VIRTQ_MODIFY_MASK_DESC_GROUP_MKEY = (u64)1 << 14,
144};149};
145 150
146enum {151enum {
include/linux/vdpa.h+39−2
@@ -204,6 +204,16 @@ struct vdpa_map_file { · 203 unmodified lines
204 * @vdev: vdpa device204 * @vdev: vdpa device
205 * @idx: virtqueue index205 * @idx: virtqueue index
206 * Returns u32: group id for this virtqueue206 * 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.
207 * @get_device_features: Get virtio features supported by the device217 * @get_device_features: Get virtio features supported by the device
208 * @vdev: vdpa device218 * @vdev: vdpa device
209 * Returns the virtio features support by the219 * Returns the virtio features support by the
@@ -242,6 +252,17 @@ struct vdpa_map_file { · 32 unmodified lines
242 * @reset: Reset device252 * @reset: Reset device
243 * @vdev: vdpa device253 * @vdev: vdpa device
244 * Returns integer: success (0) or error (< 0)254 * 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)
245 * @suspend: Suspend the device (optional)266 * @suspend: Suspend the device (optional)
246 * @vdev: vdpa device267 * @vdev: vdpa device
247 * Returns integer: success (0) or error (< 0)268 * Returns integer: success (0) or error (< 0)
@@ -317,6 +338,15 @@ struct vdpa_map_file { · 69 unmodified lines
317 * @iova: iova to be unmapped338 * @iova: iova to be unmapped
318 * @size: size of the area339 * @size: size of the area
319 * Returns integer: success (0) or error (< 0)340 * 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)
320 * @get_vq_dma_dev: Get the dma device for a specific350 * @get_vq_dma_dev: Get the dma device for a specific
321 * virtqueue (optional)351 * virtqueue (optional)
322 * @vdev: vdpa device352 * @vdev: vdpa device
@@ -360,6 +390,7 @@ struct vdpa_config_ops { · 37 unmodified lines
360 /* Device ops */390 /* Device ops */
361 u32 (*get_vq_align)(struct vdpa_device *vdev);391 u32 (*get_vq_align)(struct vdpa_device *vdev);
362 u32 (*get_vq_group)(struct vdpa_device *vdev, u16 idx);392 u32 (*get_vq_group)(struct vdpa_device *vdev, u16 idx);
393 u32 (*get_vq_desc_group)(struct vdpa_device *vdev, u16 idx);
363 u64 (*get_device_features)(struct vdpa_device *vdev);394 u64 (*get_device_features)(struct vdpa_device *vdev);
364 u64 (*get_backend_features)(const struct vdpa_device *vdev);395 u64 (*get_backend_features)(const struct vdpa_device *vdev);
365 int (*set_driver_features)(struct vdpa_device *vdev, u64 features);396 int (*set_driver_features)(struct vdpa_device *vdev, u64 features);
@@ -373,6 +404,8 @@ struct vdpa_config_ops { · 7 unmodified lines
373 u8 (*get_status)(struct vdpa_device *vdev);404 u8 (*get_status)(struct vdpa_device *vdev);
374 void (*set_status)(struct vdpa_device *vdev, u8 status);405 void (*set_status)(struct vdpa_device *vdev, u8 status);
375 int (*reset)(struct vdpa_device *vdev);406 int (*reset)(struct vdpa_device *vdev);
407 int (*compat_reset)(struct vdpa_device *vdev, u32 flags);
408#define VDPA_RESET_F_CLEAN_MAP 1
376 int (*suspend)(struct vdpa_device *vdev);409 int (*suspend)(struct vdpa_device *vdev);
377 int (*resume)(struct vdpa_device *vdev);410 int (*resume)(struct vdpa_device *vdev);
378 size_t (*get_config_size)(struct vdpa_device *vdev);411 size_t (*get_config_size)(struct vdpa_device *vdev);
@@ -394,6 +427,7 @@ struct vdpa_config_ops { · 15 unmodified lines
394 u64 iova, u64 size, u64 pa, u32 perm, void *opaque);427 u64 iova, u64 size, u64 pa, u32 perm, void *opaque);
395 int (*dma_unmap)(struct vdpa_device *vdev, unsigned int asid,428 int (*dma_unmap)(struct vdpa_device *vdev, unsigned int asid,
396 u64 iova, u64 size);429 u64 iova, u64 size);
430 int (*reset_map)(struct vdpa_device *vdev, unsigned int asid);
397 int (*set_group_asid)(struct vdpa_device *vdev, unsigned int group,431 int (*set_group_asid)(struct vdpa_device *vdev, unsigned int group,
398 unsigned int asid);432 unsigned int asid);
399 struct device *(*get_vq_dma_dev)(struct vdpa_device *vdev, u16 idx);433 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
485 return vdev->dma_dev;519 return vdev->dma_dev;
486}520}
487 521
488static inline int vdpa_reset(struct vdpa_device *vdev)522static inline int vdpa_reset(struct vdpa_device *vdev, u32 flags)
489{523{
490 const struct vdpa_config_ops *ops = vdev->config;524 const struct vdpa_config_ops *ops = vdev->config;
491 int ret;525 int ret;
492 526
493 down_write(&vdev->cf_lock);527 down_write(&vdev->cf_lock);
494 vdev->features_valid = false;528 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);
496 up_write(&vdev->cf_lock);533 up_write(&vdev->cf_lock);
497 return ret;534 return ret;
498}535}
include/linux/virtio_pci_modern.h+23−12
@@ -12,37 +12,48 @@ struct virtio_pci_modern_common_cfg { · 11 unmodified lines
12 __le16 queue_reset; /* read-write */12 __le16 queue_reset; /* read-write */
13};13};
14 14
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 */
15struct virtio_pci_modern_device {37struct virtio_pci_modern_device {
16 struct pci_dev *pci_dev;38 struct pci_dev *pci_dev;
17 39
18 struct virtio_pci_common_cfg __iomem *common;40 struct virtio_pci_common_cfg __iomem *common;
19 /* Device-specific data (non-legacy mode) */
20 void __iomem *device;41 void __iomem *device;
21 /* Base of vq notifications (non-legacy mode). */
22 void __iomem *notify_base;42 void __iomem *notify_base;
23 /* Physical base of vq notifications */
24 resource_size_t notify_pa;43 resource_size_t notify_pa;
25 /* Where to read and clear interrupt */
26 u8 __iomem *isr;44 u8 __iomem *isr;
27 45
28 /* So we can sanity-check accesses. */
29 size_t notify_len;46 size_t notify_len;
30 size_t device_len;47 size_t device_len;
48 size_t common_len;
31 49
32 /* Capability for when we need to map notifications per-vq. */
33 int notify_map_cap;50 int notify_map_cap;
34 51
35 /* Multiply queue_notify_off by this value. (non-legacy mode). */
36 u32 notify_offset_multiplier;52 u32 notify_offset_multiplier;
37
38 int modern_bars;53 int modern_bars;
39
40 struct virtio_device_id id;54 struct virtio_device_id id;
41 55
42 /* optional check for vendor virtio device, returns dev_id or -ERRNO */
43 int (*device_id_check)(struct pci_dev *pdev);56 int (*device_id_check)(struct pci_dev *pdev);
44
45 /* optional mask for devices with limited DMA space */
46 u64 dma_mask;57 u64 dma_mask;
47};58};
48 59
include/uapi/linux/vhost.h+8−0
@@ -219,4 +219,12 @@ · 218 unmodified lines
219 */219 */
220#define VHOST_VDPA_RESUME _IO(VHOST_VIRTIO, 0x7E)220#define VHOST_VDPA_RESUME _IO(VHOST_VIRTIO, 0x7E)
221 221
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)
222#endif230#endif
include/uapi/linux/vhost_types.h+7−0
@@ -185,5 +185,12 @@ struct vhost_vdpa_iova_range { · 184 unmodified lines
185 * DRIVER_OK185 * DRIVER_OK
186 */186 */
187#define VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK 0x6187#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
188 195
189#endif196#endif
include/uapi/linux/virtio_config.h+5−0
@@ -105,6 +105,11 @@ · 104 unmodified lines
105 */105 */
106#define VIRTIO_F_NOTIFICATION_DATA 38106#define VIRTIO_F_NOTIFICATION_DATA 38
107 107
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
108/*113/*
109 * This feature indicates that the driver can reset a queue individually.114 * This feature indicates that the driver can reset a queue individually.
110 */115 */