From ebd0b18c3d02891d416e642f3388a914288a3064 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 22 Jul 2020 14:53:01 +1000 Subject: [PATCH 1/5] Add basic Makefile Make it easier to build the tests by adding a Makefile. Signed-off-by: David Gibson --- Makefile | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..50354dc --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ +PROGS = kvm-huge-guest-test \ + leaktest-legacy-kvm \ + vfio-correctness-tests \ + vfio-huge-guest-test \ + vfio-iommu-map-unmap \ + vfio-iommu-stress-test \ + vfio-noiommu-pci-device-open \ + vfio-pci-device-open \ + vfio-pci-device-open-igd \ + vfio-pci-device-open-sparse-mmap \ + vfio-pci-hot-reset + +all: $(PROGS) + +clean: + rm -f *.o *~ + rm -f $(PROGS) + From 785af938878b6e2ad6798c417326a35fbb76f641 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 22 Jul 2020 14:55:16 +1000 Subject: [PATCH 2/5] Add missing stdlib.h includes vfio-correct-ness-tests and vfio-huge-guest-test use mkstemp() without including stdlib.h where it is defined. Signed-off-by: David Gibson --- vfio-correctness-tests.c | 1 + vfio-huge-guest-test.c | 1 + 2 files changed, 2 insertions(+) diff --git a/vfio-correctness-tests.c b/vfio-correctness-tests.c index cdee4ed..16232a2 100644 --- a/vfio-correctness-tests.c +++ b/vfio-correctness-tests.c @@ -387,6 +387,7 @@ struct vfio_iommu_type1_dma_unmap { #include #include #include +#include #include #include #include diff --git a/vfio-huge-guest-test.c b/vfio-huge-guest-test.c index 1ce4edd..29c800b 100644 --- a/vfio-huge-guest-test.c +++ b/vfio-huge-guest-test.c @@ -386,6 +386,7 @@ struct vfio_iommu_type1_dma_unmap { #include #include #include +#include #include #include #include From d5805a49a90da252b92863519aac929c5d391e33 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 22 Jul 2020 14:56:59 +1000 Subject: [PATCH 3/5] Add a basic .gitignore Ignore editor backups and the generate test programs. Signed-off-by: David Gibson --- .gitignore | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ff7bfa --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +*~ +kvm-huge-guest-test +leaktest-legacy-kvm +vfio-correctness-tests +vfio-huge-guest-test +vfio-iommu-map-unmap +vfio-iommu-stress-test +vfio-noiommu-pci-device-open +vfio-pci-device-open +vfio-pci-device-open-igd +vfio-pci-device-open-sparse-mmap +vfio-pci-hot-reset \ No newline at end of file From 666c5ad9709556d3b52ba71c114cdf91240145ad Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 22 Jul 2020 15:10:23 +1000 Subject: [PATCH 4/5] Safer reading of mmio in vfio-pci-device-open This test program does an fwrite() direct from mmio space. This will print garbage, which is no real problem. What might be a problem though is that this fwrite() essential amounts to a memcpy() from the mmio space to stdio's internal buffer. Since it expects to be coming from regular memory, that may be optimized to use exotic load and store instructions (e.g. using vector registers). The effects of using those on mmio space might be strange - it can result in SIGILLs, or even crashes depending on details. To avoid that, use a simpler plain loop to read the IO space out byte by byte, with a volatile qualifier to discourage the compiler from doing anything too clever. Minor tweak of an earlier fix from Pradipta Banerjee . Signed-off-by: David Gibson --- vfio-pci-device-open.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vfio-pci-device-open.c b/vfio-pci-device-open.c index 5a33cdd..b84be04 100644 --- a/vfio-pci-device-open.c +++ b/vfio-pci-device-open.c @@ -570,14 +570,16 @@ int main(int argc, char **argv) void *map = mmap(NULL, (size_t)region_info.size, PROT_READ, MAP_SHARED, device, (off_t)region_info.offset); + volatile unsigned char *p = map; + size_t j; if (map == MAP_FAILED) { printf("mmap failed\n"); continue; } printf("["); - fwrite(map, 1, region_info.size > 16 ? 16 : - region_info.size, stdout); + for (j = 0; j < 16 && j < region_info.size; j++) + printf("%02x ", p[j]); printf("]\n"); munmap(map, (size_t)region_info.size); } From f45880384d507ffeb02566277ff34d1e275c41ba Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 22 Jul 2020 21:10:27 +1000 Subject: [PATCH 5/5] More useful defaults for map-unmap test 1. Currently this attempts to map 1GiB into the IOMMU, in 4kiB chunks, which will exhaust the type1 kernel driver's default limit of 65535 mappings. Reduce the default mapping size to match the default kernel limit. 2. The chunk size is fixed to 4kiB, which will fail on platforms which don't have a 4kiB page size. Use getpagesize() instead (this can still fail if the IOMMU granularity doesn't match the system page size, but that's much rarer). 3. Currently the program loops forever, mapping and unmapping. Great for a stress test, not great for quickly seeing if things are working. Put in a maximum number of iterations (default 10). Signed-off-by: David Gibson --- vfio-iommu-map-unmap.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/vfio-iommu-map-unmap.c b/vfio-iommu-map-unmap.c index c7030b2..a181db7 100644 --- a/vfio-iommu-map-unmap.c +++ b/vfio-iommu-map-unmap.c @@ -13,8 +13,10 @@ #include #include -#define MAP_SIZE (1UL * 1024 * 1024 * 1024) -#define MAP_CHUNK (4 * 1024) +#define MAP_CHUNK (getpagesize()) +#define MAP_LIMIT 65535U +#define MAP_SIZE (MAP_LIMIT * MAP_CHUNK) +#define ITERATIONS 10 #define REALLOC_INTERVAL 30 void usage(char *name) @@ -137,7 +139,7 @@ int main(int argc, char **argv) memset(maps, 0, sizeof(void *) * (MAP_SIZE/dma_map.size)); - for (count = 0;; count++) { + for (count = 0;count < ITERATIONS; count++) { /* Every REALLOC_INTERVAL, dump our mappings to give THP something to collapse */ if (count % REALLOC_INTERVAL == 0) {