From ba9d45c374e4271f1cecf9b808ec7e99d8936877 Mon Sep 17 00:00:00 2001 From: Pierre Marsais Date: Thu, 28 Jun 2018 03:37:45 +0100 Subject: [PATCH] tests: check verbose decoding of kvm ioctl * 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 --- tests/.gitignore | 1 + tests/gen_tests.in | 1 + tests/ioctl_kvm_run-v.c | 2 + tests/ioctl_kvm_run.c | 120 ++++++++++++++++++++++++++++++------ tests/pure_executables.list | 1 + 5 files changed, 107 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 ba6ba106..caa689f3 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,82 @@ __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 < ARRAY_SIZE(sregs->interrupt_bitmap); 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 +169,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 +191,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, ®s); - 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(®s); + printf(") = 0\n"); /* Copy the code */ memcpy(mem, code, code_size); @@ -194,8 +264,22 @@ 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.40.0