aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlias Apalodimas <ilias.apalodimas@linaro.org>2017-09-21 14:19:13 +0300
committerIlias Apalodimas <ilias.apalodimas@linaro.org>2017-09-21 14:19:13 +0300
commit476d2f1d4c03be3a8fb6eecbb5d92ffac59fe783 (patch)
tree37d112745d65855477c03c189692d32c4a2678ad
parentd8b607370aeff83e9a0a0f1f276a583a49286a57 (diff)
Fucntions for mapping/unmapping DMA buffers
-rw-r--r--test.c122
-rw-r--r--vfio-netem.c15
2 files changed, 93 insertions, 44 deletions
diff --git a/test.c b/test.c
index 974df08..704aba4 100644
--- a/test.c
+++ b/test.c
@@ -14,17 +14,83 @@
const char glob_uuid[] = "d0b24768-9c51-11e7-8de5-c7b0c2769e69";
#define TEST_SIZE 1024 * 1024
+/*
+ * @fd: container fd
+ * @sz: requested size
+ * @vaddr: virtual address
+ */
+int dma_map_type1(int fd, unsigned long sz, void *vaddr)
+{
+ int ret;
+ struct vfio_iommu_type1_dma_map dma_map;
+
+ /* Allocate some space and setup a DMA mapping */
+ vaddr = mmap(NULL, (size_t)sz, PROT_READ,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (vaddr == MAP_FAILED) {
+ printf("Failed to map memory\n");
+ return -ENOMEM;
+ }
+
+ memset(&dma_map, 0, sizeof(dma_map));
+ dma_map.argsz = sizeof(dma_map);
+ dma_map.vaddr = (unsigned long)vaddr;
+ dma_map.size = sz;
+ dma_map.iova = 0;
+ dma_map.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE;
+
+ ret = ioctl(fd, VFIO_IOMMU_MAP_DMA, &dma_map);
+ if (ret)
+ printf("Failed to map DMA memory (%s)\n", strerror(errno));
+
+ return ret;
+}
+
+int dma_unmap_type1(int fd, unsigned long sz, void *vaddr)
+{
+ int ret;
+ struct vfio_iommu_type1_dma_unmap dma_unmap;
+
+ memset(&dma_unmap, 0, sizeof(dma_unmap));
+ dma_unmap.argsz = sizeof(dma_unmap);
+ dma_unmap.size = sz;
+ dma_unmap.iova = 0;
+ ret = ioctl(fd, VFIO_IOMMU_UNMAP_DMA, &dma_unmap);
+ if (ret)
+ printf("Failed to unmap DMA memory (%s)\n", strerror(errno));
+
+ ret = munmap(vaddr, (size_t)sz);
+ if (vaddr == MAP_FAILED) {
+ printf("Failed to unmap memory\n");
+ return -ENOMEM;
+ }
+
+ return ret;
+}
+
+int rtl_8169_remap(void)
+{
+#if 0
+ if (i == 2) {
+ ((uint8_t *)map)[80] = 0xc0;
+ dma_map_type1(container, TEST_SIZE, &vaddr);
+
+ ((uint64_t *)map)[32] = (unsigned long)&vaddr;
+ //dma_unmap_type1(container, TEST_SIZE, &vaddr);
+ }
+#endif
+ return 0;
+}
+
+#define DBG
int main(int argc, char* argv[])
{
- int container, group, device, i, ret;
+ int container, group, device, i;
struct vfio_group_status group_status = { .argsz = sizeof(group_status) };
struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
struct vfio_iommu_type1_info iommu_info = { .argsz = sizeof(iommu_info) };
struct vfio_region_info region_info = { .argsz = sizeof(region_info) };
- struct vfio_iommu_type1_dma_map dma_map = { .argsz = sizeof(dma_map) };
- struct vfio_iommu_type1_dma_unmap dma_unmap = { .argsz = sizeof(dma_unmap) };
void *map;
- size_t sz;
/* Create a new container */
container = open("/dev/vfio/vfio", O_RDWR);
@@ -77,24 +143,30 @@ int main(int argc, char* argv[])
continue;
}
- printf("Region:%d size %lu, offset 0x%lx, flags 0x%x\n", i,
- (unsigned long)region_info.size,
- (unsigned long)region_info.offset, region_info.flags);
+ printf("## Region:%d size %lu, offset 0x%lx, flags 0x%x ##\n",
+ i, (unsigned long)region_info.size,
+ (unsigned long)region_info.offset, region_info.flags);
if (region_info.flags & VFIO_REGION_INFO_FLAG_MMAP) {
- int j;
map = mmap(NULL, (size_t)region_info.size,
- PROT_READ, MAP_SHARED, device,
+ PROT_READ | PROT_WRITE, MAP_SHARED, device,
(off_t)region_info.offset);
if (map == MAP_FAILED) {
printf("mmap failed\n");
continue;
}
+#ifdef DBG
+ int j;
+ size_t sz;
sz = region_info.size / sizeof(uint32_t *);
for (j = 0; j < sz; j++) {
- printf("%08x\n", ((uint32_t *)map)[j]);
+ if (!(j % 8) && j != 0)
+ printf("\n");
+
+ printf("%08x ", ((uint32_t *)map)[j]);
}
printf("\n");
+#endif
/*
fwrite(map, 1, region_info.size > 16 ? 16 :
region_info.size, stdout);
@@ -103,38 +175,8 @@ int main(int argc, char* argv[])
munmap(map, (size_t)region_info.size);
}
}
- /* sample DMA mapping */
- /* Allocate some space and setup a DMA mapping */
- map = mmap(NULL, TEST_SIZE, PROT_READ,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- if (map == MAP_FAILED) {
- printf("Failed to allocate memory\n");
- goto out;
- }
-
- dma_map.vaddr = (unsigned long)map;
- dma_map.flags = VFIO_DMA_MAP_FLAG_READ;
- dma_map.size = TEST_SIZE;
- dma_map.iova = 0;
- ret = ioctl(container, VFIO_IOMMU_MAP_DMA, &dma_map);
- if (ret) {
- printf("Failed to map memory (%s)\n", strerror(errno));
- goto out;
- }
- printf("DMA Mapping: [");
- fwrite(map, 1, region_info.size, stdout);
- printf("]\n");
- /* unmap */
- dma_unmap.size = dma_map.size;
- dma_unmap.iova = 0;
- ret = ioctl(container, VFIO_IOMMU_UNMAP_DMA, &dma_unmap);
- if (ret) {
- printf("Failed to unmap memory (%s)\n", strerror(errno));
- goto out;
- }
return 0;
-
out:
return -1;
}
diff --git a/vfio-netem.c b/vfio-netem.c
index 183b375..324c80c 100644
--- a/vfio-netem.c
+++ b/vfio-netem.c
@@ -207,7 +207,7 @@ static long vfio_net_ioctl(struct mdev_device *mdev, unsigned int cmd,
return -EINVAL;
info.flags = VFIO_DEVICE_FLAGS_PCI;
- /* info.flags |= VFIO_DEVICE_FLAGS_RESET; */
+ info.flags |= VFIO_DEVICE_FLAGS_RESET;
info.num_regions = VFIO_PCI_NUM_REGIONS;
info.num_irqs = 1;
@@ -241,7 +241,7 @@ static long vfio_net_ioctl(struct mdev_device *mdev, unsigned int cmd,
info.flags = VFIO_REGION_INFO_FLAG_READ |
VFIO_REGION_INFO_FLAG_WRITE;
- /* FIXME this isn't always the case vfio-pci has checks */
+ /* FIXME not all BARS are not mappable */
info.flags |= VFIO_REGION_INFO_FLAG_MMAP;
#if 0
if (vdev->bar_mmap_supported[info.index]) {
@@ -259,10 +259,17 @@ static long vfio_net_ioctl(struct mdev_device *mdev, unsigned int cmd,
}
return copy_to_user((void __user *)arg, &info, minsz) ?
- -EFAULT : 0;
+ -EFAULT : 0;
+ } else if (cmd == VFIO_DEVICE_RESET) {
+ /*
+ * FIXME check if hardware supports this before blindly
+ * resetting
+ */
+ return pci_try_reset_function(pdev);
}
+
return 0;
}
@@ -301,7 +308,7 @@ int vfio_vring_init(struct device *dev)
err = mdev_register_device(dev, &vfio_net_ops);
if (!err)
- dev_info(dev, "MDEV-NETEM: Register for driver%s",
+ dev_info(dev, "MDEV-NETEM: Register for driver %s",
pdev->driver->name);
return err;