Parse whitespace-separated PCI BDFs from VFIO_SELFTESTS_BDF in vfio_selftests_get_bdfs() instead of requiring a single BDF. Multi-device tests such as P2P DMA tests need two or more devices even when invoked through run_kselftest.sh without command-line arguments. Single-device callers using vfio_selftests_get_bdf() continue to receive the first BDF. Signed-off-by: David Matlack --- tools/testing/selftests/vfio/lib/libvfio.c | 53 ++++++++++++++++------ 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/tools/testing/selftests/vfio/lib/libvfio.c b/tools/testing/selftests/vfio/lib/libvfio.c index 3a3d1ed635c1..448d11442b53 100644 --- a/tools/testing/selftests/vfio/lib/libvfio.c +++ b/tools/testing/selftests/vfio/lib/libvfio.c @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -32,38 +33,62 @@ static char **get_bdfs_cmdline(int *argc, char *argv[], int *nr_bdfs) return *nr_bdfs ? &argv[i] : NULL; } -static char *get_bdf_env(void) +static char **get_bdfs_env(int *nr_bdfs) { - char *bdf; + static char **bdfs; + static int count; + char *env, *tok, *saveptr; + int cap = 0; - bdf = getenv("VFIO_SELFTESTS_BDF"); - if (!bdf) + if (bdfs) { + *nr_bdfs = count; + return bdfs; + } + + env = getenv("VFIO_SELFTESTS_BDF"); + if (!env) return NULL; - VFIO_ASSERT_TRUE(is_bdf(bdf), "Invalid BDF: %s\n", bdf); - return bdf; + env = strdup(env); + VFIO_ASSERT_NOT_NULL(env); + + for (tok = strtok_r(env, " \t\n", &saveptr); tok; + tok = strtok_r(NULL, " \t\n", &saveptr)) { + VFIO_ASSERT_TRUE(is_bdf(tok), "Invalid BDF: %s\n", tok); + if (count == cap) { + cap = cap ? cap * 2 : 4; + bdfs = realloc(bdfs, cap * sizeof(*bdfs)); + VFIO_ASSERT_NOT_NULL(bdfs); + } + bdfs[count++] = tok; + } + + if (!count) { + free(env); + return NULL; + } + + *nr_bdfs = count; + return bdfs; } 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; - } + bdfs = get_bdfs_env(nr_bdfs); + if (bdfs) + return bdfs; 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, "To pass the device address(es) 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(es) via argv:\n"); -- 2.56.0.567.gdb80ae8cd5-goog