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
...

+545 -185
+2 -2
Documentation/ABI/testing/sysfs-bus-vdpa
··· 1 - What: /sys/bus/vdpa/driver_autoprobe 2 Date: March 2020 3 Contact: virtualization@lists.linux-foundation.org 4 Description: ··· 17 Writing a device name to this file will cause the kernel binds 18 devices to a compatible driver. 19 20 - This can be useful when /sys/bus/vdpa/driver_autoprobe is 21 disabled. 22 23 What: /sys/bus/vdpa/drivers/.../bind
··· 1 + What: /sys/bus/vdpa/drivers_autoprobe 2 Date: March 2020 3 Contact: virtualization@lists.linux-foundation.org 4 Description: ··· 17 Writing a device name to this file will cause the kernel binds 18 devices to a compatible driver. 19 20 + This can be useful when /sys/bus/vdpa/drivers_autoprobe is 21 disabled. 22 23 What: /sys/bus/vdpa/drivers/.../bind
+6
MAINTAINERS
··· 13790 F: include/linux/mlx5/ 13791 F: include/uapi/rdma/mlx5-abi.h 13792 13793 MELLANOX MLXCPLD I2C AND MUX DRIVER 13794 M: Vadim Pasternak <vadimp@nvidia.com> 13795 M: Michael Shych <michaelsh@nvidia.com>
··· 13790 F: include/linux/mlx5/ 13791 F: include/uapi/rdma/mlx5-abi.h 13792 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 + 13799 MELLANOX MLXCPLD I2C AND MUX DRIVER 13800 M: Vadim Pasternak <vadimp@nvidia.com> 13801 M: Michael Shych <michaelsh@nvidia.com>
+3 -1
drivers/block/virtio_blk.c
··· 1311 u16 min_io_size; 1312 u8 physical_block_exp, alignment_offset; 1313 unsigned int queue_depth; 1314 1315 if (!vdev->config->get) { 1316 dev_err(&vdev->dev, "%s failure: config access disabled\n", ··· 1410 /* No real sector limit. */ 1411 blk_queue_max_hw_sectors(q, UINT_MAX); 1412 1413 - max_size = virtio_max_dma_size(vdev); 1414 1415 /* Host can optionally specify maximum segment size and number of 1416 * segments. */
··· 1311 u16 min_io_size; 1312 u8 physical_block_exp, alignment_offset; 1313 unsigned int queue_depth; 1314 + size_t max_dma_size; 1315 1316 if (!vdev->config->get) { 1317 dev_err(&vdev->dev, "%s failure: config access disabled\n", ··· 1409 /* No real sector limit. */ 1410 blk_queue_max_hw_sectors(q, UINT_MAX); 1411 1412 + max_dma_size = virtio_max_dma_size(vdev); 1413 + max_size = max_dma_size > U32_MAX ? U32_MAX : max_dma_size; 1414 1415 /* Host can optionally specify maximum segment size and number of 1416 * segments. */
+20 -12
drivers/vdpa/mlx5/core/mlx5_vdpa.h
··· 31 struct list_head head; 32 unsigned long num_directs; 33 unsigned long num_klms; 34 - /* state of dvq mr */ 35 - bool initialized; 36 37 - /* serialize mkey creation and destruction */ 38 - struct mutex mkey_mtx; 39 bool user_mr; 40 }; 41 ··· 72 enum { 73 MLX5_VDPA_DATAVQ_GROUP, 74 MLX5_VDPA_CVQ_GROUP, 75 MLX5_VDPA_NUMVQ_GROUPS 76 }; 77 78 enum { 79 - MLX5_VDPA_NUM_AS = MLX5_VDPA_NUMVQ_GROUPS 80 }; 81 82 struct mlx5_vdpa_dev { ··· 92 u16 max_idx; 93 u32 generation; 94 95 - struct mlx5_vdpa_mr mr; 96 struct mlx5_control_vq cvq; 97 struct workqueue_struct *wq; 98 unsigned int group2asid[MLX5_VDPA_NUMVQ_GROUPS]; ··· 115 int mlx5_vdpa_create_mkey(struct mlx5_vdpa_dev *mvdev, u32 *mkey, u32 *in, 116 int inlen); 117 int mlx5_vdpa_destroy_mkey(struct mlx5_vdpa_dev *mvdev, u32 mkey); 118 - int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb, 119 - bool *change_map, unsigned int asid); 120 - int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb, 121 - unsigned int asid); 122 - void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev); 123 - void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid); 124 125 #define mlx5_vdpa_warn(__dev, format, ...) \ 126 dev_warn((__dev)->mdev->device, "%s:%d:(pid %d) warning: " format, __func__, __LINE__, \
··· 31 struct list_head head; 32 unsigned long num_directs; 33 unsigned long num_klms; 34 35 + struct vhost_iotlb *iotlb; 36 + 37 bool user_mr; 38 }; 39 ··· 74 enum { 75 MLX5_VDPA_DATAVQ_GROUP, 76 MLX5_VDPA_CVQ_GROUP, 77 + MLX5_VDPA_DATAVQ_DESC_GROUP, 78 MLX5_VDPA_NUMVQ_GROUPS 79 }; 80 81 enum { 82 + MLX5_VDPA_NUM_AS = 2 83 }; 84 85 struct mlx5_vdpa_dev { ··· 93 u16 max_idx; 94 u32 generation; 95 96 + struct mlx5_vdpa_mr *mr[MLX5_VDPA_NUM_AS]; 97 + /* serialize mr access */ 98 + struct mutex mr_mtx; 99 struct mlx5_control_vq cvq; 100 struct workqueue_struct *wq; 101 unsigned int group2asid[MLX5_VDPA_NUMVQ_GROUPS]; ··· 114 int mlx5_vdpa_create_mkey(struct mlx5_vdpa_dev *mvdev, u32 *mkey, u32 *in, 115 int inlen); 116 int mlx5_vdpa_destroy_mkey(struct mlx5_vdpa_dev *mvdev, u32 mkey); 117 + struct mlx5_vdpa_mr *mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, 118 + struct vhost_iotlb *iotlb); 119 + void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev); 120 + void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, 121 + struct mlx5_vdpa_mr *mr); 122 + void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev, 123 + struct mlx5_vdpa_mr *mr, 124 + unsigned int asid); 125 + int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev, 126 + struct vhost_iotlb *iotlb, 127 + unsigned int asid); 128 + int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev); 129 + int mlx5_vdpa_reset_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid); 130 131 #define mlx5_vdpa_warn(__dev, format, ...) \ 132 dev_warn((__dev)->mdev->device, "%s:%d:(pid %d) warning: " format, __func__, __LINE__, \
+127 -84
drivers/vdpa/mlx5/core/mr.c
··· 301 sg_free_table(&mr->sg_head); 302 } 303 304 - static int add_direct_chain(struct mlx5_vdpa_dev *mvdev, u64 start, u64 size, u8 perm, 305 struct vhost_iotlb *iotlb) 306 { 307 - struct mlx5_vdpa_mr *mr = &mvdev->mr; 308 struct mlx5_vdpa_direct_mr *dmr; 309 struct mlx5_vdpa_direct_mr *n; 310 LIST_HEAD(tmp); ··· 357 * indirect memory key that provides access to the enitre address space given 358 * by iotlb. 359 */ 360 - static int create_user_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb) 361 { 362 - struct mlx5_vdpa_mr *mr = &mvdev->mr; 363 struct mlx5_vdpa_direct_mr *dmr; 364 struct mlx5_vdpa_direct_mr *n; 365 struct vhost_iotlb_map *map; ··· 388 LOG_MAX_KLM_SIZE); 389 mr->num_klms += nnuls; 390 } 391 - err = add_direct_chain(mvdev, ps, pe - ps, pperm, iotlb); 392 if (err) 393 goto err_chain; 394 } ··· 397 pperm = map->perm; 398 } 399 } 400 - err = add_direct_chain(mvdev, ps, pe - ps, pperm, iotlb); 401 if (err) 402 goto err_chain; 403 ··· 454 mlx5_vdpa_destroy_mkey(mvdev, mr->mkey); 455 } 456 457 - static int dup_iotlb(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *src) 458 { 459 struct vhost_iotlb_map *map; 460 u64 start = 0, last = ULLONG_MAX; 461 int err; 462 463 if (!src) { 464 - err = vhost_iotlb_add_range(mvdev->cvq.iotlb, start, last, start, VHOST_ACCESS_RW); 465 return err; 466 } 467 468 for (map = vhost_iotlb_itree_first(src, start, last); map; 469 map = vhost_iotlb_itree_next(map, start, last)) { 470 - err = vhost_iotlb_add_range(mvdev->cvq.iotlb, map->start, map->last, 471 map->addr, map->perm); 472 if (err) 473 return err; ··· 478 return 0; 479 } 480 481 - static void prune_iotlb(struct mlx5_vdpa_dev *mvdev) 482 { 483 - vhost_iotlb_del_range(mvdev->cvq.iotlb, 0, ULLONG_MAX); 484 } 485 486 static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr *mr) ··· 496 } 497 } 498 499 - static void _mlx5_vdpa_destroy_cvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid) 500 { 501 - if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid) 502 - return; 503 - 504 - prune_iotlb(mvdev); 505 - } 506 - 507 - static void _mlx5_vdpa_destroy_dvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid) 508 - { 509 - struct mlx5_vdpa_mr *mr = &mvdev->mr; 510 - 511 - if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid) 512 - return; 513 - 514 - if (!mr->initialized) 515 - return; 516 - 517 if (mr->user_mr) 518 destroy_user_mr(mvdev, mr); 519 else 520 destroy_dma_mr(mvdev, mr); 521 522 - mr->initialized = false; 523 } 524 525 - void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid) 526 { 527 - struct mlx5_vdpa_mr *mr = &mvdev->mr; 528 529 - mutex_lock(&mr->mkey_mtx); 530 531 - _mlx5_vdpa_destroy_dvq_mr(mvdev, asid); 532 - _mlx5_vdpa_destroy_cvq_mr(mvdev, asid); 533 534 - mutex_unlock(&mr->mkey_mtx); 535 } 536 537 - void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev) 538 { 539 - mlx5_vdpa_destroy_mr_asid(mvdev, mvdev->group2asid[MLX5_VDPA_CVQ_GROUP]); 540 - mlx5_vdpa_destroy_mr_asid(mvdev, mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]); 541 } 542 543 - static int _mlx5_vdpa_create_cvq_mr(struct mlx5_vdpa_dev *mvdev, 544 - struct vhost_iotlb *iotlb, 545 - unsigned int asid) 546 { 547 - if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid) 548 - return 0; 549 550 - return dup_iotlb(mvdev, iotlb); 551 } 552 553 - static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev *mvdev, 554 - struct vhost_iotlb *iotlb, 555 - unsigned int asid) 556 { 557 - struct mlx5_vdpa_mr *mr = &mvdev->mr; 558 int err; 559 560 - if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid) 561 - return 0; 562 - 563 - if (mr->initialized) 564 - return 0; 565 - 566 if (iotlb) 567 - err = create_user_mr(mvdev, iotlb); 568 else 569 err = create_dma_mr(mvdev, mr); 570 571 if (err) 572 return err; 573 574 - mr->initialized = true; 575 576 return 0; 577 } 578 579 - static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, 580 - struct vhost_iotlb *iotlb, unsigned int asid) 581 { 582 int err; 583 584 - err = _mlx5_vdpa_create_dvq_mr(mvdev, iotlb, asid); 585 - if (err) 586 - return err; 587 588 - err = _mlx5_vdpa_create_cvq_mr(mvdev, iotlb, asid); 589 if (err) 590 goto out_err; 591 592 - return 0; 593 594 out_err: 595 - _mlx5_vdpa_destroy_dvq_mr(mvdev, asid); 596 - 597 - return err; 598 } 599 600 - int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb, 601 - unsigned int asid) 602 { 603 int err; 604 605 - mutex_lock(&mvdev->mr.mkey_mtx); 606 - err = _mlx5_vdpa_create_mr(mvdev, iotlb, asid); 607 - mutex_unlock(&mvdev->mr.mkey_mtx); 608 return err; 609 } 610 611 - int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb, 612 - bool *change_map, unsigned int asid) 613 { 614 - struct mlx5_vdpa_mr *mr = &mvdev->mr; 615 - int err = 0; 616 617 - *change_map = false; 618 - mutex_lock(&mr->mkey_mtx); 619 - if (mr->initialized) { 620 - mlx5_vdpa_info(mvdev, "memory map update\n"); 621 - *change_map = true; 622 } 623 - if (!*change_map) 624 - err = _mlx5_vdpa_create_mr(mvdev, iotlb, asid); 625 - mutex_unlock(&mr->mkey_mtx); 626 627 - return err; 628 }
··· 301 sg_free_table(&mr->sg_head); 302 } 303 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, 309 struct vhost_iotlb *iotlb) 310 { 311 struct mlx5_vdpa_direct_mr *dmr; 312 struct mlx5_vdpa_direct_mr *n; 313 LIST_HEAD(tmp); ··· 354 * indirect memory key that provides access to the enitre address space given 355 * by iotlb. 356 */ 357 + static int create_user_mr(struct mlx5_vdpa_dev *mvdev, 358 + struct mlx5_vdpa_mr *mr, 359 + struct vhost_iotlb *iotlb) 360 { 361 struct mlx5_vdpa_direct_mr *dmr; 362 struct mlx5_vdpa_direct_mr *n; 363 struct vhost_iotlb_map *map; ··· 384 LOG_MAX_KLM_SIZE); 385 mr->num_klms += nnuls; 386 } 387 + err = add_direct_chain(mvdev, mr, ps, pe - ps, pperm, iotlb); 388 if (err) 389 goto err_chain; 390 } ··· 393 pperm = map->perm; 394 } 395 } 396 + err = add_direct_chain(mvdev, mr, ps, pe - ps, pperm, iotlb); 397 if (err) 398 goto err_chain; 399 ··· 450 mlx5_vdpa_destroy_mkey(mvdev, mr->mkey); 451 } 452 453 + static int dup_iotlb(struct vhost_iotlb *dst, struct vhost_iotlb *src) 454 { 455 struct vhost_iotlb_map *map; 456 u64 start = 0, last = ULLONG_MAX; 457 int err; 458 459 + if (dst == src) 460 + return -EINVAL; 461 + 462 if (!src) { 463 + err = vhost_iotlb_add_range(dst, start, last, start, VHOST_ACCESS_RW); 464 return err; 465 } 466 467 for (map = vhost_iotlb_itree_first(src, start, last); map; 468 map = vhost_iotlb_itree_next(map, start, last)) { 469 + err = vhost_iotlb_add_range(dst, map->start, map->last, 470 map->addr, map->perm); 471 if (err) 472 return err; ··· 471 return 0; 472 } 473 474 + static void prune_iotlb(struct vhost_iotlb *iotlb) 475 { 476 + vhost_iotlb_del_range(iotlb, 0, ULLONG_MAX); 477 } 478 479 static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr *mr) ··· 489 } 490 } 491 492 + static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr *mr) 493 { 494 if (mr->user_mr) 495 destroy_user_mr(mvdev, mr); 496 else 497 destroy_dma_mr(mvdev, mr); 498 499 + vhost_iotlb_free(mr->iotlb); 500 } 501 502 + void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, 503 + struct mlx5_vdpa_mr *mr) 504 { 505 + if (!mr) 506 + return; 507 508 + mutex_lock(&mvdev->mr_mtx); 509 510 + _mlx5_vdpa_destroy_mr(mvdev, mr); 511 512 + for (int i = 0; i < MLX5_VDPA_NUM_AS; i++) { 513 + if (mvdev->mr[i] == mr) 514 + mvdev->mr[i] = NULL; 515 + } 516 + 517 + mutex_unlock(&mvdev->mr_mtx); 518 + 519 + kfree(mr); 520 } 521 522 + void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev, 523 + struct mlx5_vdpa_mr *new_mr, 524 + unsigned int asid) 525 { 526 + struct mlx5_vdpa_mr *old_mr = mvdev->mr[asid]; 527 + 528 + mutex_lock(&mvdev->mr_mtx); 529 + 530 + mvdev->mr[asid] = new_mr; 531 + if (old_mr) { 532 + _mlx5_vdpa_destroy_mr(mvdev, old_mr); 533 + kfree(old_mr); 534 + } 535 + 536 + mutex_unlock(&mvdev->mr_mtx); 537 + 538 } 539 540 + void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev) 541 { 542 + for (int i = 0; i < MLX5_VDPA_NUM_AS; i++) 543 + mlx5_vdpa_destroy_mr(mvdev, mvdev->mr[i]); 544 545 + prune_iotlb(mvdev->cvq.iotlb); 546 } 547 548 + static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, 549 + struct mlx5_vdpa_mr *mr, 550 + struct vhost_iotlb *iotlb) 551 { 552 int err; 553 554 if (iotlb) 555 + err = create_user_mr(mvdev, mr, iotlb); 556 else 557 err = create_dma_mr(mvdev, mr); 558 559 if (err) 560 return err; 561 562 + mr->iotlb = vhost_iotlb_alloc(0, 0); 563 + if (!mr->iotlb) { 564 + err = -ENOMEM; 565 + goto err_mr; 566 + } 567 + 568 + err = dup_iotlb(mr->iotlb, iotlb); 569 + if (err) 570 + goto err_iotlb; 571 572 return 0; 573 + 574 + err_iotlb: 575 + vhost_iotlb_free(mr->iotlb); 576 + 577 + err_mr: 578 + if (iotlb) 579 + destroy_user_mr(mvdev, mr); 580 + else 581 + destroy_dma_mr(mvdev, mr); 582 + 583 + return err; 584 } 585 586 + struct mlx5_vdpa_mr *mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, 587 + struct vhost_iotlb *iotlb) 588 { 589 + struct mlx5_vdpa_mr *mr; 590 int err; 591 592 + mr = kzalloc(sizeof(*mr), GFP_KERNEL); 593 + if (!mr) 594 + return ERR_PTR(-ENOMEM); 595 596 + mutex_lock(&mvdev->mr_mtx); 597 + err = _mlx5_vdpa_create_mr(mvdev, mr, iotlb); 598 + mutex_unlock(&mvdev->mr_mtx); 599 + 600 if (err) 601 goto out_err; 602 603 + return mr; 604 605 out_err: 606 + kfree(mr); 607 + return ERR_PTR(err); 608 } 609 610 + int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev, 611 + struct vhost_iotlb *iotlb, 612 + unsigned int asid) 613 { 614 int err; 615 616 + if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid) 617 + return 0; 618 + 619 + spin_lock(&mvdev->cvq.iommu_lock); 620 + 621 + prune_iotlb(mvdev->cvq.iotlb); 622 + err = dup_iotlb(mvdev->cvq.iotlb, iotlb); 623 + 624 + spin_unlock(&mvdev->cvq.iommu_lock); 625 + 626 return err; 627 } 628 629 + int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev) 630 { 631 + struct mlx5_vdpa_mr *mr; 632 633 + mr = mlx5_vdpa_create_mr(mvdev, NULL); 634 + if (IS_ERR(mr)) 635 + return PTR_ERR(mr); 636 + 637 + mlx5_vdpa_update_mr(mvdev, mr, 0); 638 + 639 + return mlx5_vdpa_update_cvq_iotlb(mvdev, NULL, 0); 640 + } 641 + 642 + int mlx5_vdpa_reset_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid) 643 + { 644 + if (asid >= MLX5_VDPA_NUM_AS) 645 + return -EINVAL; 646 + 647 + mlx5_vdpa_destroy_mr(mvdev, mvdev->mr[asid]); 648 + 649 + if (asid == 0 && MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) { 650 + if (mlx5_vdpa_create_dma_mr(mvdev)) 651 + mlx5_vdpa_warn(mvdev, "create DMA MR failed\n"); 652 + } else { 653 + mlx5_vdpa_update_cvq_iotlb(mvdev, NULL, asid); 654 } 655 656 + return 0; 657 }
+3 -3
drivers/vdpa/mlx5/core/resources.c
··· 256 mlx5_vdpa_warn(mvdev, "resources already allocated\n"); 257 return -EINVAL; 258 } 259 - mutex_init(&mvdev->mr.mkey_mtx); 260 res->uar = mlx5_get_uars_page(mdev); 261 if (IS_ERR(res->uar)) { 262 err = PTR_ERR(res->uar); ··· 301 err_uctx: 302 mlx5_put_uars_page(mdev, res->uar); 303 err_uars: 304 - mutex_destroy(&mvdev->mr.mkey_mtx); 305 return err; 306 } 307 ··· 318 dealloc_pd(mvdev, res->pdn, res->uid); 319 destroy_uctx(mvdev, res->uid); 320 mlx5_put_uars_page(mvdev->mdev, res->uar); 321 - mutex_destroy(&mvdev->mr.mkey_mtx); 322 res->valid = false; 323 }
··· 256 mlx5_vdpa_warn(mvdev, "resources already allocated\n"); 257 return -EINVAL; 258 } 259 + mutex_init(&mvdev->mr_mtx); 260 res->uar = mlx5_get_uars_page(mdev); 261 if (IS_ERR(res->uar)) { 262 err = PTR_ERR(res->uar); ··· 301 err_uctx: 302 mlx5_put_uars_page(mdev, res->uar); 303 err_uars: 304 + mutex_destroy(&mvdev->mr_mtx); 305 return err; 306 } 307 ··· 318 dealloc_pd(mvdev, res->pdn, res->uid); 319 destroy_uctx(mvdev, res->uid); 320 mlx5_put_uars_page(mvdev->mdev, res->uar); 321 + mutex_destroy(&mvdev->mr_mtx); 322 res->valid = false; 323 }
+106 -31
drivers/vdpa/mlx5/net/mlx5_vnet.c
··· 7 #include <uapi/linux/virtio_net.h> 8 #include <uapi/linux/virtio_ids.h> 9 #include <uapi/linux/vdpa.h> 10 #include <linux/virtio_config.h> 11 #include <linux/auxiliary_bus.h> 12 #include <linux/mlx5/cq.h> ··· 862 { 863 int inlen = MLX5_ST_SZ_BYTES(create_virtio_net_q_in); 864 u32 out[MLX5_ST_SZ_DW(create_virtio_net_q_out)] = {}; 865 void *obj_context; 866 u16 mlx_features; 867 void *cmd_hdr; ··· 917 MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr); 918 MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr); 919 MLX5_SET64(virtio_q, vq_ctx, available_addr, mvq->driver_addr); 920 - MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, ndev->mvdev.mr.mkey); 921 MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id); 922 MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size); 923 MLX5_SET(virtio_q, vq_ctx, umem_2_id, mvq->umem2.id); ··· 2312 return MLX5_VDPA_DATAVQ_GROUP; 2313 } 2314 2315 static u64 mlx_to_vritio_features(u16 dev_features) 2316 { 2317 u64 result = 0; ··· 2560 flush_workqueue(ndev->mvdev.wq); 2561 } 2562 2563 static int mlx5_vdpa_set_driver_features(struct vdpa_device *vdev, u64 features) 2564 { 2565 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev); ··· 2699 } 2700 2701 static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev, 2702 - struct vhost_iotlb *iotlb, unsigned int asid) 2703 { 2704 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev); 2705 int err; ··· 2708 suspend_vqs(ndev); 2709 err = save_channels_info(ndev); 2710 if (err) 2711 - goto err_mr; 2712 2713 teardown_driver(ndev); 2714 - mlx5_vdpa_destroy_mr_asid(mvdev, asid); 2715 - err = mlx5_vdpa_create_mr(mvdev, iotlb, asid); 2716 - if (err) 2717 - goto err_mr; 2718 2719 if (!(mvdev->status & VIRTIO_CONFIG_S_DRIVER_OK) || mvdev->suspended) 2720 - goto err_mr; 2721 2722 restore_channels_info(ndev); 2723 err = setup_driver(mvdev); 2724 if (err) 2725 - goto err_setup; 2726 2727 return 0; 2728 - 2729 - err_setup: 2730 - mlx5_vdpa_destroy_mr_asid(mvdev, asid); 2731 - err_mr: 2732 - return err; 2733 } 2734 2735 /* reslock must be held for this function */ ··· 2861 err_driver: 2862 unregister_link_notifier(ndev); 2863 err_setup: 2864 - mlx5_vdpa_destroy_mr(&ndev->mvdev); 2865 ndev->mvdev.status |= VIRTIO_CONFIG_S_FAILED; 2866 err_clear: 2867 up_write(&ndev->reslock); ··· 2876 mvdev->group2asid[i] = 0; 2877 } 2878 2879 - static int mlx5_vdpa_reset(struct vdpa_device *vdev) 2880 { 2881 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev); 2882 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev); ··· 2888 unregister_link_notifier(ndev); 2889 teardown_driver(ndev); 2890 clear_vqs_ready(ndev); 2891 - mlx5_vdpa_destroy_mr(&ndev->mvdev); 2892 ndev->mvdev.status = 0; 2893 ndev->mvdev.suspended = false; 2894 ndev->cur_num_vqs = 0; ··· 2900 init_group_to_asid_map(mvdev); 2901 ++mvdev->generation; 2902 2903 - if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) { 2904 - if (mlx5_vdpa_create_mr(mvdev, NULL, 0)) 2905 mlx5_vdpa_warn(mvdev, "create MR failed\n"); 2906 } 2907 up_write(&ndev->reslock); 2908 2909 return 0; 2910 } 2911 2912 static size_t mlx5_vdpa_get_config_size(struct vdpa_device *vdev) ··· 2946 static int set_map_data(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb, 2947 unsigned int asid) 2948 { 2949 - bool change_map; 2950 int err; 2951 2952 - err = mlx5_vdpa_handle_set_map(mvdev, iotlb, &change_map, asid); 2953 - if (err) { 2954 - mlx5_vdpa_warn(mvdev, "set map failed(%d)\n", err); 2955 - return err; 2956 } 2957 2958 - if (change_map) 2959 - err = mlx5_vdpa_change_map(mvdev, iotlb, asid); 2960 2961 return err; 2962 } 2963 ··· 2990 2991 down_write(&ndev->reslock); 2992 err = set_map_data(mvdev, iotlb, asid); 2993 up_write(&ndev->reslock); 2994 return err; 2995 } ··· 3044 ndev = to_mlx5_vdpa_ndev(mvdev); 3045 3046 free_resources(ndev); 3047 - mlx5_vdpa_destroy_mr(mvdev); 3048 if (!is_zero_ether_addr(ndev->config.mac)) { 3049 pfmdev = pci_get_drvdata(pci_physfn(mvdev->mdev->pdev)); 3050 mlx5_mpfs_del_mac(pfmdev, ndev->config.mac); ··· 3228 unsigned int asid) 3229 { 3230 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev); 3231 3232 if (group >= MLX5_VDPA_NUMVQ_GROUPS) 3233 return -EINVAL; 3234 3235 mvdev->group2asid[group] = asid; 3236 - return 0; 3237 } 3238 3239 static const struct vdpa_config_ops mlx5_vdpa_ops = { ··· 3257 .get_vq_irq = mlx5_get_vq_irq, 3258 .get_vq_align = mlx5_vdpa_get_vq_align, 3259 .get_vq_group = mlx5_vdpa_get_vq_group, 3260 .get_device_features = mlx5_vdpa_get_device_features, 3261 .set_driver_features = mlx5_vdpa_set_driver_features, 3262 .get_driver_features = mlx5_vdpa_get_driver_features, 3263 .set_config_cb = mlx5_vdpa_set_config_cb, ··· 3269 .get_status = mlx5_vdpa_get_status, 3270 .set_status = mlx5_vdpa_set_status, 3271 .reset = mlx5_vdpa_reset, 3272 .get_config_size = mlx5_vdpa_get_config_size, 3273 .get_config = mlx5_vdpa_get_config, 3274 .set_config = mlx5_vdpa_set_config, 3275 .get_generation = mlx5_vdpa_get_generation, 3276 .set_map = mlx5_vdpa_set_map, 3277 .set_group_asid = mlx5_set_group_asid, 3278 .get_vq_dma_dev = mlx5_get_vq_dma_dev, 3279 .free = mlx5_vdpa_free, ··· 3359 struct vdpa_mgmt_dev mgtdev; 3360 struct mlx5_adev *madev; 3361 struct mlx5_vdpa_net *ndev; 3362 }; 3363 3364 static int config_func_mtu(struct mlx5_core_dev *mdev, u16 mtu) ··· 3473 max_vqs = 2; 3474 } 3475 3476 - ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mlx5_vdpa_ops, 3477 MLX5_VDPA_NUMVQ_GROUPS, MLX5_VDPA_NUM_AS, name, false); 3478 if (IS_ERR(ndev)) 3479 return PTR_ERR(ndev); ··· 3556 goto err_mpfs; 3557 3558 if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) { 3559 - err = mlx5_vdpa_create_mr(mvdev, NULL, 0); 3560 if (err) 3561 goto err_res; 3562 } ··· 3586 err_res2: 3587 free_resources(ndev); 3588 err_mr: 3589 - mlx5_vdpa_destroy_mr(mvdev); 3590 err_res: 3591 mlx5_vdpa_free_resources(&ndev->mvdev); 3592 err_mpfs: ··· 3646 MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues) + 1; 3647 mgtdev->mgtdev.supported_features = get_supported_features(mdev); 3648 mgtdev->madev = madev; 3649 3650 err = vdpa_mgmtdev_register(&mgtdev->mgtdev); 3651 if (err)
··· 7 #include <uapi/linux/virtio_net.h> 8 #include <uapi/linux/virtio_ids.h> 9 #include <uapi/linux/vdpa.h> 10 + #include <uapi/linux/vhost_types.h> 11 #include <linux/virtio_config.h> 12 #include <linux/auxiliary_bus.h> 13 #include <linux/mlx5/cq.h> ··· 861 { 862 int inlen = MLX5_ST_SZ_BYTES(create_virtio_net_q_in); 863 u32 out[MLX5_ST_SZ_DW(create_virtio_net_q_out)] = {}; 864 + struct mlx5_vdpa_dev *mvdev = &ndev->mvdev; 865 + struct mlx5_vdpa_mr *vq_mr; 866 + struct mlx5_vdpa_mr *vq_desc_mr; 867 void *obj_context; 868 u16 mlx_features; 869 void *cmd_hdr; ··· 913 MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr); 914 MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr); 915 MLX5_SET64(virtio_q, vq_ctx, available_addr, mvq->driver_addr); 916 + vq_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]]; 917 + if (vq_mr) 918 + MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, vq_mr->mkey); 919 + 920 + vq_desc_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_DESC_GROUP]]; 921 + if (vq_desc_mr && MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, desc_group_mkey_supported)) 922 + MLX5_SET(virtio_q, vq_ctx, desc_group_mkey, vq_desc_mr->mkey); 923 + 924 MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id); 925 MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size); 926 MLX5_SET(virtio_q, vq_ctx, umem_2_id, mvq->umem2.id); ··· 2301 return MLX5_VDPA_DATAVQ_GROUP; 2302 } 2303 2304 + static u32 mlx5_vdpa_get_vq_desc_group(struct vdpa_device *vdev, u16 idx) 2305 + { 2306 + struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev); 2307 + 2308 + if (is_ctrl_vq_idx(mvdev, idx)) 2309 + return MLX5_VDPA_CVQ_GROUP; 2310 + 2311 + return MLX5_VDPA_DATAVQ_DESC_GROUP; 2312 + } 2313 + 2314 static u64 mlx_to_vritio_features(u16 dev_features) 2315 { 2316 u64 result = 0; ··· 2539 flush_workqueue(ndev->mvdev.wq); 2540 } 2541 2542 + static u64 mlx5_vdpa_get_backend_features(const struct vdpa_device *vdpa) 2543 + { 2544 + return BIT_ULL(VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK); 2545 + } 2546 + 2547 static int mlx5_vdpa_set_driver_features(struct vdpa_device *vdev, u64 features) 2548 { 2549 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev); ··· 2673 } 2674 2675 static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev, 2676 + struct mlx5_vdpa_mr *new_mr, 2677 + unsigned int asid) 2678 { 2679 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev); 2680 int err; ··· 2681 suspend_vqs(ndev); 2682 err = save_channels_info(ndev); 2683 if (err) 2684 + return err; 2685 2686 teardown_driver(ndev); 2687 + 2688 + mlx5_vdpa_update_mr(mvdev, new_mr, asid); 2689 2690 if (!(mvdev->status & VIRTIO_CONFIG_S_DRIVER_OK) || mvdev->suspended) 2691 + return 0; 2692 2693 restore_channels_info(ndev); 2694 err = setup_driver(mvdev); 2695 if (err) 2696 + return err; 2697 2698 return 0; 2699 } 2700 2701 /* reslock must be held for this function */ ··· 2841 err_driver: 2842 unregister_link_notifier(ndev); 2843 err_setup: 2844 + mlx5_vdpa_destroy_mr_resources(&ndev->mvdev); 2845 ndev->mvdev.status |= VIRTIO_CONFIG_S_FAILED; 2846 err_clear: 2847 up_write(&ndev->reslock); ··· 2856 mvdev->group2asid[i] = 0; 2857 } 2858 2859 + static int mlx5_vdpa_compat_reset(struct vdpa_device *vdev, u32 flags) 2860 { 2861 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev); 2862 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev); ··· 2868 unregister_link_notifier(ndev); 2869 teardown_driver(ndev); 2870 clear_vqs_ready(ndev); 2871 + if (flags & VDPA_RESET_F_CLEAN_MAP) 2872 + mlx5_vdpa_destroy_mr_resources(&ndev->mvdev); 2873 ndev->mvdev.status = 0; 2874 ndev->mvdev.suspended = false; 2875 ndev->cur_num_vqs = 0; ··· 2879 init_group_to_asid_map(mvdev); 2880 ++mvdev->generation; 2881 2882 + if ((flags & VDPA_RESET_F_CLEAN_MAP) && 2883 + MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) { 2884 + if (mlx5_vdpa_create_dma_mr(mvdev)) 2885 mlx5_vdpa_warn(mvdev, "create MR failed\n"); 2886 } 2887 up_write(&ndev->reslock); 2888 2889 return 0; 2890 + } 2891 + 2892 + static int mlx5_vdpa_reset(struct vdpa_device *vdev) 2893 + { 2894 + return mlx5_vdpa_compat_reset(vdev, 0); 2895 } 2896 2897 static size_t mlx5_vdpa_get_config_size(struct vdpa_device *vdev) ··· 2919 static int set_map_data(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb, 2920 unsigned int asid) 2921 { 2922 + struct mlx5_vdpa_mr *new_mr; 2923 int err; 2924 2925 + if (asid >= MLX5_VDPA_NUM_AS) 2926 + return -EINVAL; 2927 + 2928 + if (vhost_iotlb_itree_first(iotlb, 0, U64_MAX)) { 2929 + new_mr = mlx5_vdpa_create_mr(mvdev, iotlb); 2930 + if (IS_ERR(new_mr)) { 2931 + err = PTR_ERR(new_mr); 2932 + mlx5_vdpa_warn(mvdev, "create map failed(%d)\n", err); 2933 + return err; 2934 + } 2935 + } else { 2936 + /* Empty iotlbs don't have an mr but will clear the previous mr. */ 2937 + new_mr = NULL; 2938 } 2939 2940 + if (!mvdev->mr[asid]) { 2941 + mlx5_vdpa_update_mr(mvdev, new_mr, asid); 2942 + } else { 2943 + err = mlx5_vdpa_change_map(mvdev, new_mr, asid); 2944 + if (err) { 2945 + mlx5_vdpa_warn(mvdev, "change map failed(%d)\n", err); 2946 + goto out_err; 2947 + } 2948 + } 2949 2950 + return mlx5_vdpa_update_cvq_iotlb(mvdev, iotlb, asid); 2951 + 2952 + out_err: 2953 + mlx5_vdpa_destroy_mr(mvdev, new_mr); 2954 return err; 2955 } 2956 ··· 2943 2944 down_write(&ndev->reslock); 2945 err = set_map_data(mvdev, iotlb, asid); 2946 + up_write(&ndev->reslock); 2947 + return err; 2948 + } 2949 + 2950 + static int mlx5_vdpa_reset_map(struct vdpa_device *vdev, unsigned int asid) 2951 + { 2952 + struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev); 2953 + struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev); 2954 + int err; 2955 + 2956 + down_write(&ndev->reslock); 2957 + err = mlx5_vdpa_reset_mr(mvdev, asid); 2958 up_write(&ndev->reslock); 2959 return err; 2960 } ··· 2985 ndev = to_mlx5_vdpa_ndev(mvdev); 2986 2987 free_resources(ndev); 2988 + mlx5_vdpa_destroy_mr_resources(mvdev); 2989 if (!is_zero_ether_addr(ndev->config.mac)) { 2990 pfmdev = pci_get_drvdata(pci_physfn(mvdev->mdev->pdev)); 2991 mlx5_mpfs_del_mac(pfmdev, ndev->config.mac); ··· 3169 unsigned int asid) 3170 { 3171 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev); 3172 + int err = 0; 3173 3174 if (group >= MLX5_VDPA_NUMVQ_GROUPS) 3175 return -EINVAL; 3176 3177 mvdev->group2asid[group] = asid; 3178 + 3179 + mutex_lock(&mvdev->mr_mtx); 3180 + if (group == MLX5_VDPA_CVQ_GROUP && mvdev->mr[asid]) 3181 + err = mlx5_vdpa_update_cvq_iotlb(mvdev, mvdev->mr[asid]->iotlb, asid); 3182 + mutex_unlock(&mvdev->mr_mtx); 3183 + 3184 + return err; 3185 } 3186 3187 static const struct vdpa_config_ops mlx5_vdpa_ops = { ··· 3191 .get_vq_irq = mlx5_get_vq_irq, 3192 .get_vq_align = mlx5_vdpa_get_vq_align, 3193 .get_vq_group = mlx5_vdpa_get_vq_group, 3194 + .get_vq_desc_group = mlx5_vdpa_get_vq_desc_group, /* Op disabled if not supported. */ 3195 .get_device_features = mlx5_vdpa_get_device_features, 3196 + .get_backend_features = mlx5_vdpa_get_backend_features, 3197 .set_driver_features = mlx5_vdpa_set_driver_features, 3198 .get_driver_features = mlx5_vdpa_get_driver_features, 3199 .set_config_cb = mlx5_vdpa_set_config_cb, ··· 3201 .get_status = mlx5_vdpa_get_status, 3202 .set_status = mlx5_vdpa_set_status, 3203 .reset = mlx5_vdpa_reset, 3204 + .compat_reset = mlx5_vdpa_compat_reset, 3205 .get_config_size = mlx5_vdpa_get_config_size, 3206 .get_config = mlx5_vdpa_get_config, 3207 .set_config = mlx5_vdpa_set_config, 3208 .get_generation = mlx5_vdpa_get_generation, 3209 .set_map = mlx5_vdpa_set_map, 3210 + .reset_map = mlx5_vdpa_reset_map, 3211 .set_group_asid = mlx5_set_group_asid, 3212 .get_vq_dma_dev = mlx5_get_vq_dma_dev, 3213 .free = mlx5_vdpa_free, ··· 3289 struct vdpa_mgmt_dev mgtdev; 3290 struct mlx5_adev *madev; 3291 struct mlx5_vdpa_net *ndev; 3292 + struct vdpa_config_ops vdpa_ops; 3293 }; 3294 3295 static int config_func_mtu(struct mlx5_core_dev *mdev, u16 mtu) ··· 3402 max_vqs = 2; 3403 } 3404 3405 + 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); 3407 if (IS_ERR(ndev)) 3408 return PTR_ERR(ndev); ··· 3485 goto err_mpfs; 3486 3487 if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) { 3488 + err = mlx5_vdpa_create_dma_mr(mvdev); 3489 if (err) 3490 goto err_res; 3491 } ··· 3515 err_res2: 3516 free_resources(ndev); 3517 err_mr: 3518 + mlx5_vdpa_destroy_mr_resources(mvdev); 3519 err_res: 3520 mlx5_vdpa_free_resources(&ndev->mvdev); 3521 err_mpfs: ··· 3575 MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues) + 1; 3576 mgtdev->mgtdev.supported_features = get_supported_features(mdev); 3577 mgtdev->madev = madev; 3578 + mgtdev->vdpa_ops = mlx5_vdpa_ops; 3579 + 3580 + if (!MLX5_CAP_DEV_VDPA_EMULATION(mdev, desc_group_mkey_supported)) 3581 + mgtdev->vdpa_ops.get_vq_desc_group = NULL; 3582 3583 err = vdpa_mgmtdev_register(&mgtdev->mgtdev); 3584 if (err)
+43 -9
drivers/vdpa/vdpa_sim/vdpa_sim.c
··· 139 vq->vring.notify = NULL; 140 } 141 142 - static void vdpasim_do_reset(struct vdpasim *vdpasim) 143 { 144 int i; 145 ··· 151 &vdpasim->iommu_lock); 152 } 153 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; 159 } 160 161 vdpasim->running = true; ··· 261 if (!vdpasim->iommu_pt) 262 goto err_iommu; 263 264 - for (i = 0; i < vdpasim->dev_attr.nas; i++) 265 vhost_iotlb_init(&vdpasim->iommu[i], max_iotlb_entries, 0); 266 267 for (i = 0; i < dev_attr->nvqs; i++) 268 vringh_set_iotlb(&vdpasim->vqs[i].vring, &vdpasim->iommu[0], ··· 486 mutex_unlock(&vdpasim->mutex); 487 } 488 489 - static int vdpasim_reset(struct vdpa_device *vdpa) 490 { 491 struct vdpasim *vdpasim = vdpa_to_sim(vdpa); 492 493 mutex_lock(&vdpasim->mutex); 494 vdpasim->status = 0; 495 - vdpasim_do_reset(vdpasim); 496 mutex_unlock(&vdpasim->mutex); 497 498 return 0; 499 } 500 501 static int vdpasim_suspend(struct vdpa_device *vdpa) ··· 648 return ret; 649 } 650 651 static int vdpasim_bind_mm(struct vdpa_device *vdpa, struct mm_struct *mm) 652 { 653 struct vdpasim *vdpasim = vdpa_to_sim(vdpa); ··· 779 .get_status = vdpasim_get_status, 780 .set_status = vdpasim_set_status, 781 .reset = vdpasim_reset, 782 .suspend = vdpasim_suspend, 783 .resume = vdpasim_resume, 784 .get_config_size = vdpasim_get_config_size, ··· 790 .set_group_asid = vdpasim_set_group_asid, 791 .dma_map = vdpasim_dma_map, 792 .dma_unmap = vdpasim_dma_unmap, 793 .bind_mm = vdpasim_bind_mm, 794 .unbind_mm = vdpasim_unbind_mm, 795 .free = vdpasim_free, ··· 819 .get_status = vdpasim_get_status, 820 .set_status = vdpasim_set_status, 821 .reset = vdpasim_reset, 822 .suspend = vdpasim_suspend, 823 .resume = vdpasim_resume, 824 .get_config_size = vdpasim_get_config_size, ··· 829 .get_iova_range = vdpasim_get_iova_range, 830 .set_group_asid = vdpasim_set_group_asid, 831 .set_map = vdpasim_set_map, 832 .bind_mm = vdpasim_bind_mm, 833 .unbind_mm = vdpasim_unbind_mm, 834 .free = vdpasim_free,
··· 139 vq->vring.notify = NULL; 140 } 141 142 + static void vdpasim_do_reset(struct vdpasim *vdpasim, u32 flags) 143 { 144 int i; 145 ··· 151 &vdpasim->iommu_lock); 152 } 153 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 + } 161 } 162 163 vdpasim->running = true; ··· 259 if (!vdpasim->iommu_pt) 260 goto err_iommu; 261 262 + for (i = 0; i < vdpasim->dev_attr.nas; i++) { 263 vhost_iotlb_init(&vdpasim->iommu[i], max_iotlb_entries, 0); 264 + vhost_iotlb_add_range(&vdpasim->iommu[i], 0, ULONG_MAX, 0, 265 + VHOST_MAP_RW); 266 + vdpasim->iommu_pt[i] = true; 267 + } 268 269 for (i = 0; i < dev_attr->nvqs; i++) 270 vringh_set_iotlb(&vdpasim->vqs[i].vring, &vdpasim->iommu[0], ··· 480 mutex_unlock(&vdpasim->mutex); 481 } 482 483 + static int vdpasim_compat_reset(struct vdpa_device *vdpa, u32 flags) 484 { 485 struct vdpasim *vdpasim = vdpa_to_sim(vdpa); 486 487 mutex_lock(&vdpasim->mutex); 488 vdpasim->status = 0; 489 + vdpasim_do_reset(vdpasim, flags); 490 mutex_unlock(&vdpasim->mutex); 491 492 return 0; 493 + } 494 + 495 + static int vdpasim_reset(struct vdpa_device *vdpa) 496 + { 497 + return vdpasim_compat_reset(vdpa, 0); 498 } 499 500 static int vdpasim_suspend(struct vdpa_device *vdpa) ··· 637 return ret; 638 } 639 640 + static int vdpasim_reset_map(struct vdpa_device *vdpa, unsigned int asid) 641 + { 642 + struct vdpasim *vdpasim = vdpa_to_sim(vdpa); 643 + 644 + if (asid >= vdpasim->dev_attr.nas) 645 + return -EINVAL; 646 + 647 + spin_lock(&vdpasim->iommu_lock); 648 + if (vdpasim->iommu_pt[asid]) 649 + goto out; 650 + vhost_iotlb_reset(&vdpasim->iommu[asid]); 651 + vhost_iotlb_add_range(&vdpasim->iommu[asid], 0, ULONG_MAX, 652 + 0, VHOST_MAP_RW); 653 + vdpasim->iommu_pt[asid] = true; 654 + out: 655 + spin_unlock(&vdpasim->iommu_lock); 656 + return 0; 657 + } 658 + 659 static int vdpasim_bind_mm(struct vdpa_device *vdpa, struct mm_struct *mm) 660 { 661 struct vdpasim *vdpasim = vdpa_to_sim(vdpa); ··· 749 .get_status = vdpasim_get_status, 750 .set_status = vdpasim_set_status, 751 .reset = vdpasim_reset, 752 + .compat_reset = vdpasim_compat_reset, 753 .suspend = vdpasim_suspend, 754 .resume = vdpasim_resume, 755 .get_config_size = vdpasim_get_config_size, ··· 759 .set_group_asid = vdpasim_set_group_asid, 760 .dma_map = vdpasim_dma_map, 761 .dma_unmap = vdpasim_dma_unmap, 762 + .reset_map = vdpasim_reset_map, 763 .bind_mm = vdpasim_bind_mm, 764 .unbind_mm = vdpasim_unbind_mm, 765 .free = vdpasim_free, ··· 787 .get_status = vdpasim_get_status, 788 .set_status = vdpasim_set_status, 789 .reset = vdpasim_reset, 790 + .compat_reset = vdpasim_compat_reset, 791 .suspend = vdpasim_suspend, 792 .resume = vdpasim_resume, 793 .get_config_size = vdpasim_get_config_size, ··· 796 .get_iova_range = vdpasim_get_iova_range, 797 .set_group_asid = vdpasim_set_group_asid, 798 .set_map = vdpasim_set_map, 799 + .reset_map = vdpasim_reset_map, 800 .bind_mm = vdpasim_bind_mm, 801 .unbind_mm = vdpasim_unbind_mm, 802 .free = vdpasim_free,
+21 -19
drivers/vdpa/vdpa_user/vduse_dev.c
··· 134 static DEFINE_IDR(vduse_idr); 135 136 static dev_t vduse_major; 137 - static struct class *vduse_class; 138 static struct cdev vduse_ctrl_cdev; 139 static struct cdev vduse_cdev; 140 static struct workqueue_struct *vduse_irq_wq; ··· 1527 .default_groups = vq_groups, 1528 }; 1529 1530 static void vduse_dev_deinit_vqs(struct vduse_dev *dev) 1531 { 1532 int i; ··· 1647 mutex_unlock(&dev->lock); 1648 1649 vduse_dev_reset(dev); 1650 - device_destroy(vduse_class, MKDEV(MAJOR(vduse_major), dev->minor)); 1651 idr_remove(&vduse_idr, dev->minor); 1652 kvfree(dev->config); 1653 vduse_dev_deinit_vqs(dev); ··· 1814 1815 dev->minor = ret; 1816 dev->msg_timeout = VDUSE_MSG_DEFAULT_TIMEOUT; 1817 - dev->dev = device_create_with_groups(vduse_class, NULL, 1818 MKDEV(MAJOR(vduse_major), dev->minor), 1819 dev, vduse_dev_groups, "%s", config->name); 1820 if (IS_ERR(dev->dev)) { ··· 1830 1831 return 0; 1832 err_vqs: 1833 - device_destroy(vduse_class, MKDEV(MAJOR(vduse_major), dev->minor)); 1834 err_dev: 1835 idr_remove(&vduse_idr, dev->minor); 1836 err_idr: ··· 1942 .compat_ioctl = compat_ptr_ioctl, 1943 .llseek = noop_llseek, 1944 }; 1945 - 1946 - static char *vduse_devnode(const struct device *dev, umode_t *mode) 1947 - { 1948 - return kasprintf(GFP_KERNEL, "vduse/%s", dev_name(dev)); 1949 - } 1950 1951 struct vduse_mgmt_dev { 1952 struct vdpa_mgmt_dev mgmt_dev; ··· 2086 int ret; 2087 struct device *dev; 2088 2089 - vduse_class = class_create("vduse"); 2090 - if (IS_ERR(vduse_class)) 2091 - return PTR_ERR(vduse_class); 2092 - 2093 - vduse_class->devnode = vduse_devnode; 2094 2095 ret = alloc_chrdev_region(&vduse_major, 0, VDUSE_DEV_MAX, "vduse"); 2096 if (ret) ··· 2101 if (ret) 2102 goto err_ctrl_cdev; 2103 2104 - dev = device_create(vduse_class, NULL, vduse_major, NULL, "control"); 2105 if (IS_ERR(dev)) { 2106 ret = PTR_ERR(dev); 2107 goto err_device; ··· 2143 err_wq: 2144 cdev_del(&vduse_cdev); 2145 err_cdev: 2146 - device_destroy(vduse_class, vduse_major); 2147 err_device: 2148 cdev_del(&vduse_ctrl_cdev); 2149 err_ctrl_cdev: 2150 unregister_chrdev_region(vduse_major, VDUSE_DEV_MAX); 2151 err_chardev_region: 2152 - class_destroy(vduse_class); 2153 return ret; 2154 } 2155 module_init(vduse_init); ··· 2161 destroy_workqueue(vduse_irq_bound_wq); 2162 destroy_workqueue(vduse_irq_wq); 2163 cdev_del(&vduse_cdev); 2164 - device_destroy(vduse_class, vduse_major); 2165 cdev_del(&vduse_ctrl_cdev); 2166 unregister_chrdev_region(vduse_major, VDUSE_DEV_MAX); 2167 - class_destroy(vduse_class); 2168 } 2169 module_exit(vduse_exit); 2170
··· 134 static DEFINE_IDR(vduse_idr); 135 136 static dev_t vduse_major; 137 static struct cdev vduse_ctrl_cdev; 138 static struct cdev vduse_cdev; 139 static struct workqueue_struct *vduse_irq_wq; ··· 1528 .default_groups = vq_groups, 1529 }; 1530 1531 + static char *vduse_devnode(const struct device *dev, umode_t *mode) 1532 + { 1533 + return kasprintf(GFP_KERNEL, "vduse/%s", dev_name(dev)); 1534 + } 1535 + 1536 + static const struct class vduse_class = { 1537 + .name = "vduse", 1538 + .devnode = vduse_devnode, 1539 + }; 1540 + 1541 static void vduse_dev_deinit_vqs(struct vduse_dev *dev) 1542 { 1543 int i; ··· 1638 mutex_unlock(&dev->lock); 1639 1640 vduse_dev_reset(dev); 1641 + device_destroy(&vduse_class, MKDEV(MAJOR(vduse_major), dev->minor)); 1642 idr_remove(&vduse_idr, dev->minor); 1643 kvfree(dev->config); 1644 vduse_dev_deinit_vqs(dev); ··· 1805 1806 dev->minor = ret; 1807 dev->msg_timeout = VDUSE_MSG_DEFAULT_TIMEOUT; 1808 + dev->dev = device_create_with_groups(&vduse_class, NULL, 1809 MKDEV(MAJOR(vduse_major), dev->minor), 1810 dev, vduse_dev_groups, "%s", config->name); 1811 if (IS_ERR(dev->dev)) { ··· 1821 1822 return 0; 1823 err_vqs: 1824 + device_destroy(&vduse_class, MKDEV(MAJOR(vduse_major), dev->minor)); 1825 err_dev: 1826 idr_remove(&vduse_idr, dev->minor); 1827 err_idr: ··· 1933 .compat_ioctl = compat_ptr_ioctl, 1934 .llseek = noop_llseek, 1935 }; 1936 1937 struct vduse_mgmt_dev { 1938 struct vdpa_mgmt_dev mgmt_dev; ··· 2082 int ret; 2083 struct device *dev; 2084 2085 + ret = class_register(&vduse_class); 2086 + if (ret) 2087 + return ret; 2088 2089 ret = alloc_chrdev_region(&vduse_major, 0, VDUSE_DEV_MAX, "vduse"); 2090 if (ret) ··· 2099 if (ret) 2100 goto err_ctrl_cdev; 2101 2102 + dev = device_create(&vduse_class, NULL, vduse_major, NULL, "control"); 2103 if (IS_ERR(dev)) { 2104 ret = PTR_ERR(dev); 2105 goto err_device; ··· 2141 err_wq: 2142 cdev_del(&vduse_cdev); 2143 err_cdev: 2144 + device_destroy(&vduse_class, vduse_major); 2145 err_device: 2146 cdev_del(&vduse_ctrl_cdev); 2147 err_ctrl_cdev: 2148 unregister_chrdev_region(vduse_major, VDUSE_DEV_MAX); 2149 err_chardev_region: 2150 + class_unregister(&vduse_class); 2151 return ret; 2152 } 2153 module_init(vduse_init); ··· 2159 destroy_workqueue(vduse_irq_bound_wq); 2160 destroy_workqueue(vduse_irq_wq); 2161 cdev_del(&vduse_cdev); 2162 + device_destroy(&vduse_class, vduse_major); 2163 cdev_del(&vduse_ctrl_cdev); 2164 unregister_chrdev_region(vduse_major, VDUSE_DEV_MAX); 2165 + class_unregister(&vduse_class); 2166 } 2167 module_exit(vduse_exit); 2168
+1 -1
drivers/vhost/scsi.c
··· 1158 /* 1159 * Set prot_iter to data_iter and truncate it to 1160 * prot_bytes, and advance data_iter past any 1161 - * preceeding prot_bytes that may be present. 1162 * 1163 * Also fix up the exp_data_len to reflect only the 1164 * actual data payload length.
··· 1158 /* 1159 * Set prot_iter to data_iter and truncate it to 1160 * prot_bytes, and advance data_iter past any 1161 + * preceding prot_bytes that may be present. 1162 * 1163 * Also fix up the exp_data_len to reflect only the 1164 * actual data payload length.
+75 -4
drivers/vhost/vdpa.c
··· 131 return vhost_vdpa_alloc_as(v, asid); 132 } 133 134 static int vhost_vdpa_remove_as(struct vhost_vdpa *v, u32 asid) 135 { 136 struct vhost_vdpa_as *as = asid_to_as(v, asid); ··· 149 150 hlist_del(&as->hash_link); 151 vhost_vdpa_iotlb_unmap(v, &as->iotlb, 0ULL, 0ULL - 1, asid); 152 kfree(as); 153 154 return 0; ··· 227 irq_bypass_unregister_producer(&vq->call_ctx.producer); 228 } 229 230 - static int vhost_vdpa_reset(struct vhost_vdpa *v) 231 { 232 struct vdpa_device *vdpa = v->vdpa; 233 234 v->in_batch = 0; 235 - 236 - return vdpa_reset(vdpa); 237 } 238 239 static long vhost_vdpa_bind_mm(struct vhost_vdpa *v) ··· 323 vhost_vdpa_unsetup_vq_irq(v, i); 324 325 if (status == 0) { 326 - ret = vdpa_reset(vdpa); 327 if (ret) 328 return ret; 329 } else ··· 417 return ops->resume; 418 } 419 420 static long vhost_vdpa_get_features(struct vhost_vdpa *v, u64 __user *featurep) 421 { 422 struct vdpa_device *vdpa = v->vdpa; ··· 448 return 0; 449 else 450 return ops->get_backend_features(vdpa); 451 } 452 453 static long vhost_vdpa_set_features(struct vhost_vdpa *v, u64 __user *featurep) ··· 650 else if (copy_to_user(argp, &s, sizeof(s))) 651 return -EFAULT; 652 return 0; 653 case VHOST_VDPA_SET_GROUP_ASID: 654 if (copy_from_user(&s, argp, sizeof(s))) 655 return -EFAULT; ··· 745 if (copy_from_user(&features, featurep, sizeof(features))) 746 return -EFAULT; 747 if (features & ~(VHOST_VDPA_BACKEND_FEATURES | 748 BIT_ULL(VHOST_BACKEND_F_SUSPEND) | 749 BIT_ULL(VHOST_BACKEND_F_RESUME) | 750 BIT_ULL(VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK))) ··· 756 return -EOPNOTSUPP; 757 if ((features & BIT_ULL(VHOST_BACKEND_F_RESUME)) && 758 !vhost_vdpa_can_resume(v)) 759 return -EOPNOTSUPP; 760 vhost_set_backend_features(&v->vdev, features); 761 return 0; ··· 819 features |= BIT_ULL(VHOST_BACKEND_F_SUSPEND); 820 if (vhost_vdpa_can_resume(v)) 821 features |= BIT_ULL(VHOST_BACKEND_F_RESUME); 822 features |= vhost_vdpa_get_backend_features(v); 823 if (copy_to_user(featurep, &features, sizeof(features))) 824 r = -EFAULT; ··· 1355 vhost_vdpa_free_domain(v); 1356 vhost_dev_cleanup(&v->vdev); 1357 kfree(v->vdev.vqs); 1358 } 1359 1360 static int vhost_vdpa_open(struct inode *inode, struct file *filep)
··· 131 return vhost_vdpa_alloc_as(v, asid); 132 } 133 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 + 143 static int vhost_vdpa_remove_as(struct vhost_vdpa *v, u32 asid) 144 { 145 struct vhost_vdpa_as *as = asid_to_as(v, asid); ··· 140 141 hlist_del(&as->hash_link); 142 vhost_vdpa_iotlb_unmap(v, &as->iotlb, 0ULL, 0ULL - 1, asid); 143 + /* 144 + * Devices with vendor specific IOMMU may need to restore 145 + * iotlb to the initial or default state, which cannot be 146 + * cleaned up in the all range unmap call above. Give them 147 + * a chance to clean up or reset the map to the desired 148 + * state. 149 + */ 150 + vhost_vdpa_reset_map(v, asid); 151 kfree(as); 152 153 return 0; ··· 210 irq_bypass_unregister_producer(&vq->call_ctx.producer); 211 } 212 213 + static int _compat_vdpa_reset(struct vhost_vdpa *v) 214 { 215 struct vdpa_device *vdpa = v->vdpa; 216 + u32 flags = 0; 217 218 + if (v->vdev.vqs) { 219 + flags |= !vhost_backend_has_feature(v->vdev.vqs[0], 220 + VHOST_BACKEND_F_IOTLB_PERSIST) ? 221 + VDPA_RESET_F_CLEAN_MAP : 0; 222 + } 223 + 224 + return vdpa_reset(vdpa, flags); 225 + } 226 + 227 + static int vhost_vdpa_reset(struct vhost_vdpa *v) 228 + { 229 v->in_batch = 0; 230 + return _compat_vdpa_reset(v); 231 } 232 233 static long vhost_vdpa_bind_mm(struct vhost_vdpa *v) ··· 295 vhost_vdpa_unsetup_vq_irq(v, i); 296 297 if (status == 0) { 298 + ret = _compat_vdpa_reset(v); 299 if (ret) 300 return ret; 301 } else ··· 389 return ops->resume; 390 } 391 392 + static bool vhost_vdpa_has_desc_group(const struct vhost_vdpa *v) 393 + { 394 + struct vdpa_device *vdpa = v->vdpa; 395 + const struct vdpa_config_ops *ops = vdpa->config; 396 + 397 + return ops->get_vq_desc_group; 398 + } 399 + 400 static long vhost_vdpa_get_features(struct vhost_vdpa *v, u64 __user *featurep) 401 { 402 struct vdpa_device *vdpa = v->vdpa; ··· 412 return 0; 413 else 414 return ops->get_backend_features(vdpa); 415 + } 416 + 417 + static bool vhost_vdpa_has_persistent_map(const struct vhost_vdpa *v) 418 + { 419 + struct vdpa_device *vdpa = v->vdpa; 420 + const struct vdpa_config_ops *ops = vdpa->config; 421 + 422 + return (!ops->set_map && !ops->dma_map) || ops->reset_map || 423 + vhost_vdpa_get_backend_features(v) & BIT_ULL(VHOST_BACKEND_F_IOTLB_PERSIST); 424 } 425 426 static long vhost_vdpa_set_features(struct vhost_vdpa *v, u64 __user *featurep) ··· 605 else if (copy_to_user(argp, &s, sizeof(s))) 606 return -EFAULT; 607 return 0; 608 + case VHOST_VDPA_GET_VRING_DESC_GROUP: 609 + if (!vhost_vdpa_has_desc_group(v)) 610 + return -EOPNOTSUPP; 611 + s.index = idx; 612 + s.num = ops->get_vq_desc_group(vdpa, idx); 613 + if (s.num >= vdpa->ngroups) 614 + return -EIO; 615 + else if (copy_to_user(argp, &s, sizeof(s))) 616 + return -EFAULT; 617 + return 0; 618 case VHOST_VDPA_SET_GROUP_ASID: 619 if (copy_from_user(&s, argp, sizeof(s))) 620 return -EFAULT; ··· 690 if (copy_from_user(&features, featurep, sizeof(features))) 691 return -EFAULT; 692 if (features & ~(VHOST_VDPA_BACKEND_FEATURES | 693 + BIT_ULL(VHOST_BACKEND_F_DESC_ASID) | 694 + BIT_ULL(VHOST_BACKEND_F_IOTLB_PERSIST) | 695 BIT_ULL(VHOST_BACKEND_F_SUSPEND) | 696 BIT_ULL(VHOST_BACKEND_F_RESUME) | 697 BIT_ULL(VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK))) ··· 699 return -EOPNOTSUPP; 700 if ((features & BIT_ULL(VHOST_BACKEND_F_RESUME)) && 701 !vhost_vdpa_can_resume(v)) 702 + return -EOPNOTSUPP; 703 + if ((features & BIT_ULL(VHOST_BACKEND_F_DESC_ASID)) && 704 + !(features & BIT_ULL(VHOST_BACKEND_F_IOTLB_ASID))) 705 + return -EINVAL; 706 + if ((features & BIT_ULL(VHOST_BACKEND_F_DESC_ASID)) && 707 + !vhost_vdpa_has_desc_group(v)) 708 + return -EOPNOTSUPP; 709 + if ((features & BIT_ULL(VHOST_BACKEND_F_IOTLB_PERSIST)) && 710 + !vhost_vdpa_has_persistent_map(v)) 711 return -EOPNOTSUPP; 712 vhost_set_backend_features(&v->vdev, features); 713 return 0; ··· 753 features |= BIT_ULL(VHOST_BACKEND_F_SUSPEND); 754 if (vhost_vdpa_can_resume(v)) 755 features |= BIT_ULL(VHOST_BACKEND_F_RESUME); 756 + if (vhost_vdpa_has_desc_group(v)) 757 + features |= BIT_ULL(VHOST_BACKEND_F_DESC_ASID); 758 + if (vhost_vdpa_has_persistent_map(v)) 759 + features |= BIT_ULL(VHOST_BACKEND_F_IOTLB_PERSIST); 760 features |= vhost_vdpa_get_backend_features(v); 761 if (copy_to_user(featurep, &features, sizeof(features))) 762 r = -EFAULT; ··· 1285 vhost_vdpa_free_domain(v); 1286 vhost_dev_cleanup(&v->vdev); 1287 kfree(v->vdev.vqs); 1288 + v->vdev.vqs = NULL; 1289 } 1290 1291 static int vhost_vdpa_open(struct inode *inode, struct file *filep)
+1 -1
drivers/virtio/virtio_balloon.c
··· 745 * 2) update the host about the old page removed from vb->pages list; 746 * 747 * This function preforms the balloon page migration task. 748 - * Called through balloon_mapping->a_ops->migratepage 749 */ 750 static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info, 751 struct page *newpage, struct page *page, enum migrate_mode mode)
··· 745 * 2) update the host about the old page removed from vb->pages list; 746 * 747 * This function preforms the balloon page migration task. 748 + * Called through movable_operations->migrate_page 749 */ 750 static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info, 751 struct page *newpage, struct page *page, enum migrate_mode mode)
+36
drivers/virtio/virtio_pci_modern.c
··· 39 __virtio_set_bit(vdev, VIRTIO_F_RING_RESET); 40 } 41 42 /* virtio config->finalize_features() implementation */ 43 static int vp_finalize_features(struct virtio_device *vdev) 44 { ··· 89 "but does not have VIRTIO_F_VERSION_1\n"); 90 return -EINVAL; 91 } 92 93 vp_modern_set_features(&vp_dev->mdev, vdev->features); 94
··· 39 __virtio_set_bit(vdev, VIRTIO_F_RING_RESET); 40 } 41 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 + 75 /* virtio config->finalize_features() implementation */ 76 static int vp_finalize_features(struct virtio_device *vdev) 77 { ··· 56 "but does not have VIRTIO_F_VERSION_1\n"); 57 return -EINVAL; 58 } 59 + 60 + if (vp_check_common_size(vdev)) 61 + return -EINVAL; 62 63 vp_modern_set_features(&vp_dev->mdev, vdev->features); 64
+5 -1
drivers/virtio/virtio_pci_modern_dev.c
··· 203 offsetof(struct virtio_pci_common_cfg, queue_used_lo)); 204 BUILD_BUG_ON(VIRTIO_PCI_COMMON_Q_USEDHI != 205 offsetof(struct virtio_pci_common_cfg, queue_used_hi)); 206 } 207 208 /* ··· 296 mdev->common = vp_modern_map_capability(mdev, common, 297 sizeof(struct virtio_pci_common_cfg), 4, 298 0, sizeof(struct virtio_pci_modern_common_cfg), 299 - NULL, NULL); 300 if (!mdev->common) 301 goto err_map_common; 302 mdev->isr = vp_modern_map_capability(mdev, isr, sizeof(u8), 1,
··· 203 offsetof(struct virtio_pci_common_cfg, queue_used_lo)); 204 BUILD_BUG_ON(VIRTIO_PCI_COMMON_Q_USEDHI != 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)); 210 } 211 212 /* ··· 292 mdev->common = vp_modern_map_capability(mdev, common, 293 sizeof(struct virtio_pci_common_cfg), 4, 294 0, sizeof(struct virtio_pci_modern_common_cfg), 295 + &mdev->common_len, NULL); 296 if (!mdev->common) 297 goto err_map_common; 298 mdev->isr = vp_modern_map_capability(mdev, isr, sizeof(u8), 1,
+1 -1
drivers/virtio/virtio_vdpa.c
··· 100 { 101 struct vdpa_device *vdpa = vd_get_vdpa(vdev); 102 103 - vdpa_reset(vdpa); 104 } 105 106 static bool virtio_vdpa_notify(struct virtqueue *vq)
··· 100 { 101 struct vdpa_device *vdpa = vd_get_vdpa(vdev); 102 103 + vdpa_reset(vdpa, 0); 104 } 105 106 static bool virtio_vdpa_notify(struct virtqueue *vq)
+7 -1
include/linux/mlx5/mlx5_ifc.h
··· 1232 u8 max_emulated_devices[0x8]; 1233 u8 max_num_virtio_queues[0x18]; 1234 1235 - u8 reserved_at_a0[0x60]; 1236 1237 u8 umem_1_buffer_param_a[0x20]; 1238
··· 1232 u8 max_emulated_devices[0x8]; 1233 u8 max_num_virtio_queues[0x18]; 1234 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]; 1242 1243 u8 umem_1_buffer_param_a[0x20]; 1244
+6 -1
include/linux/mlx5/mlx5_ifc_vdpa.h
··· 74 u8 reserved_at_320[0x8]; 75 u8 pd[0x18]; 76 77 - u8 reserved_at_340[0xc0]; 78 }; 79 80 struct mlx5_ifc_virtio_net_q_object_bits { ··· 145 MLX5_VIRTQ_MODIFY_MASK_STATE = (u64)1 << 0, 146 MLX5_VIRTQ_MODIFY_MASK_DIRTY_BITMAP_PARAMS = (u64)1 << 3, 147 MLX5_VIRTQ_MODIFY_MASK_DIRTY_BITMAP_DUMP_ENABLE = (u64)1 << 4, 148 }; 149 150 enum {
··· 74 u8 reserved_at_320[0x8]; 75 u8 pd[0x18]; 76 77 + u8 reserved_at_340[0x20]; 78 + 79 + u8 desc_group_mkey[0x20]; 80 + 81 + u8 reserved_at_380[0x80]; 82 }; 83 84 struct mlx5_ifc_virtio_net_q_object_bits { ··· 141 MLX5_VIRTQ_MODIFY_MASK_STATE = (u64)1 << 0, 142 MLX5_VIRTQ_MODIFY_MASK_DIRTY_BITMAP_PARAMS = (u64)1 << 3, 143 MLX5_VIRTQ_MODIFY_MASK_DIRTY_BITMAP_DUMP_ENABLE = (u64)1 << 4, 144 + MLX5_VIRTQ_MODIFY_MASK_DESC_GROUP_MKEY = (u64)1 << 14, 145 }; 146 147 enum {
+39 -2
include/linux/vdpa.h
··· 204 * @vdev: vdpa device 205 * @idx: virtqueue index 206 * Returns u32: group id for this virtqueue 207 * @get_device_features: Get virtio features supported by the device 208 * @vdev: vdpa device 209 * Returns the virtio features support by the ··· 251 * @status: virtio device status 252 * @reset: Reset device 253 * @vdev: vdpa device 254 * Returns integer: success (0) or error (< 0) 255 * @suspend: Suspend the device (optional) 256 * @vdev: vdpa device ··· 338 * @iova: iova to be unmapped 339 * @size: size of the area 340 * Returns integer: success (0) or error (< 0) 341 * @get_vq_dma_dev: Get the dma device for a specific 342 * virtqueue (optional) 343 * @vdev: vdpa device ··· 390 /* Device ops */ 391 u32 (*get_vq_align)(struct vdpa_device *vdev); 392 u32 (*get_vq_group)(struct vdpa_device *vdev, u16 idx); 393 u64 (*get_device_features)(struct vdpa_device *vdev); 394 u64 (*get_backend_features)(const struct vdpa_device *vdev); 395 int (*set_driver_features)(struct vdpa_device *vdev, u64 features); ··· 404 u8 (*get_status)(struct vdpa_device *vdev); 405 void (*set_status)(struct vdpa_device *vdev, u8 status); 406 int (*reset)(struct vdpa_device *vdev); 407 int (*suspend)(struct vdpa_device *vdev); 408 int (*resume)(struct vdpa_device *vdev); 409 size_t (*get_config_size)(struct vdpa_device *vdev); ··· 427 u64 iova, u64 size, u64 pa, u32 perm, void *opaque); 428 int (*dma_unmap)(struct vdpa_device *vdev, unsigned int asid, 429 u64 iova, u64 size); 430 int (*set_group_asid)(struct vdpa_device *vdev, unsigned int group, 431 unsigned int asid); 432 struct device *(*get_vq_dma_dev)(struct vdpa_device *vdev, u16 idx); ··· 519 return vdev->dma_dev; 520 } 521 522 - static inline int vdpa_reset(struct vdpa_device *vdev) 523 { 524 const struct vdpa_config_ops *ops = vdev->config; 525 int ret; 526 527 down_write(&vdev->cf_lock); 528 vdev->features_valid = false; 529 - ret = ops->reset(vdev); 530 up_write(&vdev->cf_lock); 531 return ret; 532 }
··· 204 * @vdev: vdpa device 205 * @idx: virtqueue index 206 * 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. 217 * @get_device_features: Get virtio features supported by the device 218 * @vdev: vdpa device 219 * Returns the virtio features support by the ··· 241 * @status: virtio device status 242 * @reset: Reset device 243 * @vdev: vdpa device 244 + * Returns integer: success (0) or error (< 0) 245 + * @compat_reset: Reset device with compatibility quirks to 246 + * accommodate older userspace. Only needed by 247 + * parent driver which used to have bogus reset 248 + * behaviour, and has to maintain such behaviour 249 + * for compatibility with older userspace. 250 + * Historically compliant driver only has to 251 + * implement .reset, Historically non-compliant 252 + * driver should implement both. 253 + * @vdev: vdpa device 254 + * @flags: compatibility quirks for reset 255 * Returns integer: success (0) or error (< 0) 256 * @suspend: Suspend the device (optional) 257 * @vdev: vdpa device ··· 317 * @iova: iova to be unmapped 318 * @size: size of the area 319 * Returns integer: success (0) or error (< 0) 320 + * @reset_map: Reset device memory mapping to the default 321 + * state (optional) 322 + * Needed for devices that are using device 323 + * specific DMA translation and prefer mapping 324 + * to be decoupled from the virtio life cycle, 325 + * i.e. device .reset op does not reset mapping 326 + * @vdev: vdpa device 327 + * @asid: address space identifier 328 + * Returns integer: success (0) or error (< 0) 329 * @get_vq_dma_dev: Get the dma device for a specific 330 * virtqueue (optional) 331 * @vdev: vdpa device ··· 360 /* Device ops */ 361 u32 (*get_vq_align)(struct vdpa_device *vdev); 362 u32 (*get_vq_group)(struct vdpa_device *vdev, u16 idx); 363 + u32 (*get_vq_desc_group)(struct vdpa_device *vdev, u16 idx); 364 u64 (*get_device_features)(struct vdpa_device *vdev); 365 u64 (*get_backend_features)(const struct vdpa_device *vdev); 366 int (*set_driver_features)(struct vdpa_device *vdev, u64 features); ··· 373 u8 (*get_status)(struct vdpa_device *vdev); 374 void (*set_status)(struct vdpa_device *vdev, u8 status); 375 int (*reset)(struct vdpa_device *vdev); 376 + int (*compat_reset)(struct vdpa_device *vdev, u32 flags); 377 + #define VDPA_RESET_F_CLEAN_MAP 1 378 int (*suspend)(struct vdpa_device *vdev); 379 int (*resume)(struct vdpa_device *vdev); 380 size_t (*get_config_size)(struct vdpa_device *vdev); ··· 394 u64 iova, u64 size, u64 pa, u32 perm, void *opaque); 395 int (*dma_unmap)(struct vdpa_device *vdev, unsigned int asid, 396 u64 iova, u64 size); 397 + int (*reset_map)(struct vdpa_device *vdev, unsigned int asid); 398 int (*set_group_asid)(struct vdpa_device *vdev, unsigned int group, 399 unsigned int asid); 400 struct device *(*get_vq_dma_dev)(struct vdpa_device *vdev, u16 idx); ··· 485 return vdev->dma_dev; 486 } 487 488 + static inline int vdpa_reset(struct vdpa_device *vdev, u32 flags) 489 { 490 const struct vdpa_config_ops *ops = vdev->config; 491 int ret; 492 493 down_write(&vdev->cf_lock); 494 vdev->features_valid = false; 495 + if (ops->compat_reset && flags) 496 + ret = ops->compat_reset(vdev, flags); 497 + else 498 + ret = ops->reset(vdev); 499 up_write(&vdev->cf_lock); 500 return ret; 501 }
+23 -12
include/linux/virtio_pci_modern.h
··· 12 __le16 queue_reset; /* read-write */ 13 }; 14 15 struct virtio_pci_modern_device { 16 struct pci_dev *pci_dev; 17 18 struct virtio_pci_common_cfg __iomem *common; 19 - /* Device-specific data (non-legacy mode) */ 20 void __iomem *device; 21 - /* Base of vq notifications (non-legacy mode). */ 22 void __iomem *notify_base; 23 - /* Physical base of vq notifications */ 24 resource_size_t notify_pa; 25 - /* Where to read and clear interrupt */ 26 u8 __iomem *isr; 27 28 - /* So we can sanity-check accesses. */ 29 size_t notify_len; 30 size_t device_len; 31 32 - /* Capability for when we need to map notifications per-vq. */ 33 int notify_map_cap; 34 35 - /* Multiply queue_notify_off by this value. (non-legacy mode). */ 36 u32 notify_offset_multiplier; 37 - 38 int modern_bars; 39 - 40 struct virtio_device_id id; 41 42 - /* optional check for vendor virtio device, returns dev_id or -ERRNO */ 43 int (*device_id_check)(struct pci_dev *pdev); 44 - 45 - /* optional mask for devices with limited DMA space */ 46 u64 dma_mask; 47 }; 48
··· 12 __le16 queue_reset; /* read-write */ 13 }; 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 + */ 37 struct virtio_pci_modern_device { 38 struct pci_dev *pci_dev; 39 40 struct virtio_pci_common_cfg __iomem *common; 41 void __iomem *device; 42 void __iomem *notify_base; 43 resource_size_t notify_pa; 44 u8 __iomem *isr; 45 46 size_t notify_len; 47 size_t device_len; 48 + size_t common_len; 49 50 int notify_map_cap; 51 52 u32 notify_offset_multiplier; 53 int modern_bars; 54 struct virtio_device_id id; 55 56 int (*device_id_check)(struct pci_dev *pdev); 57 u64 dma_mask; 58 }; 59
+8
include/uapi/linux/vhost.h
··· 219 */ 220 #define VHOST_VDPA_RESUME _IO(VHOST_VIRTIO, 0x7E) 221 222 #endif
··· 219 */ 220 #define VHOST_VDPA_RESUME _IO(VHOST_VIRTIO, 0x7E) 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) 230 #endif
+7
include/uapi/linux/vhost_types.h
··· 185 * DRIVER_OK 186 */ 187 #define VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK 0x6 188 189 #endif
··· 185 * DRIVER_OK 186 */ 187 #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 195 196 #endif
+5
include/uapi/linux/virtio_config.h
··· 105 */ 106 #define VIRTIO_F_NOTIFICATION_DATA 38 107 108 /* 109 * This feature indicates that the driver can reset a queue individually. 110 */
··· 105 */ 106 #define VIRTIO_F_NOTIFICATION_DATA 38 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 + 113 /* 114 * This feature indicates that the driver can reset a queue individually. 115 */