* kvm.c (kvm_ioctl): Handle KVM_SET_SREGS and KVM_GET_SREGES. (kvm_ioctl_decode_sregs): New function. (kvm_ioctl_decode_regs_dtable): New function. (kvm_ioctl_decode_regs_segment): New function.
Signed-off-by: Masatake YAMATO <yam...@redhat.com> --- kvm.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/kvm.c b/kvm.c index 69a8c97a..b0eb1377 100644 --- a/kvm.c +++ b/kvm.c @@ -121,6 +121,85 @@ kvm_ioctl_decode_regs(struct tcb *const tcp, const unsigned int code, const kern #endif } +#ifdef X86_64 +static void +kvm_ioctl_decode_regs_segment(const char *prefix, struct kvm_segment *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, struct kvm_dtable *dtable) +{ + tprints(prefix); + PRINT_FIELD_X("={", *dtable, base); + PRINT_FIELD_U(", ", *dtable, limit); + tprints("}"); +} +#endif + +static int +kvm_ioctl_decode_sregs(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg) +{ + struct kvm_sregs sregs; + +#ifdef X86_64 + if (code == KVM_GET_SREGS && entering(tcp)) + return 0; + + if (umove(tcp, arg, &sregs) < 0) + return RVAL_DECODED; + + tprints(", {"); + kvm_ioctl_decode_regs_segment("cs", &sregs.cs); + if (abbrev(tcp)) { + tprints(", ...}"); + return RVAL_IOCTL_DECODED; + } + + 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("}"); + + 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) { @@ -134,6 +213,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); /* Commands not taking any arguments. */ case KVM_RUN: -- 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