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

Daniel Cohen Hillel danielcohenhillel at gmail.com
Sun Oct 22 00:52:09 UTC 2023


Hi,

I wasn't really sure how I should implement everything. Specifically, in
print_vhost_memory_region there's a flags_padding field, but currently,
there are no flags, so it's always zero. I still made it so that if the
flags are not zero they are printed as hex, just in case flags would be
added to the kernel before they are implemented in strace.

Thanks :)

On Sun, Oct 22, 2023 at 3:44 AM Daniel Cohen Hillel <
danielcohenhillel at gmail.com> wrote:

> * 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,
> +                       &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
>
>

-- 
Daniel Cohen Hillel    דניאל כהן הלל
ID: 212553804 :ת"ז
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20231022/28145653/attachment.htm>


More information about the Strace-devel mailing list