]> granicus.if.org Git - strace/commitdiff
kvm: decode the argument of KVM_{SET, GET}_REGS ioctl command
authorMasatake YAMATO <yamato@redhat.com>
Mon, 4 Dec 2017 13:08:15 +0000 (22:08 +0900)
committerDmitry V. Levin <ldv@altlinux.org>
Mon, 4 Dec 2017 18:29:38 +0000 (18:29 +0000)
* configure.ac (AC_CHECK_TYPES): Add struct kvm_regs.
* linux/arck_kvm.c: New file.
* linux/x86_64/arch_kvm.c: Likewise.
* linux/i386/arch_kvm.c: Likewise.
* linux/x32/arch_kvm.c: Likewise.
* Makefile.am (EXTRA_DIST): Add them.
* kvm.c: Include "arch_kvm.c".
[HAVE_STRUCT_KVM_REGS] (kvm_ioctl_decode_regs): New function.
(kvm_ioctl) [HAVE_STRUCT_KVM_REGS] <KVM_SET_REGS, KVM_GET_REGS>: Use it.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Makefile.am
configure.ac
kvm.c
linux/arch_kvm.c [new file with mode: 0644]
linux/i386/arch_kvm.c [new file with mode: 0644]
linux/x32/arch_kvm.c [new file with mode: 0644]
linux/x86_64/arch_kvm.c [new file with mode: 0644]

index 603760568eaac88b64d7959f31d6536c2b7159d0..c04125ec68ad6bed52f951bf32142b105a527291 100644 (file)
@@ -424,6 +424,7 @@ EXTRA_DIST =                                \
        linux/arc/set_error.c           \
        linux/arc/set_scno.c            \
        linux/arc/syscallent.h          \
+       linux/arch_kvm.c                \
        linux/arch_regs.h               \
        linux/arch_sigreturn.c          \
        linux/arm/arch_regs.c           \
@@ -506,6 +507,7 @@ EXTRA_DIST =                                \
        linux/hppa/set_scno.c           \
        linux/hppa/signalent.h          \
        linux/hppa/syscallent.h         \
+       linux/i386/arch_kvm.c           \
        linux/i386/arch_regs.c          \
        linux/i386/arch_regs.h          \
        linux/i386/arch_rt_sigframe.c   \
@@ -805,6 +807,7 @@ EXTRA_DIST =                                \
        linux/unix_diag.h               \
        linux/userent.h                 \
        linux/userent0.h                \
+       linux/x32/arch_kvm.c            \
        linux/x32/arch_regs.c           \
        linux/x32/arch_regs.h           \
        linux/x32/arch_rt_sigframe.c    \
@@ -824,6 +827,7 @@ EXTRA_DIST =                                \
        linux/x32/syscallent.h          \
        linux/x32/syscallent1.h         \
        linux/x32/userent.h             \
+       linux/x86_64/arch_kvm.c         \
        linux/x86_64/arch_regs.c        \
        linux/x86_64/arch_regs.h        \
        linux/x86_64/arch_rt_sigframe.c \
index dad995c40f99f867343462663a21a35b2d3f26c9..9a3646acaf724ff70230097e16bc6d4d3a0c66cb 100644 (file)
@@ -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_regs,
+       struct kvm_userspace_memory_region
+]),,, [#include <linux/kvm.h>])
 
 AC_CHECK_HEADERS([linux/btrfs.h], [
        AC_CHECK_MEMBERS(m4_normalize([
diff --git a/kvm.c b/kvm.c
index f49fb8dec71b14c633439e308acef1dcbad95156..2d5962c29c0d442f30a5824ae6ab7a499d0ed077 100644 (file)
--- 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)
@@ -66,6 +67,24 @@ kvm_ioctl_set_user_memory_region(struct tcb *const tcp, const kernel_ulong_t arg
 }
 # endif /* HAVE_STRUCT_KVM_USERSPACE_MEMORY_REGION */
 
+# ifdef HAVE_STRUCT_KVM_REGS
+static int
+kvm_ioctl_decode_regs(struct tcb *const tcp, const unsigned int code,
+                     const kernel_ulong_t arg)
+{
+       struct kvm_regs regs;
+
+       if (code == KVM_GET_REGS && entering(tcp))
+               return 0;
+
+       tprints(", ");
+       if (!umove_or_printaddr(tcp, arg, &regs))
+               arch_print_kvm_regs(tcp, arg, &regs);
+
+       return RVAL_IOCTL_DECODED;
+}
+# endif /* HAVE_STRUCT_KVM_REGS */
+
 int
 kvm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg)
 {
@@ -78,6 +97,12 @@ kvm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t a
                return kvm_ioctl_set_user_memory_region(tcp, arg);
 # endif
 
+# ifdef HAVE_STRUCT_KVM_REGS
+       case KVM_SET_REGS:
+       case KVM_GET_REGS:
+               return kvm_ioctl_decode_regs(tcp, code, arg);
+# endif
+
        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 (file)
index 0000000..d1292a5
--- /dev/null
@@ -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 /* HAVE_STRUCT_KVM_REGS */
diff --git a/linux/i386/arch_kvm.c b/linux/i386/arch_kvm.c
new file mode 100644 (file)
index 0000000..e8e982e
--- /dev/null
@@ -0,0 +1 @@
+#include "x86_64/arch_kvm.c"
diff --git a/linux/x32/arch_kvm.c b/linux/x32/arch_kvm.c
new file mode 100644 (file)
index 0000000..e8e982e
--- /dev/null
@@ -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 (file)
index 0000000..f5ade5d
--- /dev/null
@@ -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 /* HAVE_STRUCT_KVM_REGS */