示例#1
0
文件: virtio-net.c 项目: RIFTIO/dpdk
/*
 * 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;
}
示例#2
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;
}
示例#3
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);
}
示例#4
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.
 */
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;
}