WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] xenctx: compat-mode/HVM support

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] xenctx: compat-mode/HVM support
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 08 Jan 2009 06:57:30 -0800
Delivery-date: Thu, 08 Jan 2009 07:01:03 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1231153733 0
# Node ID 9cc632cc6d400685679671b6bbc58dfe4c5e287e
# Parent  34f52eafd4e32b297a24f58cef60770e00c5bb15
xenctx: compat-mode/HVM support

Add support to xenctx for guests that have a different word size
to the tools (x86 only, but shouldn't break ia64).  Again, only 32-bit
HVM guests are supported until EFER.LMA is easier to get at.

Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx>
---
 tools/xentrace/xenctx.c |  328 +++++++++++++++++++++++++++++-------------------
 1 files changed, 204 insertions(+), 124 deletions(-)

diff -r 34f52eafd4e3 -r 9cc632cc6d40 tools/xentrace/xenctx.c
--- a/tools/xentrace/xenctx.c   Mon Jan 05 11:08:25 2009 +0000
+++ b/tools/xentrace/xenctx.c   Mon Jan 05 11:08:53 2009 +0000
@@ -24,6 +24,8 @@
 #include <getopt.h>
 
 #include "xenctrl.h"
+#include <xen/foreign/x86_32.h>
+#include <xen/foreign/x86_64.h>
 
 int xc_handle = 0;
 int domid = 0;
@@ -31,28 +33,18 @@ int stack_trace = 0;
 int stack_trace = 0;
 int disp_all = 0;
 
-#if defined (__i386__)
-#if defined (__OpenBSD__)
-#define FMT_SIZE_T             "%08lx"
-#define INSTR_POINTER(regs)    (unsigned long)(regs->eip)
-#else
-#define FMT_SIZE_T             "%08x"
-#define INSTR_POINTER(regs)    (regs->eip)
-#endif
-#define STACK_POINTER(regs)    (regs->esp)
-#define FRAME_POINTER(regs)    (regs->ebp)
-#define STACK_ROWS             4
-#define STACK_COLS             8
-#elif defined (__x86_64__)
-#define FMT_SIZE_T             "%016lx"
-#define STACK_POINTER(regs)    (regs->rsp)
-#define FRAME_POINTER(regs)    (regs->rbp)
-#define INSTR_POINTER(regs)    (regs->rip)
-#define STACK_ROWS             4
-#define STACK_COLS             4
+#if defined (__i386__) || defined (__x86_64__)
+typedef unsigned long long guest_word_t;
+#define FMT_32B_WORD "%08llx"
+#define FMT_64B_WORD "%016llx"
+/* Word-length of the guest's own data structures */
+int guest_word_size = sizeof (unsigned long);
+/* Word-length of the context record we get from xen */
+int ctxt_word_size = sizeof (unsigned long);
 #elif defined (__ia64__)
 /* On ia64, we can't translate virtual address to physical address.  */
 #define NO_TRANSLATION
+typedef size_t guest_word_t;
 
 /* Which registers should be displayed.  */
 int disp_cr_regs;
@@ -63,22 +55,19 @@ int disp_tlb;
 #endif
 
 struct symbol {
-    size_t address;
+    guest_word_t address;
     char type;
     char *name;
     struct symbol *next;
 } *symbol_table = NULL;
 
-size_t kernel_stext, kernel_etext, kernel_sinittext, kernel_einittext, 
kernel_hypercallpage;
-
-static int is_kernel_text(size_t addr)
-{
-#if defined (__i386__)
+guest_word_t kernel_stext, kernel_etext, kernel_sinittext, kernel_einittext, 
kernel_hypercallpage;
+
+static int is_kernel_text(guest_word_t addr)
+{
+#if defined (__i386__) || defined (__x86_64__)
     if (symbol_table == NULL)
-        return (addr > 0xc000000);
-#elif defined (__x86_64__)
-    if (symbol_table == NULL)
-        return (addr > 0xffffffff80000000UL);
+        return (addr > ((guest_word_size == 4) ? 0xc000000 : 
0xffffffff80000000ULL));
 #elif defined (__ia64__)
     if (symbol_table == NULL)
         return (addr > 0xa000000000000000UL);
@@ -134,7 +123,7 @@ static void insert_symbol(struct symbol 
     prev = symbol;
 }
 
-static struct symbol *lookup_symbol(size_t address)
+static struct symbol *lookup_symbol(guest_word_t address)
 {
     struct symbol *s = symbol_table;
 
@@ -147,7 +136,7 @@ static struct symbol *lookup_symbol(size
     return NULL;
 }
 
-static void print_symbol(size_t addr)
+static void print_symbol(guest_word_t addr)
 {
     struct symbol *s;
 
@@ -255,21 +244,23 @@ static void print_flags(uint64_t flags)
     printf("\n");
 }
 
-static void print_special(unsigned long *regs, const char *name, unsigned int 
mask)
+static void print_special(void *regs, const char *name, unsigned int mask, int 
width)
 {
     unsigned int i;
 
     printf("\n");
     for (i = 0; mask; mask >>= 1, ++i)
-        if (mask & 1)
-            printf("%s%u: " FMT_SIZE_T "\n", name, i, (size_t)regs[i]);
-}
-#endif
-
-#ifdef __i386__
-static void print_ctx(vcpu_guest_context_t *ctx1)
-{
-    struct cpu_user_regs *regs = &ctx1->user_regs;
+        if (mask & 1) {
+            if (width == 4)
+                printf("%s%u: %08"PRIx32"\n", name, i, ((uint32_t *) regs)[i]);
+            else
+                printf("%s%u: %08"PRIx64"\n", name, i, ((uint64_t *) regs)[i]);
+        }
+}
+
+static void print_ctx_32(vcpu_guest_context_x86_32_t *ctx)
+{
+    struct cpu_user_regs_x86_32 *regs = &ctx->user_regs;
 
     printf("cs:eip: %04x:%08x ", regs->cs, regs->eip);
     print_symbol(regs->eip);
@@ -291,54 +282,87 @@ static void print_ctx(vcpu_guest_context
     printf(" gs:     %04x\n", regs->gs);
 
     if (disp_all) {
-        print_special(ctx1->ctrlreg, "cr", 0x1d);
-        print_special(ctx1->debugreg, "dr", 0xcf);
-    }
-}
-#elif defined(__x86_64__)
-static void print_ctx(vcpu_guest_context_t *ctx1)
-{
-    struct cpu_user_regs *regs = &ctx1->user_regs;
-
-    printf("rip: %016lx ", regs->rip);
+        print_special(ctx->ctrlreg, "cr", 0x1d, 4);
+        print_special(ctx->debugreg, "dr", 0xcf, 4);
+    }
+}
+
+static void print_ctx_64(vcpu_guest_context_x86_64_t *ctx)
+{
+    struct cpu_user_regs_x86_64 *regs = &ctx->user_regs;
+
+    printf("rip: %016"PRIx64" ", regs->rip);
     print_symbol(regs->rip);
     print_flags(regs->rflags);
-    printf("rsp: %016lx\n", regs->rsp);
-
-    printf("rax: %016lx\t", regs->rax);
-    printf("rcx: %016lx\t", regs->rcx);
-    printf("rdx: %016lx\n", regs->rdx);
-
-    printf("rbx: %016lx\t", regs->rbx);
-    printf("rsi: %016lx\t", regs->rsi);
-    printf("rdi: %016lx\n", regs->rdi);
-
-    printf("rbp: %016lx\t", regs->rbp);
-    printf(" r8: %016lx\t", regs->r8);
-    printf(" r9: %016lx\n", regs->r9);
-
-    printf("r10: %016lx\t", regs->r10);
-    printf("r11: %016lx\t", regs->r11);
-    printf("r12: %016lx\n", regs->r12);
-
-    printf("r13: %016lx\t", regs->r13);
-    printf("r14: %016lx\t", regs->r14);
-    printf("r15: %016lx\n", regs->r15);
+    printf("rsp: %016"PRIx64"\n", regs->rsp);
+
+    printf("rax: %016"PRIx64"\t", regs->rax);
+    printf("rcx: %016"PRIx64"\t", regs->rcx);
+    printf("rdx: %016"PRIx64"\n", regs->rdx);
+
+    printf("rbx: %016"PRIx64"\t", regs->rbx);
+    printf("rsi: %016"PRIx64"\t", regs->rsi);
+    printf("rdi: %016"PRIx64"\n", regs->rdi);
+
+    printf("rbp: %016"PRIx64"\t", regs->rbp);
+    printf(" r8: %016"PRIx64"\t", regs->r8);
+    printf(" r9: %016"PRIx64"\n", regs->r9);
+
+    printf("r10: %016"PRIx64"\t", regs->r10);
+    printf("r11: %016"PRIx64"\t", regs->r11);
+    printf("r12: %016"PRIx64"\n", regs->r12);
+
+    printf("r13: %016"PRIx64"\t", regs->r13);
+    printf("r14: %016"PRIx64"\t", regs->r14);
+    printf("r15: %016"PRIx64"\n", regs->r15);
 
     printf(" cs: %04x\t", regs->cs);
     printf(" ss: %04x\t", regs->ss);
     printf(" ds: %04x\t", regs->ds);
     printf(" es: %04x\n", regs->es);
 
-    printf(" fs: %04x @ %016lx\n", regs->fs, ctx1->fs_base);
-    printf(" gs: %04x @ %016lx/%016lx\n", regs->gs,
-           ctx1->gs_base_kernel, ctx1->gs_base_user);
+    printf(" fs: %04x @ %016"PRIx64"\n", regs->fs, ctx->fs_base);
+    printf(" gs: %04x @ %016"PRIx64"/%016"PRIx64"\n", regs->gs,
+           ctx->gs_base_kernel, ctx->gs_base_user);
 
     if (disp_all) {
-        print_special(ctx1->ctrlreg, "cr", 0x1d);
-        print_special(ctx1->debugreg, "dr", 0xcf);
-    }
-}
+        print_special(ctx->ctrlreg, "cr", 0x1d, 8);
+        print_special(ctx->debugreg, "dr", 0xcf, 8);
+    }
+}
+
+static void print_ctx(vcpu_guest_context_any_t *ctx)
+{
+    if (ctxt_word_size == 4) 
+        print_ctx_32(&ctx->x32);
+    else 
+        print_ctx_64(&ctx->x64);
+}
+
+static guest_word_t instr_pointer(vcpu_guest_context_any_t *ctx)
+{
+    if (ctxt_word_size == 4) 
+        return ctx->x32.user_regs.eip;
+    else 
+        return ctx->x64.user_regs.rip;
+}
+
+static guest_word_t stack_pointer(vcpu_guest_context_any_t *ctx)
+{
+    if (ctxt_word_size == 4) 
+        return ctx->x32.user_regs.esp;
+    else 
+        return ctx->x64.user_regs.rsp;
+}
+
+static guest_word_t frame_pointer(vcpu_guest_context_any_t *ctx)
+{
+    if (ctxt_word_size == 4) 
+        return ctx->x32.user_regs.ebp;
+    else 
+        return ctx->x64.user_regs.rbp;
+}
+
 #elif defined(__ia64__)
 
 #define PTE_ED_SHIFT              52
@@ -401,9 +425,9 @@ static void print_tr(int i, const struct
            tr->itir >> ITIR_KEY_SHIFT & ITIR_KEY_MASK);
 }
 
-void print_ctx(vcpu_guest_context_t *ctx)
-{
-    struct vcpu_guest_context_regs *regs = &ctx->regs;
+void print_ctx(vcpu_guest_context_any_t *ctx)
+{
+    struct vcpu_guest_context_regs *regs = &ctx.c->regs;
     struct vcpu_tr_regs *tr = &ctx->regs.tr;
     int i;
     unsigned int rbs_size, cfm_sof;
@@ -584,7 +608,7 @@ void print_ctx(vcpu_guest_context_t *ctx
 #endif
 
 #ifndef NO_TRANSLATION
-static void *map_page(vcpu_guest_context_t *ctx, int vcpu, size_t virt)
+static void *map_page(vcpu_guest_context_any_t *ctx, int vcpu, guest_word_t 
virt)
 {
     static unsigned long previous_mfn = 0;
     static void *mapped = NULL;
@@ -611,33 +635,53 @@ static void *map_page(vcpu_guest_context
     return (void *)(mapped + offset);
 }
 
-static void print_stack(vcpu_guest_context_t *ctx, int vcpu)
-{
-    struct cpu_user_regs *regs = &ctx->user_regs;
-    size_t stack = STACK_POINTER(regs);
-    size_t stack_limit = (STACK_POINTER(regs) & XC_PAGE_MASK) + XC_PAGE_SIZE;
-    size_t frame;
-    size_t instr;
-    size_t *p;
+static guest_word_t read_stack_word(guest_word_t *src, int width)
+{
+    guest_word_t word = 0;
+    /* Little-endian only */
+    memcpy(&word, src, width);
+    return word;
+}
+
+static void print_stack_word(guest_word_t word, int width)
+{
+    if (width == 4)
+        printf(FMT_32B_WORD, word);
+    else
+        printf(FMT_64B_WORD, word);
+}
+
+static void print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
+{
+    guest_word_t stack = stack_pointer(ctx);
+    guest_word_t stack_limit;
+    guest_word_t frame;
+    guest_word_t instr;
+    guest_word_t word;
+    guest_word_t *p;
     int i;
 
+    stack_limit = ((stack_pointer(ctx) + XC_PAGE_SIZE)
+                   & ~((guest_word_t) XC_PAGE_SIZE - 1)); 
     printf("\n");
     printf("Stack:\n");
-    for (i=1; i<STACK_ROWS+1 && stack < stack_limit; i++) {
-        while(stack < stack_limit && stack < STACK_POINTER(regs) + 
i*STACK_COLS*sizeof(stack)) {
+    for (i=1; i<5 && stack < stack_limit; i++) {
+        while(stack < stack_limit && stack < stack_pointer(ctx) + i*32) {
             p = map_page(ctx, vcpu, stack);
-            printf(" " FMT_SIZE_T, *p);
-            stack += sizeof(stack);
+            word = read_stack_word(p, width);
+            printf(" ");
+            print_stack_word(word, width);
+            stack += width;
         }
         printf("\n");
     }
     printf("\n");
 
     printf("Code:\n");
-    instr = INSTR_POINTER(regs) - 21;
+    instr = instr_pointer(ctx) - 21;
     for(i=0; i<32; i++) {
         unsigned char *c = map_page(ctx, vcpu, instr+i);
-        if (instr+i == INSTR_POINTER(regs))
+        if (instr+i == instr_pointer(ctx))
             printf("<%02x> ", *c);
         else
             printf("%02x ", *c);
@@ -650,52 +694,65 @@ static void print_stack(vcpu_guest_conte
         printf("Stack Trace:\n");
     else
         printf("Call Trace:\n");
-    printf("%c [<" FMT_SIZE_T ">] ",
-        stack_trace ? '*' : ' ', INSTR_POINTER(regs));
-
-    print_symbol(INSTR_POINTER(regs));
+    printf("%c [<", stack_trace ? '*' : ' ');
+    print_stack_word(instr_pointer(ctx), width);
+    printf(">] ");
+
+    print_symbol(instr_pointer(ctx));
     printf(" <--\n");
     if (frame_ptrs) {
-        stack = STACK_POINTER(regs);
-        frame = FRAME_POINTER(regs);
+        stack = stack_pointer(ctx);
+        frame = frame_pointer(ctx);
         while(frame && stack < stack_limit) {
             if (stack_trace) {
                 while (stack < frame) {
                     p = map_page(ctx, vcpu, stack);
-                    printf("|   " FMT_SIZE_T "   ", *p);
-                    printf("\n");
-                    stack += sizeof(*p);
+                    printf("|   ");
+                    print_stack_word(read_stack_word(p, width), width);
+                    printf("   \n");
+                    stack += width;
                 }
             } else {
                 stack = frame;
             }
 
             p = map_page(ctx, vcpu, stack);
-            frame = *p;
-            if (stack_trace)
-                printf("|-- " FMT_SIZE_T "\n", *p);
-            stack += sizeof(*p);
+            frame = read_stack_word(p, width);
+            if (stack_trace) {
+                printf("|-- ");
+                print_stack_word(read_stack_word(p, width), width);
+                printf("\n");
+            }
+            stack += width;
 
             if (frame) {
                 p = map_page(ctx, vcpu, stack);
-                printf("%c [<" FMT_SIZE_T ">] ", stack_trace ? '|' : ' ', *p);
-                print_symbol(*p);
+                word = read_stack_word(p, width);
+                printf("%c [<", stack_trace ? '|' : ' ');
+                print_stack_word(word, width);
+                printf(">] ");
+                print_symbol(word);
                 printf("\n");
-                stack += sizeof(*p);
+                stack += width;
             }
         }
     } else {
-        stack = STACK_POINTER(regs);
+        stack = stack_pointer(ctx);
         while(stack < stack_limit) {
             p = map_page(ctx, vcpu, stack);
-            if (is_kernel_text(*p)) {
-                printf("  [<" FMT_SIZE_T ">] ", *p);
-                print_symbol(*p);
+            word = read_stack_word(p, width);
+            if (is_kernel_text(word)) {
+                printf("  [<");
+                print_stack_word(word, width);
+                printf(">] ");
+                print_symbol(word);
                 printf("\n");
             } else if (stack_trace) {
-                printf("    " FMT_SIZE_T "\n", *p);
+                printf("    ");
+                print_stack_word(word, width);
+                printf("\n");
             }
-            stack += sizeof(*p);
+            stack += width;
         }
     }
 }
@@ -729,10 +786,33 @@ static void dump_ctx(int vcpu)
         exit(-1);
     }
 
-    print_ctx(&ctx.c);
+#if defined(__i386__) || defined(__x86_64__)
+    {
+        struct xen_domctl domctl;
+        memset(&domctl, 0, sizeof domctl);
+        domctl.domain = domid;
+        domctl.cmd = XEN_DOMCTL_get_address_size;
+        if (xc_domctl(xc_handle, &domctl) == 0)
+            ctxt_word_size = guest_word_size = domctl.u.address_size.size / 8;
+        if (dominfo.hvm) {
+            xen_capabilities_info_t xen_caps = "";
+            if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0) {
+                perror("xc_version");
+                exit(-1);
+            }
+            /* HVM guest context records are always host-sized */
+            ctxt_word_size = (strstr(xen_caps, "xen-3.0-x86_64")) ? 8 : 4;
+            /* XXX For now we can't tell whether a HVM guest is in long
+             * XXX mode; eventually fix this here and in xc_pagetab.c */
+            guest_word_size = 4;
+        }
+    }
+#endif
+
+    print_ctx(&ctx);
 #ifndef NO_TRANSLATION
-    if (is_kernel_text(INSTR_POINTER((&ctx.c.user_regs))))
-        print_stack(&ctx.c, vcpu);
+    if (is_kernel_text(instr_pointer(&ctx)))
+        print_stack(&ctx, vcpu, guest_word_size);
 #endif
 
     if (!dominfo.paused) {
@@ -774,9 +854,9 @@ int main(int argc, char **argv)
 int main(int argc, char **argv)
 {
     int ch;
-    static const char *sopts = "fs:h"
+    static const char *sopts = "fs:ha"
 #ifdef __ia64__
-        "ar:"
+        "r:"
 #endif
         ;
     static const struct option lopts[] = {

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] xenctx: compat-mode/HVM support, Xen patchbot-unstable <=