summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Matlack <dmatlack@google.com>2025-11-26 23:17:18 +0000
committerAlex Williamson <alex@shazbot.org>2025-11-28 10:58:06 -0700
commit6282ca8585010bfb4ab658243a1665428bcfa9de (patch)
tree46be02784f54661a41b2c55f6d9871036281919d
parentfa246a1d06d74219b79d3e78b0cf47851a60d117 (diff)
vfio: selftests: Allow passing multiple BDFs on the command line
Add support for passing multiple device BDFs to a test via the command line. This is a prerequisite for multi-device tests. Single-device tests can continue using vfio_selftests_get_bdf(), which will continue to return argv[argc - 1] (if it is a BDF string), or the environment variable $VFIO_SELFTESTS_BDF otherwise. For multi-device tests, a new helper called vfio_selftests_get_bdfs() is introduced which will return an array of all BDFs found at the end of argv[], as well as the number of BDFs found (passed back to the caller via argument). The array of BDFs returned does not need to be freed by the caller. The environment variable VFIO_SELFTESTS_BDF continues to support only a single BDF for the time being. Reviewed-by: Alex Mastro <amastro@fb.com> Tested-by: Alex Mastro <amastro@fb.com> Reviewed-by: Raghavendra Rao Ananta <rananta@google.com> Signed-off-by: David Matlack <dmatlack@google.com> Link: https://lore.kernel.org/r/20251126231733.3302983-4-dmatlack@google.com Signed-off-by: Alex Williamson <alex@shazbot.org>
-rw-r--r--tools/testing/selftests/vfio/lib/include/vfio_util.h2
-rw-r--r--tools/testing/selftests/vfio/lib/vfio_pci_device.c57
2 files changed, 48 insertions, 11 deletions
diff --git a/tools/testing/selftests/vfio/lib/include/vfio_util.h b/tools/testing/selftests/vfio/lib/include/vfio_util.h
index 69ec0c856481..0b9a5628d23e 100644
--- a/tools/testing/selftests/vfio/lib/include/vfio_util.h
+++ b/tools/testing/selftests/vfio/lib/include/vfio_util.h
@@ -208,6 +208,8 @@ struct iova_allocator {
* If BDF cannot be determined then the test will exit with KSFT_SKIP.
*/
const char *vfio_selftests_get_bdf(int *argc, char *argv[]);
+char **vfio_selftests_get_bdfs(int *argc, char *argv[], int *nr_bdfs);
+
const char *vfio_pci_get_cdev_path(const char *bdf);
extern const char *default_iommu_mode;
diff --git a/tools/testing/selftests/vfio/lib/vfio_pci_device.c b/tools/testing/selftests/vfio/lib/vfio_pci_device.c
index b479a359da12..eda8f14de797 100644
--- a/tools/testing/selftests/vfio/lib/vfio_pci_device.c
+++ b/tools/testing/selftests/vfio/lib/vfio_pci_device.c
@@ -868,29 +868,64 @@ static bool is_bdf(const char *str)
return count == 4 && length == strlen(str);
}
-const char *vfio_selftests_get_bdf(int *argc, char *argv[])
+static char **get_bdfs_cmdline(int *argc, char *argv[], int *nr_bdfs)
{
- char *bdf;
+ int i;
- if (*argc > 1 && is_bdf(argv[*argc - 1]))
- return argv[--(*argc)];
+ for (i = *argc - 1; i > 0 && is_bdf(argv[i]); i--)
+ continue;
+
+ i++;
+ *nr_bdfs = *argc - i;
+ *argc -= *nr_bdfs;
+
+ return *nr_bdfs ? &argv[i] : NULL;
+}
+
+static char *get_bdf_env(void)
+{
+ char *bdf;
bdf = getenv("VFIO_SELFTESTS_BDF");
- if (bdf) {
- VFIO_ASSERT_TRUE(is_bdf(bdf), "Invalid BDF: %s\n", bdf);
- return bdf;
+ if (!bdf)
+ return NULL;
+
+ VFIO_ASSERT_TRUE(is_bdf(bdf), "Invalid BDF: %s\n", bdf);
+ return bdf;
+}
+
+char **vfio_selftests_get_bdfs(int *argc, char *argv[], int *nr_bdfs)
+{
+ static char *env_bdf;
+ char **bdfs;
+
+ bdfs = get_bdfs_cmdline(argc, argv, nr_bdfs);
+ if (bdfs)
+ return bdfs;
+
+ env_bdf = get_bdf_env();
+ if (env_bdf) {
+ *nr_bdfs = 1;
+ return &env_bdf;
}
- fprintf(stderr, "Unable to determine which device to use, skipping test.\n");
+ fprintf(stderr, "Unable to determine which device(s) to use, skipping test.\n");
fprintf(stderr, "\n");
fprintf(stderr, "To pass the device address via environment variable:\n");
fprintf(stderr, "\n");
- fprintf(stderr, " export VFIO_SELFTESTS_BDF=segment:bus:device.function\n");
+ fprintf(stderr, " export VFIO_SELFTESTS_BDF=\"segment:bus:device.function\"\n");
fprintf(stderr, " %s [options]\n", argv[0]);
fprintf(stderr, "\n");
- fprintf(stderr, "To pass the device address via argv:\n");
+ fprintf(stderr, "To pass the device address(es) via argv:\n");
fprintf(stderr, "\n");
- fprintf(stderr, " %s [options] segment:bus:device.function\n", argv[0]);
+ fprintf(stderr, " %s [options] segment:bus:device.function ...\n", argv[0]);
fprintf(stderr, "\n");
exit(KSFT_SKIP);
}
+
+const char *vfio_selftests_get_bdf(int *argc, char *argv[])
+{
+ int nr_bdfs;
+
+ return vfio_selftests_get_bdfs(argc, argv, &nr_bdfs)[0];
+}