aboutsummaryrefslogtreecommitdiff
path: root/samples/test_dma_map.c
diff options
context:
space:
mode:
Diffstat (limited to 'samples/test_dma_map.c')
-rw-r--r--samples/test_dma_map.c216
1 files changed, 0 insertions, 216 deletions
diff --git a/samples/test_dma_map.c b/samples/test_dma_map.c
deleted file mode 100644
index e797b57..0000000
--- a/samples/test_dma_map.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Userspace mediated device sample application
- *
- * Copyright (c) 2019, Nutanix Inc. All rights reserved.
- * Author: Thanos Makatos <thanos@nutanix.com>
- * Swapnil Ingle <swapnil.ingle@nutanix.com>
- * Felipe Franciosi <felipe@nutanix.com>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Nutanix nor the names of its contributors may be
- * used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <stdbool.h>
-#include <string.h>
-#include <linux/vfio.h>
-#include <limits.h>
-#include <assert.h>
-#include <sys/ioctl.h>
-#include <inttypes.h>
-#include <err.h>
-#include "../lib/muser_priv.h"
-
-#define ARRAY_SIZE(array) (sizeof(array) / sizeof(*array))
-
-#define VFIO_PATH "/dev/vfio/"
-#define VFIO_CTR_PATH VFIO_PATH "vfio"
-#define SYSFS_PCI_DEV_PATH "/sys/bus/pci/devices/"
-#define SYSFS_IOMMU_GROUP "/iommu_group"
-
-static int
-pci_group_id(const char *bdf)
-{
- char *dev_path;
- char group_path[PATH_MAX];
- int group_id;
-
- assert(bdf);
-
- asprintf(&dev_path, SYSFS_PCI_DEV_PATH "%s" SYSFS_IOMMU_GROUP, bdf);
- memset(group_path, 0, sizeof(group_path));
- readlink(dev_path, group_path, sizeof(group_path));
- free(dev_path);
- sscanf(basename(group_path), "%d", &group_id);
- return group_id;
-}
-
-static void*
-test_map_dma(const int fd, void *vaddr, unsigned long size, unsigned long iova)
-{
- int err;
- struct vfio_iommu_type1_dma_map dma_map = {
- .argsz = sizeof(dma_map),
- .flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE,
- .vaddr = (unsigned long long)vaddr,
- .iova = iova,
- .size = size,
- };
- fprintf(stderr, "attempting to MAP_DMA IOVA=%llx\n", dma_map.iova);
-
- err = ioctl(fd, VFIO_IOMMU_MAP_DMA, &dma_map);
- if (err) {
- fprintf(stderr, "failed to MAP_DMA: %d (%s)\n", err,
- strerror(errno));
- return NULL;
- }
-
- return (void*)dma_map.vaddr;
-}
-
-static void
-test_unmap_dma(const int fd, unsigned long size, unsigned long long iova)
-{
- int err;
- struct vfio_iommu_type1_dma_unmap dma_unmap = {
- .argsz = sizeof dma_unmap,
- .size = size,
- .iova = iova,
- .flags = 0
- };
-
- err = ioctl(fd, VFIO_IOMMU_UNMAP_DMA, &dma_unmap);
- if (err) {
- perror("UNMAP_DMA\n");
- return;
- }
- printf("unmapped IOVA=%llx\n", dma_unmap.iova);
-}
-
-static int
-get_container_fd(const char *path)
-{
- int err, vfio_ctr_fd, vfio_grp_fd, vfio_dev_fd;
- char *grp_path;
-
- vfio_ctr_fd = open(VFIO_CTR_PATH, O_RDWR);
- assert(vfio_ctr_fd >= 0);
-
- // Open the VFIO entry for this device's IOMMU GROUP.
- err = asprintf(&grp_path, VFIO_PATH "%d", pci_group_id(path));
- assert(err > 0);
- vfio_grp_fd = open(grp_path, O_RDWR);
- assert(vfio_grp_fd >= 0);
- free(grp_path);
-
- // Add the group to the container.
- err = ioctl(vfio_grp_fd, VFIO_GROUP_SET_CONTAINER, &vfio_ctr_fd);
- assert(!err);
-
- // Enable IOMMU type 1 on container.
- err = ioctl(vfio_ctr_fd, VFIO_SET_IOMMU, VFIO_TYPE1v2_IOMMU);
- assert(!err);
-
- // Get a device fd from VFIO.
- vfio_dev_fd = ioctl(vfio_grp_fd, VFIO_GROUP_GET_DEVICE_FD, path);
- assert(vfio_dev_fd >= 0);
-
- return vfio_ctr_fd;
-}
-
-int main(int argc, char * argv[])
-{
- int vfio_ctr_fd;
- void *dma_map_addr;
- struct iovec dma_regions[] = {
- {.iov_base = (void*)0x0, .iov_len = 1 << 21},
- {.iov_base = (void*)(1 << 21), .iov_len = 1 << 21},
- };
- size_t i;
- bool huge = true;
- int fd;
- int flags = MAP_SHARED;
- void *vaddr;
- size_t size = 1 << 23; /* FIXME */
- int ret;
-
- if (argc != 2) {
- fprintf(stderr, "usage: %s <MUSER device UUID>\n", argv[0]);
- return EXIT_FAILURE;
- }
-
- vfio_ctr_fd = get_container_fd(argv[1]);
-
- if (huge) {
- char template[] = "/dev/hugepages/XXXXXX";
- fd = mkstemp(template);
- assert(fd != -1);
- }
-
- ret = lseek(fd, size, SEEK_END);
- if (ret == -1) {
- err(EXIT_FAILURE, "failed to seek at %lu", size);
- }
-
- /*
- * Allocate some space and setup a DMA mapping.
- * It *must* be MAP_SHARED.
- */
- vaddr = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, fd, 0);
- if (vaddr == MAP_FAILED) {
- err(EXIT_FAILURE, "failed to mmap");
- }
-
- for (i = 0; i < ARRAY_SIZE(dma_regions); i++) {
- if ((unsigned long long)dma_regions[i].iov_base + dma_regions[i].iov_len > size
- || (huge && (dma_regions[i].iov_len < (1 << 21)))) {
- err(EXIT_FAILURE, "bad IOVA %#lx-%#lx\n",
- (unsigned long)dma_regions[i].iov_base,
- (unsigned long)dma_regions[i].iov_base + dma_regions[i].iov_len);
- }
- dma_map_addr = test_map_dma(vfio_ctr_fd, vaddr,
- dma_regions[i].iov_len,
- (unsigned long)dma_regions[i].iov_base);
- if (!dma_map_addr)
- exit(EXIT_FAILURE);
- }
-
- printf("press enter to continue\n");
- getchar();
-
- for (i = 0; i < ARRAY_SIZE(dma_regions); i++) {
- test_unmap_dma(vfio_ctr_fd,
- (unsigned long long)dma_regions[i].iov_len,
- (unsigned long long)dma_regions[i].iov_base);
- }
- return 0;
-}