[PATCH v2 3/3] tests: check verbose decoding of kvm ioctl

Pierre Marsais pierre.marsais at lse.epita.fr
Thu Jun 28 02:37:45 UTC 2018


* tests/ioctl_kvm_run-v.c: New file.
* tests/ioctl_kvm_run.c: Include xlat.h and xlat/kvm_cpuid_flags.h.
(print_kvm_segment, print_kvm_sregs, print_kvm_regs): New functions.
(run_kvm): Use them.
(print_cpuid_ioctl) [VERBOSE]: Print verbose ioctl decoding.
* tests/gen_tests.in (ioctl_kvm_run-v): New entry.
* tests/pure_executables.list: Add ioctl_kvm_run-v.
* tests/.gitignore: Likewise.

Signed-off-by: Pierre Marsais <pierre.marsais at lse.epita.fr>
---
 tests/.gitignore            |   1 +
 tests/gen_tests.in          |   1 +
 tests/ioctl_kvm_run-v.c     |   2 +
 tests/ioctl_kvm_run.c       | 118 ++++++++++++++++++++++++++++++------
 tests/pure_executables.list |   1 +
 5 files changed, 105 insertions(+), 18 deletions(-)
 create mode 100644 tests/ioctl_kvm_run-v.c

diff --git a/tests/.gitignore b/tests/.gitignore
index 2285a357..6d84f607 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -145,6 +145,7 @@ ioctl_evdev
 ioctl_evdev-v
 ioctl_inotify
 ioctl_kvm_run
+ioctl_kvm_run-v
 ioctl_loop
 ioctl_loop-nv
 ioctl_loop-v
diff --git a/tests/gen_tests.in b/tests/gen_tests.in
index 24e0510e..3f6b01c7 100644
--- a/tests/gen_tests.in
+++ b/tests/gen_tests.in
@@ -140,6 +140,7 @@ ioctl_evdev	+ioctl.test
 ioctl_evdev-v	+ioctl.test -v
 ioctl_inotify	+ioctl.test
 ioctl_kvm_run	+ioctl.test -a36 -y
+ioctl_kvm_run-v	+ioctl.test -v -a36 -y
 ioctl_loop	+ioctl.test
 ioctl_loop-nv	+ioctl.test -a22 -e verbose=none
 ioctl_loop-v	+ioctl.test -v
diff --git a/tests/ioctl_kvm_run-v.c b/tests/ioctl_kvm_run-v.c
new file mode 100644
index 00000000..388339b0
--- /dev/null
+++ b/tests/ioctl_kvm_run-v.c
@@ -0,0 +1,2 @@
+#define VERBOSE 1
+#include "ioctl_kvm_run.c"
diff --git a/tests/ioctl_kvm_run.c b/tests/ioctl_kvm_run.c
index 70a6dea5..5e995be5 100644
--- a/tests/ioctl_kvm_run.c
+++ b/tests/ioctl_kvm_run.c
@@ -48,6 +48,9 @@
 #  define KVM_MAX_CPUID_ENTRIES 80
 # endif
 
+#include "xlat.h"
+#include "xlat/kvm_cpuid_flags.h"
+
 static int
 kvm_ioctl(int fd, unsigned long cmd, const char *cmd_str, void *arg)
 {
@@ -82,6 +85,80 @@ __asm__(
 	".size code_size, . - code_size	\n"
 	);
 
+static void print_kvm_segment(const struct kvm_segment *seg)
+{
+	printf("{base=%#jx, limit=%u, selector=%u, type=%u, present=%u, "
+	       "dpl=%u, db=%u, s=%u, l=%u, g=%u, avl=%u}",
+	       (uintmax_t) seg->base, seg->limit, seg->selector, seg->type,
+	       seg->present, seg->dpl, seg->db, seg->s, seg->l, seg->g,
+	       seg->avl);
+}
+
+static void print_kvm_sregs(const struct kvm_sregs *sregs)
+{
+	printf("{cs=");
+	print_kvm_segment(&sregs->cs);
+#if VERBOSE
+	printf(", ds=");
+	print_kvm_segment(&sregs->ds);
+	printf(", es=");
+	print_kvm_segment(&sregs->es);
+	printf(", fs=");
+	print_kvm_segment(&sregs->fs);
+	printf(", gs=");
+	print_kvm_segment(&sregs->gs);
+	printf(", ss=");
+	print_kvm_segment(&sregs->ss);
+	printf(", tr=");
+	print_kvm_segment(&sregs->tr);
+	printf(", ldt=");
+	print_kvm_segment(&sregs->ldt);
+	printf(", gdt={base=%#jx, limit=%u}, idt={base=%#jx, limit=%u}, "
+	      "cr0=%llu, cr2=%llu, cr3=%llu, cr4=%llu, cr8=%llu, efer=%llu, "
+	      "apic_base=%#jx", (uintmax_t) sregs->gdt.base, sregs->gdt.limit,
+	      (uintmax_t) sregs->idt.base, sregs->idt.limit, sregs->cr0,
+	      sregs->cr2, sregs->cr3, sregs->cr4, sregs->cr8, sregs->efer,
+	      (uintmax_t)sregs->apic_base);
+	printf(", interrupt_bitmap=[");
+	for (size_t i = 0; i < sizeof(sregs->interrupt_bitmap) /
+			       sizeof(sregs->interrupt_bitmap[0]); i++) {
+		if (i)
+			printf(", ");
+		printf("%#jx", (uintmax_t) sregs->interrupt_bitmap[i]);
+	}
+	printf("]");
+#else
+	printf(", ...");
+#endif
+	printf("}");
+}
+
+static void print_kvm_regs(const struct kvm_regs *regs)
+{
+	printf("{rax=%#jx", (uintmax_t) regs->rax);
+#if VERBOSE
+	printf(", rbx=%#jx, rcx=%#jx, rdx=%#jx, rsi=%#jx, rdi=%#jx",
+	       (uintmax_t) regs->rbx, (uintmax_t) regs->rcx,
+	       (uintmax_t) regs->rdx, (uintmax_t) regs->rsi,
+	       (uintmax_t) regs->rdi);
+#else
+	printf(", ...");
+#endif
+	printf(", rsp=%#jx, rbp=%#jx", (uintmax_t) regs->rsp,
+	       (uintmax_t) regs->rbp);
+#if VERBOSE
+	printf(", r8=%#jx, r9=%#jx, r10=%#jx, r11=%#jx, r12=%#jx, r13=%#jx"
+	       ", r14=%#jx, r15=%#jx",
+	       (uintmax_t) regs->r8, (uintmax_t) regs->r9,
+	       (uintmax_t) regs->r10, (uintmax_t) regs->r11,
+	       (uintmax_t) regs->r12, (uintmax_t) regs->r13,
+	       (uintmax_t) regs->r14, (uintmax_t) regs->r15);
+#else
+	printf(", ...");
+#endif
+	printf(", rip=%#jx, rflags=%#jx}", (uintmax_t) regs->rip,
+	       (uintmax_t) regs->rflags);
+}
 
 static void
 run_kvm(const int vcpu_fd, struct kvm_run *const run, const size_t mmap_size,
@@ -90,23 +167,16 @@ run_kvm(const int vcpu_fd, struct kvm_run *const run, const size_t mmap_size,
 	/* Initialize CS to point at 0, via a read-modify-write of sregs. */
 	struct kvm_sregs sregs;
 	KVM_IOCTL(vcpu_fd, KVM_GET_SREGS, &sregs);
-	printf("ioctl(%d<%s>, KVM_GET_SREGS, {cs={base=%#jx, limit=%u, selector=%u"
-	       ", type=%u, present=%u, dpl=%u, db=%u, s=%u, l=%u, g=%u, avl=%u}"
-	       ", ...}) = 0\n", vcpu_fd, vcpu_dev, (uintmax_t) sregs.cs.base,
-	       sregs.cs.limit, sregs.cs.selector, sregs.cs.type,
-	       sregs.cs.present, sregs.cs.dpl, sregs.cs.db, sregs.cs.s,
-	       sregs.cs.l, sregs.cs.g, sregs.cs.avl);
+	printf("ioctl(%d<%s>, KVM_GET_SREGS, ", vcpu_fd, vcpu_dev);
+	print_kvm_sregs(&sregs);
+	printf(") = 0\n");
 
 	sregs.cs.base = 0;
 	sregs.cs.selector = 0;
 	KVM_IOCTL(vcpu_fd, KVM_SET_SREGS, &sregs);
-	printf("ioctl(%d<%s>, KVM_SET_SREGS, {cs={base=%#jx, limit=%u"
-	       ", selector=%u, type=%u, present=%u, dpl=%u, db=%u, s=%u"
-	       ", l=%u, g=%u, avl=%u}, ...}) = 0\n",
-	       vcpu_fd, vcpu_dev, (uintmax_t) sregs.cs.base,
-	       sregs.cs.limit, sregs.cs.selector, sregs.cs.type,
-	       sregs.cs.present, sregs.cs.dpl, sregs.cs.db, sregs.cs.s,
-	       sregs.cs.l, sregs.cs.g, sregs.cs.avl);
+	printf("ioctl(%d<%s>, KVM_SET_SREGS, ", vcpu_fd, vcpu_dev);
+	print_kvm_sregs(&sregs);
+	printf(") = 0\n");
 
 	/*
 	 * Initialize registers: instruction pointer for our code, addends,
@@ -119,11 +189,9 @@ run_kvm(const int vcpu_fd, struct kvm_run *const run, const size_t mmap_size,
 		.rflags = 0x2,
 	};
 	KVM_IOCTL(vcpu_fd, KVM_SET_REGS, &regs);
-	printf("ioctl(%d<%s>, KVM_SET_REGS, {rax=%#jx, ..."
-	       ", rsp=%#jx, rbp=%#jx, ..., rip=%#jx, rflags=%#jx}) = 0\n",
-	       vcpu_fd, vcpu_dev, (uintmax_t) regs.rax,
-	       (uintmax_t) regs.rsp, (uintmax_t) regs.rbp,
-	       (uintmax_t) regs.rip, (uintmax_t) regs.rflags);
+	printf("ioctl(%d<%s>, KVM_SET_REGS, ", vcpu_fd, vcpu_dev);
+	print_kvm_regs(&regs);
+	printf(") = 0\n");
 
 	/* Copy the code */
 	memcpy(mem, code, code_size);
@@ -194,8 +262,22 @@ static void print_cpuid_ioctl(int fd, const char* fd_dev,
 {
 	printf("ioctl(%d<%s>, %s, {nent=%u, entries=[",
 	       fd, fd_dev, ioctl_name, cpuid->nent);
+#if VERBOSE
+	for (size_t i = 0; i < cpuid->nent; i++) {
+		if (i)
+			printf(", ");
+		printf("{function=%#x, index=%#x, flags=",
+		       cpuid->entries[i].function, cpuid->entries[i].index);
+		printflags(kvm_cpuid_flags, cpuid->entries[i].flags,
+			   "KVM_CPUID_FLAG_???");
+		printf(", eax=%#x, ebx=%#x, ecx=%#x, edx=%#x}",
+		       cpuid->entries[i].eax, cpuid->entries[i].ebx,
+		       cpuid->entries[i].ecx, cpuid->entries[i].edx);
+	}
+#else
 	if (cpuid->nent)
 		printf("...");
+#endif
 	printf("]}) = 0\n");
 }
 
diff --git a/tests/pure_executables.list b/tests/pure_executables.list
index 39565d0c..4d9cf63f 100755
--- a/tests/pure_executables.list
+++ b/tests/pure_executables.list
@@ -114,6 +114,7 @@ ioctl_dm
 ioctl_evdev
 ioctl_inotify
 ioctl_kvm_run
+ioctl_kvm_run-v
 ioctl_loop
 ioctl_mtd
 ioctl_rtc
-- 
2.18.0



More information about the Strace-devel mailing list