[PATCH 1/3] ioctl: add a stub for decoding vhost related ioctls

Daniel Cohen Hillel danielcohenhillel at gmail.com
Sat Oct 28 22:18:48 UTC 2023


* vhost.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* configure.ac (AC_CHECK_HEADERS): Add linux/vhost.h.
* defs.h (kvm_ioctl): New prototype.
* ioctl.c (ioctl_decode) HAVE_LINUX_VHOST_H]: Use vhost_ioctl.
---
 configure.ac    |  1 +
 src/Makefile.am |  1 +
 src/defs.h      |  1 +
 src/ioctl.c     |  4 ++++
 src/vhost.c     | 25 +++++++++++++++++++++++++
 5 files changed, 32 insertions(+)
 create mode 100644 src/vhost.c

diff --git a/configure.ac b/configure.ac
index 125f37208..0649c55f0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -467,6 +467,7 @@ AC_CHECK_HEADERS(m4_normalize([
 AC_CHECK_HEADERS(m4_normalize([
 	linux/ipc.h
 	linux/kvm.h
+	linux/vhost.h
 ]),,, [AC_INCLUDES_DEFAULT
 #include <linux/types.h>
 ])
diff --git a/src/Makefile.am b/src/Makefile.am
index 6bd12eb60..098479f22 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -395,6 +395,7 @@ libstrace_a_SOURCES =	\
 	utime.c		\
 	utimes.c	\
 	v4l2.c		\
+	vhost.c		\
 	wait.c		\
 	wait.h		\
 	watchdog_ioctl.c \
diff --git a/src/defs.h b/src/defs.h
index 811d2d850..27d2105d3 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -1447,6 +1447,7 @@ DECL_IOCTL(tee);
 DECL_IOCTL(term);
 DECL_IOCTL(ubi);
 DECL_IOCTL(uffdio);
+DECL_IOCTL(vhost);
 DECL_IOCTL(watchdog);
 # undef DECL_IOCTL
 
diff --git a/src/ioctl.c b/src/ioctl.c
index fc6cef933..58635df6d 100644
--- a/src/ioctl.c
+++ b/src/ioctl.c
@@ -425,6 +425,10 @@ ioctl_decode(struct tcb *tcp, const struct finfo *finfo)
 #ifdef HAVE_LINUX_KVM_H
 	case 0xae:
 		return kvm_ioctl(tcp, code, arg);
+#endif
+#ifdef HAVE_LINUX_VHOST_H
+	case 0xaf:
+		return vhost_ioctl(tcp, code, arg);
 #endif
 	case 0xb4:
 		return gpio_ioctl(tcp, code, arg);
diff --git a/src/vhost.c b/src/vhost.c
new file mode 100644
index 000000000..5df77e039
--- /dev/null
+++ b/src/vhost.c
@@ -0,0 +1,25 @@
+/*
+ * Support for decoding of VHOST_* ioctl commands.
+ *
+ * Copyright (c) 2023 Daniel Cohen Hillel <danielcohenhillel at gmail.com>
+ * Copyright (c) 2023 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "defs.h"
+
+#ifdef HAVE_LINUX_VHOST_H
+# include <linux/vhost.h>
+
+int
+vhost_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg)
+{
+	switch (code) {
+	default:
+		return RVAL_DECODED;
+	}
+}
+
+#endif /* HAVE_LINUX_VHOST_H */
\ No newline at end of file
-- 
2.34.1


>From 9f676521f92249ff58a6747f97735e0edbf5ef07 Mon Sep 17 00:00:00 2001
From: Daniel Cohen Hillel <danielcohenhillel at gmail.com>
Date: Sun, 22 Oct 2023 03:30:10 +0300
Subject: [PATCH 2/3] vhost: decode arguments of various VHOST_* ioctls

* configure.ac (AC_CHECK_TYPES): Add structs under `linux/vhost_types.h`:
          	struct vhost_vring_file,
	        struct vhost_vring_state,
	        struct vhost_vring_addr,
	        struct vhost_memory,
	        struct vhost_memory_region
* xlat/vhost_vring_flags.in: New file.
* vhost.c:
 [HAVE_STRUCT_VHOST_VRING_FILE]: vhost_ioctl_decode_vring_file: New function.
 [HAVE_STRUCT_VHOST_VRING_STATE]: vhost_ioctl_decode_vring_state: New function.
 [HAVE_STRUCT_VHOST_VRING_ADDR]:
     include "xlat/vhost_vring_flags.h"
     and vhost_ioctl_decode_vring_set_addr: New function.
 [HAVE_STRUCT_VHOST_MEMORY, HAVE_STRUCT_VHOST_MEMORY_REGION]:
         print_vhost_memory_region, vhost_ioctl_decode_set_mem_table: New functions
(vhost_ioctl): Added new functions to the switch case (under correct ifdefs)
* List of new supported ioctls:
    - VHOST_SET_VRING_KICK
    - VHOST_SET_VRING_CALL
    - VHOST_SET_VRING_ERR
    - VHOST_NET_SET_BACKEND
    - VHOST_SET_VRING_NUM
    - VHOST_SET_VRING_BASE
    - VHOST_GET_VRING_BASE
    - VHOST_SET_VRING_ENDIAN
    - VHOST_GET_VRING_ENDIAN
    - VHOST_SET_VRING_BUSYLOOP_TIMEOUT
    - VHOST_GET_VRING_BUSYLOOP_TIMEOUT
    - VHOST_VDPA_SET_VRING_ENABLE
    - VHOST_SET_VRING_ADDR
    - VHOST_SET_MEM_TABLE
---
 configure.ac                  |   8 ++
 src/vhost.c                   | 180 ++++++++++++++++++++++++++++++++++
 src/xlat/vhost_vring_flags.in |   1 +
 3 files changed, 189 insertions(+)
 create mode 100644 src/xlat/vhost_vring_flags.in

diff --git a/configure.ac b/configure.ac
index 0649c55f0..73da08ae2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -546,6 +546,14 @@ AC_CHECK_TYPES(m4_normalize([
 	struct kvm_ioeventfd
 ]),,, [#include <linux/kvm.h>])
 
+AC_CHECK_TYPES(m4_normalize([
+	struct vhost_vring_file,
+	struct vhost_vring_state,
+	struct vhost_vring_addr,
+	struct vhost_memory,
+	struct vhost_memory_region
+]),,, [#include <linux/vhost_types.h>])
+
 AC_CHECK_TYPES(m4_normalize([
 	struct sockaddr_alg_new
 ]),,, [#include <netinet/in.h>
diff --git a/src/vhost.c b/src/vhost.c
index 5df77e039..b73d5ecac 100644
--- a/src/vhost.c
+++ b/src/vhost.c
@@ -13,10 +13,190 @@
 #ifdef HAVE_LINUX_VHOST_H
 # include <linux/vhost.h>
 
+# ifdef HAVE_STRUCT_VHOST_VRING_FILE
+static int
+vhost_ioctl_decode_vring_file(struct tcb *const tcp, const unsigned int code,
+		       const kernel_ulong_t arg)
+{
+    struct vhost_vring_file f;
+
+	tprint_arg_next();
+
+	if (umove_or_printaddr(tcp, arg, &f))
+		return RVAL_IOCTL_DECODED;
+
+	tprint_struct_begin();
+
+	PRINT_FIELD_U(f, index);
+	tprint_struct_next();
+	PRINT_FIELD_FD(f, fd, tcp);
+
+	tprint_struct_end();
+
+	return RVAL_IOCTL_DECODED;
+}
+# endif /* HAVE_STRUCT_VHOST_VRING_FILE */
+
+# ifdef HAVE_STRUCT_VHOST_VRING_STATE
+static int
+vhost_ioctl_decode_vring_state(struct tcb *const tcp, const unsigned int code,
+		       const kernel_ulong_t arg)
+{
+    struct vhost_vring_state s;
+
+    if (entering(tcp) && (
+           code == VHOST_GET_VRING_BASE
+        || code == VHOST_GET_VRING_ENDIAN
+        || code == VHOST_GET_VRING_BUSYLOOP_TIMEOUT)) {
+            return 0;
+    }
+
+	tprint_arg_next();
+
+	if (umove_or_printaddr(tcp, arg, &s))
+		return RVAL_IOCTL_DECODED;
+
+	tprint_struct_begin();
+
+	PRINT_FIELD_U(s, index);
+	tprint_struct_next();
+	PRINT_FIELD_U(s, num);
+
+	tprint_struct_end();
+
+	return RVAL_IOCTL_DECODED;
+}
+# endif /* HAVE_STRUCT_VHOST_VRING_STATE */
+
+# ifdef HAVE_STRUCT_VHOST_VRING_ADDR
+#  include "xlat/vhost_vring_flags.h"
+static int
+vhost_ioctl_decode_vring_set_addr(struct tcb *const tcp, const unsigned int code,
+		       const kernel_ulong_t arg)
+{
+    struct vhost_vring_addr addr;
+
+	tprint_arg_next();
+
+	if (umove_or_printaddr(tcp, arg, &addr))
+		return RVAL_IOCTL_DECODED;
+
+	tprint_struct_begin();
+
+	PRINT_FIELD_U(addr, index);
+	tprint_struct_next();
+	PRINT_FIELD_FLAGS(addr, flags, vhost_vring_flags, "VHOST_VRING_F_???");
+	tprint_struct_next();
+	PRINT_FIELD_X(addr, desc_user_addr);
+	tprint_struct_next();
+	PRINT_FIELD_X(addr, used_user_addr);
+	tprint_struct_next();
+	PRINT_FIELD_X(addr, avail_user_addr);
+    if (addr.flags & VHOST_VRING_F_LOG) {
+        tprint_struct_next();
+        PRINT_FIELD_X(addr, log_guest_addr);
+    }
+
+	tprint_struct_end();
+
+	return RVAL_IOCTL_DECODED;
+}
+# endif /* HAVE_STRUCT_VHOST_VRING_ADDR */
+
+# ifdef HAVE_STRUCT_VHOST_MEMORY
+# ifdef HAVE_STRUCT_VHOST_MEMORY_REGION
+static bool
+print_vhost_memory_region(struct tcb *const tcp,
+		      void* elem_buf, size_t elem_size, void* data)
+{
+	struct vhost_memory_region region = *((struct vhost_memory_region *)elem_buf);
+
+	tprint_struct_begin();
+
+	PRINT_FIELD_X(region, guest_phys_addr);
+	tprint_struct_next();
+	PRINT_FIELD_U(region, memory_size);
+	tprint_struct_next();
+	PRINT_FIELD_X(region, userspace_addr);
+
+    // No flags currently specified
+    if (region.flags_padding != 0) {
+        tprint_struct_next();
+        PRINT_FIELD_X(region, flags_padding);
+    }
+
+	tprint_struct_end();
+
+	return true;
+}
+
+static int
+vhost_ioctl_decode_set_mem_table(struct tcb *const tcp, const unsigned int code,
+		       const kernel_ulong_t arg)
+{
+	struct vhost_memory vhost_memory_hdr;
+
+	tprint_arg_next();
+
+	if (umove_or_printaddr(tcp, arg, &vhost_memory_hdr))
+		return RVAL_IOCTL_DECODED;
+
+	tprint_struct_begin();
+
+	PRINT_FIELD_U(vhost_memory_hdr, nregions);
+	tprint_struct_next();
+
+	if (abbrev(tcp)) {
+		tprint_array_begin();
+		if (vhost_memory_hdr.nregions)
+			tprint_more_data_follows();
+		tprint_array_end();
+	} else {
+		struct vhost_memory_region region;
+		print_array(tcp, arg + sizeof(vhost_memory_hdr), vhost_memory_hdr.nregions,
+			&region, sizeof(region), tfetch_mem,
+			print_vhost_memory_region, NULL);
+	}
+
+	tprint_struct_end();
+
+	return RVAL_IOCTL_DECODED;
+}
+# endif /* HAVE_STRUCT_VHOST_MEMORY */
+# endif /* HAVE_STRUCT_VHOST_MEMORY_REGION */
+
 int
 vhost_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg)
 {
 	switch (code) {
+    # ifdef HAVE_STRUCT_VHOST_VRING_FILE
+    case VHOST_SET_VRING_KICK:
+    case VHOST_SET_VRING_CALL:
+    case VHOST_SET_VRING_ERR:
+    case VHOST_NET_SET_BACKEND:
+        return vhost_ioctl_decode_vring_file(tcp, code, arg);
+    # endif
+    # ifdef HAVE_STRUCT_VHOST_VRING_STATE
+    case VHOST_SET_VRING_NUM:
+    case VHOST_SET_VRING_BASE:
+    case VHOST_GET_VRING_BASE:
+    case VHOST_SET_VRING_ENDIAN:
+    case VHOST_GET_VRING_ENDIAN:
+    case VHOST_SET_VRING_BUSYLOOP_TIMEOUT:
+    case VHOST_GET_VRING_BUSYLOOP_TIMEOUT:
+    case VHOST_VDPA_SET_VRING_ENABLE:
+        return vhost_ioctl_decode_vring_state(tcp, code, arg);
+    # endif
+    # ifdef HAVE_STRUCT_VHOST_VRING_STATE
+    case VHOST_SET_VRING_ADDR:
+        return vhost_ioctl_decode_vring_set_addr(tcp, code, arg);
+    # endif
+    # ifdef HAVE_STRUCT_VHOST_MEMORY
+    # ifdef HAVE_STRUCT_VHOST_MEMORY_REGION
+    case VHOST_SET_MEM_TABLE:
+        return vhost_ioctl_decode_set_mem_table(tcp, code, arg);
+    # endif
+    # endif
 	default:
 		return RVAL_DECODED;
 	}
diff --git a/src/xlat/vhost_vring_flags.in b/src/xlat/vhost_vring_flags.in
new file mode 100644
index 000000000..2be344666
--- /dev/null
+++ b/src/xlat/vhost_vring_flags.in
@@ -0,0 +1 @@
+VHOST_VRING_F_LOG   (1<<0)
\ No newline at end of file
-- 
2.34.1


>From e93d33f09bd7942622858cb762ca199103ee2145 Mon Sep 17 00:00:00 2001
From: Daniel Cohen Hillel <danielcohenhillel at gmail.com>
Date: Sun, 29 Oct 2023 01:09:00 +0300
Subject: [PATCH 3/3] tests: check decoding of VHOST_* ioctl commands

* tests/ioctl_vhost.c: New file.
* tests/ioctl_vhost.test: New test.
* tests/Makefile.am (DECODER_TESTS): Add ioctl_vhost.test.
* tests/pure_executables.list: Add ioctl_vhost.
* tests/.gitignore: Likewise.
---
 tests/.gitignore            |   1 +
 tests/Makefile.am           |   1 +
 tests/ioctl_vhost.c         | 165 ++++++++++++++++++++++++++++++++++++
 tests/ioctl_vhost.test      |  11 +++
 tests/pure_executables.list |   1 +
 5 files changed, 179 insertions(+)
 create mode 100644 tests/ioctl_vhost.c
 create mode 100755 tests/ioctl_vhost.test

diff --git a/tests/.gitignore b/tests/.gitignore
index e1553ac67..089fa3d72 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -413,6 +413,7 @@ ioctl_v4l2-v
 ioctl_v4l2-v-Xabbrev
 ioctl_v4l2-v-Xraw
 ioctl_v4l2-v-Xverbose
+ioctl_vhost
 ioctl_watchdog
 ioctl_winsize
 ioperm
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f885b7129..a0aa8f5c2 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -529,6 +529,7 @@ DECODER_TESTS = \
 	ioctl.test \
 	ioctl_block--pidns-translation.test \
 	ioctl_evdev-success.test \
+	ioctl_vhost.test \
 	ipc_msgbuf.test \
 	kern_features-fault.test \
 	llseek.test \
diff --git a/tests/ioctl_vhost.c b/tests/ioctl_vhost.c
new file mode 100644
index 000000000..8dc55addb
--- /dev/null
+++ b/tests/ioctl_vhost.c
@@ -0,0 +1,165 @@
+/*
+ * Test decoding of VHOST_* ioctl commands. Requires root.
+ *
+ * Copyright (c) 2023 Daniel Cohen Hillel <danielcohenhillel at gmail.com>
+ * Copyright (c) 2023 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "tests.h"
+
+#if defined HAVE_LINUX_VHOST_H				\
+ && defined HAVE_STRUCT_VHOST_VRING_FILE			\
+ && defined HAVE_STRUCT_VHOST_VRING_STATE			\
+ && defined HAVE_STRUCT_VHOST_VRING_ADDR	\
+ && defined HAVE_STRUCT_VHOST_MEMORY	\
+ && defined HAVE_STRUCT_VHOST_MEMORY_REGION
+ 
+# include <fcntl.h>
+# include <stdint.h>
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+# include <errno.h>
+# include <sched.h>
+# include <unistd.h>
+# include <sys/ioctl.h>
+# include <sys/mman.h>
+# include <sys/eventfd.h>
+# include <linux/errno.h>
+# include <linux/vhost.h>
+# include <linux/vhost_types.h>
+#include "pidns.h"
+#include "scno.h"
+
+static const char dev[] = "/dev/vhost-net";
+
+int test_vhost_state(int vhost_fd, unsigned long request, const char *request_str);
+int test_vhost_state(int vhost_fd, unsigned long request, const char *request_str)
+{
+	int ret;
+	struct vhost_vring_state state = {.index=0, .num=0x100};
+
+	ret = ioctl(vhost_fd, request, &state);
+	if (ret != 0)
+		error_msg_and_skip("%s returned %d", request_str, ret);
+
+	printf("ioctl(%d<%s>, %s, {index=%u, num=%u}) = %d\n", vhost_fd, dev, request_str, state.index, state.num, ret);
+	return ret;
+}
+#define TEST_VHOST_STATE(VHOST_FD, REQUEST) test_vhost_state(VHOST_FD, REQUEST, #REQUEST)
+
+int test_vhost_file(int vhost_fd, unsigned long request, const char *request_str);
+int test_vhost_file(int vhost_fd, unsigned long request, const char *request_str)
+{
+	int ret;
+	struct vhost_vring_file file;
+
+	file.index = 0;
+	file.fd = eventfd(0, EFD_CLOEXEC|EFD_NONBLOCK);
+
+	ret = ioctl(vhost_fd, request, &file);
+	if (ret != 0)
+		error_msg_and_skip("%s returned %d", request_str, ret);
+	close(file.fd);
+
+	printf("ioctl(%d<%s>, %s, {index=%u, fd=%d<anon_inode:[eventfd]>}) = %d\n", vhost_fd, dev, request_str, file.index, file.fd, ret);
+	return ret;
+}
+#define TEST_VHOST_FILE(VHOST_FD, REQUEST) test_vhost_file(VHOST_FD, REQUEST, #REQUEST)
+
+int test_vhost_vring_addr(int vhost_fd);
+int test_vhost_vring_addr(int vhost_fd)
+{
+	int ret;
+	struct vhost_vring_addr addr = {
+		.index=0,
+		.flags=0,
+		.desc_user_addr=0xdead0000,
+		.used_user_addr=0xbeef0000,
+		.avail_user_addr=0xcafe0000,
+		.log_guest_addr=0
+		};
+	ret = ioctl(vhost_fd, VHOST_SET_VRING_ADDR, &addr);
+	if (ret != 0)
+		error_msg_and_skip("VHOST_SET_VRING_ADDR returned %d", ret);
+
+	printf("ioctl(%d<%s>, VHOST_SET_VRING_ADDR, {index=%u, flags=0, desc_user_addr=%#llx, used_user_addr=%#llx, avail_user_addr=%#llx}) = %d\n",
+		vhost_fd, dev, addr.index, addr.desc_user_addr, addr.used_user_addr, addr.avail_user_addr, ret);
+	return ret;
+}
+
+int test_vhost_mem_table(int vhost_fd);
+int test_vhost_mem_table(int vhost_fd)
+{
+	int ret;
+	int mem_nregions;
+	struct vhost_memory *vhost_mem;
+	struct vhost_memory_region mem_region = {.guest_phys_addr=0, .memory_size=10, .userspace_addr=0xdacadebe};
+
+	mem_nregions = 1;
+	vhost_mem = malloc(sizeof(struct vhost_memory) + mem_nregions * sizeof(struct vhost_memory_region));
+
+	vhost_mem->nregions = mem_nregions;
+	vhost_mem->regions[0] = mem_region;
+
+	ret = ioctl(vhost_fd, VHOST_SET_MEM_TABLE, vhost_mem);
+	if (ret != 0) {
+		free(vhost_mem);
+		error_msg_and_skip("VHOST_SET_MEM_TABLE returned %d", ret);
+	}
+	printf("ioctl(%d<%s>, VHOST_SET_MEM_TABLE, {nregions=%d, [{guest_phys_addr=%#llx, memory_size=%lld, userspace_addr=%#llx}]}) = %d\n",
+		vhost_fd, dev, mem_nregions, mem_region.guest_phys_addr, mem_region.memory_size, mem_region.userspace_addr, ret);
+
+	free(vhost_mem);
+
+	return ret;
+}
+
+int
+main(void)
+{
+	skip_if_unavailable("/proc/self/fd/");
+
+	if (getuid() != 0 || getgid() != 0)
+		error_msg_and_skip("ioctl_vhost tests requires that you run as root");
+
+	int vhost = openat(AT_FDCWD, dev, O_RDWR);
+	if (vhost < 0)
+		perror_msg_and_skip("open: %s", dev);
+
+	int ret = ioctl(vhost, VHOST_SET_OWNER, 0);
+	if  (ret != 0)
+		error_msg_and_skip("VHOST_SET_OWNER returned %d", ret);
+	printf("ioctl(%d<%s>, VHOST_SET_OWNER, 0) = %d\n", vhost, dev, ret);
+
+
+	TEST_VHOST_FILE(vhost, VHOST_SET_VRING_CALL);
+	TEST_VHOST_FILE(vhost, VHOST_SET_VRING_ERR);
+	TEST_VHOST_FILE(vhost, VHOST_SET_VRING_KICK);
+	// Note: VHOST_NET_SET_BACKEND requires special treatment, so it isn't tested (but it's the same)
+
+	test_vhost_mem_table(vhost);
+
+	TEST_VHOST_STATE(vhost, VHOST_SET_VRING_NUM);
+	TEST_VHOST_STATE(vhost, VHOST_SET_VRING_BASE);
+	TEST_VHOST_STATE(vhost, VHOST_GET_VRING_BASE);
+	TEST_VHOST_STATE(vhost, VHOST_SET_VRING_BUSYLOOP_TIMEOUT);
+	TEST_VHOST_STATE(vhost, VHOST_GET_VRING_BUSYLOOP_TIMEOUT);
+	// Note: VHOST_SET_VRING_ENDIAN and VHOST_VDPA_SET_VRING_ENABLE don't work with vhost-net
+
+	test_vhost_vring_addr(vhost);
+
+	puts("+++ exited with 0 +++");
+	return 0;
+}
+
+#else /* !HAVE_LINUX_KVM_H */
+
+SKIP_MAIN_UNDEFINED("HAVE_LINUX_VHOST_H && HAVE_STRUCT_VHOST_VRING_FILE"
+    "HAVE_STRUCT_VHOST_VRING_STATE && HAVE_STRUCT_VHOST_VRING_ADDR"
+    "HAVE_STRUCT_VHOST_MEMORY && HAVE_STRUCT_VHOST_MEMORY_REGION")
+
+#endif
\ No newline at end of file
diff --git a/tests/ioctl_vhost.test b/tests/ioctl_vhost.test
new file mode 100755
index 000000000..f277b0afe
--- /dev/null
+++ b/tests/ioctl_vhost.test
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+# Check decoding of VHOST_* ioctl commands.
+
+. "${srcdir=.}/init.sh"
+
+check_prog grep
+run_prog > /dev/null
+run_strace --no-abbrev -a36 -y -eioctl $args > "$EXP"
+grep -v '^ioctl([012],' < "$LOG" > "$OUT"
+match_diff "$OUT" "$EXP"
\ No newline at end of file
diff --git a/tests/pure_executables.list b/tests/pure_executables.list
index a68e79ccd..8b3062106 100755
--- a/tests/pure_executables.list
+++ b/tests/pure_executables.list
@@ -267,6 +267,7 @@ ioctl_v4l2-v
 ioctl_v4l2-v-Xabbrev
 ioctl_v4l2-v-Xraw
 ioctl_v4l2-v-Xverbose
+ioctl_vhost
 ioctl_watchdog
 ioctl_winsize
 ioperm
-- 
2.34.1



More information about the Strace-devel mailing list