* 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 (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. Signed-off-by: Masatake YAMATO <yam...@redhat.com> --- configure.ac | 4 ++- kvm.c | 23 +++++++++++++++++ linux/arch_kvm.c | 10 +++++++ linux/x86_64/arch_kvm.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index e637ea95..3f18e0c3 100644 --- a/configure.ac +++ b/configure.ac @@ -543,9 +543,11 @@ AC_CHECK_TYPES([struct blk_user_trace_setup],,, [#include <linux/blktrace_api.h> AC_CHECK_TYPES(m4_normalize([ struct kvm_userspace_memory_region, - struct kvm_regs + struct kvm_regs, + struct kvm_sregs ]),,, [#include <linux/kvm.h>]) + AC_CHECK_HEADERS([linux/btrfs.h], [ AC_CHECK_MEMBERS(m4_normalize([ struct btrfs_ioctl_feature_flags.compat_flags, diff --git a/kvm.c b/kvm.c index 9d42b22a..12ea8c6b 100644 --- a/kvm.c +++ b/kvm.c @@ -88,6 +88,26 @@ kvm_ioctl_decode_regs(struct tcb *const tcp, const unsigned int code, const kern #endif } +static int +kvm_ioctl_decode_sregs(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg) +{ +#ifdef HAVE_STRUCT_KVM_REGS + struct kvm_sregs sregs; + + if (code == KVM_GET_SREGS && entering(tcp)) + return 0; + + tprints(", "); + if (umove_or_printaddr(tcp, arg, &sregs) < 0) + return RVAL_DECODED; + + arch_print_kvm_sregs(tcp, arg, &sregs); + return RVAL_IOCTL_DECODED; +#else + return RVAL_DECODED; +#endif +} + int kvm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg) { @@ -99,6 +119,9 @@ kvm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t a case KVM_SET_REGS: case KVM_GET_REGS: return kvm_ioctl_decode_regs(tcp, code, arg); + case KVM_SET_SREGS: + case KVM_GET_SREGS: + return kvm_ioctl_decode_sregs(tcp, code, arg); 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 ef4b7958..64ea0aca 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 + +#ifdef HAVE_STRUCT_KVM_SREGS +static void +arch_print_kvm_sregs(struct tcb *const tcp, + const kernel_ulong_t addr, + const struct kvm_regs *const sregs) +{ + printaddr(addr); +} +#endif diff --git a/linux/x86_64/arch_kvm.c b/linux/x86_64/arch_kvm.c index 30110491..ba28d0cb 100644 --- a/linux/x86_64/arch_kvm.c +++ b/linux/x86_64/arch_kvm.c @@ -36,3 +36,72 @@ arch_print_kvm_regs(struct tcb *const tcp, tprints("}"); } #endif + +#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("}"); +} + +static void +arch_print_kvm_sregs(struct tcb *const tcp, + const kernel_ulong_t addr, + const struct kvm_sregs *const sregs) +{ + tprints("{"); + kvm_ioctl_decode_regs_segment("cs", &sregs->cs); + if (abbrev(tcp)) { + tprints(", ...}"); + return; + } + + kvm_ioctl_decode_regs_segment(", ds", &sregs->ds); + kvm_ioctl_decode_regs_segment(", es", &sregs->es); + kvm_ioctl_decode_regs_segment(", fs", &sregs->fs); + kvm_ioctl_decode_regs_segment(", gs", &sregs->gs); + kvm_ioctl_decode_regs_segment(", ss", &sregs->ss); + kvm_ioctl_decode_regs_segment(", tr", &sregs->tr); + kvm_ioctl_decode_regs_segment(", ldt", &sregs->ldt); + kvm_ioctl_decode_regs_dtable(", gdt", &sregs->gdt); + kvm_ioctl_decode_regs_dtable(", idt", &sregs->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=["); + for (int i = 0; i < (KVM_NR_INTERRUPTS + 63) / 64; i++) { + if (i != 0) + tprints(", "); + tprintf("%" PRI__u64, sregs->interrupt_bitmap[i]); + } + tprints("]"); + tprints("}"); +} +#endif -- 2.13.6 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel