Pull virtio updates from Michael Tsirkin: "Mostly fixes all over the place, a couple of cleanups" * tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost: (32 commits) virtio_blk: Fix signedness bug in virtblk_prep_rq() vdpa_sim_net: should not drop the multicast/broadcast packet vdpasim: fix memory leak when freeing IOTLBs vdpa: conditionally fill max max queue pair for stats vdpa/vp_vdpa: fix kfree a wrong pointer in vp_vdpa_remove vduse: Validate vq_num in vduse_validate_config() tools/virtio: remove smp_read_barrier_depends() tools/virtio: remove stray characters vhost_vdpa: fix the crash in unmap a large memory virtio: Implementing attribute show with sysfs_emit virtio-crypto: fix memory leak in virtio_crypto_alg_skcipher_close_session() tools/virtio: Variable type completion vdpa_sim: fix vringh initialization in vdpasim_queue_ready() virtio_blk: use UINT_MAX instead of -1U vhost-vdpa: fix an iotlb memory leak vhost: fix range used in translate_desc() vringh: fix range used in iotlb_translate() vhost/vsock: Fix error handling in vhost_vsock_init() vdpa_sim: fix possible memory leak in vdpasim_net_init() and vdpasim_blk_init() tools: Delete the unneeded semicolon after curly braces ...
Unified · Split
| @@ -315,22 +315,35 @@ static void virtio_commit_rqs(struct blk_mq_hw_ctx *hctx) · 314 unmodified lines | |||
| 315 | virtqueue_notify(vq->vq); | 315 | virtqueue_notify(vq->vq); |
| 316 | } | 316 | } |
| 317 | 317 | ||
| 318 | static blk_status_t virtblk_fail_to_queue(struct request *req, int rc) | ||
| 319 | { | ||
| 320 | virtblk_cleanup_cmd(req); | ||
| 321 | switch (rc) { | ||
| 322 | case -ENOSPC: | ||
| 323 | return BLK_STS_DEV_RESOURCE; | ||
| 324 | case -ENOMEM: | ||
| 325 | return BLK_STS_RESOURCE; | ||
| 326 | default: | ||
| 327 | return BLK_STS_IOERR; | ||
| 328 | } | ||
| 329 | } | ||
| 330 | |||
| 318 | static blk_status_t virtblk_prep_rq(struct blk_mq_hw_ctx *hctx, | 331 | static blk_status_t virtblk_prep_rq(struct blk_mq_hw_ctx *hctx, |
| 319 | struct virtio_blk *vblk, | 332 | struct virtio_blk *vblk, |
| 320 | struct request *req, | 333 | struct request *req, |
| 321 | struct virtblk_req *vbr) | 334 | struct virtblk_req *vbr) |
| 322 | { | 335 | { |
| 323 | blk_status_t status; | 336 | blk_status_t status; |
| 337 | int num; | ||
| 324 | 338 | ||
| 325 | status = virtblk_setup_cmd(vblk->vdev, req, vbr); | 339 | status = virtblk_setup_cmd(vblk->vdev, req, vbr); |
| 326 | if (unlikely(status)) | 340 | if (unlikely(status)) |
| 327 | return status; | 341 | return status; |
| 328 | 342 | ||
| 329 | vbr->sg_table.nents = virtblk_map_data(hctx, req, vbr); | 343 | num = virtblk_map_data(hctx, req, vbr); |
| 330 | if (unlikely(vbr->sg_table.nents < 0)) { | 344 | if (unlikely(num < 0)) |
| 331 | virtblk_cleanup_cmd(req); | 345 | return virtblk_fail_to_queue(req, -ENOMEM); |
| 332 | return BLK_STS_RESOURCE; | 346 | vbr->sg_table.nents = num; |
| 333 | } | ||
| 334 | 347 | ||
| 335 | blk_mq_start_request(req); | 348 | blk_mq_start_request(req); |
| 336 | 349 | ||
| @@ -364,15 +377,7 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx, · 27 unmodified lines | |||
| 364 | blk_mq_stop_hw_queue(hctx); | 377 | blk_mq_stop_hw_queue(hctx); |
| 365 | spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags); | 378 | spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags); |
| 366 | virtblk_unmap_data(req, vbr); | 379 | virtblk_unmap_data(req, vbr); |
| 367 | virtblk_cleanup_cmd(req); | 380 | return virtblk_fail_to_queue(req, err); |
| 368 | switch (err) { | ||
| 369 | case -ENOSPC: | ||
| 370 | return BLK_STS_DEV_RESOURCE; | ||
| 371 | case -ENOMEM: | ||
| 372 | return BLK_STS_RESOURCE; | ||
| 373 | default: | ||
| 374 | return BLK_STS_IOERR; | ||
| 375 | } | ||
| 376 | } | 381 | } |
| 377 | 382 | ||
| 378 | if (bd->last && virtqueue_kick_prepare(vblk->vqs[qid].vq)) | 383 | if (bd->last && virtqueue_kick_prepare(vblk->vqs[qid].vq)) |
| @@ -991,7 +996,7 @@ static int virtblk_probe(struct virtio_device *vdev) · 612 unmodified lines | |||
| 991 | blk_queue_max_segments(q, sg_elems); | 996 | blk_queue_max_segments(q, sg_elems); |
| 992 | 997 | ||
| 993 | /* No real sector limit. */ | 998 | /* No real sector limit. */ |
| 994 | blk_queue_max_hw_sectors(q, -1U); | 999 | blk_queue_max_hw_sectors(q, UINT_MAX); |
| 995 | 1000 | ||
| 996 | max_size = virtio_max_dma_size(vdev); | 1001 | max_size = virtio_max_dma_size(vdev); |
| 997 | 1002 | ||
| @@ -239,7 +239,8 @@ static int virtio_crypto_alg_skcipher_close_session( · 238 unmodified lines | |||
| 239 | pr_err("virtio_crypto: Close session failed status: %u, session_id: 0x%llx\n", | 239 | pr_err("virtio_crypto: Close session failed status: %u, session_id: 0x%llx\n", |
| 240 | ctrl_status->status, destroy_session->session_id); | 240 | ctrl_status->status, destroy_session->session_id); |
| 241 | 241 | ||
| 242 | return -EINVAL; | 242 | err = -EINVAL; |
| 243 | goto out; | ||
| 243 | } | 244 | } |
| 244 | 245 | ||
| 245 | err = 0; | 246 | err = 0; |
| @@ -116,8 +116,9 @@ int mlx5_vdpa_create_mkey(struct mlx5_vdpa_dev *mvdev, u32 *mkey, u32 *in, · 115 unmodified lines | |||
| 116 | int inlen); | 116 | int inlen); |
| 117 | int mlx5_vdpa_destroy_mkey(struct mlx5_vdpa_dev *mvdev, u32 mkey); | 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, | 118 | int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb, |
| 119 | bool *change_map); | 119 | bool *change_map, unsigned int asid); |
| 120 | int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb); | 120 | int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb, |
| 121 | unsigned int asid); | ||
| 121 | void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev); | 122 | void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev); |
| 122 | 123 | ||
| 123 | #define mlx5_vdpa_warn(__dev, format, ...) \ | 124 | #define mlx5_vdpa_warn(__dev, format, ...) \ |
| @@ -311,7 +311,6 @@ static int add_direct_chain(struct mlx5_vdpa_dev *mvdev, u64 start, u64 size, u8 · 310 unmodified lines | |||
| 311 | u64 st; | 311 | u64 st; |
| 312 | u64 sz; | 312 | u64 sz; |
| 313 | int err; | 313 | int err; |
| 314 | int i = 0; | ||
| 315 | 314 | ||
| 316 | st = start; | 315 | st = start; |
| 317 | while (size) { | 316 | while (size) { |
| @@ -336,7 +335,6 @@ static int add_direct_chain(struct mlx5_vdpa_dev *mvdev, u64 start, u64 size, u8 · 18 unmodified lines | |||
| 336 | mr->num_directs++; | 335 | mr->num_directs++; |
| 337 | mr->num_klms++; | 336 | mr->num_klms++; |
| 338 | st += sz; | 337 | st += sz; |
| 339 | i++; | ||
| 340 | } | 338 | } |
| 341 | list_splice_tail(&tmp, &mr->head); | 339 | list_splice_tail(&tmp, &mr->head); |
| 342 | return 0; | 340 | return 0; |
| @@ -511,7 +509,8 @@ out: · 168 unmodified lines | |||
| 511 | mutex_unlock(&mr->mkey_mtx); | 509 | mutex_unlock(&mr->mkey_mtx); |
| 512 | } | 510 | } |
| 513 | 511 | ||
| 514 | static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb) | 512 | static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, |
| 513 | struct vhost_iotlb *iotlb, unsigned int asid) | ||
| 515 | { | 514 | { |
| 516 | struct mlx5_vdpa_mr *mr = &mvdev->mr; | 515 | struct mlx5_vdpa_mr *mr = &mvdev->mr; |
| 517 | int err; | 516 | int err; |
| @@ -519,42 +518,49 @@ static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb · 1 unmodified line | |||
| 519 | if (mr->initialized) | 518 | if (mr->initialized) |
| 520 | return 0; | 519 | return 0; |
| 521 | 520 | ||
| 522 | if (iotlb) | 521 | if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] == asid) { |
| 523 | err = create_user_mr(mvdev, iotlb); | 522 | if (iotlb) |
| 524 | else | 523 | err = create_user_mr(mvdev, iotlb); |
| 525 | err = create_dma_mr(mvdev, mr); | 524 | else |
| 525 | err = create_dma_mr(mvdev, mr); | ||
| 526 | 526 | ||
| 527 | if (err) | 527 | if (err) |
| 528 | return err; | 528 | return err; |
| 529 | } | ||
| 529 | 530 | ||
| 530 | err = dup_iotlb(mvdev, iotlb); | 531 | if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] == asid) { |
| 531 | if (err) | 532 | err = dup_iotlb(mvdev, iotlb); |
| 532 | goto out_err; | 533 | if (err) |
| 534 | goto out_err; | ||
| 535 | } | ||
| 533 | 536 | ||
| 534 | mr->initialized = true; | 537 | mr->initialized = true; |
| 535 | return 0; | 538 | return 0; |
| 536 | 539 | ||
| 537 | out_err: | 540 | out_err: |
| 538 | if (iotlb) | 541 | if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] == asid) { |
| 539 | destroy_user_mr(mvdev, mr); | 542 | if (iotlb) |
| 540 | else | 543 | destroy_user_mr(mvdev, mr); |
| 541 | destroy_dma_mr(mvdev, mr); | 544 | else |
| 545 | destroy_dma_mr(mvdev, mr); | ||
| 546 | } | ||
| 542 | 547 | ||
| 543 | return err; | 548 | return err; |
| 544 | } | 549 | } |
| 545 | 550 | ||
| 546 | int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb) | 551 | int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb, |
| 552 | unsigned int asid) | ||
| 547 | { | 553 | { |
| 548 | int err; | 554 | int err; |
| 549 | 555 | ||
| 550 | mutex_lock(&mvdev->mr.mkey_mtx); | 556 | mutex_lock(&mvdev->mr.mkey_mtx); |
| 551 | err = _mlx5_vdpa_create_mr(mvdev, iotlb); | 557 | err = _mlx5_vdpa_create_mr(mvdev, iotlb, asid); |
| 552 | mutex_unlock(&mvdev->mr.mkey_mtx); | 558 | mutex_unlock(&mvdev->mr.mkey_mtx); |
| 553 | return err; | 559 | return err; |
| 554 | } | 560 | } |
| 555 | 561 | ||
| 556 | int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb, | 562 | int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb, |
| 557 | bool *change_map) | 563 | bool *change_map, unsigned int asid) |
| 558 | { | 564 | { |
| 559 | struct mlx5_vdpa_mr *mr = &mvdev->mr; | 565 | struct mlx5_vdpa_mr *mr = &mvdev->mr; |
| 560 | int err = 0; | 566 | int err = 0; |
| @@ -566,7 +572,7 @@ int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *io · 5 unmodified lines | |||
| 566 | *change_map = true; | 572 | *change_map = true; |
| 567 | } | 573 | } |
| 568 | if (!*change_map) | 574 | if (!*change_map) |
| 569 | err = _mlx5_vdpa_create_mr(mvdev, iotlb); | 575 | err = _mlx5_vdpa_create_mr(mvdev, iotlb, asid); |
| 570 | mutex_unlock(&mr->mkey_mtx); | 576 | mutex_unlock(&mr->mkey_mtx); |
| 571 | 577 | ||
| 572 | return err; | 578 | return err; |
| @@ -1468,11 +1468,13 @@ static int mlx5_vdpa_add_mac_vlan_rules(struct mlx5_vdpa_net *ndev, u8 *mac, · 1467 unmodified lines | |||
| 1468 | dmac_v = MLX5_ADDR_OF(fte_match_param, headers_v, outer_headers.dmac_47_16); | 1468 | dmac_v = MLX5_ADDR_OF(fte_match_param, headers_v, outer_headers.dmac_47_16); |
| 1469 | eth_broadcast_addr(dmac_c); | 1469 | eth_broadcast_addr(dmac_c); |
| 1470 | ether_addr_copy(dmac_v, mac); | 1470 | ether_addr_copy(dmac_v, mac); |
| 1471 | MLX5_SET(fte_match_set_lyr_2_4, headers_c, cvlan_tag, 1); | 1471 | if (ndev->mvdev.actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VLAN)) { |
| 1472 | MLX5_SET(fte_match_set_lyr_2_4, headers_c, cvlan_tag, 1); | ||
| 1473 | MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, headers_c, first_vid); | ||
| 1474 | } | ||
| 1472 | if (tagged) { | 1475 | if (tagged) { |
| 1473 | MLX5_SET(fte_match_set_lyr_2_4, headers_v, cvlan_tag, 1); | 1476 | MLX5_SET(fte_match_set_lyr_2_4, headers_v, cvlan_tag, 1); |
| 1474 | MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, headers_c, first_vid); | 1477 | MLX5_SET(fte_match_set_lyr_2_4, headers_v, first_vid, vid); |
| 1475 | MLX5_SET(fte_match_set_lyr_2_4, headers_c, first_vid, vid); | ||
| 1476 | } | 1478 | } |
| 1477 | flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; | 1479 | flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; |
| 1478 | dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR; | 1480 | dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR; |
| @@ -1684,7 +1686,7 @@ static virtio_net_ctrl_ack handle_ctrl_mac(struct mlx5_vdpa_dev *mvdev, u8 cmd) · 205 unmodified lines | |||
| 1684 | 1686 | ||
| 1685 | /* Need recreate the flow table entry, so that the packet could forward back | 1687 | /* Need recreate the flow table entry, so that the packet could forward back |
| 1686 | */ | 1688 | */ |
| 1687 | mac_vlan_del(ndev, ndev->config.mac, 0, false); | 1689 | mac_vlan_del(ndev, mac_back, 0, false); |
| 1688 | 1690 | ||
| 1689 | if (mac_vlan_add(ndev, ndev->config.mac, 0, false)) { | 1691 | if (mac_vlan_add(ndev, ndev->config.mac, 0, false)) { |
| 1690 | mlx5_vdpa_warn(mvdev, "failed to insert forward rules, try to restore\n"); | 1692 | mlx5_vdpa_warn(mvdev, "failed to insert forward rules, try to restore\n"); |
| @@ -1821,6 +1823,9 @@ static virtio_net_ctrl_ack handle_ctrl_vlan(struct mlx5_vdpa_dev *mvdev, u8 cmd) · 130 unmodified lines | |||
| 1821 | size_t read; | 1823 | size_t read; |
| 1822 | u16 id; | 1824 | u16 id; |
| 1823 | 1825 | ||
| 1826 | if (!(ndev->mvdev.actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VLAN))) | ||
| 1827 | return status; | ||
| 1828 | |||
| 1824 | switch (cmd) { | 1829 | switch (cmd) { |
| 1825 | case VIRTIO_NET_CTRL_VLAN_ADD: | 1830 | case VIRTIO_NET_CTRL_VLAN_ADD: |
| 1826 | read = vringh_iov_pull_iotlb(&cvq->vring, &cvq->riov, &vlan, sizeof(vlan)); | 1831 | read = vringh_iov_pull_iotlb(&cvq->vring, &cvq->riov, &vlan, sizeof(vlan)); |
| @@ -2389,7 +2394,8 @@ static void restore_channels_info(struct mlx5_vdpa_net *ndev) · 562 unmodified lines | |||
| 2389 | } | 2394 | } |
| 2390 | } | 2395 | } |
| 2391 | 2396 | ||
| 2392 | static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb) | 2397 | static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev, |
| 2398 | struct vhost_iotlb *iotlb, unsigned int asid) | ||
| 2393 | { | 2399 | { |
| 2394 | struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev); | 2400 | struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev); |
| 2395 | int err; | 2401 | int err; |
| @@ -2401,7 +2407,7 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb · 5 unmodified lines | |||
| 2401 | 2407 | ||
| 2402 | teardown_driver(ndev); | 2408 | teardown_driver(ndev); |
| 2403 | mlx5_vdpa_destroy_mr(mvdev); | 2409 | mlx5_vdpa_destroy_mr(mvdev); |
| 2404 | err = mlx5_vdpa_create_mr(mvdev, iotlb); | 2410 | err = mlx5_vdpa_create_mr(mvdev, iotlb, asid); |
| 2405 | if (err) | 2411 | if (err) |
| 2406 | goto err_mr; | 2412 | goto err_mr; |
| 2407 | 2413 | ||
| @@ -2582,7 +2588,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev) · 174 unmodified lines | |||
| 2582 | ++mvdev->generation; | 2588 | ++mvdev->generation; |
| 2583 | 2589 | ||
| 2584 | if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) { | 2590 | if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) { |
| 2585 | if (mlx5_vdpa_create_mr(mvdev, NULL)) | 2591 | if (mlx5_vdpa_create_mr(mvdev, NULL, 0)) |
| 2586 | mlx5_vdpa_warn(mvdev, "create MR failed\n"); | 2592 | mlx5_vdpa_warn(mvdev, "create MR failed\n"); |
| 2587 | } | 2593 | } |
| 2588 | up_write(&ndev->reslock); | 2594 | up_write(&ndev->reslock); |
| @@ -2618,41 +2624,20 @@ static u32 mlx5_vdpa_get_generation(struct vdpa_device *vdev) · 29 unmodified lines | |||
| 2618 | return mvdev->generation; | 2624 | return mvdev->generation; |
| 2619 | } | 2625 | } |
| 2620 | 2626 | ||
| 2621 | static int set_map_control(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb) | 2627 | static int set_map_data(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb, |
| 2622 | { | 2628 | unsigned int asid) |
| 2623 | u64 start = 0ULL, last = 0ULL - 1; | ||
| 2624 | struct vhost_iotlb_map *map; | ||
| 2625 | int err = 0; | ||
| 2626 | |||
| 2627 | spin_lock(&mvdev->cvq.iommu_lock); | ||
| 2628 | vhost_iotlb_reset(mvdev->cvq.iotlb); | ||
| 2629 | |||
| 2630 | for (map = vhost_iotlb_itree_first(iotlb, start, last); map; | ||
| 2631 | map = vhost_iotlb_itree_next(map, start, last)) { | ||
| 2632 | err = vhost_iotlb_add_range(mvdev->cvq.iotlb, map->start, | ||
| 2633 | map->last, map->addr, map->perm); | ||
| 2634 | if (err) | ||
| 2635 | goto out; | ||
| 2636 | } | ||
| 2637 | |||
| 2638 | out: | ||
| 2639 | spin_unlock(&mvdev->cvq.iommu_lock); | ||
| 2640 | return err; | ||
| 2641 | } | ||
| 2642 | |||
| 2643 | static int set_map_data(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb) | ||
| 2644 | { | 2629 | { |
| 2645 | bool change_map; | 2630 | bool change_map; |
| 2646 | int err; | 2631 | int err; |
| 2647 | 2632 | ||
| 2648 | err = mlx5_vdpa_handle_set_map(mvdev, iotlb, &change_map); | 2633 | err = mlx5_vdpa_handle_set_map(mvdev, iotlb, &change_map, asid); |
| 2649 | if (err) { | 2634 | if (err) { |
| 2650 | mlx5_vdpa_warn(mvdev, "set map failed(%d)\n", err); | 2635 | mlx5_vdpa_warn(mvdev, "set map failed(%d)\n", err); |
| 2651 | return err; | 2636 | return err; |
| 2652 | } | 2637 | } |
| 2653 | 2638 | ||
| 2654 | if (change_map) | 2639 | if (change_map) |
| 2655 | err = mlx5_vdpa_change_map(mvdev, iotlb); | 2640 | err = mlx5_vdpa_change_map(mvdev, iotlb, asid); |
| 2656 | 2641 | ||
| 2657 | return err; | 2642 | return err; |
| 2658 | } | 2643 | } |
| @@ -2665,16 +2650,7 @@ static int mlx5_vdpa_set_map(struct vdpa_device *vdev, unsigned int asid, · 6 unmodified lines | |||
| 2665 | int err = -EINVAL; | 2650 | int err = -EINVAL; |
| 2666 | 2651 | ||
| 2667 | down_write(&ndev->reslock); | 2652 | down_write(&ndev->reslock); |
| 2668 | if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] == asid) { | 2653 | err = set_map_data(mvdev, iotlb, asid); |
| 2669 | err = set_map_data(mvdev, iotlb); | ||
| 2670 | if (err) | ||
| 2671 | goto out; | ||
| 2672 | } | ||
| 2673 | |||
| 2674 | if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] == asid) | ||
| 2675 | err = set_map_control(mvdev, iotlb); | ||
| 2676 | |||
| 2677 | out: | ||
| 2678 | up_write(&ndev->reslock); | 2654 | up_write(&ndev->reslock); |
| 2679 | return err; | 2655 | return err; |
| 2680 | } | 2656 | } |
| @@ -2840,8 +2816,8 @@ static int mlx5_vdpa_suspend(struct vdpa_device *vdev) · 159 unmodified lines | |||
| 2840 | int i; | 2816 | int i; |
| 2841 | 2817 | ||
| 2842 | down_write(&ndev->reslock); | 2818 | down_write(&ndev->reslock); |
| 2843 | mlx5_notifier_unregister(mvdev->mdev, &ndev->nb); | ||
| 2844 | ndev->nb_registered = false; | 2819 | ndev->nb_registered = false; |
| 2820 | mlx5_notifier_unregister(mvdev->mdev, &ndev->nb); | ||
| 2845 | flush_workqueue(ndev->mvdev.wq); | 2821 | flush_workqueue(ndev->mvdev.wq); |
| 2846 | for (i = 0; i < ndev->cur_num_vqs; i++) { | 2822 | for (i = 0; i < ndev->cur_num_vqs; i++) { |
| 2847 | mvq = &ndev->vqs[i]; | 2823 | mvq = &ndev->vqs[i]; |
| @@ -3019,7 +2995,7 @@ static void update_carrier(struct work_struct *work) · 171 unmodified lines | |||
| 3019 | else | 2995 | else |
| 3020 | ndev->config.status &= cpu_to_mlx5vdpa16(mvdev, ~VIRTIO_NET_S_LINK_UP); | 2996 | ndev->config.status &= cpu_to_mlx5vdpa16(mvdev, ~VIRTIO_NET_S_LINK_UP); |
| 3021 | 2997 | ||
| 3022 | if (ndev->config_cb.callback) | 2998 | if (ndev->nb_registered && ndev->config_cb.callback) |
| 3023 | ndev->config_cb.callback(ndev->config_cb.private); | 2999 | ndev->config_cb.callback(ndev->config_cb.private); |
| 3024 | 3000 | ||
| 3025 | kfree(wqent); | 3001 | kfree(wqent); |
| @@ -3036,21 +3012,13 @@ static int event_handler(struct notifier_block *nb, unsigned long event, void *p · 10 unmodified lines | |||
| 3036 | switch (eqe->sub_type) { | 3012 | switch (eqe->sub_type) { |
| 3037 | case MLX5_PORT_CHANGE_SUBTYPE_DOWN: | 3013 | case MLX5_PORT_CHANGE_SUBTYPE_DOWN: |
| 3038 | case MLX5_PORT_CHANGE_SUBTYPE_ACTIVE: | 3014 | case MLX5_PORT_CHANGE_SUBTYPE_ACTIVE: |
| 3039 | down_read(&ndev->reslock); | ||
| 3040 | if (!ndev->nb_registered) { | ||
| 3041 | up_read(&ndev->reslock); | ||
| 3042 | return NOTIFY_DONE; | ||
| 3043 | } | ||
| 3044 | wqent = kzalloc(sizeof(*wqent), GFP_ATOMIC); | 3015 | wqent = kzalloc(sizeof(*wqent), GFP_ATOMIC); |
| 3045 | if (!wqent) { | 3016 | if (!wqent) |
| 3046 | up_read(&ndev->reslock); | ||
| 3047 | return NOTIFY_DONE; | 3017 | return NOTIFY_DONE; |
| 3048 | } | ||
| 3049 | 3018 | ||
| 3050 | wqent->mvdev = &ndev->mvdev; | 3019 | wqent->mvdev = &ndev->mvdev; |
| 3051 | INIT_WORK(&wqent->work, update_carrier); | 3020 | INIT_WORK(&wqent->work, update_carrier); |
| 3052 | queue_work(ndev->mvdev.wq, &wqent->work); | 3021 | queue_work(ndev->mvdev.wq, &wqent->work); |
| 3053 | up_read(&ndev->reslock); | ||
| 3054 | ret = NOTIFY_OK; | 3022 | ret = NOTIFY_OK; |
| 3055 | break; | 3023 | break; |
| 3056 | default: | 3024 | default: |
| @@ -3185,7 +3153,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, · 128 unmodified lines | |||
| 3185 | goto err_mpfs; | 3153 | goto err_mpfs; |
| 3186 | 3154 | ||
| 3187 | if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) { | 3155 | if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) { |
| 3188 | err = mlx5_vdpa_create_mr(mvdev, NULL); | 3156 | err = mlx5_vdpa_create_mr(mvdev, NULL, 0); |
| 3189 | if (err) | 3157 | if (err) |
| 3190 | goto err_res; | 3158 | goto err_res; |
| 3191 | } | 3159 | } |
| @@ -3237,8 +3205,8 @@ static void mlx5_vdpa_dev_del(struct vdpa_mgmt_dev *v_mdev, struct vdpa_device * · 45 unmodified lines | |||
| 3237 | struct workqueue_struct *wq; | 3205 | struct workqueue_struct *wq; |
| 3238 | 3206 | ||
| 3239 | if (ndev->nb_registered) { | 3207 | if (ndev->nb_registered) { |
| 3240 | mlx5_notifier_unregister(mvdev->mdev, &ndev->nb); | ||
| 3241 | ndev->nb_registered = false; | 3208 | ndev->nb_registered = false; |
| 3209 | mlx5_notifier_unregister(mvdev->mdev, &ndev->nb); | ||
| 3242 | } | 3210 | } |
| 3243 | wq = mvdev->wq; | 3211 | wq = mvdev->wq; |
| 3244 | mvdev->wq = NULL; | 3212 | mvdev->wq = NULL; |
| @@ -855,7 +855,7 @@ static int vdpa_dev_net_config_fill(struct vdpa_device *vdev, struct sk_buff *ms · 854 unmodified lines | |||
| 855 | 855 | ||
| 856 | features_device = vdev->config->get_device_features(vdev); | 856 | features_device = vdev->config->get_device_features(vdev); |
| 857 | 857 | ||
| 858 | if (nla_put_u64_64bit(msg, VDPA_ATTR_VDPA_DEV_SUPPORTED_FEATURES, features_device, | 858 | if (nla_put_u64_64bit(msg, VDPA_ATTR_DEV_FEATURES, features_device, |
| 859 | VDPA_ATTR_PAD)) | 859 | VDPA_ATTR_PAD)) |
| 860 | return -EMSGSIZE; | 860 | return -EMSGSIZE; |
| 861 | 861 | ||
| @@ -935,7 +935,6 @@ static int vdpa_fill_stats_rec(struct vdpa_device *vdev, struct sk_buff *msg, · 73 unmodified lines | |||
| 935 | { | 935 | { |
| 936 | struct virtio_net_config config = {}; | 936 | struct virtio_net_config config = {}; |
| 937 | u64 features; | 937 | u64 features; |
| 938 | u16 max_vqp; | ||
| 939 | u8 status; | 938 | u8 status; |
| 940 | int err; | 939 | int err; |
| 941 | 940 | ||
| @@ -946,15 +945,15 @@ static int vdpa_fill_stats_rec(struct vdpa_device *vdev, struct sk_buff *msg, · 4 unmodified lines | |||
| 946 | } | 945 | } |
| 947 | vdpa_get_config_unlocked(vdev, 0, &config, sizeof(config)); | 946 | vdpa_get_config_unlocked(vdev, 0, &config, sizeof(config)); |
| 948 | 947 | ||
| 949 | max_vqp = __virtio16_to_cpu(true, config.max_virtqueue_pairs); | ||
| 950 | if (nla_put_u16(msg, VDPA_ATTR_DEV_NET_CFG_MAX_VQP, max_vqp)) | ||
| 951 | return -EMSGSIZE; | ||
| 952 | |||
| 953 | features = vdev->config->get_driver_features(vdev); | 948 | features = vdev->config->get_driver_features(vdev); |
| 954 | if (nla_put_u64_64bit(msg, VDPA_ATTR_DEV_NEGOTIATED_FEATURES, | 949 | if (nla_put_u64_64bit(msg, VDPA_ATTR_DEV_NEGOTIATED_FEATURES, |
| 955 | features, VDPA_ATTR_PAD)) | 950 | features, VDPA_ATTR_PAD)) |
| 956 | return -EMSGSIZE; | 951 | return -EMSGSIZE; |
| 957 | 952 | ||
| 953 | err = vdpa_dev_net_mq_config_fill(msg, features, &config); | ||
| 954 | if (err) | ||
| 955 | return err; | ||
| 956 | |||
| 958 | if (nla_put_u32(msg, VDPA_ATTR_DEV_QUEUE_INDEX, index)) | 957 | if (nla_put_u32(msg, VDPA_ATTR_DEV_QUEUE_INDEX, index)) |
| 959 | return -EMSGSIZE; | 958 | return -EMSGSIZE; |
| 960 | 959 | ||
| @@ -67,8 +67,7 @@ static void vdpasim_queue_ready(struct vdpasim *vdpasim, unsigned int idx) · 66 unmodified lines | |||
| 67 | { | 67 | { |
| 68 | struct vdpasim_virtqueue *vq = &vdpasim->vqs[idx]; | 68 | struct vdpasim_virtqueue *vq = &vdpasim->vqs[idx]; |
| 69 | 69 | ||
| 70 | vringh_init_iotlb(&vq->vring, vdpasim->dev_attr.supported_features, | 70 | vringh_init_iotlb(&vq->vring, vdpasim->features, vq->num, false, |
| 71 | VDPASIM_QUEUE_MAX, false, | ||
| 72 | (struct vring_desc *)(uintptr_t)vq->desc_addr, | 71 | (struct vring_desc *)(uintptr_t)vq->desc_addr, |
| 73 | (struct vring_avail *) | 72 | (struct vring_avail *) |
| 74 | (uintptr_t)vq->driver_addr, | 73 | (uintptr_t)vq->driver_addr, |
| @@ -690,7 +689,9 @@ static void vdpasim_free(struct vdpa_device *vdpa) · 615 unmodified lines | |||
| 690 | } | 689 | } |
| 691 | 690 | ||
| 692 | kvfree(vdpasim->buffer); | 691 | kvfree(vdpasim->buffer); |
| 693 | vhost_iotlb_free(vdpasim->iommu); | 692 | for (i = 0; i < vdpasim->dev_attr.nas; i++) |
| 693 | vhost_iotlb_reset(&vdpasim->iommu[i]); | ||
| 694 | kfree(vdpasim->iommu); | ||
| 694 | kfree(vdpasim->vqs); | 695 | kfree(vdpasim->vqs); |
| 695 | kfree(vdpasim->config); | 696 | kfree(vdpasim->config); |
| 696 | } | 697 | } |
| @@ -427,8 +427,10 @@ static int __init vdpasim_blk_init(void) · 426 unmodified lines | |||
| 427 | int ret; | 427 | int ret; |
| 428 | 428 | ||
| 429 | ret = device_register(&vdpasim_blk_mgmtdev); | 429 | ret = device_register(&vdpasim_blk_mgmtdev); |
| 430 | if (ret) | 430 | if (ret) { |
| 431 | put_device(&vdpasim_blk_mgmtdev); | ||
| 431 | return ret; | 432 | return ret; |
| 433 | } | ||
| 432 | 434 | ||
| 433 | ret = vdpa_mgmtdev_register(&mgmt_dev); | 435 | ret = vdpa_mgmtdev_register(&mgmt_dev); |
| 434 | if (ret) | 436 | if (ret) |
| @@ -62,6 +62,9 @@ static bool receive_filter(struct vdpasim *vdpasim, size_t len) · 61 unmodified lines | |||
| 62 | if (len < ETH_ALEN + hdr_len) | 62 | if (len < ETH_ALEN + hdr_len) |
| 63 | return false; | 63 | return false; |
| 64 | 64 | ||
| 65 | if (is_broadcast_ether_addr(vdpasim->buffer + hdr_len) || | ||
| 66 | is_multicast_ether_addr(vdpasim->buffer + hdr_len)) | ||
| 67 | return true; | ||
| 65 | if (!strncmp(vdpasim->buffer + hdr_len, vio_config->mac, ETH_ALEN)) | 68 | if (!strncmp(vdpasim->buffer + hdr_len, vio_config->mac, ETH_ALEN)) |
| 66 | return true; | 69 | return true; |
| 67 | 70 | ||
| @@ -305,8 +308,10 @@ static int __init vdpasim_net_init(void) · 237 unmodified lines | |||
| 305 | int ret; | 308 | int ret; |
| 306 | 309 | ||
| 307 | ret = device_register(&vdpasim_net_mgmtdev); | 310 | ret = device_register(&vdpasim_net_mgmtdev); |
| 308 | if (ret) | 311 | if (ret) { |
| 312 | put_device(&vdpasim_net_mgmtdev); | ||
| 309 | return ret; | 313 | return ret; |
| 314 | } | ||
| 310 | 315 | ||
| 311 | ret = vdpa_mgmtdev_register(&mgmt_dev); | 316 | ret = vdpa_mgmtdev_register(&mgmt_dev); |
| 312 | if (ret) | 317 | if (ret) |
| @@ -1440,6 +1440,9 @@ static bool vduse_validate_config(struct vduse_dev_config *config) · 1439 unmodified lines | |||
| 1440 | if (config->config_size > PAGE_SIZE) | 1440 | if (config->config_size > PAGE_SIZE) |
| 1441 | return false; | 1441 | return false; |
| 1442 | 1442 | ||
| 1443 | if (config->vq_num > 0xffff) | ||
| 1444 | return false; | ||
| 1445 | |||
| 1443 | if (!device_is_allowed(config->device_id)) | 1446 | if (!device_is_allowed(config->device_id)) |
| 1444 | return false; | 1447 | return false; |
| 1445 | 1448 | ||
| @@ -647,7 +647,7 @@ static void vp_vdpa_remove(struct pci_dev *pdev) · 646 unmodified lines | |||
| 647 | mdev = vp_vdpa_mgtdev->mdev; | 647 | mdev = vp_vdpa_mgtdev->mdev; |
| 648 | vp_modern_remove(mdev); | 648 | vp_modern_remove(mdev); |
| 649 | vdpa_mgmtdev_unregister(&vp_vdpa_mgtdev->mgtdev); | 649 | vdpa_mgmtdev_unregister(&vp_vdpa_mgtdev->mgtdev); |
| 650 | kfree(&vp_vdpa_mgtdev->mgtdev.id_table); | 650 | kfree(vp_vdpa_mgtdev->mgtdev.id_table); |
| 651 | kfree(mdev); | 651 | kfree(mdev); |
| 652 | kfree(vp_vdpa_mgtdev); | 652 | kfree(vp_vdpa_mgtdev); |
| 653 | } | 653 | } |
| @@ -65,6 +65,10 @@ static DEFINE_IDA(vhost_vdpa_ida); · 64 unmodified lines | |||
| 65 | 65 | ||
| 66 | static dev_t vhost_vdpa_major; | 66 | static dev_t vhost_vdpa_major; |
| 67 | 67 | ||
| 68 | static void vhost_vdpa_iotlb_unmap(struct vhost_vdpa *v, | ||
| 69 | struct vhost_iotlb *iotlb, u64 start, | ||
| 70 | u64 last, u32 asid); | ||
| 71 | |||
| 68 | static inline u32 iotlb_to_asid(struct vhost_iotlb *iotlb) | 72 | static inline u32 iotlb_to_asid(struct vhost_iotlb *iotlb) |
| 69 | { | 73 | { |
| 70 | struct vhost_vdpa_as *as = container_of(iotlb, struct | 74 | struct vhost_vdpa_as *as = container_of(iotlb, struct |
| @@ -135,7 +139,7 @@ static int vhost_vdpa_remove_as(struct vhost_vdpa *v, u32 asid) · 64 unmodified lines | |||
| 135 | return -EINVAL; | 139 | return -EINVAL; |
| 136 | 140 | ||
| 137 | hlist_del(&as->hash_link); | 141 | hlist_del(&as->hash_link); |
| 138 | vhost_iotlb_reset(&as->iotlb); | 142 | vhost_vdpa_iotlb_unmap(v, &as->iotlb, 0ULL, 0ULL - 1, asid); |
| 139 | kfree(as); | 143 | kfree(as); |
| 140 | 144 | ||
| 141 | return 0; | 145 | return 0; |
| @@ -683,10 +687,20 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep, · 541 unmodified lines | |||
| 683 | mutex_unlock(&d->mutex); | 687 | mutex_unlock(&d->mutex); |
| 684 | return r; | 688 | return r; |
| 685 | } | 689 | } |
| 690 | static void vhost_vdpa_general_unmap(struct vhost_vdpa *v, | ||
| 691 | struct vhost_iotlb_map *map, u32 asid) | ||
| 692 | { | ||
| 693 | struct vdpa_device *vdpa = v->vdpa; | ||
| 694 | const struct vdpa_config_ops *ops = vdpa->config; | ||
| 695 | if (ops->dma_map) { | ||
| 696 | ops->dma_unmap(vdpa, asid, map->start, map->size); | ||
| 697 | } else if (ops->set_map == NULL) { | ||
| 698 | iommu_unmap(v->domain, map->start, map->size); | ||
| 699 | } | ||
| 700 | } | ||
| 686 | 701 | ||
| 687 | static void vhost_vdpa_pa_unmap(struct vhost_vdpa *v, | 702 | static void vhost_vdpa_pa_unmap(struct vhost_vdpa *v, struct vhost_iotlb *iotlb, |
| 688 | struct vhost_iotlb *iotlb, | 703 | u64 start, u64 last, u32 asid) |
| 689 | u64 start, u64 last) | ||
| 690 | { | 704 | { |
| 691 | struct vhost_dev *dev = &v->vdev; | 705 | struct vhost_dev *dev = &v->vdev; |
| 692 | struct vhost_iotlb_map *map; | 706 | struct vhost_iotlb_map *map; |
| @@ -703,13 +717,13 @@ static void vhost_vdpa_pa_unmap(struct vhost_vdpa *v, · 10 unmodified lines | |||
| 703 | unpin_user_page(page); | 717 | unpin_user_page(page); |
| 704 | } | 718 | } |
| 705 | atomic64_sub(PFN_DOWN(map->size), &dev->mm->pinned_vm); | 719 | atomic64_sub(PFN_DOWN(map->size), &dev->mm->pinned_vm); |
| 720 | vhost_vdpa_general_unmap(v, map, asid); | ||
| 706 | vhost_iotlb_map_free(iotlb, map); | 721 | vhost_iotlb_map_free(iotlb, map); |
| 707 | } | 722 | } |
| 708 | } | 723 | } |
| 709 | 724 | ||
| 710 | static void vhost_vdpa_va_unmap(struct vhost_vdpa *v, | 725 | static void vhost_vdpa_va_unmap(struct vhost_vdpa *v, struct vhost_iotlb *iotlb, |
| 711 | struct vhost_iotlb *iotlb, | 726 | u64 start, u64 last, u32 asid) |
| 712 | u64 start, u64 last) | ||
| 713 | { | 727 | { |
| 714 | struct vhost_iotlb_map *map; | 728 | struct vhost_iotlb_map *map; |
| 715 | struct vdpa_map_file *map_file; | 729 | struct vdpa_map_file *map_file; |
| @@ -718,20 +732,21 @@ static void vhost_vdpa_va_unmap(struct vhost_vdpa *v, · 2 unmodified lines | |||
| 718 | map_file = (struct vdpa_map_file *)map->opaque; | 732 | map_file = (struct vdpa_map_file *)map->opaque; |
| 719 | fput(map_file->file); | 733 | fput(map_file->file); |
| 720 | kfree(map_file); | 734 | kfree(map_file); |
| 735 | vhost_vdpa_general_unmap(v, map, asid); | ||
| 721 | vhost_iotlb_map_free(iotlb, map); | 736 | vhost_iotlb_map_free(iotlb, map); |
| 722 | } | 737 | } |
| 723 | } | 738 | } |
| 724 | 739 | ||
| 725 | static void vhost_vdpa_iotlb_unmap(struct vhost_vdpa *v, | 740 | static void vhost_vdpa_iotlb_unmap(struct vhost_vdpa *v, |
| 726 | struct vhost_iotlb *iotlb, | 741 | struct vhost_iotlb *iotlb, u64 start, |
| 727 | u64 start, u64 last) | 742 | u64 last, u32 asid) |
| 728 | { | 743 | { |
| 729 | struct vdpa_device *vdpa = v->vdpa; | 744 | struct vdpa_device *vdpa = v->vdpa; |
| 730 | 745 | ||
| 731 | if (vdpa->use_va) | 746 | if (vdpa->use_va) |
| 732 | return vhost_vdpa_va_unmap(v, iotlb, start, last); | 747 | return vhost_vdpa_va_unmap(v, iotlb, start, last, asid); |
| 733 | 748 | ||
| 734 | return vhost_vdpa_pa_unmap(v, iotlb, start, last); | 749 | return vhost_vdpa_pa_unmap(v, iotlb, start, last, asid); |
| 735 | } | 750 | } |
| 736 | 751 | ||
| 737 | static int perm_to_iommu_flags(u32 perm) | 752 | static int perm_to_iommu_flags(u32 perm) |
| @@ -798,17 +813,12 @@ static void vhost_vdpa_unmap(struct vhost_vdpa *v, · 60 unmodified lines | |||
| 798 | const struct vdpa_config_ops *ops = vdpa->config; | 813 | const struct vdpa_config_ops *ops = vdpa->config; |
| 799 | u32 asid = iotlb_to_asid(iotlb); | 814 | u32 asid = iotlb_to_asid(iotlb); |
| 800 | 815 | ||
| 801 | vhost_vdpa_iotlb_unmap(v, iotlb, iova, iova + size - 1); | 816 | vhost_vdpa_iotlb_unmap(v, iotlb, iova, iova + size - 1, asid); |
| 802 | 817 | ||
| 803 | if (ops->dma_map) { | 818 | if (ops->set_map) { |
| 804 | ops->dma_unmap(vdpa, asid, iova, size); | ||
| 805 | } else if (ops->set_map) { | ||
| 806 | if (!v->in_batch) | 819 | if (!v->in_batch) |
| 807 | ops->set_map(vdpa, asid, iotlb); | 820 | ops->set_map(vdpa, asid, iotlb); |
| 808 | } else { | ||
| 809 | iommu_unmap(v->domain, iova, size); | ||
| 810 | } | 821 | } |
| 811 | |||
| 812 | /* If we are in the middle of batch processing, delay the free | 822 | /* If we are in the middle of batch processing, delay the free |
| 813 | * of AS until BATCH_END. | 823 | * of AS until BATCH_END. |
| 814 | */ | 824 | */ |
| @@ -1162,14 +1172,14 @@ static void vhost_vdpa_cleanup(struct vhost_vdpa *v) · 347 unmodified lines | |||
| 1162 | struct vhost_vdpa_as *as; | 1172 | struct vhost_vdpa_as *as; |
| 1163 | u32 asid; | 1173 | u32 asid; |
| 1164 | 1174 | ||
| 1165 | vhost_dev_cleanup(&v->vdev); | ||
| 1166 | kfree(v->vdev.vqs); | ||
| 1167 | |||
| 1168 | for (asid = 0; asid < v->vdpa->nas; asid++) { | 1175 | for (asid = 0; asid < v->vdpa->nas; asid++) { |
| 1169 | as = asid_to_as(v, asid); | 1176 | as = asid_to_as(v, asid); |
| 1170 | if (as) | 1177 | if (as) |
| 1171 | vhost_vdpa_remove_as(v, asid); | 1178 | vhost_vdpa_remove_as(v, asid); |
| 1172 | } | 1179 | } |
| 1180 | |||
| 1181 | vhost_dev_cleanup(&v->vdev); | ||
| 1182 | kfree(v->vdev.vqs); | ||
| 1173 | } | 1183 | } |
| 1174 | 1184 | ||
| 1175 | static int vhost_vdpa_open(struct inode *inode, struct file *filep) | 1185 | static int vhost_vdpa_open(struct inode *inode, struct file *filep) |
| @@ -2053,7 +2053,7 @@ static int translate_desc(struct vhost_virtqueue *vq, u64 addr, u32 len, · 2052 unmodified lines | |||
| 2053 | struct vhost_dev *dev = vq->dev; | 2053 | struct vhost_dev *dev = vq->dev; |
| 2054 | struct vhost_iotlb *umem = dev->iotlb ? dev->iotlb : dev->umem; | 2054 | struct vhost_iotlb *umem = dev->iotlb ? dev->iotlb : dev->umem; |
| 2055 | struct iovec *_iov; | 2055 | struct iovec *_iov; |
| 2056 | u64 s = 0; | 2056 | u64 s = 0, last = addr + len - 1; |
| 2057 | int ret = 0; | 2057 | int ret = 0; |
| 2058 | 2058 | ||
| 2059 | while ((u64)len > s) { | 2059 | while ((u64)len > s) { |
| @@ -2063,7 +2063,7 @@ static int translate_desc(struct vhost_virtqueue *vq, u64 addr, u32 len, · 3 unmodified lines | |||
| 2063 | break; | 2063 | break; |
| 2064 | } | 2064 | } |
| 2065 | 2065 | ||
| 2066 | map = vhost_iotlb_itree_first(umem, addr, addr + len - 1); | 2066 | map = vhost_iotlb_itree_first(umem, addr, last); |
| 2067 | if (map == NULL || map->start > addr) { | 2067 | if (map == NULL || map->start > addr) { |
| 2068 | if (umem != dev->iotlb) { | 2068 | if (umem != dev->iotlb) { |
| 2069 | ret = -EFAULT; | 2069 | ret = -EFAULT; |
| @@ -1102,7 +1102,7 @@ static int iotlb_translate(const struct vringh *vrh, · 1101 unmodified lines | |||
| 1102 | struct vhost_iotlb_map *map; | 1102 | struct vhost_iotlb_map *map; |
| 1103 | struct vhost_iotlb *iotlb = vrh->iotlb; | 1103 | struct vhost_iotlb *iotlb = vrh->iotlb; |
| 1104 | int ret = 0; | 1104 | int ret = 0; |
| 1105 | u64 s = 0; | 1105 | u64 s = 0, last = addr + len - 1; |
| 1106 | 1106 | ||
| 1107 | spin_lock(vrh->iotlb_lock); | 1107 | spin_lock(vrh->iotlb_lock); |
| 1108 | 1108 | ||
| @@ -1114,8 +1114,7 @@ static int iotlb_translate(const struct vringh *vrh, · 5 unmodified lines | |||
| 1114 | break; | 1114 | break; |
| 1115 | } | 1115 | } |
| 1116 | 1116 | ||
| 1117 | map = vhost_iotlb_itree_first(iotlb, addr, | 1117 | map = vhost_iotlb_itree_first(iotlb, addr, last); |
| 1118 | addr + len - 1); | ||
| 1119 | if (!map || map->start > addr) { | 1118 | if (!map || map->start > addr) { |
| 1120 | ret = -EINVAL; | 1119 | ret = -EINVAL; |
| 1121 | break; | 1120 | break; |
| @@ -959,7 +959,14 @@ static int __init vhost_vsock_init(void) · 958 unmodified lines | |||
| 959 | VSOCK_TRANSPORT_F_H2G); | 959 | VSOCK_TRANSPORT_F_H2G); |
| 960 | if (ret < 0) | 960 | if (ret < 0) |
| 961 | return ret; | 961 | return ret; |
| 962 | return misc_register(&vhost_vsock_misc); | 962 | |
| 963 | ret = misc_register(&vhost_vsock_misc); | ||
| 964 | if (ret) { | ||
| 965 | vsock_core_unregister(&vhost_transport.transport); | ||
| 966 | return ret; | ||
| 967 | } | ||
| 968 | |||
| 969 | return 0; | ||
| 963 | }; | 970 | }; |
| 964 | 971 | ||
| 965 | static void __exit vhost_vsock_exit(void) | 972 | static void __exit vhost_vsock_exit(void) |
| @@ -15,7 +15,7 @@ static ssize_t device_show(struct device *_d, · 14 unmodified lines | |||
| 15 | struct device_attribute *attr, char *buf) | 15 | struct device_attribute *attr, char *buf) |
| 16 | { | 16 | { |
| 17 | struct virtio_device *dev = dev_to_virtio(_d); | 17 | struct virtio_device *dev = dev_to_virtio(_d); |
| 18 | return sprintf(buf, "0x%04x\n", dev->id.device); | 18 | return sysfs_emit(buf, "0x%04x\n", dev->id.device); |
| 19 | } | 19 | } |
| 20 | static DEVICE_ATTR_RO(device); | 20 | static DEVICE_ATTR_RO(device); |
| 21 | 21 | ||
| @@ -23,7 +23,7 @@ static ssize_t vendor_show(struct device *_d, · 1 unmodified line | |||
| 23 | struct device_attribute *attr, char *buf) | 23 | struct device_attribute *attr, char *buf) |
| 24 | { | 24 | { |
| 25 | struct virtio_device *dev = dev_to_virtio(_d); | 25 | struct virtio_device *dev = dev_to_virtio(_d); |
| 26 | return sprintf(buf, "0x%04x\n", dev->id.vendor); | 26 | return sysfs_emit(buf, "0x%04x\n", dev->id.vendor); |
| 27 | } | 27 | } |
| 28 | static DEVICE_ATTR_RO(vendor); | 28 | static DEVICE_ATTR_RO(vendor); |
| 29 | 29 | ||
| @@ -31,7 +31,7 @@ static ssize_t status_show(struct device *_d, · 1 unmodified line | |||
| 31 | struct device_attribute *attr, char *buf) | 31 | struct device_attribute *attr, char *buf) |
| 32 | { | 32 | { |
| 33 | struct virtio_device *dev = dev_to_virtio(_d); | 33 | struct virtio_device *dev = dev_to_virtio(_d); |
| 34 | return sprintf(buf, "0x%08x\n", dev->config->get_status(dev)); | 34 | return sysfs_emit(buf, "0x%08x\n", dev->config->get_status(dev)); |
| 35 | } | 35 | } |
| 36 | static DEVICE_ATTR_RO(status); | 36 | static DEVICE_ATTR_RO(status); |
| 37 | 37 | ||
| @@ -39,7 +39,7 @@ static ssize_t modalias_show(struct device *_d, · 1 unmodified line | |||
| 39 | struct device_attribute *attr, char *buf) | 39 | struct device_attribute *attr, char *buf) |
| 40 | { | 40 | { |
| 41 | struct virtio_device *dev = dev_to_virtio(_d); | 41 | struct virtio_device *dev = dev_to_virtio(_d); |
| 42 | return sprintf(buf, "virtio:d%08Xv%08X\n", | 42 | return sysfs_emit(buf, "virtio:d%08Xv%08X\n", |
| 43 | dev->id.device, dev->id.vendor); | 43 | dev->id.device, dev->id.vendor); |
| 44 | } | 44 | } |
| 45 | static DEVICE_ATTR_RO(modalias); | 45 | static DEVICE_ATTR_RO(modalias); |
| @@ -54,9 +54,9 @@ static ssize_t features_show(struct device *_d, · 8 unmodified lines | |||
| 54 | /* We actually represent this as a bitstring, as it could be | 54 | /* We actually represent this as a bitstring, as it could be |
| 55 | * arbitrary length in future. */ | 55 | * arbitrary length in future. */ |
| 56 | for (i = 0; i < sizeof(dev->features)*8; i++) | 56 | for (i = 0; i < sizeof(dev->features)*8; i++) |
| 57 | len += sprintf(buf+len, "%c", | 57 | len += sysfs_emit_at(buf, len, "%c", |
| 58 | __virtio_test_bit(dev, i) ? '1' : '0'); | 58 | __virtio_test_bit(dev, i) ? '1' : '0'); |
| 59 | len += sprintf(buf+len, "\n"); | 59 | len += sysfs_emit_at(buf, len, "\n"); |
| 60 | return len; | 60 | return len; |
| 61 | } | 61 | } |
| 62 | static DEVICE_ATTR_RO(features); | 62 | static DEVICE_ATTR_RO(features); |
| @@ -303,14 +303,14 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev, · 302 unmodified lines | |||
| 303 | int err; | 303 | int err; |
| 304 | 304 | ||
| 305 | if (index >= vp_modern_get_num_queues(mdev)) | 305 | if (index >= vp_modern_get_num_queues(mdev)) |
| 306 | return ERR_PTR(-ENOENT); | 306 | return ERR_PTR(-EINVAL); |
| 307 | 307 | ||
| 308 | /* Check if queue is either not available or already active. */ | 308 | /* Check if queue is either not available or already active. */ |
| 309 | num = vp_modern_get_queue_size(mdev, index); | 309 | num = vp_modern_get_queue_size(mdev, index); |
| 310 | if (!num || vp_modern_get_queue_enable(mdev, index)) | 310 | if (!num || vp_modern_get_queue_enable(mdev, index)) |
| 311 | return ERR_PTR(-ENOENT); | 311 | return ERR_PTR(-ENOENT); |
| 312 | 312 | ||
| 313 | if (num & (num - 1)) { | 313 | if (!is_power_of_2(num)) { |
| 314 | dev_warn(&vp_dev->pci_dev->dev, "bad queue size %u", num); | 314 | dev_warn(&vp_dev->pci_dev->dev, "bad queue size %u", num); |
| 315 | return ERR_PTR(-EINVAL); | 315 | return ERR_PTR(-EINVAL); |
| 316 | } | 316 | } |
| @@ -1052,7 +1052,7 @@ static int vring_alloc_queue_split(struct vring_virtqueue_split *vring_split, · 1051 unmodified lines | |||
| 1052 | dma_addr_t dma_addr; | 1052 | dma_addr_t dma_addr; |
| 1053 | 1053 | ||
| 1054 | /* We assume num is a power of 2. */ | 1054 | /* We assume num is a power of 2. */ |
| 1055 | if (num & (num - 1)) { | 1055 | if (!is_power_of_2(num)) { |
| 1056 | dev_warn(&vdev->dev, "Bad virtqueue length %u\n", num); | 1056 | dev_warn(&vdev->dev, "Bad virtqueue length %u\n", num); |
| 1057 | return -EINVAL; | 1057 | return -EINVAL; |
| 1058 | } | 1058 | } |
| @@ -53,11 +53,9 @@ enum vdpa_attr { · 52 unmodified lines | |||
| 53 | VDPA_ATTR_DEV_VENDOR_ATTR_NAME, /* string */ | 53 | VDPA_ATTR_DEV_VENDOR_ATTR_NAME, /* string */ |
| 54 | VDPA_ATTR_DEV_VENDOR_ATTR_VALUE, /* u64 */ | 54 | VDPA_ATTR_DEV_VENDOR_ATTR_VALUE, /* u64 */ |
| 55 | 55 | ||
| 56 | /* virtio features that are provisioned to the vDPA device */ | ||
| 56 | VDPA_ATTR_DEV_FEATURES, /* u64 */ | 57 | VDPA_ATTR_DEV_FEATURES, /* u64 */ |
| 57 | 58 | ||
| 58 | /* virtio features that are supported by the vDPA device */ | ||
| 59 | VDPA_ATTR_VDPA_DEV_SUPPORTED_FEATURES, /* u64 */ | ||
| 60 | |||
| 61 | /* new attributes must be added above here */ | 59 | /* new attributes must be added above here */ |
| 62 | VDPA_ATTR_MAX, | 60 | VDPA_ATTR_MAX, |
| 63 | }; | 61 | }; |
| @@ -140,25 +140,19 @@ static inline void busy_wait(void) · 139 unmodified lines | |||
| 140 | #define smp_wmb() smp_release() | 140 | #define smp_wmb() smp_release() |
| 141 | #endif | 141 | #endif |
| 142 | 142 | ||
| 143 | #ifdef __alpha__ | ||
| 144 | #define smp_read_barrier_depends() smp_acquire() | ||
| 145 | #else | ||
| 146 | #define smp_read_barrier_depends() do {} while(0) | ||
| 147 | #endif | ||
| 148 | |||
| 149 | static __always_inline | 143 | static __always_inline |
| 150 | void __read_once_size(const volatile void *p, void *res, int size) | 144 | void __read_once_size(const volatile void *p, void *res, int size) |
| 151 | { | 145 | { |
| 152 | switch (size) { \ | 146 | switch (size) { |
| 153 | case 1: *(unsigned char *)res = *(volatile unsigned char *)p; break; \ | 147 | case 1: *(unsigned char *)res = *(volatile unsigned char *)p; break; |
| 154 | case 2: *(unsigned short *)res = *(volatile unsigned short *)p; break; \ | 148 | case 2: *(unsigned short *)res = *(volatile unsigned short *)p; break; |
| 155 | case 4: *(unsigned int *)res = *(volatile unsigned int *)p; break; \ | 149 | case 4: *(unsigned int *)res = *(volatile unsigned int *)p; break; |
| 156 | case 8: *(unsigned long long *)res = *(volatile unsigned long long *)p; break; \ | 150 | case 8: *(unsigned long long *)res = *(volatile unsigned long long *)p; break; |
| 157 | default: \ | 151 | default: |
| 158 | barrier(); \ | 152 | barrier(); |
| 159 | __builtin_memcpy((void *)res, (const void *)p, size); \ | 153 | __builtin_memcpy((void *)res, (const void *)p, size); |
| 160 | barrier(); \ | 154 | barrier(); |
| 161 | } \ | 155 | } |
| 162 | } | 156 | } |
| 163 | 157 | ||
| 164 | static __always_inline void __write_once_size(volatile void *p, void *res, int size) | 158 | static __always_inline void __write_once_size(volatile void *p, void *res, int size) |
| @@ -175,13 +169,22 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s · 10 unmodified lines | |||
| 175 | } | 169 | } |
| 176 | } | 170 | } |
| 177 | 171 | ||
| 172 | #ifdef __alpha__ | ||
| 178 | #define READ_ONCE(x) \ | 173 | #define READ_ONCE(x) \ |
| 179 | ({ \ | 174 | ({ \ |
| 180 | union { typeof(x) __val; char __c[1]; } __u; \ | 175 | union { typeof(x) __val; char __c[1]; } __u; \ |
| 181 | __read_once_size(&(x), __u.__c, sizeof(x)); \ | 176 | __read_once_size(&(x), __u.__c, sizeof(x)); \ |
| 182 | smp_read_barrier_depends(); /* Enforce dependency ordering from x */ \ | 177 | smp_mb(); /* Enforce dependency ordering from x */ \ |
| 178 | __u.__val; \ | ||
| 179 | }) | ||
| 180 | #else | ||
| 181 | #define READ_ONCE(x) \ | ||
| 182 | ({ \ | ||
| 183 | union { typeof(x) __val; char __c[1]; } __u; \ | ||
| 184 | __read_once_size(&(x), __u.__c, sizeof(x)); \ | ||
| 183 | __u.__val; \ | 185 | __u.__val; \ |
| 184 | }) | 186 | }) |
| 187 | #endif | ||
| 185 | 188 | ||
| 186 | #define WRITE_ONCE(x, val) \ | 189 | #define WRITE_ONCE(x, val) \ |
| 187 | ({ \ | 190 | ({ \ |
| @@ -75,7 +75,7 @@ static int wait_order(int ctl_fd) · 74 unmodified lines | |||
| 75 | 75 | ||
| 76 | if (ret) | 76 | if (ret) |
| 77 | break; | 77 | break; |
| 78 | }; | 78 | } |
| 79 | 79 | ||
| 80 | return ret; | 80 | return ret; |
| 81 | 81 | ||
| @@ -173,7 +173,7 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, · 172 unmodified lines | |||
| 173 | long started = 0, completed = 0, next_reset = reset_n; | 173 | long started = 0, completed = 0, next_reset = reset_n; |
| 174 | long completed_before, started_before; | 174 | long completed_before, started_before; |
| 175 | int r, test = 1; | 175 | int r, test = 1; |
| 176 | unsigned len; | 176 | unsigned int len; |
| 177 | long long spurious = 0; | 177 | long long spurious = 0; |
| 178 | const bool random_batch = batch == RANDOM_BATCH; | 178 | const bool random_batch = batch == RANDOM_BATCH; |
| 179 | 179 | ||
| @@ -308,6 +308,7 @@ static int parallel_test(u64 features, · 307 unmodified lines | |||
| 308 | 308 | ||
| 309 | gvdev.vdev.features = features; | 309 | gvdev.vdev.features = features; |
| 310 | INIT_LIST_HEAD(&gvdev.vdev.vqs); | 310 | INIT_LIST_HEAD(&gvdev.vdev.vqs); |
| 311 | spin_lock_init(&gvdev.vdev.vqs_list_lock); | ||
| 311 | gvdev.to_host_fd = to_host[1]; | 312 | gvdev.to_host_fd = to_host[1]; |
| 312 | gvdev.notifies = 0; | 313 | gvdev.notifies = 0; |
| 313 | 314 | ||
| @@ -455,6 +456,7 @@ int main(int argc, char *argv[]) · 141 unmodified lines | |||
| 455 | getrange = getrange_iov; | 456 | getrange = getrange_iov; |
| 456 | vdev.features = 0; | 457 | vdev.features = 0; |
| 457 | INIT_LIST_HEAD(&vdev.vqs); | 458 | INIT_LIST_HEAD(&vdev.vqs); |
| 459 | spin_lock_init(&vdev.vqs_list_lock); | ||
| 458 | 460 | ||
| 459 | while (argv[1]) { | 461 | while (argv[1]) { |
| 460 | if (strcmp(argv[1], "--indirect") == 0) | 462 | if (strcmp(argv[1], "--indirect") == 0) |