[PATCH v3 2/4] kvm: decode the argument for KVM_{SET, GET}_REGS ioctl command
Dmitry V. Levin
ldv at altlinux.org
Mon Dec 4 11:28:08 UTC 2017
On Mon, Dec 04, 2017 at 08:04:50PM +0900, Masatake YAMATO wrote:
> * configure.ac (AC_CHECK_TYPES): Add struct kvm_regs.
> * linux/arck_kvm.c: New file.
> * linux/x86_64/arch_kvm.c: New file.
> * linux/x32/arch_kvm.c: New files.
> * Makefile.am (EXTRA_DIST): Add the new files.
> * kvm.c Include "arch_kvm.c".
> (kvm_ioctl_decode_regs): New function.
> (kvm_ioctl) <KVM_SET_REGS, KVM_GET_REGS>: Use it.
>
> Changes in v2:
> * Decode only if struct kvm_regs is available.
> * Introduce files in which arch-specific and generic stub decoders
> are defined. Use them from kvm_ioctl_decode_regs.
> * Use umove_or_printaddr instead of umove.
>
> All items are suggested by ldv.
>
> Change in v3:
> * Don't check the existence of struct kvm_regs.
> We assume we can rely on struct kvm_regs being
> available. Suggested by ldv.
> * Add linux/x32/arch_kvm.c.
> * Add new files to EXTRA_DIST.
>
> All items are suggested by ldv.
>
> Signed-off-by: Masatake YAMATO <yamato at redhat.com>
> ---
> Makefile.am | 3 +++
> configure.ac | 5 ++++-
> kvm.c | 24 ++++++++++++++++++++++++
> linux/arch_kvm.c | 9 +++++++++
> linux/x32/arch_kvm.c | 1 +
> linux/x86_64/arch_kvm.c | 38 ++++++++++++++++++++++++++++++++++++++
> 6 files changed, 79 insertions(+), 1 deletion(-)
> create mode 100644 linux/arch_kvm.c
> create mode 100644 linux/x32/arch_kvm.c
> create mode 100644 linux/x86_64/arch_kvm.c
>
> diff --git a/Makefile.am b/Makefile.am
> index 60376056..cd78721e 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -426,6 +426,7 @@ EXTRA_DIST = \
> linux/arc/syscallent.h \
> linux/arch_regs.h \
> linux/arch_sigreturn.c \
> + linux/arch_kvm.c \
Please keep this list sorted.
> linux/arm/arch_regs.c \
> linux/arm/arch_regs.h \
> linux/arm/arch_rt_sigframe.c \
> @@ -807,6 +808,7 @@ EXTRA_DIST = \
> linux/userent0.h \
> linux/x32/arch_regs.c \
> linux/x32/arch_regs.h \
> + linux/x32/arch_kvm.c \
Likewise.
> linux/x32/arch_rt_sigframe.c \
> linux/x32/arch_sigreturn.c \
> linux/x32/errnoent1.h \
> @@ -826,6 +828,7 @@ EXTRA_DIST = \
> linux/x32/userent.h \
> linux/x86_64/arch_regs.c \
> linux/x86_64/arch_regs.h \
> + linux/x86_64/arch_kvm.c \
Likewise.
> linux/x86_64/arch_rt_sigframe.c \
> linux/x86_64/arch_sigreturn.c \
> linux/x86_64/errnoent1.h \
> diff --git a/configure.ac b/configure.ac
> index dad995c4..e637ea95 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -541,7 +541,10 @@ AC_CHECK_TYPES([struct statfs64], [
>
> AC_CHECK_TYPES([struct blk_user_trace_setup],,, [#include <linux/blktrace_api.h>])
>
> -AC_CHECK_TYPES([struct kvm_userspace_memory_region],,, [#include <linux/kvm.h>])
> +AC_CHECK_TYPES(m4_normalize([
> + struct kvm_userspace_memory_region,
> + struct kvm_regs
Please make this list sorted.
> +]),,, [#include <linux/kvm.h>])
>
> AC_CHECK_HEADERS([linux/btrfs.h], [
> AC_CHECK_MEMBERS(m4_normalize([
> diff --git a/kvm.c b/kvm.c
> index 8f68aef5..9d42b22a 100644
> --- a/kvm.c
> +++ b/kvm.c
> @@ -33,6 +33,7 @@
> #ifdef HAVE_LINUX_KVM_H
> # include <linux/kvm.h>
> # include "print_fields.h"
> +# include "arch_kvm.c"
>
> static int
> kvm_ioctl_create_vcpu(struct tcb *const tcp, const kernel_ulong_t arg)
> @@ -67,6 +68,26 @@ kvm_ioctl_set_user_memory_region(struct tcb *const tcp, const kernel_ulong_t arg
> #endif
> }
>
> +static int
> +kvm_ioctl_decode_regs(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg)
> +{
> +#ifdef HAVE_STRUCT_KVM_REGS
> + struct kvm_regs regs;
> +
> + if (code == KVM_GET_REGS && entering(tcp))
> + return 0;
> +
> + tprints(", ");
> + if (umove_or_printaddr(tcp, arg, ®s))
> + return RVAL_DECODED;
> +
> + arch_print_kvm_regs(tcp, arg, ®s);
> + return RVAL_IOCTL_DECODED;
> +#else
> + return RVAL_DECODED;
> +#endif
> +}
> +
> int
> kvm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg)
> {
> @@ -75,6 +96,9 @@ kvm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t a
> return kvm_ioctl_create_vcpu(tcp, arg);
> case KVM_SET_USER_MEMORY_REGION:
> return kvm_ioctl_set_user_memory_region(tcp, arg);
> + case KVM_SET_REGS:
> + case KVM_GET_REGS:
> + return kvm_ioctl_decode_regs(tcp, code, arg);
If HAVE_STRUCT_KVM_REGS is not set, then KVM_SET_REGS and KVM_GET_REGS
are not available (they are defined to sizeof(struct kvm_regs) based
constants), too, and their use also has to be guarded.
> case KVM_CREATE_VM:
> return RVAL_DECODED | RVAL_FD;
> case KVM_RUN:
> diff --git a/linux/arch_kvm.c b/linux/arch_kvm.c
> new file mode 100644
> index 00000000..ef4b7958
> --- /dev/null
> +++ b/linux/arch_kvm.c
> @@ -0,0 +1,9 @@
> +#ifdef HAVE_STRUCT_KVM_REGS
> +static void
> +arch_print_kvm_regs(struct tcb *const tcp,
> + const kernel_ulong_t addr,
> + const struct kvm_regs *const regs)
> +{
> + printaddr(addr);
> +}
> +#endif
> diff --git a/linux/x32/arch_kvm.c b/linux/x32/arch_kvm.c
> new file mode 100644
> index 00000000..e8e982ee
> --- /dev/null
> +++ b/linux/x32/arch_kvm.c
> @@ -0,0 +1 @@
> +#include "x86_64/arch_kvm.c"
> diff --git a/linux/x86_64/arch_kvm.c b/linux/x86_64/arch_kvm.c
> new file mode 100644
> index 00000000..30110491
> --- /dev/null
> +++ b/linux/x86_64/arch_kvm.c
> @@ -0,0 +1,38 @@
> +#ifdef HAVE_STRUCT_KVM_REGS
> +static void
> +arch_print_kvm_regs(struct tcb *const tcp,
> + const kernel_ulong_t addr,
> + const struct kvm_regs *const regs)
> +{
> + PRINT_FIELD_X("{", *regs, rax);
> + if (abbrev(tcp))
> + tprints(", ...");
> + else {
> + PRINT_FIELD_X(", ", *regs, rbx);
> + PRINT_FIELD_X(", ", *regs, rcx);
> + PRINT_FIELD_X(", ", *regs, rdx);
> + PRINT_FIELD_X(", ", *regs, rsi);
> + PRINT_FIELD_X(", ", *regs, rdi);
> + }
> + PRINT_FIELD_X(", ", *regs, rsp);
> + PRINT_FIELD_X(", ", *regs, rbp);
> + if (abbrev(tcp))
> + tprints(", ...");
> + else {
> + PRINT_FIELD_X(", ", *regs, r8);
> + PRINT_FIELD_X(", ", *regs, r9);
> + PRINT_FIELD_X(", ", *regs, r10);
> + PRINT_FIELD_X(", ", *regs, r11);
> + PRINT_FIELD_X(", ", *regs, r12);
> + PRINT_FIELD_X(", ", *regs, r13);
> + PRINT_FIELD_X(", ", *regs, r14);
> + PRINT_FIELD_X(", ", *regs, r15);
> + }
> + PRINT_FIELD_X(", ", *regs, rip);
> +
> + /* TODO: we can decode this more */
> + PRINT_FIELD_X(", ", *regs, rflags);
> +
> + tprints("}");
> +}
> +#endif
This is big enough to worth a commented #endif, like
#endif /* HAVE_STRUCT_KVM_REGS */
--
ldv
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20171204/9b5b3675/attachment.bin>
More information about the Strace-devel
mailing list