[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v2 11/12] xenctx: Dump registers via hvm info if available.



On 11/06/13 15:35, Andrew Cooper wrote:
On 06/11/13 20:08, Don Slutz wrote:
From: Don Slutz <Don@xxxxxxxxxxxxxxx>

This allows the output of registers that are not available in the
not HVM view.

Look up symbols for various registers as kernel data.

Also a minor check that ip, sp, and cr3 are the same.

Signed-off-by: Don Slutz <Don@xxxxxxxxxxxxxxx>
What about tools/misc/xen-hvmctx ?
1st I have heard of it.  Will look into this.

This is a particularly awkward tool where we have two tools in different
subtrees which do about 80% the same thing.
80% looks high to me (xenctx does  do  stack, code, and symbol table also), but 
I do agree that having 2 tools to do 1 thing (display cpu registers) is 
confusing.
I would certainly not object if someone were to merge these two tools
into one.  It is particularly awkward as xen-hvmctx ends up being
installed into /usr/sbin/ and is therefore on the $PATH, while xenctx
ends up off the $PATH in /usr/lib/xen/bin/
The way I would do this is to make 1 source file, delete the 2nd, and install 
the same code as both xenctx and xen-hvmctx.  argv[0] can be decoded and the 
default action adjusted based on the name. In this case there would be command 
line options to get the current old output for each tool.
     -Don Slutz
I am also fairly sure we have other examples of tools like this with
sightly different variants living in different locations.

~Andrew

---
  tools/xentrace/xenctx.c |  284 ++++++++++++++++++++++++++++++++++++++++++++++-
  1 files changed, 282 insertions(+), 2 deletions(-)

diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index 6ec9c74..d3cbb22 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -415,6 +415,247 @@ static void print_ctx(vcpu_guest_context_any_t *ctx)
          print_ctx_64(&ctx->x64);
  }
+#if defined(__i386__) || defined(__x86_64__)
+static void print_cpuctx_regs64(struct hvm_hw_cpu *ctx)
+{
+    printf("rip: %016"PRIx64, ctx->rip);
+    print_symbol(ctx->rip, KERNEL_TEXT_ADDR);
+    print_flags(ctx->rflags);
+    printf("rsp: %016"PRIx64"\n", ctx->rsp);
+
+    printf("rax: %016"PRIx64"\t", ctx->rax);
+    printf("rcx: %016"PRIx64"\t", ctx->rcx);
+    printf("rdx: %016"PRIx64"\n", ctx->rdx);
+
+    printf("rbx: %016"PRIx64"\t", ctx->rbx);
+    printf("rsi: %016"PRIx64"\t", ctx->rsi);
+    printf("rdi: %016"PRIx64"\n", ctx->rdi);
+
+    printf("rbp: %016"PRIx64"\t", ctx->rbp);
+    printf(" r8: %016"PRIx64"\t", ctx->r8);
+    printf(" r9: %016"PRIx64"\n", ctx->r9);
+
+    printf("r10: %016"PRIx64"\t", ctx->r10);
+    printf("r11: %016"PRIx64"\t", ctx->r11);
+    printf("r12: %016"PRIx64"\n", ctx->r12);
+
+    printf("r13: %016"PRIx64"\t", ctx->r13);
+    printf("r14: %016"PRIx64"\t", ctx->r14);
+    printf("r15: %016"PRIx64"\n", ctx->r15);
+
+    printf("  cs: %04x @ %016"PRIx64, ctx->cs_sel, ctx->cs_base);
+    if (ctx->cs_base)
+        print_symbol(ctx->cs_base, KERNEL_DATA_ADDR);
+    printf("\n           /%08x(%x)\n", ctx->cs_limit, ctx->cs_arbytes);
+    printf("  ss: %04x @ %016"PRIx64, ctx->ss_sel, ctx->ss_base);
+    if (ctx->ss_base)
+        print_symbol(ctx->ss_base, KERNEL_DATA_ADDR);
+    printf("\n           /%08x(%x)\n", ctx->ss_limit, ctx->ss_arbytes);
+    printf("  ds: %04x @ %016"PRIx64, ctx->ds_sel, ctx->ds_base);
+    if (ctx->ds_base)
+        print_symbol(ctx->ds_base, KERNEL_DATA_ADDR);
+    printf("\n           /%08x(%x)\n", ctx->ds_limit, ctx->ds_arbytes);
+    printf("  es: %04x @ %016"PRIx64, ctx->es_sel, ctx->es_base);
+    if (ctx->es_base)
+        print_symbol(ctx->es_base, KERNEL_DATA_ADDR);
+    printf("\n           /%08x(%x)\n", ctx->es_limit, ctx->es_arbytes);
+    printf("  fs: %04x @ %016"PRIx64, ctx->fs_sel, ctx->fs_base);
+    if (ctx->fs_base)
+        print_symbol(ctx->fs_base, KERNEL_DATA_ADDR);
+    printf("\n           /%08x(%x)\n", ctx->fs_limit, ctx->fs_arbytes);
+    printf("  gs: %04x @ %016"PRIx64"\\%016"PRIx64, ctx->gs_sel,
+           ctx->gs_base, ctx->shadow_gs);
+    if (ctx->gs_base)
+        print_symbol(ctx->gs_base, KERNEL_DATA_ADDR);
+    printf("\\");
+    if (ctx->shadow_gs)
+        print_symbol(ctx->shadow_gs, KERNEL_DATA_ADDR);
+    printf("\n           /%08x(%x)\n", ctx->gs_limit, ctx->gs_arbytes);
+
+    if (xenctx.disp_all) {
+        printf("  tr: %04x @ %016"PRIx64, ctx->tr_sel, ctx->tr_base);
+        if (ctx->tr_base)
+            print_symbol(ctx->tr_base, KERNEL_DATA_ADDR);
+        printf("\n           /%08x(%x)\n", ctx->tr_limit, ctx->tr_arbytes);
+        printf(" ldt: %04x @ %016"PRIx64, ctx->ldtr_sel, ctx->ldtr_base);
+        if (ctx->ldtr_base)
+            print_symbol(ctx->ldtr_base, KERNEL_DATA_ADDR);
+        printf("\n           /%08x(%x)\n", ctx->ldtr_limit, ctx->ldtr_arbytes);
+        printf("\n");
+        printf("cr0: %08"PRIx64"\n", ctx->cr0);
+        printf("cr2: %08"PRIx64, ctx->cr2);
+        print_symbol(ctx->cr2, KERNEL_DATA_ADDR);
+        printf("\n");
+        printf("cr3: %08"PRIx64"\n", ctx->cr3);
+        printf("cr4: %08"PRIx64"\n", ctx->cr4);
+        printf("\n");
+        printf("dr0: %08"PRIx64, ctx->dr0);
+        print_symbol(ctx->dr0, KERNEL_DATA_ADDR);
+        printf("\n");
+        printf("dr1: %08"PRIx64, ctx->dr1);
+        print_symbol(ctx->dr1, KERNEL_DATA_ADDR);
+        printf("\n");
+        printf("dr2: %08"PRIx64, ctx->dr2);
+        print_symbol(ctx->dr2, KERNEL_DATA_ADDR);
+        printf("\n");
+        printf("dr3: %08"PRIx64, ctx->dr3);
+        print_symbol(ctx->dr3, KERNEL_DATA_ADDR);
+        printf("\n");
+        printf("dr6: %08"PRIx64"\n", ctx->dr6);
+        printf("dr7: %08"PRIx64"\n", ctx->dr7);
+        printf("\n");
+        printf("gdt: %016"PRIx64"/%lx", ctx->gdtr_base, 
(long)(ctx->gdtr_limit));
+        print_symbol(ctx->gdtr_base, KERNEL_DATA_ADDR);
+        printf("\n");
+        printf("idt: %016"PRIx64"/%lx", ctx->idtr_base, 
(long)(ctx->idtr_limit));
+        print_symbol(ctx->idtr_base, KERNEL_DATA_ADDR);
+        printf("\n");
+        printf("\n");
+        printf(" EFER: %08"PRIx64" flags: %08"PRIx64"\n",
+               ctx->msr_efer, ctx->msr_flags);
+        printf("SYSENTER cs: %08"PRIx64" esp: %08"PRIx64" eip: %08"PRIx64,
+               ctx->sysenter_cs, ctx->sysenter_esp, ctx->sysenter_eip);
+        print_symbol(ctx->sysenter_eip, KERNEL_TEXT_ADDR);
+        printf("\n");
+        printf(" STAR: %08"PRIx64" SFMASK: %08"PRIx64"\n",
+               ctx->msr_star, ctx->msr_syscall_mask);
+        printf("LSTAR: %08"PRIx64, ctx->msr_lstar);
+        print_symbol(ctx->msr_lstar, KERNEL_TEXT_ADDR);
+        printf("\n");
+        printf("CSTAR: %08"PRIx64, ctx->msr_cstar);
+        print_symbol(ctx->msr_cstar, KERNEL_TEXT_ADDR);
+        printf("\n");
+        printf("\n");
+        printf("\n");
+        printf(" tsc: %016"PRIx64"\n", ctx->tsc);
+        printf("\n");
+        printf("\n");
+        printf("pending_event: %lx  pending_vector: %lx\n",
+               (long)(ctx->pending_event), (long)(ctx->pending_vector));
+        printf("pending error_code: %lx\n\n", (long)(ctx->error_code));
+    }
+}
+
+static void print_cpuctx_regs32(struct hvm_hw_cpu *ctx)
+{
+    printf("cs:eip: %04x:%08x", ctx->cs_sel, (uint32_t)ctx->rip);
+    print_symbol((uint32_t)ctx->rip, KERNEL_TEXT_ADDR);
+    print_flags((uint32_t)ctx->rflags);
+    printf("ss:esp: %04x:%08x\n", ctx->ss_sel, (uint32_t)ctx->rsp);
+    printf("\n");
+
+    printf("eax: %08x\t", (uint32_t)ctx->rax);
+    printf("ebx: %08x\t", (uint32_t)ctx->rbx);
+    printf("ecx: %08x\t", (uint32_t)ctx->rcx);
+    printf("edx: %08x\n", (uint32_t)ctx->rdx);
+
+    printf("esi: %08x\t", (uint32_t)ctx->rsi);
+    printf("edi: %08x\t", (uint32_t)ctx->rdi);
+    printf("ebp: %08x\n", (uint32_t)ctx->rbp);
+    printf("\n");
+
+    printf("  cs: %04x @ %08"PRIx64, ctx->cs_sel, ctx->cs_base);
+    if (ctx->cs_base)
+        print_symbol(ctx->cs_base, KERNEL_DATA_ADDR);
+    printf("\n           /%08x(%x)\n", ctx->cs_limit, ctx->cs_arbytes);
+    printf("  ss: %04x @ %08"PRIx64, ctx->ss_sel, ctx->ss_base);
+    if (ctx->ss_base)
+        print_symbol(ctx->ss_base, KERNEL_DATA_ADDR);
+    printf("\n           /%08x(%x)\n", ctx->ss_limit, ctx->ss_arbytes);
+    printf("  ds: %04x @ %08"PRIx64, ctx->ds_sel, ctx->ds_base);
+    if (ctx->ds_base)
+        print_symbol(ctx->ds_base, KERNEL_DATA_ADDR);
+    printf("\n           /%08x(%x)\n", ctx->ds_limit, ctx->ds_arbytes);
+    printf("  es: %04x @ %08"PRIx64, ctx->es_sel, ctx->es_base);
+    if (ctx->es_base)
+        print_symbol(ctx->es_base, KERNEL_DATA_ADDR);
+    printf("\n           /%08x(%x)\n", ctx->es_limit, ctx->es_arbytes);
+    printf("  fs: %04x @ %08"PRIx64, ctx->fs_sel, ctx->fs_base);
+    if (ctx->fs_base)
+        print_symbol(ctx->fs_base, KERNEL_DATA_ADDR);
+    printf("\n           /%08x(%x)\n", ctx->fs_limit, ctx->fs_arbytes);
+    printf("  gs: %04x @ %08"PRIx64"\\%08"PRIx64, ctx->gs_sel,
+           ctx->gs_base, ctx->shadow_gs);
+    if (ctx->gs_base)
+        print_symbol(ctx->gs_base, KERNEL_DATA_ADDR);
+    printf("\\");
+    if (ctx->shadow_gs)
+        print_symbol(ctx->shadow_gs, KERNEL_DATA_ADDR);
+    printf("\n           /%08x(%x)\n", ctx->gs_limit, ctx->gs_arbytes);
+
+    if (xenctx.disp_all) {
+        printf("  tr: %04x @ %08"PRIx64, ctx->tr_sel, ctx->tr_base);
+        if (ctx->tr_base)
+            print_symbol(ctx->tr_base, KERNEL_DATA_ADDR);
+        printf("\n           /%08x(%x)\n", ctx->tr_limit, ctx->tr_arbytes);
+        printf(" ldt: %04x @ %08"PRIx64, ctx->ldtr_sel, ctx->ldtr_base);
+        if (ctx->ldtr_base)
+            print_symbol(ctx->ldtr_base, KERNEL_DATA_ADDR);
+        printf("\n           /%08x(%x)\n", ctx->ldtr_limit, ctx->ldtr_arbytes);
+        printf("\n");
+        printf("cr0: %08"PRIx64"\n", ctx->cr0);
+        printf("cr2: %08"PRIx64, ctx->cr2);
+        print_symbol(ctx->cr2, KERNEL_DATA_ADDR);
+        printf("\n");
+        printf("cr3: %08"PRIx64"\n", ctx->cr3);
+        printf("cr4: %08"PRIx64"\n", ctx->cr4);
+        printf("\n");
+        printf("dr0: %08"PRIx64, ctx->dr0);
+        print_symbol(ctx->dr0, KERNEL_DATA_ADDR);
+        printf("\n");
+        printf("dr1: %08"PRIx64, ctx->dr1);
+        print_symbol(ctx->dr1, KERNEL_DATA_ADDR);
+        printf("\n");
+        printf("dr2: %08"PRIx64, ctx->dr2);
+        print_symbol(ctx->dr2, KERNEL_DATA_ADDR);
+        printf("\n");
+        printf("dr3: %08"PRIx64, ctx->dr3);
+        print_symbol(ctx->dr3, KERNEL_DATA_ADDR);
+        printf("\n");
+        printf("dr6: %08"PRIx64"\n", ctx->dr6);
+        printf("dr7: %08"PRIx64"\n", ctx->dr7);
+        printf("\n");
+        printf("gdt: %08"PRIx64"/%lx", ctx->gdtr_base, 
(long)(ctx->gdtr_limit));
+        print_symbol(ctx->gdtr_base, KERNEL_DATA_ADDR);
+        printf("\n");
+        printf("idt: %08"PRIx64"/%lx", ctx->idtr_base, 
(long)(ctx->idtr_limit));
+        print_symbol(ctx->idtr_base, KERNEL_DATA_ADDR);
+        printf("\n");
+        printf("\n");
+        printf(" EFER: %08"PRIx64" flags: %08"PRIx64"\n",
+               ctx->msr_efer, ctx->msr_flags);
+        printf("SYSENTER cs: %08"PRIx64" esp: %08"PRIx64" eip: %08"PRIx64,
+               ctx->sysenter_cs, ctx->sysenter_esp, ctx->sysenter_eip);
+        print_symbol(ctx->sysenter_eip, KERNEL_TEXT_ADDR);
+        printf("\n");
+        printf(" STAR: %08"PRIx64" SFMASK: %08"PRIx64"\n",
+               ctx->msr_star, ctx->msr_syscall_mask);
+        printf("LSTAR: %08"PRIx64, ctx->msr_lstar);
+        print_symbol(ctx->msr_lstar, KERNEL_TEXT_ADDR);
+        printf("\n");
+        printf("CSTAR: %08"PRIx64, ctx->msr_cstar);
+        print_symbol(ctx->msr_cstar, KERNEL_TEXT_ADDR);
+        printf("\n");
+        printf("\n");
+        printf(" tsc: %016"PRIx64"\n", ctx->tsc);
+        printf("\n");
+        printf("\n");
+        printf("pending_event: %lx  pending_vector: %lx\n",
+               (long)(ctx->pending_event), (long)(ctx->pending_vector));
+        printf("pending error_code: %lx\n\n", (long)(ctx->error_code));
+    }
+}
+
+static void print_cpuctx(struct hvm_hw_cpu *ctx)
+{
+    if (guest_word_size == 8)
+        print_cpuctx_regs64(ctx);
+    else
+        print_cpuctx_regs32(ctx);
+
+}
+#endif
+
  #define NONPROT_MODE_SEGMENT_SHIFT 4
static guest_word_t instr_pointer(vcpu_guest_context_any_t *ctx)
@@ -887,6 +1128,9 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int 
vcpu, int width, guest
  static void dump_ctx(int vcpu, guest_word_t mem_addr, guest_word_t stk_addr)
  {
      vcpu_guest_context_any_t ctx;
+#if defined(__i386__) || defined(__x86_64__)
+    struct hvm_hw_cpu cpuctx;
+#endif
if (xc_vcpu_getcontext(xenctx.xc_handle, xenctx.domid, vcpu, &ctx) < 0) {
          perror("xc_vcpu_getcontext");
@@ -896,7 +1140,6 @@ static void dump_ctx(int vcpu, guest_word_t mem_addr, 
guest_word_t stk_addr)
  #if defined(__i386__) || defined(__x86_64__)
      {
          if (xenctx.dominfo.hvm) {
-            struct hvm_hw_cpu cpuctx;
              xen_capabilities_info_t xen_caps = "";
              if (xc_domain_hvm_getcontext_partial(
                      xenctx.xc_handle, xenctx.domid, HVM_SAVE_CODE(CPU),
@@ -931,7 +1174,44 @@ static void dump_ctx(int vcpu, guest_word_t mem_addr, 
guest_word_t stk_addr)
  #endif
      } else {
          if (!stk_addr) {
-            print_ctx(&ctx);
+#if defined(__i386__) || defined(__x86_64__)
+            if (xenctx.dominfo.hvm && ctxt_word_size == 8) {
+                if (guest_word_size == 4) {
+                    if ((((uint32_t)ctx.x64.user_regs.eip) != cpuctx.rip) ||
+                        (((uint32_t)ctx.x64.user_regs.esp) != cpuctx.rsp) ||
+                        (((uint32_t)ctx.x64.ctrlreg[3]) != cpuctx.cr3)) {
+                        fprintf(stderr, "Regs mismatch ip=%llx vs %llx sp=%llx vs 
%llx cr3=%llx vs %llx\n",
+                                (long long)((uint32_t)ctx.x64.user_regs.eip),
+                                (long long)cpuctx.rip,
+                                (long long)((uint32_t)ctx.x64.user_regs.esp),
+                                (long long)cpuctx.rsp,
+                                (long long)((uint32_t)ctx.x64.ctrlreg[3]),
+                                (long long)cpuctx.cr3);
+                        fprintf(stdout, "=============Regs mismatch 
start=============\n");
+                        print_ctx(&ctx);
+                        fprintf(stdout, "=============Regs mismatch 
end=============\n");
+                    }
+                } else {
+                    if ((ctx.x64.user_regs.eip != cpuctx.rip) ||
+                        (ctx.x64.user_regs.esp != cpuctx.rsp) ||
+                        (ctx.x64.ctrlreg[3] != cpuctx.cr3)) {
+                        fprintf(stderr, "Regs mismatch ip=%llx vs %llx sp=%llx vs 
%llx cr3=%llx vs %llx\n",
+                                (long long)ctx.x64.user_regs.eip,
+                                (long long)cpuctx.rip,
+                                (long long)ctx.x64.user_regs.esp,
+                                (long long)cpuctx.rsp,
+                                (long long)ctx.x64.ctrlreg[3],
+                                (long long)cpuctx.cr3);
+                        fprintf(stdout, "=============Regs mismatch 
start=============\n");
+                        print_ctx(&ctx);
+                        fprintf(stdout, "=============Regs mismatch 
end=============\n");
+                    }
+                }
+                print_cpuctx(&cpuctx);
+            }
+            else
+#endif
+                print_ctx(&ctx);
          }
  #ifndef NO_TRANSLATION
          if (!stk_addr) {


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.