| 66 | } |
| 67 | |
| 68 | uint64_t |
| 69 | __vhost_iova_to_vva(struct virtio_net *dev, struct vhost_virtqueue *vq, |
| 70 | uint64_t iova, uint64_t *size, uint8_t perm) |
| 71 | { |
| 72 | uint64_t vva, tmp_size; |
| 73 | |
| 74 | if (unlikely(!*size)) |
| 75 | return 0; |
| 76 | |
| 77 | tmp_size = *size; |
| 78 | |
| 79 | vva = vhost_user_iotlb_cache_find(dev, iova, &tmp_size, perm); |
| 80 | if (tmp_size == *size) { |
| 81 | if (dev->flags & VIRTIO_DEV_STATS_ENABLED) |
| 82 | vq->stats.iotlb_hits++; |
| 83 | return vva; |
| 84 | } |
| 85 | |
| 86 | if (dev->flags & VIRTIO_DEV_STATS_ENABLED) |
| 87 | vq->stats.iotlb_misses++; |
| 88 | |
| 89 | iova += tmp_size; |
| 90 | |
| 91 | if (!vhost_user_iotlb_pending_miss(dev, iova, perm)) { |
| 92 | /* |
| 93 | * iotlb_lock is read-locked for a full burst, |
| 94 | * but it only protects the iotlb cache. |
| 95 | * In case of IOTLB miss, we might block on the socket, |
| 96 | * which could cause a deadlock with QEMU if an IOTLB update |
| 97 | * is being handled. We can safely unlock here to avoid it. |
| 98 | */ |
| 99 | vhost_user_iotlb_rd_unlock(vq); |
| 100 | |
| 101 | vhost_user_iotlb_pending_insert(dev, iova, perm); |
| 102 | if (vhost_iotlb_miss(dev, iova, perm)) { |
| 103 | VHOST_LOG_DATA(dev->ifname, ERR, |
| 104 | "IOTLB miss req failed for IOVA 0x%" PRIx64 "\n", |
| 105 | iova); |
| 106 | vhost_user_iotlb_pending_remove(dev, iova, 1, perm); |
| 107 | } |
| 108 | |
| 109 | vhost_user_iotlb_rd_lock(vq); |
| 110 | } |
| 111 | |
| 112 | tmp_size = *size; |
| 113 | /* Retry in case of VDUSE, as it is synchronous */ |
| 114 | vva = vhost_user_iotlb_cache_find(dev, iova, &tmp_size, perm); |
| 115 | if (tmp_size == *size) |
| 116 | return vva; |
| 117 | |
| 118 | return 0; |
| 119 | } |
| 120 | |
| 121 | #define VHOST_LOG_PAGE 4096 |
| 122 |
no test coverage detected