All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH BlueZ v2 0/4] test-runner: use virtio-fs by default, functional test speedup
@ 2026-09-12 18:18 Pauli Virtanen
  2026-09-12 18:18 ` [PATCH BlueZ v2 1/4] tools/test-runner: replace alloca() based argv setup Pauli Virtanen
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Pauli Virtanen @ 2026-09-12 18:18 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Pauli Virtanen

v2:
- refactor start_qemu() argv building
- split out rootfs setup to separate functions
- fix bug in check_virtualization() that causes problems here

***

Use virtio-fs instead of 9p, which gives 3x reduction in CPU time for
functional tests:

Before:
$ time make check-functional
real	1m56,857s
user	8m37,727s
sys	2m21,655s

After:
$ time make check-functional
real	1m4,714s
user	2m52,831s
sys	0m37,379s

Wall clock improvement becomes more significant under CPU load.

Requires /usr/libexec/virtiofsd installed, and CONFIG_VIRTIO_FS=y in
kernel. Enable that option in tester configs.

If virtiofsd is not available, fall back to 9p as before.

Pauli Virtanen (4):
  tools/test-runner: replace alloca() based argv setup
  doc: enable virtio-fs in tester kernel configs
  tools/test-runner: use virtiofsd for filesystem passthrough
  tools/test-runner: Fix CPUID register clobbers

 doc/ci.config       |   2 +
 doc/test-runner.rst |  10 +-
 doc/tester.config   |   2 +
 tools/test-runner.c | 414 +++++++++++++++++++++++++++++++++++---------
 4 files changed, 346 insertions(+), 82 deletions(-)

-- 
2.55.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH BlueZ v2 1/4] tools/test-runner: replace alloca() based argv setup
  2026-09-12 18:18 [PATCH BlueZ v2 0/4] test-runner: use virtio-fs by default, functional test speedup Pauli Virtanen
@ 2026-09-12 18:18 ` Pauli Virtanen
  2026-09-12 19:17   ` test-runner: use virtio-fs by default, functional test speedup bluez.test.bot
  2026-09-12 18:18 ` [PATCH BlueZ v2 2/4] doc: enable virtio-fs in tester kernel configs Pauli Virtanen
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 6+ messages in thread
From: Pauli Virtanen @ 2026-09-12 18:18 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Pauli Virtanen

Rewrite alloca() based argv array construction that required manual size
counting with vasprintf string array. This allows splitting start_qemu()
to multiple functions.
---
 tools/test-runner.c | 132 +++++++++++++++++++++++++++++---------------
 1 file changed, 89 insertions(+), 43 deletions(-)

diff --git a/tools/test-runner.c b/tools/test-runner.c
index 63fedece0..a0ac321ca 100644
--- a/tools/test-runner.c
+++ b/tools/test-runner.c
@@ -21,6 +21,7 @@
 #include <stdbool.h>
 #include <signal.h>
 #include <string.h>
+#include <stdarg.h>
 #include <getopt.h>
 #include <poll.h>
 #include <dirent.h>
@@ -41,6 +42,10 @@
 #define WAIT_ANY (-1)
 #endif
 
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+#define _cleanup_(f) __attribute__((cleanup(f)))
+
 #define CMDLINE_MAX (2048 * 10)
 #define EXTRA_OPT_MAX 64
 
@@ -65,6 +70,58 @@ static char *pcie_dev;
 static char *extra_opts[EXTRA_OPT_MAX];
 static int num_extra_opts;
 
+struct strv {
+	char **strv;
+	size_t size;
+	size_t i;
+};
+
+#define STRV_ERROR(s) ((s).size == 0)
+
+static void __attribute__((format(printf, 2, 3)))
+strv_append(struct strv *s, const char *fmt, ...)
+{
+	va_list ap;
+	int ret;
+
+	if (s->size == 0 || s->i >= s->size - 1)
+		goto fail;
+
+	va_start(ap, fmt);
+	ret = vasprintf(&s->strv[s->i], fmt, ap);
+	va_end(ap);
+
+	if (ret < 0) {
+		perror("vasprintf");
+		s->strv[s->i] = NULL;
+		goto fail;
+	}
+
+	s->strv[++s->i] = NULL;
+	return;
+
+fail:
+	s->size = 0;
+}
+
+static void strv_concat(struct strv *s, const char *const *str)
+{
+	while (*str) {
+		strv_append(s, "%s", *str);
+		str++;
+	}
+}
+
+static void strv_cleanup(struct strv *s)
+{
+	size_t i;
+
+	for (i = 0; i < s->i; ++i)
+		free(s->strv[i]);
+
+	memset(s, 0, sizeof(*s));
+}
+
 static const char *qemu_table[] = {
 	"qemu-system-x86_64",
 	"qemu-system-i386",
@@ -225,8 +282,7 @@ static void prepare_sandbox(void)
 	enable_printk();
 }
 
-static char *const qemu_argv[] = {
-	"",
+static const char *const qemu_argv[] = {
 	"-nodefaults",
 	"-no-user-config",
 	"-monitor", "none",
@@ -510,7 +566,9 @@ static int start_qemu(void)
 {
 	char cwd[PATH_MAX/2], initcmd[PATH_MAX], testargs[PATH_MAX];
 	char cmdline[CMDLINE_MAX];
-	char **argv;
+	char *argv_strv[EXTRA_OPT_MAX + 64];
+	struct strv _cleanup_(strv_cleanup) argv = { argv_strv,
+							ARRAY_SIZE(argv_strv) };
 	int i, pos, status = 0;
 	pid_t pid;
 
@@ -533,7 +591,7 @@ static int start_qemu(void)
 		if (n < 0 || n >= len) {
 			fprintf(stderr, "Buffer overflow detected in "
 					"testargs\n");
-			exit(EXIT_FAILURE);
+			return EXIT_FAILURE;
 		}
 
 		pos += n;
@@ -558,66 +616,54 @@ static int start_qemu(void)
 				run_auto, audio_server ? audio_server : "",
 				testargs);
 
-	argv = alloca(sizeof(qemu_argv) +
-			(sizeof(char *) * (8 + (num_devs * 4))) +
-			(sizeof(char *) * (usb_dev ? 4 : 0)) +
-			(sizeof(char *) * (pcie_dev ? 2 : 0)) +
-			(sizeof(char *) * num_extra_opts));
-	memcpy(argv, qemu_argv, sizeof(qemu_argv));
-
-	pos = (sizeof(qemu_argv) / sizeof(char *)) - 1;
-
 	/* Make sure qemu_binary is not null */
 	if (!qemu_binary) {
 		fprintf(stderr, "No QEMU binary is set\n");
-		exit(1);
+		return EXIT_FAILURE;
 	}
-	argv[0] = (char *) qemu_binary;
+
+	strv_append(&argv, "%s", qemu_binary);
+	strv_concat(&argv, qemu_argv);
 
 	if (qemu_host_cpu) {
-		argv[pos++] = "-cpu";
-		argv[pos++] = "host";
+		strv_append(&argv, "-cpu");
+		strv_append(&argv, "host");
 	}
 
-	argv[pos++] = "-kernel";
-	argv[pos++] = (char *) kernel_image;
-	argv[pos++] = "-append";
-	argv[pos++] = (char *) cmdline;
+	strv_append(&argv, "-kernel");
+	strv_append(&argv, "%s", kernel_image);
+	strv_append(&argv, "-append");
+	strv_append(&argv, "%s", cmdline);
 
 	for (i = 0; i < num_devs; i++) {
-		char *chrdev, *serdev;
-
-		chrdev = alloca(48 + strlen(device_path));
-		sprintf(chrdev, "socket,path=%s,id=bt%d", device_path, i);
-
-		serdev = alloca(64);
-		sprintf(serdev, "virtconsole,chardev=bt%d,name=bt.%d", i, i);
-
-		argv[pos++] = "-chardev";
-		argv[pos++] = chrdev;
-		argv[pos++] = "-device";
-		argv[pos++] = serdev;
+		strv_append(&argv, "-chardev");
+		strv_append(&argv, "socket,path=%s,id=bt%d", device_path, i);
+		strv_append(&argv, "-device");
+		strv_append(&argv, "virtconsole,chardev=bt%d,name=bt.%d", i, i);
 	}
 
 	if (usb_dev) {
-		argv[pos++] = "-device";
-		argv[pos++] = "qemu-xhci";
-		argv[pos++] = "-device";
-		argv[pos++] = usb_dev;
+		strv_append(&argv, "-device");
+		strv_append(&argv, "qemu-xhci");
+		strv_append(&argv, "-device");
+		strv_append(&argv, "%s", usb_dev);
 	}
 
 	if (pcie_dev) {
-		argv[pos++] = "-device";
-		argv[pos++] = pcie_dev;
+		strv_append(&argv, "-device");
+		strv_append(&argv, "%s", pcie_dev);
 	}
 
 	for (i = 0; i < num_extra_opts; ++i)
-		argv[pos++] = extra_opts[i];
+		strv_append(&argv, "%s", extra_opts[i]);
 
-	argv[pos] = NULL;
+	if (STRV_ERROR(argv)) {
+		fprintf(stderr, "Failed to build argument list\n");
+		return EXIT_FAILURE;
+	}
 
 	if (!pcie_dev) {
-		execve(argv[0], argv, qemu_envp);
+		execve(argv.strv[0], argv.strv, qemu_envp);
 		return EXIT_FAILURE;
 	}
 
@@ -635,7 +681,7 @@ static int start_qemu(void)
 	}
 
 	if (pid == 0) {
-		execve(argv[0], argv, qemu_envp);
+		execve(argv.strv[0], argv.strv, qemu_envp);
 		exit(EXIT_FAILURE);
 	}
 
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH BlueZ v2 2/4] doc: enable virtio-fs in tester kernel configs
  2026-09-12 18:18 [PATCH BlueZ v2 0/4] test-runner: use virtio-fs by default, functional test speedup Pauli Virtanen
  2026-09-12 18:18 ` [PATCH BlueZ v2 1/4] tools/test-runner: replace alloca() based argv setup Pauli Virtanen
@ 2026-09-12 18:18 ` Pauli Virtanen
  2026-09-12 18:18 ` [PATCH BlueZ v2 3/4] tools/test-runner: use virtiofsd for filesystem passthrough Pauli Virtanen
  2026-09-12 18:18 ` [PATCH BlueZ v2 4/4] tools/test-runner: Fix CPUID register clobbers Pauli Virtanen
  3 siblings, 0 replies; 6+ messages in thread
From: Pauli Virtanen @ 2026-09-12 18:18 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Pauli Virtanen

Add support for virtio-fs in tester configs.
---
 doc/ci.config     | 2 ++
 doc/tester.config | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/doc/ci.config b/doc/ci.config
index 2da3e14c4..99d59c5d3 100644
--- a/doc/ci.config
+++ b/doc/ci.config
@@ -7,6 +7,8 @@
 CONFIG_VIRTIO=y
 CONFIG_VIRTIO_PCI=y
 CONFIG_VIRTIO_CONSOLE=y
+CONFIG_VIRTIO_FS=y
+CONFIG_FUSE_FS=y
 
 CONFIG_HYPERVISOR_GUEST=y
 CONFIG_PARAVIRT=y
diff --git a/doc/tester.config b/doc/tester.config
index b9c5f34bc..e68740dc0 100644
--- a/doc/tester.config
+++ b/doc/tester.config
@@ -2,6 +2,8 @@ CONFIG_PCI=y
 CONFIG_VIRTIO=y
 CONFIG_VIRTIO_PCI=y
 CONFIG_VIRTIO_CONSOLE=y
+CONFIG_VIRTIO_FS=y
+CONFIG_FUSE_FS=y
 
 CONFIG_HYPERVISOR_GUEST=y
 CONFIG_PARAVIRT=y
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH BlueZ v2 3/4] tools/test-runner: use virtiofsd for filesystem passthrough
  2026-09-12 18:18 [PATCH BlueZ v2 0/4] test-runner: use virtio-fs by default, functional test speedup Pauli Virtanen
  2026-09-12 18:18 ` [PATCH BlueZ v2 1/4] tools/test-runner: replace alloca() based argv setup Pauli Virtanen
  2026-09-12 18:18 ` [PATCH BlueZ v2 2/4] doc: enable virtio-fs in tester kernel configs Pauli Virtanen
@ 2026-09-12 18:18 ` Pauli Virtanen
  2026-09-12 18:18 ` [PATCH BlueZ v2 4/4] tools/test-runner: Fix CPUID register clobbers Pauli Virtanen
  3 siblings, 0 replies; 6+ messages in thread
From: Pauli Virtanen @ 2026-09-12 18:18 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Pauli Virtanen

The 9p mount passthrough I/O is fairly CPU hungry and slow. This matters
for e.g. running Python in test-runner, since it has to read some amount
of files for startup.

Add support for virtio-fs, which is significantly less CPU intensive.

Enable it by default if /usr/libexec/virtiofsd is available, fall back
to 9p if virtiofsd not usable.

Before:
$ time make check-functional
real	2m9,736s
user	1m29,570s
sys	0m32,715s

After:
$ time make check-functional
real	1m35,703s
user	0m28,938s
sys	0m7,453s
---
 doc/test-runner.rst |  10 +-
 tools/test-runner.c | 233 +++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 227 insertions(+), 16 deletions(-)

diff --git a/doc/test-runner.rst b/doc/test-runner.rst
index 6787507c3..12f80df04 100644
--- a/doc/test-runner.rst
+++ b/doc/test-runner.rst
@@ -8,8 +8,8 @@ DESCRIPTION
 ===========
 
 **test-runner(1)** is used to test Kernel changes to the Bluetooth subsystem,
-it launches a virtual machine using qemu(1) and mounts the local filesystem
-using virtio (9p).
+it launches a virtual machine using qemu(1) with the host filesystem mounted
+read-only inside the guest.
 
 OPTIONS
 =======
@@ -26,6 +26,7 @@ OPTIONS
 :-P/--pcie=<qemu_args>: Provide PCIe device
 :-q/--qemu=<path>: QEMU binary
 :-k/--kernel=<image>: Kernel image (bzImage)
+:-F/--virtiofs[=<path>]: Path to virtiofsd, or no to disable virtio-fs
 :-h/--help: Show help options
 
 Kernel
@@ -47,6 +48,8 @@ option (like the Bluetooth subsystem) can be enabled on top of this.
 	CONFIG_VIRTIO=y
 	CONFIG_VIRTIO_PCI=y
 	CONFIG_VIRTIO_CONSOLE=y
+	CONFIG_VIRTIO_FS=y
+	CONFIG_FUSE_FS=y
 
 	CONFIG_NET=y
 	CONFIG_INET=y
@@ -69,6 +72,9 @@ option (like the Bluetooth subsystem) can be enabled on top of this.
 	CONFIG_DEVTMPFS=y
 	CONFIG_DEBUG_FS=y
 
+Filesystem passthrough uses virtio-fs when ``virtiofsd`` is installed on the
+host, otherwise 9p. Use ``-Fno`` for kernels without ``CONFIG_VIRTIO_FS``.
+
 Bluetooth
 ---------
 
diff --git a/tools/test-runner.c b/tools/test-runner.c
index a0ac321ca..9eaf39d35 100644
--- a/tools/test-runner.c
+++ b/tools/test-runner.c
@@ -69,6 +69,7 @@ static char *usb_dev;
 static char *pcie_dev;
 static char *extra_opts[EXTRA_OPT_MAX];
 static int num_extra_opts;
+static const char *virtiofsd = "/usr/libexec/virtiofsd";
 
 struct strv {
 	char **strv;
@@ -291,9 +292,6 @@ static const char *const qemu_argv[] = {
 	"-m", "256M",
 	"-net", "none",
 	"-no-reboot",
-	"-fsdev", "local,id=fsdev-root,path=/,readonly=on,security_model=none,"
-	"multidevs=remap",
-	"-device", "virtio-9p-pci,fsdev=fsdev-root,mount_tag=/dev/root",
 	"-chardev", "stdio,id=con,mux=on",
 	"-serial", "chardev:con",
 	"-device", "virtio-serial",
@@ -551,6 +549,183 @@ static void pcie_unbind_vfio(void)
 	pcie_probe(pcie_bdf);
 }
 
+static bool check_virtiofsd(void)
+{
+	if (!virtiofsd)
+		return false;
+
+	if (access(virtiofsd, X_OK)) {
+		fprintf(stderr, "%s not available: virtiofs disabled\n",
+								virtiofsd);
+		return false;
+	}
+
+	return true;
+}
+
+struct rootfs {
+	char tmpdir[PATH_MAX - 16];
+	pid_t pid;
+};
+
+static volatile sig_atomic_t terminate;
+
+static void terminate_signal(int sig)
+{
+	terminate = 1;
+}
+
+static bool rootfs_setup(struct rootfs *r, struct strv *argv)
+{
+	const char *mem = "256M";
+	size_t i;
+
+	memset(r, 0, sizeof(*r));
+
+	if (!virtiofsd) {
+		strv_append(argv, "-fsdev");
+		strv_append(argv, "local,id=fsdev-root,path=/,readonly=on,"
+					"security_model=none,multidevs=remap");
+		strv_append(argv, "-device");
+		strv_append(argv, "virtio-9p-pci,fsdev=fsdev-root,"
+							"mount_tag=/dev/root");
+		return true;
+	}
+
+	/* Make sure to clean up the tmpdir always on SIGINT */
+	signal(SIGINT, terminate_signal);
+	signal(SIGTERM, terminate_signal);
+	signal(SIGHUP, terminate_signal);
+
+	snprintf(r->tmpdir, ARRAY_SIZE(r->tmpdir),
+					"/tmp/bluez-test-runner.XXXXXX");
+	if (!mkdtemp(r->tmpdir)) {
+		perror("mkdtemp failed");
+		return false;
+	}
+
+	strv_append(argv, "-chardev");
+	strv_append(argv, "socket,id=virtiofs0,path=%s/virtiofs", r->tmpdir);
+	strv_append(argv, "-device");
+	strv_append(argv, "vhost-user-fs-pci,queue-size=1024,"
+					"chardev=virtiofs0,tag=/dev/root");
+
+	/* Find out memory size */
+	for (i = 0; i + 1 < argv->i; ++i) {
+		if (strcmp(argv->strv[i], "-m") == 0)
+			mem = argv->strv[i+1];
+	}
+	for (i = 0; i + 1 < (size_t)num_extra_opts; ++i) {
+		if (strcmp(extra_opts[i], "-m") == 0)
+			mem = extra_opts[i+1];
+	}
+	if (!mem[0] || !strchr("kKmMgGtT", mem[strlen(mem) - 1])) {
+		fprintf(stderr, "Can't parse -m %s for virtiofs\n", mem);
+		return false;
+	}
+
+	strv_append(argv, "-object");
+	strv_append(argv, "memory-backend-memfd,id=mem0,size=%s,share=on", mem);
+	strv_append(argv, "-numa");
+	strv_append(argv, "node,memdev=mem0");
+
+	return true;
+}
+
+static bool rootfs_start(struct rootfs *r)
+{
+	pid_t pid;
+	char path[PATH_MAX];
+	struct stat st;
+
+	if (!virtiofsd)
+		return true;
+
+	printf("Using virtiofsd %s\n", virtiofsd);
+
+	snprintf(path, sizeof(path), "%s/virtiofs", r->tmpdir);
+
+	pid = fork();
+	if (pid < 0) {
+		perror("fork");
+		return false;
+	}
+
+	if (pid == 0) {
+		char *envp[1];
+		const char *cmd[] = {
+			virtiofsd,
+			"--socket-path", path,
+			"--shared-dir", "/",
+			"--readonly",
+			"--tag", "/dev/root",
+			/* Drop unnecessary capabilities, if run as root */
+			"--modcaps=-chown:-dac_override:-fowner:-fsetid:"
+					"-setgid:-setuid:-mknod:-setfcap",
+			/*
+			 * Disabling namespace sandbox is needed to allow the
+			 * guest to mount other virtio/9p filesystems.
+			 */
+			"--sandbox", "none",
+			NULL
+		};
+
+		envp[0] = NULL;
+		execve(cmd[0], (char **)cmd, envp);
+		exit(EXIT_FAILURE);
+	}
+
+	r->pid = pid;
+
+	while (!terminate) {
+		int status;
+		pid_t ret;
+
+		if (!stat(path, &st))
+			break;
+
+		ret = waitpid(pid, &status, WNOHANG);
+		if (ret < 0 && errno == EINTR) {
+			continue;
+		} else if (ret < 0) {
+			perror("waitpid");
+			return false;
+		} else if (ret) {
+			fprintf(stderr, "%s failed to start\n", virtiofsd);
+			r->pid = 0;
+			return false;
+		}
+
+		sleep(1);
+	}
+
+	return !terminate;
+}
+
+static void rootfs_cleanup(struct rootfs *r)
+{
+	char path[PATH_MAX];
+	int status;
+
+	if (r->pid > 0) {
+		kill(r->pid, SIGTERM);
+		while (waitpid(r->pid, &status, 0) < 0) {
+			if (errno != EINTR)
+				break;
+		}
+	}
+
+	if (r->tmpdir[0]) {
+		snprintf(path, sizeof(path), "%s/virtiofs", r->tmpdir);
+		unlink(path);
+		snprintf(path, sizeof(path), "%s/virtiofs.pid", r->tmpdir);
+		unlink(path);
+		rmdir(r->tmpdir);
+	}
+
+	memset(r, 0, sizeof(*r));
+}
+
 static pid_t qemu_pid;
 
 /* Forwards the signal to QEMU so it can shutdown, the host driver is then
@@ -565,10 +740,12 @@ static void qemu_signal(int sig)
 static int start_qemu(void)
 {
 	char cwd[PATH_MAX/2], initcmd[PATH_MAX], testargs[PATH_MAX];
+	const char *fscmdline;
 	char cmdline[CMDLINE_MAX];
 	char *argv_strv[EXTRA_OPT_MAX + 64];
 	struct strv _cleanup_(strv_cleanup) argv = { argv_strv,
 							ARRAY_SIZE(argv_strv) };
+	struct rootfs _cleanup_(rootfs_cleanup) rootfs = {{0}};
 	int i, pos, status = 0;
 	pid_t pid;
 
@@ -597,15 +774,20 @@ static int start_qemu(void)
 		pos += n;
 	}
 
+	if (!virtiofsd)
+		fscmdline = "rootfstype=9p "
+				"rootflags=trans=virtio,version=9p2000.u";
+	else
+		fscmdline = "rootfstype=virtiofs root=/dev/root";
+
 	snprintf(cmdline, sizeof(cmdline),
 				"console=hvc0 earlyprintk=serial "
-				"no_hash_pointers=1 rootfstype=9p "
-				"rootflags=trans=virtio,version=9p2000.u "
-				"%s quiet ro init=%s "
+				"no_hash_pointers=1 %s %s quiet ro init=%s "
 				"TESTHOME=%s TESTDBUS=%u TESTDAEMON=%u "
 				"TESTDBUSSESSION=%u XDG_RUNTIME_DIR=/run/user/0 "
 				"TESTMONITOR=%u TESTEMULATOR=%u TESTDEVS=%d "
 				"TESTAUTO=%u TESTAUDIO='%s' TESTARGS=\'%s\'",
+				fscmdline,
 				/* PCIe passthrough requires ACPI and APIC for
 				 * device enumeration and MSI interrupts.
 				 */
@@ -654,6 +836,9 @@ static int start_qemu(void)
 		strv_append(&argv, "%s", pcie_dev);
 	}
 
+	if (!rootfs_setup(&rootfs, &argv))
+		return EXIT_FAILURE;
+
 	for (i = 0; i < num_extra_opts; ++i)
 		strv_append(&argv, "%s", extra_opts[i]);
 
@@ -662,16 +847,17 @@ static int start_qemu(void)
 		return EXIT_FAILURE;
 	}
 
-	if (!pcie_dev) {
+	if (!rootfs_start(&rootfs))
+		return EXIT_FAILURE;
+
+	/* Exec directly if no setup/cleanup needed */
+	if (!pcie_dev && !rootfs.pid) {
 		execve(argv.strv[0], argv.strv, qemu_envp);
 		return EXIT_FAILURE;
 	}
 
-	/* With a device passed through the host driver has to be restored
-	 * once the guest is done with it, so QEMU cannot simply replace this
-	 * process here.
-	 */
-	pcie_bind_vfio();
+	if (pcie_dev)
+		pcie_bind_vfio();
 
 	pid = fork();
 	if (pid < 0) {
@@ -694,6 +880,9 @@ static int start_qemu(void)
 	signal(SIGTERM, qemu_signal);
 	signal(SIGHUP, qemu_signal);
 
+	if (terminate)
+		kill(qemu_pid, SIGTERM);
+
 	while (waitpid(pid, &status, 0) < 0) {
 		if (errno != EINTR)
 			break;
@@ -701,7 +890,8 @@ static int start_qemu(void)
 
 	qemu_pid = -1;
 
-	pcie_unbind_vfio();
+	if (pcie_dev)
+		pcie_unbind_vfio();
 
 	return WIFEXITED(status) ? WEXITSTATUS(status) : EXIT_FAILURE;
 }
@@ -1570,6 +1760,7 @@ static void usage(void)
 		"\t-q, --qemu <path>      QEMU binary\n"
 		"\t-H, --qemu-host-cpu    Use host CPU (requires KVM support)\n"
 		"\t-k, --kernel <image>   Kernel bzImage or source tree path\n"
+		"\t-F, --virtiofs[=<path>]  Virtiofsd path or 'no'\n"
 		"\t-o, --option <opt>     Additional argument passed to QEMU\n"
 		"\t-h, --help             Show help options\n");
 }
@@ -1590,6 +1781,7 @@ static const struct option main_options[] = {
 	{ "usb",     required_argument, NULL, 'U' },
 	{ "pcie",    required_argument, NULL, 'P' },
 	{ "option",  required_argument, NULL, 'o' },
+	{ "virtiofs", optional_argument, NULL, 'F' },
 	{ "version", no_argument,       NULL, 'v' },
 	{ "help",    no_argument,       NULL, 'h' },
 	{ }
@@ -1598,6 +1790,7 @@ static const struct option main_options[] = {
 int main(int argc, char *argv[])
 {
 	char kernel_path[PATH_MAX];
+	bool virtiofs_auto = true;
 
 	if (getpid() == 1 && getppid() == 0) {
 		prepare_sandbox();
@@ -1611,7 +1804,7 @@ int main(int argc, char *argv[])
 	for (;;) {
 		int opt;
 
-		opt = getopt_long(argc, argv, "au::bdsl::mq:Hk:A::U:P:o:vh",
+		opt = getopt_long(argc, argv, "au::bdsl::mq:Hk:A::U:P:o:F::vh",
 						main_options, NULL);
 		if (opt < 0)
 			break;
@@ -1666,6 +1859,15 @@ int main(int argc, char *argv[])
 			}
 			extra_opts[num_extra_opts++] = optarg;
 			break;
+		case 'F':
+			virtiofs_auto = false;
+			if (optarg) {
+				if (strcmp(optarg, "no") == 0)
+					virtiofsd = NULL;
+				else
+					virtiofsd = optarg;
+			}
+			break;
 		case 'v':
 			printf("%s\n", VERSION);
 			return EXIT_SUCCESS;
@@ -1677,6 +1879,9 @@ int main(int argc, char *argv[])
 		}
 	}
 
+	if (virtiofs_auto && !check_virtiofsd())
+		virtiofsd = NULL;
+
 	if (run_auto) {
 		if (argc - optind > 0) {
 			fprintf(stderr, "Invalid command line parameters\n");
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH BlueZ v2 4/4] tools/test-runner: Fix CPUID register clobbers
  2026-09-12 18:18 [PATCH BlueZ v2 0/4] test-runner: use virtio-fs by default, functional test speedup Pauli Virtanen
                   ` (2 preceding siblings ...)
  2026-09-12 18:18 ` [PATCH BlueZ v2 3/4] tools/test-runner: use virtiofsd for filesystem passthrough Pauli Virtanen
@ 2026-09-12 18:18 ` Pauli Virtanen
  3 siblings, 0 replies; 6+ messages in thread
From: Pauli Virtanen @ 2026-09-12 18:18 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Pauli Virtanen

CPUID modifies EAX, EBX, ECX and EDX, but the inline asm clobber list is
incomplete.  Use the __get_cpuid() intrinsic instead.

Fixes rootfs_setup(r, argv) crashing due to impossible r != &rootfs due
to clobbered registers.

Assisted-by: qwen3.8-flash-next  # finding the bug
---
 tools/test-runner.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/tools/test-runner.c b/tools/test-runner.c
index 9eaf39d35..2de05e26d 100644
--- a/tools/test-runner.c
+++ b/tools/test-runner.c
@@ -33,6 +33,11 @@
 #include <sys/param.h>
 #include <sys/reboot.h>
 
+#if defined(__GNUC__) && (defined(__i386__) || defined(__amd64__))
+#include <cpuid.h>
+#define HAVE_GET_CPUID
+#endif
+
 #include "bluetooth/bluetooth.h"
 #include "bluetooth/hci.h"
 #include "bluetooth/hci_lib.h"
@@ -306,12 +311,10 @@ static char *const qemu_envp[] = {
 
 static void check_virtualization(void)
 {
-#if defined(__GNUC__) && (defined(__i386__) || defined(__amd64__))
-	uint32_t ecx;
+#ifdef HAVE_GET_CPUID
+	unsigned int eax, ebx, ecx, edx;
 
-	__asm__ __volatile__("cpuid" : "=c" (ecx) : "a" (1) : "memory");
-
-	if (!!(ecx & (1 << 5)))
+	if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) && (ecx & (1 << 5)))
 		printf("Found support for Virtual Machine eXtensions\n");
 #endif
 }
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* RE: test-runner: use virtio-fs by default, functional test speedup
  2026-09-12 18:18 ` [PATCH BlueZ v2 1/4] tools/test-runner: replace alloca() based argv setup Pauli Virtanen
@ 2026-09-12 19:17   ` bluez.test.bot
  0 siblings, 0 replies; 6+ messages in thread
From: bluez.test.bot @ 2026-09-12 19:17 UTC (permalink / raw)
  To: linux-bluetooth, pav

[-- Attachment #1: Type: text/plain, Size: 3496 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/series/1163573/

---Test result---

Test Summary:
CheckPatch                    FAIL      2.15 seconds
GitLint                       FAIL      1.33 seconds
BuildEll                      PASS      19.81 seconds
BluezMake                     PASS      373.66 seconds
MakeCheck                     PASS      14.08 seconds
MakeDistcheck                 PASS      141.19 seconds
CheckValgrind                 PASS      237.21 seconds
CheckSmatch                   PASS      298.62 seconds
bluezmakeextell               PASS      97.14 seconds
IncrementalBuild              PASS      417.21 seconds
ScanBuild                     PASS      1131.54 seconds

Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[BlueZ,v2,1/4] tools/test-runner: replace alloca() based argv setup
WARNING:PREFER_DEFINED_ATTRIBUTE_MACRO: Prefer __printf(2, 3) over __attribute__((format(printf, 2, 3)))
#129: FILE: tools/test-runner.c:81:
+static void __attribute__((format(printf, 2, 3)))

/github/workspace/src/patch/14810752.patch total: 0 errors, 1 warnings, 202 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
      mechanically convert to the typical style using --fix or --fix-inplace.

/github/workspace/src/patch/14810752.patch has style problems, please review.

NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO

NOTE: If any of the errors are false positives, please report
      them to the maintainer, see CHECKPATCH in MAINTAINERS.


[BlueZ,v2,3/4] tools/test-runner: use virtiofsd for filesystem passthrough
WARNING:VOLATILE: Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst
#199: FILE: tools/test-runner.c:571:
+static volatile sig_atomic_t terminate;

WARNING:STATIC_CONST_CHAR_ARRAY: char * array declaration might be better as static const
#284: FILE: tools/test-runner.c:656:
+		const char *cmd[] = {

/github/workspace/src/patch/14810754.patch total: 0 errors, 2 warnings, 371 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
      mechanically convert to the typical style using --fix or --fix-inplace.

/github/workspace/src/patch/14810754.patch has style problems, please review.

NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO

NOTE: If any of the errors are false positives, please report
      them to the maintainer, see CHECKPATCH in MAINTAINERS.


##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[BlueZ,v2,3/4] tools/test-runner: use virtiofsd for filesystem passthrough

14: B3 Line contains hard tab characters (\t): "real	2m9,736s"
15: B3 Line contains hard tab characters (\t): "user	1m29,570s"
16: B3 Line contains hard tab characters (\t): "sys	0m32,715s"
20: B3 Line contains hard tab characters (\t): "real	1m35,703s"
21: B3 Line contains hard tab characters (\t): "user	0m28,938s"
22: B3 Line contains hard tab characters (\t): "sys	0m7,453s"


https://github.com/bluez/bluez/pull/2522

---
Regards,
Linux Bluetooth


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-09-12 19:17 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-12 18:18 [PATCH BlueZ v2 0/4] test-runner: use virtio-fs by default, functional test speedup Pauli Virtanen
2026-09-12 18:18 ` [PATCH BlueZ v2 1/4] tools/test-runner: replace alloca() based argv setup Pauli Virtanen
2026-09-12 19:17   ` test-runner: use virtio-fs by default, functional test speedup bluez.test.bot
2026-09-12 18:18 ` [PATCH BlueZ v2 2/4] doc: enable virtio-fs in tester kernel configs Pauli Virtanen
2026-09-12 18:18 ` [PATCH BlueZ v2 3/4] tools/test-runner: use virtiofsd for filesystem passthrough Pauli Virtanen
2026-09-12 18:18 ` [PATCH BlueZ v2 4/4] tools/test-runner: Fix CPUID register clobbers Pauli Virtanen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.