diff options
author | Damjan Marion <damarion@cisco.com> | 2018-09-30 18:26:20 +0200 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2018-10-23 14:21:10 +0000 |
commit | 68b4da67deb2e8ca224bb5abaeb9dbc7ae8e378c (patch) | |
tree | cd1ee2c463aefdb31c73665eafb876568054f49e /src/vlib/linux/vfio.c | |
parent | fc3b8b8ad08d2d4cc375149ecdc10c37d4a80940 (diff) |
Numa-aware, growable physical memory allocator (pmalloc)
Change-Id: Ic4c46bc733afae8bf0d8146623ed15633928de30
Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'src/vlib/linux/vfio.c')
-rw-r--r-- | src/vlib/linux/vfio.c | 68 |
1 files changed, 31 insertions, 37 deletions
diff --git a/src/vlib/linux/vfio.c b/src/vlib/linux/vfio.c index e72f10388ca..d300a683dd7 100644 --- a/src/vlib/linux/vfio.c +++ b/src/vlib/linux/vfio.c @@ -34,52 +34,46 @@ linux_vfio_main_t vfio_main; -static int -vfio_map_regions (vlib_main_t * vm, int fd) +clib_error_t * +vfio_map_physmem_page (vlib_main_t * vm, void *addr) { - vlib_physmem_main_t *vpm = &physmem_main; + vlib_physmem_main_t *vpm = &vm->physmem_main; linux_vfio_main_t *lvm = &vfio_main; - vlib_physmem_region_t *pr; struct vfio_iommu_type1_dma_map dm = { 0 }; - int i; + uword log2_page_size = vpm->pmalloc_main->log2_page_sz; + uword physmem_start = pointer_to_uword (vpm->pmalloc_main->base); + + if (lvm->container_fd == -1) + return clib_error_return (0, "No cointainer fd"); + + u32 page_index = vlib_physmem_get_page_index (vm, addr); + + if (clib_bitmap_get (lvm->physmem_pages_mapped, page_index)) + { + vlib_log_debug (lvm->log_default, "map DMA va:%p page:%u already " + "mapped", addr, page_index); + return 0; + } dm.argsz = sizeof (struct vfio_iommu_type1_dma_map); dm.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE; + dm.vaddr = physmem_start + (page_index << log2_page_size); + dm.size = 1ULL << log2_page_size; + dm.iova = dm.vaddr; + vlib_log_debug (lvm->log_default, "map DMA page:%u va:0x%lx iova:%lx " + "size:0x%lx", page_index, dm.vaddr, dm.iova, dm.size); - /* *INDENT-OFF* */ - pool_foreach (pr, vpm->regions, + if (ioctl (lvm->container_fd, VFIO_IOMMU_MAP_DMA, &dm) == -1) { - vec_foreach_index (i, pr->page_table) - { - int rv; - dm.vaddr = pointer_to_uword (pr->mem) + ((u64)i << pr->log2_page_size); - dm.size = 1ull << pr->log2_page_size; - dm.iova = dm.vaddr; - vlib_log_debug (lvm->log_default, "map DMA va:0x%lx iova:%lx " - "size:0x%lx", dm.vaddr, dm.iova, dm.size); - - if ((rv = ioctl (fd, VFIO_IOMMU_MAP_DMA, &dm)) && - errno != EINVAL) - { - vlib_log_err (lvm->log_default, "map DMA va:0x%lx iova:%lx " - "size:0x%lx failed, error %s (errno %d)", - dm.vaddr, dm.iova, dm.size, strerror (errno), - errno); - return rv; - } - } - }); - /* *INDENT-ON* */ - return 0; -} - -void -linux_vfio_dma_map_regions (vlib_main_t * vm) -{ - linux_vfio_main_t *lvm = &vfio_main; + vlib_log_err (lvm->log_default, "map DMA page:%u va:0x%lx iova:%lx " + "size:0x%lx failed, error %s (errno %d)", page_index, + dm.vaddr, dm.iova, dm.size, strerror (errno), errno); + return clib_error_return_unix (0, "physmem DMA map failed"); + } - if (lvm->container_fd != -1) - vfio_map_regions (vm, lvm->container_fd); + lvm->physmem_pages_mapped = clib_bitmap_set (lvm->physmem_pages_mapped, + page_index, 1); + return 0; } static linux_pci_vfio_iommu_group_t * |