| 2629 | } |
| 2630 | |
| 2631 | static int |
| 2632 | vhost_user_iotlb_msg(struct virtio_net **pdev, |
| 2633 | struct vhu_msg_context *ctx, |
| 2634 | int main_fd __rte_unused) |
| 2635 | { |
| 2636 | struct virtio_net *dev = *pdev; |
| 2637 | struct vhost_iotlb_msg *imsg = &ctx->msg.payload.iotlb; |
| 2638 | uint16_t i; |
| 2639 | uint64_t vva, len, pg_sz; |
| 2640 | |
| 2641 | switch (imsg->type) { |
| 2642 | case VHOST_IOTLB_UPDATE: |
| 2643 | len = imsg->size; |
| 2644 | vva = qva_to_vva(dev, imsg->uaddr, &len); |
| 2645 | if (!vva) |
| 2646 | return RTE_VHOST_MSG_RESULT_ERR; |
| 2647 | |
| 2648 | pg_sz = hua_to_alignment(dev->mem, (void *)(uintptr_t)vva); |
| 2649 | |
| 2650 | vhost_user_iotlb_cache_insert(dev, imsg->iova, vva, 0, len, pg_sz, imsg->perm); |
| 2651 | |
| 2652 | for (i = 0; i < dev->nr_vring; i++) { |
| 2653 | struct vhost_virtqueue *vq = dev->virtqueue[i]; |
| 2654 | |
| 2655 | if (!vq) |
| 2656 | continue; |
| 2657 | |
| 2658 | if (is_vring_iotlb(dev, vq, imsg)) { |
| 2659 | rte_rwlock_write_lock(&vq->access_lock); |
| 2660 | translate_ring_addresses(&dev, &vq); |
| 2661 | *pdev = dev; |
| 2662 | rte_rwlock_write_unlock(&vq->access_lock); |
| 2663 | } |
| 2664 | } |
| 2665 | break; |
| 2666 | case VHOST_IOTLB_INVALIDATE: |
| 2667 | vhost_user_iotlb_cache_remove(dev, imsg->iova, imsg->size); |
| 2668 | |
| 2669 | for (i = 0; i < dev->nr_vring; i++) { |
| 2670 | struct vhost_virtqueue *vq = dev->virtqueue[i]; |
| 2671 | |
| 2672 | if (!vq) |
| 2673 | continue; |
| 2674 | |
| 2675 | if (is_vring_iotlb(dev, vq, imsg)) { |
| 2676 | rte_rwlock_write_lock(&vq->access_lock); |
| 2677 | vring_invalidate(dev, vq); |
| 2678 | rte_rwlock_write_unlock(&vq->access_lock); |
| 2679 | } |
| 2680 | } |
| 2681 | break; |
| 2682 | default: |
| 2683 | VHOST_LOG_CONFIG(dev->ifname, ERR, "invalid IOTLB message type (%d)\n", |
| 2684 | imsg->type); |
| 2685 | return RTE_VHOST_MSG_RESULT_ERR; |
| 2686 | } |
| 2687 | |
| 2688 | return RTE_VHOST_MSG_RESULT_OK; |
nothing calls this directly
no test coverage detected