diff options
author | Masatake YAMATO <yamato@redhat.com> | 2017-12-04 22:08:16 +0900 |
---|---|---|
committer | Dmitry V. Levin <ldv@altlinux.org> | 2017-12-04 18:29:38 +0000 |
commit | 647709d8e5d123414276346412c51c673a478049 (patch) | |
tree | 5955d1765190f7306946e2381ee70c0e049edbc4 | |
parent | 1d3b9b2c94aece61b7f4686627d7fb9417dc1510 (diff) | |
download | strace-647709d8e5d123414276346412c51c673a478049.tar.gz |
kvm: decode the argument of KVM_{SET, GET}_SREGS ioctl command
* configure.ac (AC_CHECK_TYPES): Add struct kvm_sregs.
* kvm.c [HAVE_STRUCT_KVM_SREGS] (kvm_ioctl_decode_sregs): New function.
(kvm_ioctl) [HAVE_STRUCT_KVM_SREGS] <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.
(kvm_ioctl_decode_regs_dtable, kvm_ioctl_decode_regs_segment,
arch_print_kvm_sregs): New functions.
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | kvm.c | 24 | ||||
-rw-r--r-- | linux/arch_kvm.c | 10 | ||||
-rw-r--r-- | linux/x86_64/arch_kvm.c | 72 |
4 files changed, 107 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac index 9a3646aca..729ef3f7d 100644 --- a/configure.ac +++ b/configure.ac @@ -543,6 +543,7 @@ AC_CHECK_TYPES([struct blk_user_trace_setup],,, [#include <linux/blktrace_api.h> AC_CHECK_TYPES(m4_normalize([ struct kvm_regs, + struct kvm_sregs, struct kvm_userspace_memory_region ]),,, [#include <linux/kvm.h>]) @@ -85,6 +85,24 @@ kvm_ioctl_decode_regs(struct tcb *const tcp, const unsigned int code, } # 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) { @@ -103,6 +121,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 d1292a5b1..f12f32ab4 100644 --- a/linux/arch_kvm.c +++ b/linux/arch_kvm.c @@ -7,3 +7,13 @@ 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 f5ade5d89..f0075cae5 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 */ |