[PATCH v5 3/4] kvm: decode the argument for KVM_{SET, GET}_SREGS ioctl command

Masatake YAMATO yamato at redhat.com
Thu Dec 7 14:03:34 UTC 2017


* configure.ac (AC_CHECK_TYPES): Add struct kvm_sregs.
* kvm.c (kvm_ioctl_decode_regs_segment): New function.
(kvm_ioctl) <KVM_SET_SREGS, KVM_GET_SREGS>: Use it.
* linux/arch_kvm.c (arch_print_kvm_sregs): New function.
* linux/x86_64/arch_kvm.c (PRINT_FIELD_KVM_SREGS_STRUCT): New macro.
(arch_print_kvm_sregs): New function.
(kvm_ioctl_decode_regs_dtable): Ditto.
(kvm_ioctl_decode_regs_segment): Ditto.

Changes in v2:
* Decode only if struct kvm_sregs is available.
* Put arch-specific and generic stub decoders to arch_kvm.c.
* Use umove_or_printaddr instead of umove.

    Above 3 items are suggested by ldv.

* Use more const modifiers.

Change in v3:
* Put ifdef guards around codes using kvm_sregs.
  Suggested by ldv.

Highlights in v4:
* Guards the case label with ifdef HAVE_STRUCT_KVM_SREGS.
* Fix a critical typo s/HAVE_STRUCT_KVM_REGS/HAVE_STRUCT_KVM_SREGS/.
* Fix a critical typo s/kvm_regs/kvm_sregs/.
* Introduce PRINT_FIELD_KVM_SREGS_STRUCT macro for simplifying
  the code for decoding sregs.

Changes in v5:
* Don't return RVAL_DECODED if the decoder prints something.
  Suggested by ldv.

Signed-off-by: Masatake YAMATO <yamato at redhat.com>
---
 configure.ac            |  5 ++--
 kvm.c                   | 23 ++++++++++++++++
 linux/arch_kvm.c        | 11 ++++++++
 linux/x86_64/arch_kvm.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 109 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index 5103d479..729ef3f7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -542,8 +542,9 @@ AC_CHECK_TYPES([struct statfs64], [
 AC_CHECK_TYPES([struct blk_user_trace_setup],,, [#include <linux/blktrace_api.h>])
 
 AC_CHECK_TYPES(m4_normalize([
-	struct kvm_regs
-	struct kvm_userspace_memory_region,
+	struct kvm_regs,
+	struct kvm_sregs,
+	struct kvm_userspace_memory_region
 ]),,, [#include <linux/kvm.h>])
 
 AC_CHECK_HEADERS([linux/btrfs.h], [
diff --git a/kvm.c b/kvm.c
index 5731cc25..987e7815 100644
--- a/kvm.c
+++ b/kvm.c
@@ -84,6 +84,23 @@ kvm_ioctl_decode_regs(struct tcb *const tcp, const unsigned int code, const kern
 }
 # endif /* HAVE_STRUCT_KVM_REGS */
 
+# ifdef HAVE_STRUCT_KVM_SREGS
+static int
+kvm_ioctl_decode_sregs(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg)
+{
+	struct kvm_sregs sregs;
+
+	if (code == KVM_GET_SREGS && entering(tcp))
+		return 0;
+
+	tprints(", ");
+	if (!umove_or_printaddr(tcp, arg, &sregs))
+		arch_print_kvm_sregs(tcp, arg, &sregs);
+
+	return RVAL_IOCTL_DECODED;
+}
+# endif	/* HAVE_STRUCT_KVM_SREGS */
+
 int
 kvm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg)
 {
@@ -102,6 +119,12 @@ kvm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t a
 		return kvm_ioctl_decode_regs(tcp, code, arg);
 # endif
 
+# ifdef HAVE_STRUCT_KVM_SREGS
+	case KVM_SET_SREGS:
+	case KVM_GET_SREGS:
+		return kvm_ioctl_decode_sregs(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
index d1292a5b..bb1119a4 100644
--- a/linux/arch_kvm.c
+++ b/linux/arch_kvm.c
@@ -7,3 +7,14 @@ arch_print_kvm_regs(struct tcb *const tcp,
 	printaddr(addr);
 }
 #endif	/* HAVE_STRUCT_KVM_REGS */
+
+#ifdef HAVE_STRUCT_KVM_SREGS
+static void
+arch_print_kvm_sregs(struct tcb *const tcp,
+		    const kernel_ulong_t addr,
+		    const struct kvm_sregs *const sregs)
+{
+	printaddr(addr);
+}
+#endif	/* HAVE_STRUCT_KVM_SREGS */
+
diff --git a/linux/x86_64/arch_kvm.c b/linux/x86_64/arch_kvm.c
index f5ade5d8..d76ca034 100644
--- a/linux/x86_64/arch_kvm.c
+++ b/linux/x86_64/arch_kvm.c
@@ -36,3 +36,75 @@ arch_print_kvm_regs(struct tcb *const tcp,
 	tprints("}");
 }
 #endif	/* HAVE_STRUCT_KVM_REGS */
+
+#ifdef HAVE_STRUCT_KVM_SREGS
+static void
+kvm_ioctl_decode_regs_segment(const char *prefix,
+			      const struct kvm_segment *const segment)
+{
+	tprints(prefix);
+	PRINT_FIELD_X("={", *segment, base);
+	PRINT_FIELD_U(", ", *segment, limit);
+	PRINT_FIELD_U(", ", *segment, selector);
+	PRINT_FIELD_U(", ", *segment, type);
+	PRINT_FIELD_U(", ", *segment, present);
+	PRINT_FIELD_U(", ", *segment, dpl);
+	PRINT_FIELD_U(", ", *segment, db);
+	PRINT_FIELD_U(", ", *segment, s);
+	PRINT_FIELD_U(", ", *segment, l);
+	PRINT_FIELD_U(", ", *segment, g);
+	PRINT_FIELD_U(", ", *segment, avl);
+	tprints("}");
+}
+
+static void
+kvm_ioctl_decode_regs_dtable(const char *prefix,
+			     const struct kvm_dtable *const dtable)
+{
+	tprints(prefix);
+	PRINT_FIELD_X("={", *dtable, base);
+	PRINT_FIELD_U(", ", *dtable, limit);
+	tprints("}");
+}
+
+# define PRINT_FIELD_KVM_SREGS_STRUCT(prefix_, where_, type_, field_)	\
+  kvm_ioctl_decode_regs_ ## type_(prefix_ #field_, &(where_)->field_)
+
+static void
+arch_print_kvm_sregs(struct tcb *const tcp,
+		     const kernel_ulong_t addr,
+		     const struct kvm_sregs *const sregs)
+{
+	PRINT_FIELD_KVM_SREGS_STRUCT("{", sregs, segment, cs);
+	if (abbrev(tcp)) {
+		tprints(", ...}");
+		return;
+	}
+
+	PRINT_FIELD_KVM_SREGS_STRUCT(", ", sregs, segment, ds);
+	PRINT_FIELD_KVM_SREGS_STRUCT(", ", sregs, segment, es);
+	PRINT_FIELD_KVM_SREGS_STRUCT(", ", sregs, segment, fs);
+	PRINT_FIELD_KVM_SREGS_STRUCT(", ", sregs, segment, gs);
+	PRINT_FIELD_KVM_SREGS_STRUCT(", ", sregs, segment, ss);
+	PRINT_FIELD_KVM_SREGS_STRUCT(", ", sregs, segment, tr);
+	PRINT_FIELD_KVM_SREGS_STRUCT(", ", sregs, segment, ldt);
+	PRINT_FIELD_KVM_SREGS_STRUCT(", ", sregs, dtable, gdt);
+	PRINT_FIELD_KVM_SREGS_STRUCT(", ", sregs, dtable, idt);
+	PRINT_FIELD_U(", ", *sregs, cr0);
+	PRINT_FIELD_U(", ", *sregs, cr2);
+	PRINT_FIELD_U(", ", *sregs, cr3);
+	PRINT_FIELD_U(", ", *sregs, cr4);
+	PRINT_FIELD_U(", ", *sregs, cr8);
+	PRINT_FIELD_U(", ", *sregs, efer);
+	PRINT_FIELD_X(", ", *sregs, apic_base);
+	tprints(", interrupt_bitmap=[");
+
+	unsigned int i;
+	for (i = 0; i < ARRAY_SIZE(sregs->interrupt_bitmap); i++) {
+		if (i != 0)
+			tprints(", ");
+		tprintf("%#" PRI__x64, sregs->interrupt_bitmap[i]);
+	}
+	tprints("]}");
+}
+#endif	/* HAVE_STRUCT_KVM_SREGS */
-- 
2.13.6





More information about the Strace-devel mailing list