From 2f207eb3053f8408396c75c378aff236ecb110a3 Mon Sep 17 00:00:00 2001 From: Swapnil Ingle Date: Tue, 17 Nov 2020 05:37:40 -0500 Subject: Fix compiler errors for non-dbg build Signed-off-by: Swapnil Ingle --- lib/cap.c | 7 +++++-- lib/dma.h | 4 +++- lib/muser_ctx.c | 21 ++++++++++++++------- samples/client.c | 5 +++-- samples/gpio-pci-idio-16.c | 5 +---- samples/server.c | 28 +++++++++++++++++++--------- 6 files changed, 45 insertions(+), 25 deletions(-) diff --git a/lib/cap.c b/lib/cap.c index 451c85a..c8c302c 100644 --- a/lib/cap.c +++ b/lib/cap.c @@ -209,6 +209,7 @@ handle_pm_write(lm_ctx_t *lm_ctx, uint8_t *cap, char *const buf, return -EINVAL; } assert(false); /* FIXME implement */ + break; case offsetof(struct pmcap, pmcs): if (count != sizeof(struct pmcs)) { return -EINVAL; @@ -413,14 +414,15 @@ caps_create(lm_ctx_t *lm_ctx, lm_cap_t **lm_caps, int nr_caps) struct caps *caps; if (nr_caps <= 0 || nr_caps >= LM_MAX_CAPS) { - err = EINVAL; - goto out; + errno = EINVAL; + return NULL; } assert(lm_caps != NULL); caps = calloc(1, sizeof *caps); if (caps == NULL) { + err = ENOMEM; goto out; } @@ -466,6 +468,7 @@ out: if (err) { free(caps); caps = NULL; + errno = err; } return caps; } diff --git a/lib/dma.h b/lib/dma.h index 7715b89..987d8ba 100644 --- a/lib/dma.h +++ b/lib/dma.h @@ -303,7 +303,9 @@ dma_unmap_addr(dma_controller_t *dma, int r; r = dma_addr_to_sg(dma, dma_addr, len, &sg, 1, PROT_NONE); - assert(r == 1); + if (r != 1) { + assert(false); + } dma_unmap_sg(dma, &sg, &iov, 1); } diff --git a/lib/muser_ctx.c b/lib/muser_ctx.c index 9224b11..a9a6bdb 100644 --- a/lib/muser_ctx.c +++ b/lib/muser_ctx.c @@ -139,13 +139,21 @@ static inline int recv_blocking(int sock, void *buf, size_t len, int flags) int ret, fret; fret = fcntl(sock, F_SETFL, f & ~O_NONBLOCK); - assert(fret != -1); + if (fret == -1) { + ret = -errno; + fprintf(stderr, "failed to set O_NONBLOCK: %m\n"); + goto out; + } ret = recv(sock, buf, len, flags); fret = fcntl(sock, F_SETFL, f); - assert(fret != -1); + if (fret == -1) { + ret = -errno; + fprintf(stderr, "failed to unset O_NONBLOCK: %m\n"); + } +out: return ret; } @@ -693,7 +701,6 @@ irqs_set_data_bool(lm_ctx_t *lm_ctx, struct vfio_irq_set *irq_set, void *data) eventfd_t val; assert(data != NULL); - for (i = irq_set->start, d8 = data; i < (irq_set->start + irq_set->count); i++, d8++) { efd = lm_ctx->irqs.efds[i]; @@ -1314,7 +1321,8 @@ handle_migration_data_offset(lm_ctx_t *lm_ctx, __u64 *offset, bool is_write) /* * data_offset is invariant during an iteration. */ - break; + ret = 0; + break; default: /* * reading data_offset is undefined out of sequence @@ -1323,7 +1331,6 @@ handle_migration_data_offset(lm_ctx_t *lm_ctx, __u64 *offset, bool is_write) return -EINVAL; } - *offset = lm_ctx->migration.iter.offset + sizeof(struct vfio_device_migration_info); return ret; @@ -1361,7 +1368,7 @@ static ssize_t handle_migration_region_access(lm_ctx_t *lm_ctx, char *buf, size_t count, loff_t pos, bool is_write) { - int ret; + int ret = -EINVAL; assert(lm_ctx != NULL); assert(buf != NULL); @@ -1626,7 +1633,7 @@ static int handle_device_set_irqs(lm_ctx_t *lm_ctx, uint32_t size, int *fds, int nr_fds, struct vfio_irq_set *irq_set) { - void *data; + void *data = NULL; assert(lm_ctx != NULL); assert(irq_set != NULL); diff --git a/samples/client.c b/samples/client.c index d6be91d..bd8d2b3 100644 --- a/samples/client.c +++ b/samples/client.c @@ -550,7 +550,7 @@ static int handle_dma_io(int sock, struct vfio_user_dma_region *dma_regions, static int get_dirty_bitmaps(int sock, struct vfio_user_dma_region *dma_regions, - int nr_dma_regions) + UNUSED int nr_dma_regions) { struct vfio_iommu_type1_dirty_bitmap dirty_bitmap = {0}; struct vfio_iommu_type1_dirty_bitmap_get bitmaps[2]; @@ -566,7 +566,8 @@ get_dirty_bitmaps(int sock, struct vfio_user_dma_region *dma_regions, char data[ARRAY_SIZE(bitmaps)]; assert(dma_regions != NULL); - assert(nr_dma_regions >= (int)ARRAY_SIZE(bitmaps)); + //FIXME: Is below assert correct? + //assert(nr_dma_regions >= (int)ARRAY_SIZE(bitmaps)); for (i = 0; i < ARRAY_SIZE(bitmaps); i++) { bitmaps[i].iova = dma_regions[i].addr; diff --git a/samples/gpio-pci-idio-16.c b/samples/gpio-pci-idio-16.c index 9a79d0c..d9bfa0e 100644 --- a/samples/gpio-pci-idio-16.c +++ b/samples/gpio-pci-idio-16.c @@ -114,9 +114,6 @@ int main(int argc, char *argv[]) lm_ctx = lm_ctx_create(&dev_info); if (lm_ctx == NULL) { - if (errno == EINTR) { - goto out; - } fprintf(stderr, "failed to initialize device emulation: %m\n"); return -1; } @@ -126,7 +123,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "failed to realize device emulation: %m\n"); } } -out: + lm_ctx_destroy(lm_ctx); return ret; } diff --git a/samples/server.c b/samples/server.c index 01978f3..5e3c89e 100644 --- a/samples/server.c +++ b/samples/server.c @@ -96,6 +96,8 @@ bar1_access(UNUSED void *pvt, UNUSED char * const buf, UNUSED size_t count, UNUSED loff_t offset, UNUSED const bool is_write) { assert(false); + + return -ENOTSUP; } bool irq_triggered = false; @@ -207,6 +209,8 @@ unsigned long map_area(UNUSED void *pvt, UNUSED unsigned long off, UNUSED unsigned long len) { assert(false); + + return 0; } static int device_reset(UNUSED void *pvt) @@ -264,7 +268,9 @@ migration_read_data(void *pvt, UNUSED void *buf, __u64 size, { struct server_data *server_data = pvt; - assert(server_data->migration.data_size >= size); + if (server_data->migration.data_size < size) { + assert(false); + } return 0; } @@ -273,6 +279,8 @@ static size_t migration_write_data(UNUSED void *pvt, UNUSED void *data, UNUSED __u64 size) { assert(false); + + return 0; } int main(int argc, char *argv[]){ @@ -283,7 +291,6 @@ int main(int argc, char *argv[]){ struct server_data server_data = {0}; int nr_sparse_areas = 2, size = 1024, i; struct lm_sparse_mmap_areas *sparse_areas; - lm_ctx_t *lm_ctx; while ((opt = getopt(argc, argv, "v")) != -1) { @@ -310,7 +317,8 @@ int main(int argc, char *argv[]){ sparse_areas = calloc(1, sizeof(*sparse_areas) + (nr_sparse_areas * sizeof(struct lm_mmap_area))); if (sparse_areas == NULL) { - err(EXIT_FAILURE, "MMAP sparse areas ENOMEM"); + ret = -ENOMEM; + fprintf(stderr, "MMAP sparse areas ENOMEM\n"); goto out; } sparse_areas->nr_mmap_areas = nr_sparse_areas; @@ -359,15 +367,16 @@ int main(int argc, char *argv[]){ sigemptyset(&act.sa_mask); if (sigaction(SIGUSR1, &act, NULL) == -1) { - err(EXIT_FAILURE, "failed to register signal handler"); + fprintf(stderr, "failed to register signal handler\n"); + ret = -EFAULT; + goto out; } lm_ctx = lm_ctx_create(&dev_info); if (lm_ctx == NULL) { - if (errno == EINTR) { - goto out; - } - err(EXIT_FAILURE, "failed to initialize device emulation"); + fprintf(stderr, "failed to initialize device emulation\n"); + ret = -1; + goto out; } do { @@ -394,8 +403,9 @@ int main(int argc, char *argv[]){ fprintf(stderr, "failed to realize device emulation: %s\n", strerror(-ret)); } -out: lm_ctx_destroy(lm_ctx); + +out: free(server_data.bar1); free(sparse_areas); return ret; -- cgit v1.1 From 0a3cf29466b3785c12c9fbae502df5351137ec03 Mon Sep 17 00:00:00 2001 From: Swapnil Ingle Date: Tue, 17 Nov 2020 05:38:57 -0500 Subject: remove test_dma_map.c,test_mmap.c and test_read.c Those files were intended for kmod. No use for vfio-user. Signed-off-by: Swapnil Ingle --- samples/CMakeLists.txt | 4 - samples/test_dma_map.c | 216 ---------------------------------------- samples/test_mmap.c | 199 ------------------------------------- samples/test_read.c | 263 ------------------------------------------------- 4 files changed, 682 deletions(-) delete mode 100644 samples/test_dma_map.c delete mode 100644 samples/test_mmap.c delete mode 100644 samples/test_read.c diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 49a9201..bb963da 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -28,10 +28,6 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -add_executable(test_read test_read.c) -add_executable(test_mmap test_mmap.c) -add_executable(test_dma_map test_dma_map.c) - add_executable(server server.c) target_link_libraries(server muser ssl crypto) add_executable(client client.c ../lib/muser_ctx.c ../lib/muser_pci.c ../lib/dma.c ../lib/cap.c) 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 - * Swapnil Ingle - * Felipe Franciosi - * - * 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 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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 \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; -} diff --git a/samples/test_mmap.c b/samples/test_mmap.c deleted file mode 100644 index 02c32f1..0000000 --- a/samples/test_mmap.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Userspace mediated device sample application - * - * Copyright (c) 2019, Nutanix Inc. All rights reserved. - * Author: Thanos Makatos - * Swapnil Ingle - * Felipe Franciosi - * - * 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 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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 inline void* -test_map_dma(const int fd, const unsigned long size, const unsigned long iova) -{ - int err; - struct vfio_iommu_type1_dma_map dma_map = { - .argsz = sizeof(dma_map), - .size = size, - .iova = iova, - .flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE, - }; - - /* Allocate some space and setup a DMA mapping */ - /* FIXME it *must* be MAP_SHARED */ - dma_map.vaddr = (unsigned long long)mmap(0, size, PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_ANONYMOUS, 0, 0); - if (dma_map.vaddr == (unsigned long)MAP_FAILED) { - perror("failed to map DMA"); - return NULL; - } - printf("%llx\n", dma_map.vaddr); - strcpy((char*)dma_map.vaddr, "foo"); - - 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 (errno=%d)", err, errno); - return NULL; - } - printf("[%s]\n", (char*)dma_map.vaddr); - - return (void*)dma_map.vaddr; -} - -static inline void -test_unmap_dma(const int fd, const unsigned long size, const unsigned 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); -} - -int main(int argc, char * argv[]) -{ - int err, vfio_ctr_fd, vfio_grp_fd, vfio_dev_fd; - char *grp_path; -#ifdef DEBUG - struct vfio_group_status grp_status; -#endif - struct vfio_iommu_type1_info iommu_info; - void *dma_map_addr = NULL; - - if (argc != 2) { - printf("Usage: %s \n", argv[0]); - printf(" ex: %s 0000:82:00.0\n", argv[0]); - return EXIT_FAILURE; - } - - vfio_ctr_fd = open(VFIO_CTR_PATH, O_RDWR); - assert(vfio_ctr_fd >= 0); - -#ifdef DEBUG - err = ioctl(vfio_ctr_fd, VFIO_GET_API_VERSION); - assert(err == VFIO_API_VERSION); - err = ioctl(vfio_ctr_fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU); - assert(err == 1); -#endif - - // Open the VFIO entry for this device's IOMMU GROUP. - err = asprintf(&grp_path, VFIO_PATH "%d", pci_group_id(argv[1])); - assert(err > 0); - vfio_grp_fd = open(grp_path, O_RDWR); - assert(vfio_grp_fd >= 0); - free(grp_path); - -#ifdef DEBUG - // Ensure group is viable. - memset(&grp_status, 0, sizeof(grp_status)); - grp_status.argsz = sizeof(grp_status); - err = ioctl(vfio_grp_fd, VFIO_GROUP_GET_STATUS, &grp_status); - assert(!err); - assert((grp_status.flags & VFIO_GROUP_FLAGS_VIABLE) == 1); -#endif - - // 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); - - // Fetch IOMMU information from VFIO. - memset(&iommu_info, 0, sizeof(iommu_info)); - iommu_info.argsz = sizeof(iommu_info); - err = ioctl(vfio_ctr_fd, VFIO_IOMMU_GET_INFO, &iommu_info); - assert(!err); - - // Get a device fd from VFIO. - vfio_dev_fd = ioctl(vfio_grp_fd, VFIO_GROUP_GET_DEVICE_FD, argv[1]); - assert(vfio_dev_fd >= 0); - - void *p; - p = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ | PROT_WRITE, - MAP_SHARED, vfio_dev_fd, 0); - assert(p != MAP_FAILED); - printf("%p\n", p); - printf("%s\n", (char*)p); - - dma_map_addr = test_map_dma(vfio_ctr_fd, 4096, 0xdeadbeef000); - if (!dma_map_addr) - exit(EXIT_FAILURE); - test_unmap_dma(vfio_ctr_fd, 4096, 0xdeadbeef000); - - return 0; -} diff --git a/samples/test_read.c b/samples/test_read.c deleted file mode 100644 index d8798c3..0000000 --- a/samples/test_read.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Userspace mediated device sample application - * - * Copyright (c) 2019, Nutanix Inc. All rights reserved. - * Author: Thanos Makatos - * Swapnil Ingle - * Felipe Franciosi - * - * 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 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define VFIO_PATH "/dev/vfio/" -#define VFIO_CTR_PATH VFIO_PATH "vfio" -#define SYSFS_MUSER_DEV_PATH "/sys/class/muser/muser/" -#define SYSFS_IOMMU_GROUP "/iommu_group" - -static int -test_read(int vfio_dev_fd, off_t offset) -{ - size_t bytes, i; - char buf[256]; - - memset(buf, 0, sizeof(buf)); - printf("* Reading %zd bytes at %#zx\n", sizeof(buf), offset); - bytes = pread(vfio_dev_fd, buf, sizeof(buf), offset); - printf("** bytes = %zd\n", bytes); - assert(bytes == sizeof(buf)); - printf("** Read %zd bytes\n", bytes); - - for (i = 0; i < sizeof(buf); i++) { - if (i % 16 == 0) { - printf("%04lX:", i); - } - printf(" %02hhX", buf[i]); - if (i % 16 == 15) { - printf("\n"); - } - } - if (i % 16 != 0) { - printf("\n"); - } - - return 0; -} - -static int -pci_group_id(const char *uuid) -{ - char *dev_path; - char group_path[PATH_MAX]; - int group_id; - - assert(uuid != NULL); - - asprintf(&dev_path, SYSFS_MUSER_DEV_PATH "%s" SYSFS_IOMMU_GROUP, uuid); - 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; -} - -void print_sparse_mmap_info(struct vfio_region_info *reg) -{ - struct vfio_region_info_cap_sparse_mmap *sparse; - - printf("argsz %u, cap_off %u\n", reg->argsz, reg->cap_offset); - if (reg->cap_offset) { - sparse = (struct vfio_region_info_cap_sparse_mmap *) - ((void *)reg + reg->cap_offset); - printf("cap_hdr: id %u version %u\n", sparse->header.id, - sparse->header.version); - printf("sparse: nr_areas %u, off 0x%llx size 0x%llx\n", sparse->nr_areas, - sparse->areas[0].offset, sparse->areas[0].size); - } -} - -int -main(int argc, char * argv[]) -{ - int vfio_ctr_fd, vfio_grp_fd, vfio_dev_fd; - char *grp_path; - size_t size = 0; - int i; - int err; - - if (argc != 2) { - printf("Usage: %s \n", argv[0]); - return EXIT_FAILURE; - } - - // Create a new VFIO container. - printf("* Creating new VFIO container...\n"); - vfio_ctr_fd = open(VFIO_CTR_PATH, O_RDWR); - assert(vfio_ctr_fd >= 0); - printf("** vfio_ctr_fd = %d\n", vfio_ctr_fd); - - // Ensure kernel VFIO is compatible. - printf("* Fetching VFIO API version...\n"); - err = ioctl(vfio_ctr_fd, VFIO_GET_API_VERSION); - assert(err == VFIO_API_VERSION); - - // Ensure VFIO supports TYPE1 IOMMU. - printf("* Checking for IOMMU TYPE1 extension in VFIO...\n"); - err = ioctl(vfio_ctr_fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU); - assert(err == 1); - - // Open the VFIO entry for this device's IOMMU GROUP. - err = asprintf(&grp_path, VFIO_PATH "%d", pci_group_id(argv[1])); - assert(err > 0); - printf("* Opening the VFIO group (%s)...\n", grp_path); - vfio_grp_fd = open(grp_path, O_RDWR); - assert(vfio_grp_fd >= 0); - printf("** vfio_grp_fd = %d\n", vfio_grp_fd); - free(grp_path); - - // Ensure group is viable. - struct vfio_group_status grp_status; - printf("* Ensuring all devices in this group are bound to VFIO...\n"); - memset(&grp_status, 0, sizeof(grp_status)); - grp_status.argsz = sizeof(grp_status); - err = ioctl(vfio_grp_fd, VFIO_GROUP_GET_STATUS, &grp_status); - assert(!err); - assert((grp_status.flags & VFIO_GROUP_FLAGS_VIABLE) == 1); - - // Add the group to the container. - printf("* Adding group to container...\n"); - err = ioctl(vfio_grp_fd, VFIO_GROUP_SET_CONTAINER, &vfio_ctr_fd); - assert(!err); - - // Enable IOMMU type 1 on container. - printf("* Setting IOMMU Type 1 on container...\n"); - err = ioctl(vfio_ctr_fd, VFIO_SET_IOMMU, VFIO_TYPE1v2_IOMMU); - assert(!err); - - // Fetch IOMMU information from VFIO. - struct vfio_iommu_type1_info iommu_info; - printf("* Fetching IOMMU information...\n"); - memset(&iommu_info, 0, sizeof(iommu_info)); - iommu_info.argsz = sizeof(iommu_info); - err = ioctl(vfio_ctr_fd, VFIO_IOMMU_GET_INFO, &iommu_info); - assert(!err); - - // Get a device fd from VFIO. - printf("* Getting a device (%s) fd from group...\n", argv[1]); - vfio_dev_fd = ioctl(vfio_grp_fd, VFIO_GROUP_GET_DEVICE_FD, argv[1]); - assert(vfio_dev_fd >= 0); - printf("** vfio_dev_fd = %d\n", vfio_dev_fd); - - // Fetch device information. - printf("* Fetching device information...\n"); - struct vfio_device_info dev_info; - memset(&dev_info, 0, sizeof(dev_info)); - dev_info.argsz = sizeof(dev_info); - err = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_INFO, &dev_info); - assert(err == 0); - assert(dev_info.num_regions <= VFIO_PCI_NUM_REGIONS); - - // Fetch region information for this device. - struct vfio_region_info *reg_info[VFIO_PCI_NUM_REGIONS] = {0}; - struct vfio_region_info *reg; - printf("* Fetching information for %u regions\n", dev_info.num_regions); - for (i = 0; i < (int)dev_info.num_regions; i++) { - size = sizeof(struct vfio_region_info); - reg = calloc(1, size); - assert(reg != NULL); - reg->argsz = size; - reg->index = i; -retry: - err = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_REGION_INFO, reg); - if (err != 0) { - // This region doesn't exist or isn't accessible. - printf("** %d: Region info unavailable\n", i); - memset(reg, 0, size); - } else { - printf("** %d: argsz=0x%X, flags=0x%X, index=0x%X, " - "size=0x%llX, offset=0x%llX\n", - i, - reg->argsz, - reg->flags, - reg->index, - reg->size, - reg->offset); - if (reg->argsz > size) { - size = reg->argsz; - reg = realloc(reg, reg->argsz); - goto retry; - } - print_sparse_mmap_info(reg); - } - reg_info[i] = reg; - } - - // Fetch irq information for this device. - struct vfio_irq_info irq_info[VFIO_PCI_NUM_IRQS]; - printf("* Fetching information for %u irqs\n", dev_info.num_irqs); - for (i = 0; i < (int)dev_info.num_irqs; i++) { - memset(&irq_info[i], 0, sizeof(irq_info[i])); - irq_info[i].argsz = sizeof(irq_info[i]); - irq_info[i].index = i; - err = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_IRQ_INFO, irq_info[i]); - if (err != 0) { - // This irq doesn't exist or isn't accessible. - printf("** %d: Irq info unavailable\n", i); - memset(&irq_info[i], 0, sizeof(irq_info[i])); - } else { - printf("** %d: argsz=0x%X, flags=0x%X, index=0x%X, count=%u\n", - i, - irq_info[i].argsz, - irq_info[i].flags, - irq_info[i].index, - irq_info[i].count); - } - } - - // Test. - err = test_read(vfio_dev_fd, reg_info[VFIO_PCI_CONFIG_REGION_INDEX]->offset); - assert(!err); - for (i = 0; i < (int)dev_info.num_regions; i++) { - free(reg_info[i]); - } - - return 0; -} -- cgit v1.1