[PATCH 1/2] ioctl: add a stub for decoding vhost related ioctls
Daniel Cohen Hillel
danielcohenhillel at gmail.com
Sun Oct 22 00:43:55 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 2e85282a9547269fdf8df98609fbe83ef3084c03 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/2] 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..42f1aa1ec 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;
+
+ 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, &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;
+
+ 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,
+ ®ion, 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
More information about the Strace-devel
mailing list