/* * Called from CUSE IOCTL: VHOST_SET_VRING_ADDR * The virtio device sends us the desc, used and avail ring addresses. * This function then converts these to our address space. */ int vhost_set_vring_addr(struct vhost_device_ctx ctx, struct vhost_vring_addr *addr) { struct virtio_net *dev; struct vhost_virtqueue *vq; dev = get_device(ctx); if ((dev == NULL) || (dev->mem == NULL)) return -1; /* addr->index refers to the queue index. The txq 1, rxq is 0. */ vq = dev->virtqueue[addr->index]; /* The addresses are converted from QEMU virtual to Vhost virtual. */ vq->desc = (struct vring_desc *)(uintptr_t)qva_to_vva(dev, addr->desc_user_addr); if (vq->desc == 0) { RTE_LOG(ERR, VHOST_CONFIG, "(%"PRIu64") Failed to find desc ring address.\n", dev->device_fh); return -1; } dev = numa_realloc(dev, addr->index); vq = dev->virtqueue[addr->index]; vq->avail = (struct vring_avail *)(uintptr_t)qva_to_vva(dev, addr->avail_user_addr); if (vq->avail == 0) { RTE_LOG(ERR, VHOST_CONFIG, "(%"PRIu64") Failed to find avail ring address.\n", dev->device_fh); return -1; } vq->used = (struct vring_used *)(uintptr_t)qva_to_vva(dev, addr->used_user_addr); if (vq->used == 0) { RTE_LOG(ERR, VHOST_CONFIG, "(%"PRIu64") Failed to find used ring address.\n", dev->device_fh); return -1; } vq->log_guest_addr = addr->log_guest_addr; LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") mapped address desc: %p\n", dev->device_fh, vq->desc); LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") mapped address avail: %p\n", dev->device_fh, vq->avail); LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") mapped address used: %p\n", dev->device_fh, vq->used); LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") log_guest_addr: %"PRIx64"\n", dev->device_fh, vq->log_guest_addr); return 0; }
/* * Called from CUSE IOCTL: VHOST_SET_VRING_ADDR * The virtio device sends us the desc, used and avail ring addresses. This function * then converts these to our address space. */ static int set_vring_addr(struct vhost_device_ctx ctx, struct vhost_vring_addr *addr) { struct virtio_net *dev; struct vhost_virtqueue *vq; dev = get_device(ctx); if (dev == NULL) return -1; /* addr->index refers to the queue index. The TX queue is 1, RX queue is 0. */ vq = dev->virtqueue[addr->index]; /* The addresses are converted from QEMU virtual to Vhost virtual. */ vq->desc = (struct vring_desc *)(uintptr_t)qva_to_vva(dev, addr->desc_user_addr); if (vq->desc == 0) { RTE_LOG(ERR, VHOST_CONFIG, "(%"PRIu64") Failed to find descriptor ring address.\n", dev->device_fh); return -1; } vq->avail = (struct vring_avail *)(uintptr_t)qva_to_vva(dev, addr->avail_user_addr); if (vq->avail == 0) { RTE_LOG(ERR, VHOST_CONFIG, "(%"PRIu64") Failed to find available ring address.\n", dev->device_fh); return -1; } vq->used = (struct vring_used *)(uintptr_t)qva_to_vva(dev, addr->used_user_addr); if (vq->used == 0) { RTE_LOG(ERR, VHOST_CONFIG, "(%"PRIu64") Failed to find used ring address.\n", dev->device_fh); return -1; } LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") mapped address desc: %p\n", dev->device_fh, vq->desc); LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") mapped address avail: %p\n", dev->device_fh, vq->avail); LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") mapped address used: %p\n", dev->device_fh, vq->used); return 0; }
/* * Converts ring address to Vhost virtual address. * If IOMMU is enabled, the ring address is a guest IO virtual address, * else it is a QEMU virtual address. */ static uint64_t ring_addr_to_vva(struct virtio_net *dev, struct vhost_virtqueue *vq, uint64_t ra, uint64_t *size) { if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)) { uint64_t vva; vva = vhost_user_iotlb_cache_find(vq, ra, size, VHOST_ACCESS_RW); if (!vva) vhost_user_iotlb_miss(dev, ra, VHOST_ACCESS_RW); return vva; } return qva_to_vva(dev, ra, size); }
/* * Called from CUSE IOCTL: VHOST_SET_VRING_ADDR * The virtio device sends us the desc, used and avail ring addresses. * This function then converts these to our address space. */ int vhost_set_vring_addr(int vid, struct vhost_vring_addr *addr) { struct virtio_net *dev; struct vhost_virtqueue *vq; dev = get_device(vid); if ((dev == NULL) || (dev->mem == NULL)) return -1; /* addr->index refers to the queue index. The txq 1, rxq is 0. */ vq = dev->virtqueue[addr->index]; /* The addresses are converted from QEMU virtual to Vhost virtual. */ vq->desc = (struct vring_desc *)(uintptr_t)qva_to_vva(dev, addr->desc_user_addr); if (vq->desc == 0) { RTE_LOG(ERR, VHOST_CONFIG, "(%d) failed to find desc ring address.\n", dev->vid); return -1; } dev = numa_realloc(dev, addr->index); vq = dev->virtqueue[addr->index]; vq->avail = (struct vring_avail *)(uintptr_t)qva_to_vva(dev, addr->avail_user_addr); if (vq->avail == 0) { RTE_LOG(ERR, VHOST_CONFIG, "(%d) failed to find avail ring address.\n", dev->vid); return -1; } vq->used = (struct vring_used *)(uintptr_t)qva_to_vva(dev, addr->used_user_addr); if (vq->used == 0) { RTE_LOG(ERR, VHOST_CONFIG, "(%d) failed to find used ring address.\n", dev->vid); return -1; } if (vq->last_used_idx != vq->used->idx) { RTE_LOG(WARNING, VHOST_CONFIG, "last_used_idx (%u) and vq->used->idx (%u) mismatches; " "some packets maybe resent for Tx and dropped for Rx\n", vq->last_used_idx, vq->used->idx); vq->last_used_idx = vq->used->idx; } vq->log_guest_addr = addr->log_guest_addr; LOG_DEBUG(VHOST_CONFIG, "(%d) mapped address desc: %p\n", dev->vid, vq->desc); LOG_DEBUG(VHOST_CONFIG, "(%d) mapped address avail: %p\n", dev->vid, vq->avail); LOG_DEBUG(VHOST_CONFIG, "(%d) mapped address used: %p\n", dev->vid, vq->used); LOG_DEBUG(VHOST_CONFIG, "(%d) log_guest_addr: %" PRIx64 "\n", dev->vid, vq->log_guest_addr); return 0; }