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 | 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 | 331 | static blk_status_t virtblk_prep_rq(struct blk_mq_hw_ctx *hctx, |
| 319 | 332 | struct virtio_blk *vblk, |
| 320 | 333 | struct request *req, |
| 321 | 334 | struct virtblk_req *vbr) |
| 322 | 335 | { |
| 323 | 336 | blk_status_t status; |
| 337 | + int num; | |
| 324 | 338 | |
| 325 | 339 | status = virtblk_setup_cmd(vblk->vdev, req, vbr); |
| 326 | 340 | if (unlikely(status)) |
| 327 | 341 | return status; |
| 328 | 342 | |
| 329 | − vbr->sg_table.nents = virtblk_map_data(hctx, req, vbr); | |
| 330 | − if (unlikely(vbr->sg_table.nents < 0)) { | |
| 331 | − virtblk_cleanup_cmd(req); | |
| 332 | − return BLK_STS_RESOURCE; | |
| 333 | − } | |
| 343 | + num = virtblk_map_data(hctx, req, vbr); | |
| 344 | + if (unlikely(num < 0)) | |
| 345 | + return virtblk_fail_to_queue(req, -ENOMEM); | |
| 346 | + vbr->sg_table.nents = num; | |
| 334 | 347 | |
| 335 | 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 | 377 | blk_mq_stop_hw_queue(hctx); |
| 365 | 378 | spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags); |
| 366 | 379 | virtblk_unmap_data(req, vbr); |
| 367 | − virtblk_cleanup_cmd(req); | |
| 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 | − } | |
| 380 | + return virtblk_fail_to_queue(req, err); | |
| 376 | 381 | } |
| 377 | 382 | |
| 378 | 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 | 996 | blk_queue_max_segments(q, sg_elems); |
| 992 | 997 | |
| 993 | 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 | 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 | 239 | pr_err("virtio_crypto: Close session failed status: %u, session_id: 0x%llx\n", |
| 240 | 240 | ctrl_status->status, destroy_session->session_id); |
| 241 | 241 | |
| 242 | − return -EINVAL; | |
| 242 | + err = -EINVAL; | |
| 243 | + goto out; | |
| 243 | 244 | } |
| 244 | 245 | |
| 245 | 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 | 116 | int inlen); |
| 117 | 117 | int mlx5_vdpa_destroy_mkey(struct mlx5_vdpa_dev *mvdev, u32 mkey); |
| 118 | 118 | int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb, |
| 119 | − bool *change_map); | |
| 120 | −int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb); | |
| 119 | + bool *change_map, unsigned int asid); | |
| 120 | +int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb, | |
| 121 | + unsigned int asid); | |
| 121 | 122 | void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev); |
| 122 | 123 | |
| 123 | 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 | 311 | u64 st; |
| 312 | 312 | u64 sz; |
| 313 | 313 | int err; |
| 314 | − int i = 0; | |
| 315 | 314 | |
| 316 | 315 | st = start; |
| 317 | 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 | 335 | mr->num_directs++; |
| 337 | 336 | mr->num_klms++; |
| 338 | 337 | st += sz; |
| 339 | − i++; | |
| 340 | 338 | } |
| 341 | 339 | list_splice_tail(&tmp, &mr->head); |
| 342 | 340 | return 0; |
| @@ -511,7 +509,8 @@ out: · 168 unmodified lines | ||
| 511 | 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 | 515 | struct mlx5_vdpa_mr *mr = &mvdev->mr; |
| 517 | 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 | 518 | if (mr->initialized) |
| 520 | 519 | return 0; |
| 521 | 520 | |
| 522 | − if (iotlb) | |
| 523 | − err = create_user_mr(mvdev, iotlb); | |
| 524 | − else | |
| 525 | − err = create_dma_mr(mvdev, mr); | |
| 521 | + if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] == asid) { | |
| 522 | + if (iotlb) | |
| 523 | + err = create_user_mr(mvdev, iotlb); | |
| 524 | + else | |
| 525 | + err = create_dma_mr(mvdev, mr); | |
| 526 | 526 | |
| 527 | − if (err) | |
| 528 | − return err; | |
| 527 | + if (err) | |
| 528 | + return err; | |
| 529 | + } | |
| 529 | 530 | |
| 530 | − err = dup_iotlb(mvdev, iotlb); | |
| 531 | − if (err) | |
| 532 | − goto out_err; | |
| 531 | + if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] == asid) { | |
| 532 | + err = dup_iotlb(mvdev, iotlb); | |
| 533 | + if (err) | |
| 534 | + goto out_err; | |
| 535 | + } | |
| 533 | 536 | |
| 534 | 537 | mr->initialized = true; |
| 535 | 538 | return 0; |
| 536 | 539 | |
| 537 | 540 | out_err: |
| 538 | − if (iotlb) | |
| 539 | − destroy_user_mr(mvdev, mr); | |
| 540 | − else | |
| 541 | − destroy_dma_mr(mvdev, mr); | |
| 541 | + if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] == asid) { | |
| 542 | + if (iotlb) | |
| 543 | + destroy_user_mr(mvdev, mr); | |
| 544 | + else | |
| 545 | + destroy_dma_mr(mvdev, mr); | |
| 546 | + } | |
| 542 | 547 | |
| 543 | 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 | 554 | int err; |
| 549 | 555 | |
| 550 | 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 | 558 | mutex_unlock(&mvdev->mr.mkey_mtx); |
| 553 | 559 | return err; |
| 554 | 560 | } |
| 555 | 561 | |
| 556 | 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 | 565 | struct mlx5_vdpa_mr *mr = &mvdev->mr; |
| 560 | 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 | 572 | *change_map = true; |
| 567 | 573 | } |
| 568 | 574 | if (!*change_map) |
| 569 | − err = _mlx5_vdpa_create_mr(mvdev, iotlb); | |
| 575 | + err = _mlx5_vdpa_create_mr(mvdev, iotlb, asid); | |
| 570 | 576 | mutex_unlock(&mr->mkey_mtx); |
| 571 | 577 | |
| 572 | 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 | 1468 | dmac_v = MLX5_ADDR_OF(fte_match_param, headers_v, outer_headers.dmac_47_16); |
| 1469 | 1469 | eth_broadcast_addr(dmac_c); |
| 1470 | 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 | 1475 | if (tagged) { |
| 1473 | 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); | |
| 1475 | − MLX5_SET(fte_match_set_lyr_2_4, headers_c, first_vid, vid); | |
| 1477 | + MLX5_SET(fte_match_set_lyr_2_4, headers_v, first_vid, vid); | |
| 1476 | 1478 | } |
| 1477 | 1479 | flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; |
| 1478 | 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 | 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 | 1691 | if (mac_vlan_add(ndev, ndev->config.mac, 0, false)) { |
| 1690 | 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 | 1823 | size_t read; |
| 1822 | 1824 | u16 id; |
| 1823 | 1825 | |
| 1826 | + if (!(ndev->mvdev.actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VLAN))) | |
| 1827 | + return status; | |
| 1828 | + | |
| 1824 | 1829 | switch (cmd) { |
| 1825 | 1830 | case VIRTIO_NET_CTRL_VLAN_ADD: |
| 1826 | 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 | 2400 | struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev); |
| 2395 | 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 | 2408 | teardown_driver(ndev); |
| 2403 | 2409 | mlx5_vdpa_destroy_mr(mvdev); |
| 2404 | − err = mlx5_vdpa_create_mr(mvdev, iotlb); | |
| 2410 | + err = mlx5_vdpa_create_mr(mvdev, iotlb, asid); | |
| 2405 | 2411 | if (err) |
| 2406 | 2412 | goto err_mr; |
| 2407 | 2413 | |
| @@ -2582,7 +2588,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev) · 174 unmodified lines | ||
| 2582 | 2588 | ++mvdev->generation; |
| 2583 | 2589 | |
| 2584 | 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 | 2592 | mlx5_vdpa_warn(mvdev, "create MR failed\n"); |
| 2587 | 2593 | } |
| 2588 | 2594 | up_write(&ndev->reslock); |
| @@ -2618,41 +2624,20 @@ static u32 mlx5_vdpa_get_generation(struct vdpa_device *vdev) · 29 unmodified lines | ||
| 2618 | 2624 | return mvdev->generation; |
| 2619 | 2625 | } |
| 2620 | 2626 | |
| 2621 | −static int set_map_control(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb) | |
| 2622 | −{ | |
| 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) | |
| 2627 | +static int set_map_data(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb, | |
| 2628 | + unsigned int asid) | |
| 2644 | 2629 | { |
| 2645 | 2630 | bool change_map; |
| 2646 | 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 | 2634 | if (err) { |
| 2650 | 2635 | mlx5_vdpa_warn(mvdev, "set map failed(%d)\n", err); |
| 2651 | 2636 | return err; |
| 2652 | 2637 | } |
| 2653 | 2638 | |
| 2654 | 2639 | if (change_map) |
| 2655 | − err = mlx5_vdpa_change_map(mvdev, iotlb); | |
| 2640 | + err = mlx5_vdpa_change_map(mvdev, iotlb, asid); | |
| 2656 | 2641 | |
| 2657 | 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 | 2650 | int err = -EINVAL; |
| 2666 | 2651 | |
| 2667 | 2652 | down_write(&ndev->reslock); |
| 2668 | − if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] == 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: | |
| 2653 | + err = set_map_data(mvdev, iotlb, asid); | |
| 2678 | 2654 | up_write(&ndev->reslock); |
| 2679 | 2655 | return err; |
| 2680 | 2656 | } |
| @@ -2840,8 +2816,8 @@ static int mlx5_vdpa_suspend(struct vdpa_device *vdev) · 159 unmodified lines | ||
| 2840 | 2816 | int i; |
| 2841 | 2817 | |
| 2842 | 2818 | down_write(&ndev->reslock); |
| 2843 | − mlx5_notifier_unregister(mvdev->mdev, &ndev->nb); | |
| 2844 | 2819 | ndev->nb_registered = false; |
| 2820 | + mlx5_notifier_unregister(mvdev->mdev, &ndev->nb); | |
| 2845 | 2821 | flush_workqueue(ndev->mvdev.wq); |
| 2846 | 2822 | for (i = 0; i < ndev->cur_num_vqs; i++) { |
| 2847 | 2823 | mvq = &ndev->vqs[i]; |
| @@ -3019,7 +2995,7 @@ static void update_carrier(struct work_struct *work) · 171 unmodified lines | ||
| 3019 | 2995 | else |
| 3020 | 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 | 2999 | ndev->config_cb.callback(ndev->config_cb.private); |
| 3024 | 3000 | |
| 3025 | 3001 | kfree(wqent); |
| @@ -3036,21 +3012,13 @@ static int event_handler(struct notifier_block *nb, unsigned long event, void *p · 10 unmodified lines | ||
| 3036 | 3012 | switch (eqe->sub_type) { |
| 3037 | 3013 | case MLX5_PORT_CHANGE_SUBTYPE_DOWN: |
| 3038 | 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 | 3015 | wqent = kzalloc(sizeof(*wqent), GFP_ATOMIC); |
| 3045 | − if (!wqent) { | |
| 3046 | − up_read(&ndev->reslock); | |
| 3016 | + if (!wqent) | |
| 3047 | 3017 | return NOTIFY_DONE; |
| 3048 | − } | |
| 3049 | 3018 | |
| 3050 | 3019 | wqent->mvdev = &ndev->mvdev; |
| 3051 | 3020 | INIT_WORK(&wqent->work, update_carrier); |
| 3052 | 3021 | queue_work(ndev->mvdev.wq, &wqent->work); |
| 3053 | − up_read(&ndev->reslock); | |
| 3054 | 3022 | ret = NOTIFY_OK; |
| 3055 | 3023 | break; |
| 3056 | 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 | 3153 | goto err_mpfs; |
| 3186 | 3154 | |
| 3187 | 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 | 3157 | if (err) |
| 3190 | 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 | 3205 | struct workqueue_struct *wq; |
| 3238 | 3206 | |
| 3239 | 3207 | if (ndev->nb_registered) { |
| 3240 | − mlx5_notifier_unregister(mvdev->mdev, &ndev->nb); | |
| 3241 | 3208 | ndev->nb_registered = false; |
| 3209 | + mlx5_notifier_unregister(mvdev->mdev, &ndev->nb); | |
| 3242 | 3210 | } |
| 3243 | 3211 | wq = mvdev->wq; |
| 3244 | 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 | 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 | 859 | VDPA_ATTR_PAD)) |
| 860 | 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 | 936 | struct virtio_net_config config = {}; |
| 937 | 937 | u64 features; |
| 938 | − u16 max_vqp; | |
| 939 | 938 | u8 status; |
| 940 | 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 | 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 | 948 | features = vdev->config->get_driver_features(vdev); |
| 954 | 949 | if (nla_put_u64_64bit(msg, VDPA_ATTR_DEV_NEGOTIATED_FEATURES, |
| 955 | 950 | features, VDPA_ATTR_PAD)) |
| 956 | 951 | return -EMSGSIZE; |
| 957 | 952 | |
| 953 | + err = vdpa_dev_net_mq_config_fill(msg, features, &config); | |
| 954 | + if (err) | |
| 955 | + return err; | |
| 956 | + | |
| 958 | 957 | if (nla_put_u32(msg, VDPA_ATTR_DEV_QUEUE_INDEX, index)) |
| 959 | 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 | 68 | struct vdpasim_virtqueue *vq = &vdpasim->vqs[idx]; |
| 69 | 69 | |
| 70 | − vringh_init_iotlb(&vq->vring, vdpasim->dev_attr.supported_features, | |
| 71 | − VDPASIM_QUEUE_MAX, false, | |
| 70 | + vringh_init_iotlb(&vq->vring, vdpasim->features, vq->num, false, | |
| 72 | 71 | (struct vring_desc *)(uintptr_t)vq->desc_addr, |
| 73 | 72 | (struct vring_avail *) |
| 74 | 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 | 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 | 695 | kfree(vdpasim->vqs); |
| 695 | 696 | kfree(vdpasim->config); |
| 696 | 697 | } |
| @@ -427,8 +427,10 @@ static int __init vdpasim_blk_init(void) · 426 unmodified lines | ||
| 427 | 427 | int ret; |
| 428 | 428 | |
| 429 | 429 | ret = device_register(&vdpasim_blk_mgmtdev); |
| 430 | − if (ret) | |
| 430 | + if (ret) { | |
| 431 | + put_device(&vdpasim_blk_mgmtdev); | |
| 431 | 432 | return ret; |
| 433 | + } | |
| 432 | 434 | |
| 433 | 435 | ret = vdpa_mgmtdev_register(&mgmt_dev); |
| 434 | 436 | if (ret) |
| @@ -62,6 +62,9 @@ static bool receive_filter(struct vdpasim *vdpasim, size_t len) · 61 unmodified lines | ||
| 62 | 62 | if (len < ETH_ALEN + hdr_len) |
| 63 | 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 | 68 | if (!strncmp(vdpasim->buffer + hdr_len, vio_config->mac, ETH_ALEN)) |
| 66 | 69 | return true; |
| 67 | 70 | |
| @@ -305,8 +308,10 @@ static int __init vdpasim_net_init(void) · 237 unmodified lines | ||
| 305 | 308 | int ret; |
| 306 | 309 | |
| 307 | 310 | ret = device_register(&vdpasim_net_mgmtdev); |
| 308 | − if (ret) | |
| 311 | + if (ret) { | |
| 312 | + put_device(&vdpasim_net_mgmtdev); | |
| 309 | 313 | return ret; |
| 314 | + } | |
| 310 | 315 | |
| 311 | 316 | ret = vdpa_mgmtdev_register(&mgmt_dev); |
| 312 | 317 | if (ret) |
| @@ -1440,6 +1440,9 @@ static bool vduse_validate_config(struct vduse_dev_config *config) · 1439 unmodified lines | ||
| 1440 | 1440 | if (config->config_size > PAGE_SIZE) |
| 1441 | 1441 | return false; |
| 1442 | 1442 | |
| 1443 | + if (config->vq_num > 0xffff) | |
| 1444 | + return false; | |
| 1445 | + | |
| 1443 | 1446 | if (!device_is_allowed(config->device_id)) |
| 1444 | 1447 | return false; |
| 1445 | 1448 | |
| @@ -647,7 +647,7 @@ static void vp_vdpa_remove(struct pci_dev *pdev) · 646 unmodified lines | ||
| 647 | 647 | mdev = vp_vdpa_mgtdev->mdev; |
| 648 | 648 | vp_modern_remove(mdev); |
| 649 | 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 | 651 | kfree(mdev); |
| 652 | 652 | kfree(vp_vdpa_mgtdev); |
| 653 | 653 | } |
| @@ -65,6 +65,10 @@ static DEFINE_IDA(vhost_vdpa_ida); · 64 unmodified lines | ||
| 65 | 65 | |
| 66 | 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 | 72 | static inline u32 iotlb_to_asid(struct vhost_iotlb *iotlb) |
| 69 | 73 | { |
| 70 | 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 | 139 | return -EINVAL; |
| 136 | 140 | |
| 137 | 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 | 143 | kfree(as); |
| 140 | 144 | |
| 141 | 145 | return 0; |
| @@ -683,10 +687,20 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep, · 541 unmodified lines | ||
| 683 | 687 | mutex_unlock(&d->mutex); |
| 684 | 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, | |
| 688 | − struct vhost_iotlb *iotlb, | |
| 689 | − u64 start, u64 last) | |
| 702 | +static void vhost_vdpa_pa_unmap(struct vhost_vdpa *v, struct vhost_iotlb *iotlb, | |
| 703 | + u64 start, u64 last, u32 asid) | |
| 690 | 704 | { |
| 691 | 705 | struct vhost_dev *dev = &v->vdev; |
| 692 | 706 | struct vhost_iotlb_map *map; |
| @@ -703,13 +717,13 @@ static void vhost_vdpa_pa_unmap(struct vhost_vdpa *v, · 10 unmodified lines | ||
| 703 | 717 | unpin_user_page(page); |
| 704 | 718 | } |
| 705 | 719 | atomic64_sub(PFN_DOWN(map->size), &dev->mm->pinned_vm); |
| 720 | + vhost_vdpa_general_unmap(v, map, asid); | |
| 706 | 721 | vhost_iotlb_map_free(iotlb, map); |
| 707 | 722 | } |
| 708 | 723 | } |
| 709 | 724 | |
| 710 | −static void vhost_vdpa_va_unmap(struct vhost_vdpa *v, | |
| 711 | − struct vhost_iotlb *iotlb, | |
| 712 | − u64 start, u64 last) | |
| 725 | +static void vhost_vdpa_va_unmap(struct vhost_vdpa *v, struct vhost_iotlb *iotlb, | |
| 726 | + u64 start, u64 last, u32 asid) | |
| 713 | 727 | { |
| 714 | 728 | struct vhost_iotlb_map *map; |
| 715 | 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 | 732 | map_file = (struct vdpa_map_file *)map->opaque; |
| 719 | 733 | fput(map_file->file); |
| 720 | 734 | kfree(map_file); |
| 735 | + vhost_vdpa_general_unmap(v, map, asid); | |
| 721 | 736 | vhost_iotlb_map_free(iotlb, map); |
| 722 | 737 | } |
| 723 | 738 | } |
| 724 | 739 | |
| 725 | 740 | static void vhost_vdpa_iotlb_unmap(struct vhost_vdpa *v, |
| 726 | − struct vhost_iotlb *iotlb, | |
| 727 | − u64 start, u64 last) | |
| 741 | + struct vhost_iotlb *iotlb, u64 start, | |
| 742 | + u64 last, u32 asid) | |
| 728 | 743 | { |
| 729 | 744 | struct vdpa_device *vdpa = v->vdpa; |
| 730 | 745 | |
| 731 | 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 | 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 | 813 | const struct vdpa_config_ops *ops = vdpa->config; |
| 799 | 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) { | |
| 804 | − ops->dma_unmap(vdpa, asid, iova, size); | |
| 805 | − } else if (ops->set_map) { | |
| 818 | + if (ops->set_map) { | |
| 806 | 819 | if (!v->in_batch) |
| 807 | 820 | ops->set_map(vdpa, asid, iotlb); |
| 808 | − } else { | |
| 809 | − iommu_unmap(v->domain, iova, size); | |
| 810 | 821 | } |
| 811 | − | |
| 812 | 822 | /* If we are in the middle of batch processing, delay the free |
| 813 | 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 | 1172 | struct vhost_vdpa_as *as; |
| 1163 | 1173 | u32 asid; |
| 1164 | 1174 | |
| 1165 | − vhost_dev_cleanup(&v->vdev); | |
| 1166 | − kfree(v->vdev.vqs); | |
| 1167 | − | |
| 1168 | 1175 | for (asid = 0; asid < v->vdpa->nas; asid++) { |
| 1169 | 1176 | as = asid_to_as(v, asid); |
| 1170 | 1177 | if (as) |
| 1171 | 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 | 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 | 2053 | struct vhost_dev *dev = vq->dev; |
| 2054 | 2054 | struct vhost_iotlb *umem = dev->iotlb ? dev->iotlb : dev->umem; |
| 2055 | 2055 | struct iovec *_iov; |
| 2056 | − u64 s = 0; | |
| 2056 | + u64 s = 0, last = addr + len - 1; | |
| 2057 | 2057 | int ret = 0; |
| 2058 | 2058 | |
| 2059 | 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 | 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 | 2067 | if (map == NULL || map->start > addr) { |
| 2068 | 2068 | if (umem != dev->iotlb) { |
| 2069 | 2069 | ret = -EFAULT; |
| @@ -1102,7 +1102,7 @@ static int iotlb_translate(const struct vringh *vrh, · 1101 unmodified lines | ||
| 1102 | 1102 | struct vhost_iotlb_map *map; |
| 1103 | 1103 | struct vhost_iotlb *iotlb = vrh->iotlb; |
| 1104 | 1104 | int ret = 0; |
| 1105 | − u64 s = 0; | |
| 1105 | + u64 s = 0, last = addr + len - 1; | |
| 1106 | 1106 | |
| 1107 | 1107 | spin_lock(vrh->iotlb_lock); |
| 1108 | 1108 | |
| @@ -1114,8 +1114,7 @@ static int iotlb_translate(const struct vringh *vrh, · 5 unmodified lines | ||
| 1114 | 1114 | break; |
| 1115 | 1115 | } |
| 1116 | 1116 | |
| 1117 | − map = vhost_iotlb_itree_first(iotlb, addr, | |
| 1118 | − addr + len - 1); | |
| 1117 | + map = vhost_iotlb_itree_first(iotlb, addr, last); | |
| 1119 | 1118 | if (!map || map->start > addr) { |
| 1120 | 1119 | ret = -EINVAL; |
| 1121 | 1120 | break; |
| @@ -959,7 +959,14 @@ static int __init vhost_vsock_init(void) · 958 unmodified lines | ||
| 959 | 959 | VSOCK_TRANSPORT_F_H2G); |
| 960 | 960 | if (ret < 0) |
| 961 | 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 | 972 | static void __exit vhost_vsock_exit(void) |
| @@ -15,7 +15,7 @@ static ssize_t device_show(struct device *_d, · 14 unmodified lines | ||
| 15 | 15 | struct device_attribute *attr, char *buf) |
| 16 | 16 | { |
| 17 | 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 | 20 | static DEVICE_ATTR_RO(device); |
| 21 | 21 | |
| @@ -23,7 +23,7 @@ static ssize_t vendor_show(struct device *_d, · 1 unmodified line | ||
| 23 | 23 | struct device_attribute *attr, char *buf) |
| 24 | 24 | { |
| 25 | 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 | 28 | static DEVICE_ATTR_RO(vendor); |
| 29 | 29 | |
| @@ -31,7 +31,7 @@ static ssize_t status_show(struct device *_d, · 1 unmodified line | ||
| 31 | 31 | struct device_attribute *attr, char *buf) |
| 32 | 32 | { |
| 33 | 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 | 36 | static DEVICE_ATTR_RO(status); |
| 37 | 37 | |
| @@ -39,7 +39,7 @@ static ssize_t modalias_show(struct device *_d, · 1 unmodified line | ||
| 39 | 39 | struct device_attribute *attr, char *buf) |
| 40 | 40 | { |
| 41 | 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 | 43 | dev->id.device, dev->id.vendor); |
| 44 | 44 | } |
| 45 | 45 | static DEVICE_ATTR_RO(modalias); |
| @@ -54,9 +54,9 @@ static ssize_t features_show(struct device *_d, · 8 unmodified lines | ||
| 54 | 54 | /* We actually represent this as a bitstring, as it could be |
| 55 | 55 | * arbitrary length in future. */ |
| 56 | 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 | 58 | __virtio_test_bit(dev, i) ? '1' : '0'); |
| 59 | − len += sprintf(buf+len, "\n"); | |
| 59 | + len += sysfs_emit_at(buf, len, "\n"); | |
| 60 | 60 | return len; |
| 61 | 61 | } |
| 62 | 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 | 303 | int err; |
| 304 | 304 | |
| 305 | 305 | if (index >= vp_modern_get_num_queues(mdev)) |
| 306 | − return ERR_PTR(-ENOENT); | |
| 306 | + return ERR_PTR(-EINVAL); | |
| 307 | 307 | |
| 308 | 308 | /* Check if queue is either not available or already active. */ |
| 309 | 309 | num = vp_modern_get_queue_size(mdev, index); |
| 310 | 310 | if (!num || vp_modern_get_queue_enable(mdev, index)) |
| 311 | 311 | return ERR_PTR(-ENOENT); |
| 312 | 312 | |
| 313 | − if (num & (num - 1)) { | |
| 313 | + if (!is_power_of_2(num)) { | |
| 314 | 314 | dev_warn(&vp_dev->pci_dev->dev, "bad queue size %u", num); |
| 315 | 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 | 1052 | dma_addr_t dma_addr; |
| 1053 | 1053 | |
| 1054 | 1054 | /* We assume num is a power of 2. */ |
| 1055 | − if (num & (num - 1)) { | |
| 1055 | + if (!is_power_of_2(num)) { | |
| 1056 | 1056 | dev_warn(&vdev->dev, "Bad virtqueue length %u\n", num); |
| 1057 | 1057 | return -EINVAL; |
| 1058 | 1058 | } |
| @@ -53,11 +53,9 @@ enum vdpa_attr { · 52 unmodified lines | ||
| 53 | 53 | VDPA_ATTR_DEV_VENDOR_ATTR_NAME, /* string */ |
| 54 | 54 | VDPA_ATTR_DEV_VENDOR_ATTR_VALUE, /* u64 */ |
| 55 | 55 | |
| 56 | + /* virtio features that are provisioned to the vDPA device */ | |
| 56 | 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 | 59 | /* new attributes must be added above here */ |
| 62 | 60 | VDPA_ATTR_MAX, |
| 63 | 61 | }; |
| @@ -140,25 +140,19 @@ static inline void busy_wait(void) · 139 unmodified lines | ||
| 140 | 140 | #define smp_wmb() smp_release() |
| 141 | 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 | 143 | static __always_inline |
| 150 | 144 | void __read_once_size(const volatile void *p, void *res, int size) |
| 151 | 145 | { |
| 152 | − switch (size) { \ | |
| 153 | − case 1: *(unsigned char *)res = *(volatile unsigned char *)p; break; \ | |
| 154 | − case 2: *(unsigned short *)res = *(volatile unsigned short *)p; break; \ | |
| 155 | − case 4: *(unsigned int *)res = *(volatile unsigned int *)p; break; \ | |
| 156 | − case 8: *(unsigned long long *)res = *(volatile unsigned long long *)p; break; \ | |
| 157 | − default: \ | |
| 158 | − barrier(); \ | |
| 159 | − __builtin_memcpy((void *)res, (const void *)p, size); \ | |
| 160 | − barrier(); \ | |
| 161 | − } \ | |
| 146 | + switch (size) { | |
| 147 | + case 1: *(unsigned char *)res = *(volatile unsigned char *)p; break; | |
| 148 | + case 2: *(unsigned short *)res = *(volatile unsigned short *)p; break; | |
| 149 | + case 4: *(unsigned int *)res = *(volatile unsigned int *)p; break; | |
| 150 | + case 8: *(unsigned long long *)res = *(volatile unsigned long long *)p; break; | |
| 151 | + default: | |
| 152 | + barrier(); | |
| 153 | + __builtin_memcpy((void *)res, (const void *)p, size); | |
| 154 | + barrier(); | |
| 155 | + } | |
| 162 | 156 | } |
| 163 | 157 | |
| 164 | 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 | 173 | #define READ_ONCE(x) \ |
| 179 | 174 | ({ \ |
| 180 | 175 | union { typeof(x) __val; char __c[1]; } __u; \ |
| 181 | 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 | 185 | __u.__val; \ |
| 184 | 186 | }) |
| 187 | +#endif | |
| 185 | 188 | |
| 186 | 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 | 76 | if (ret) |
| 77 | 77 | break; |
| 78 | − }; | |
| 78 | + } | |
| 79 | 79 | |
| 80 | 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 | 173 | long started = 0, completed = 0, next_reset = reset_n; |
| 174 | 174 | long completed_before, started_before; |
| 175 | 175 | int r, test = 1; |
| 176 | − unsigned len; | |
| 176 | + unsigned int len; | |
| 177 | 177 | long long spurious = 0; |
| 178 | 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 | 309 | gvdev.vdev.features = features; |
| 310 | 310 | INIT_LIST_HEAD(&gvdev.vdev.vqs); |
| 311 | + spin_lock_init(&gvdev.vdev.vqs_list_lock); | |
| 311 | 312 | gvdev.to_host_fd = to_host[1]; |
| 312 | 313 | gvdev.notifies = 0; |
| 313 | 314 | |
| @@ -455,6 +456,7 @@ int main(int argc, char *argv[]) · 141 unmodified lines | ||
| 455 | 456 | getrange = getrange_iov; |
| 456 | 457 | vdev.features = 0; |
| 457 | 458 | INIT_LIST_HEAD(&vdev.vqs); |
| 459 | + spin_lock_init(&vdev.vqs_list_lock); | |
| 458 | 460 | |
| 459 | 461 | while (argv[1]) { |
| 460 | 462 | if (strcmp(argv[1], "--indirect") == 0) |