X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_vhost%2Fvhost_cuse%2Fvirtio-net-cdev.c;h=ae2c3faf352f1caac5f8b3cc305158107c8e1188;hb=54292e9520e0141b691579868c6e29a7a0628915;hp=58ac3dd3c0336889149313d6347e68a1ab02f22a;hpb=c89d3e5afd35e5b12a1056c3667ddfd28fc260c9;p=dpdk.git diff --git a/lib/librte_vhost/vhost_cuse/virtio-net-cdev.c b/lib/librte_vhost/vhost_cuse/virtio-net-cdev.c index 58ac3dd3c0..ae2c3faf35 100644 --- a/lib/librte_vhost/vhost_cuse/virtio-net-cdev.c +++ b/lib/librte_vhost/vhost_cuse/virtio-net-cdev.c @@ -43,11 +43,19 @@ #include #include #include +#include +#include +#include +#include #include #include +#include "rte_virtio_net.h" #include "vhost-net.h" +#include "virtio-net-cdev.h" +#include "virtio-net.h" +#include "eventfd_copy.h" /* Line size for reading maps file. */ static const uint32_t BUFSIZE = PATH_MAX; @@ -253,3 +261,163 @@ host_memory_map(pid_t pid, uint64_t addr, return 0; } + +int +cuse_set_mem_table(struct vhost_device_ctx ctx, + const struct vhost_memory *mem_regions_addr, uint32_t nregions) +{ + uint64_t size = offsetof(struct vhost_memory, regions); + uint32_t idx, valid_regions; + struct virtio_memory_regions *pregion; + struct vhost_memory_region *mem_regions = (void *)(uintptr_t) + ((uint64_t)(uintptr_t)mem_regions_addr + size); + uint64_t base_address = 0, mapped_address, mapped_size; + struct virtio_net *dev; + + dev = get_device(ctx); + if (dev == NULL) + return -1; + + if (dev->mem && dev->mem->mapped_address) { + munmap((void *)(uintptr_t)dev->mem->mapped_address, + (size_t)dev->mem->mapped_size); + free(dev->mem); + dev->mem = NULL; + } + + dev->mem = calloc(1, sizeof(struct virtio_memory) + + sizeof(struct virtio_memory_regions) * nregions); + if (dev->mem == NULL) { + RTE_LOG(ERR, VHOST_CONFIG, + "(%"PRIu64") Failed to allocate memory for dev->mem\n", + dev->device_fh); + return -1; + } + + pregion = &dev->mem->regions[0]; + + for (idx = 0; idx < nregions; idx++) { + pregion[idx].guest_phys_address = + mem_regions[idx].guest_phys_addr; + pregion[idx].guest_phys_address_end = + pregion[idx].guest_phys_address + + mem_regions[idx].memory_size; + pregion[idx].memory_size = + mem_regions[idx].memory_size; + pregion[idx].userspace_address = + mem_regions[idx].userspace_addr; + + LOG_DEBUG(VHOST_CONFIG, + "REGION: %u - GPA: %p - QVA: %p - SIZE (%"PRIu64")\n", + idx, + (void *)(uintptr_t)pregion[idx].guest_phys_address, + (void *)(uintptr_t)pregion[idx].userspace_address, + pregion[idx].memory_size); + + /*set the base address mapping*/ + if (pregion[idx].guest_phys_address == 0x0) { + base_address = + pregion[idx].userspace_address; + /* Map VM memory file */ + if (host_memory_map(ctx.pid, base_address, + &mapped_address, &mapped_size) != 0) { + free(dev->mem); + dev->mem = NULL; + return -1; + } + dev->mem->mapped_address = mapped_address; + dev->mem->base_address = base_address; + dev->mem->mapped_size = mapped_size; + } + } + + /* Check that we have a valid base address. */ + if (base_address == 0) { + RTE_LOG(ERR, VHOST_CONFIG, + "Failed to find base address of qemu memory file.\n"); + free(dev->mem); + dev->mem = NULL; + return -1; + } + + valid_regions = nregions; + for (idx = 0; idx < nregions; idx++) { + if ((pregion[idx].userspace_address < base_address) || + (pregion[idx].userspace_address > + (base_address + mapped_size))) + valid_regions--; + } + + + if (valid_regions != nregions) { + valid_regions = 0; + for (idx = nregions; 0 != idx--; ) { + if ((pregion[idx].userspace_address < base_address) || + (pregion[idx].userspace_address > + (base_address + mapped_size))) { + memmove(&pregion[idx], &pregion[idx + 1], + sizeof(struct virtio_memory_regions) * + valid_regions); + } else + valid_regions++; + } + } + + for (idx = 0; idx < valid_regions; idx++) { + pregion[idx].address_offset = + mapped_address - base_address + + pregion[idx].userspace_address - + pregion[idx].guest_phys_address; + } + dev->mem->nregions = valid_regions; + + return 0; +} + +/* + * Function to get the tap device name from the provided file descriptor and + * save it in the device structure. + */ +static int +get_ifname(struct vhost_device_ctx ctx, struct virtio_net *dev, int tap_fd, int pid) +{ + int fd_tap; + struct ifreq ifr; + uint32_t ifr_size; + int ret; + + fd_tap = eventfd_copy(tap_fd, pid); + if (fd_tap < 0) + return -1; + + ret = ioctl(fd_tap, TUNGETIFF, &ifr); + + if (close(fd_tap) < 0) + RTE_LOG(ERR, VHOST_CONFIG, + "(%"PRIu64") fd close failed\n", + dev->device_fh); + + if (ret >= 0) { + ifr_size = strnlen(ifr.ifr_name, sizeof(ifr.ifr_name)); + ops->set_ifname(ctx, ifr.ifr_name, ifr_size); + } else + RTE_LOG(ERR, VHOST_CONFIG, + "(%"PRIu64") TUNGETIFF ioctl failed\n", + dev->device_fh); + + return 0; +} + +int cuse_set_backend(struct vhost_device_ctx ctx, struct vhost_vring_file *file) +{ + struct virtio_net *dev; + + dev = get_device(ctx); + if (dev == NULL) + return -1; + + if (!(dev->flags & VIRTIO_DEV_RUNNING) && file->fd != VIRTIO_DEV_STOPPED) + get_ifname(ctx, dev, file->fd, ctx.pid); + + return ops->set_backend(ctx, file); +}