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

[Xen-changelog] Fix show_registers() on x86/64. Get rid of



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 6f7c5439a6c49e0f74b673e8d7863365075086be
# Parent  57e6d721842703c08bf7dafbfb5efe3c9a44725d
Fix show_registers() on x86/64. Get rid of
GUEST_CONTEXT() macro and the eflags==0 hack to detect
an HVM-guest stack frame. Various cleanups and fixes.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r 57e6d7218427 -r 6f7c5439a6c4 xen/arch/x86/boot/x86_64.S
--- a/xen/arch/x86/boot/x86_64.S        Fri Feb  3 18:45:14 2006
+++ b/xen/arch/x86/boot/x86_64.S        Fri Feb  3 19:30:54 2006
@@ -185,6 +185,7 @@
 ignore_int:
         cld
         leaq    int_msg(%rip),%rdi
+        xorl    %eax,%eax
         call    printf
 1:      jmp     1b
 
diff -r 57e6d7218427 -r 6f7c5439a6c4 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Fri Feb  3 18:45:14 2006
+++ b/xen/arch/x86/domain.c     Fri Feb  3 19:30:54 2006
@@ -384,7 +384,7 @@
     }
     else if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
     {
-       hvm_modify_guest_state(v);
+        hvm_modify_guest_state(v);
     }
 
     if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
@@ -433,10 +433,10 @@
             d->arch.phys_table = v->arch.guest_table;
         v->arch.guest_table = mk_pagetable(0);
 
-       if (!hvm_initialize_guest_resources(v))
+        if ( !hvm_initialize_guest_resources(v) )
             return -EINVAL;
-          
-       hvm_switch_on = 1;
+
+        hvm_switch_on = 1;
     }
 
     update_pagetables(v);
@@ -613,7 +613,7 @@
     unsigned int dirty_segment_mask = 0;
 
     if ( HVM_DOMAIN(v) )
-       hvm_save_segments(v);
+        hvm_save_segments(v);
 
     __asm__ __volatile__ ( "mov %%ds,%0" : "=m" (regs->ds) );
     __asm__ __volatile__ ( "mov %%es,%0" : "=m" (regs->es) );
@@ -773,7 +773,7 @@
         {
             load_LDT(next);
             load_segments(next);
-           if ( HVM_DOMAIN(next) )
+            if ( HVM_DOMAIN(next) )
                 hvm_load_msrs(next);
         }
     }
@@ -964,7 +964,7 @@
             v->arch.guest_table_user = mk_pagetable(0);
         }
 
-       if ( HVM_DOMAIN(v) )
+        if ( HVM_DOMAIN(v) )
             hvm_relinquish_guest_resources(v);
     }
 
diff -r 57e6d7218427 -r 6f7c5439a6c4 xen/arch/x86/hvm/svm/x86_32/exits.S
--- a/xen/arch/x86/hvm/svm/x86_32/exits.S       Fri Feb  3 18:45:14 2006
+++ b/xen/arch/x86/hvm/svm/x86_32/exits.S       Fri Feb  3 19:30:54 2006
@@ -62,7 +62,6 @@
         pushl $HVM_MONITOR_EFLAGS; \
         popf; \
         subl $(NR_SKIPPED_REGS*4), %esp; \
-        movl $0, 0xc(%esp); /* eflags==0 identifies cpu_user_regs as HVM guest 
*/ \
         pushl %eax; \
         pushl %ebp; \
         pushl %edi; \
diff -r 57e6d7218427 -r 6f7c5439a6c4 xen/arch/x86/hvm/vmx/x86_32/exits.S
--- a/xen/arch/x86/hvm/vmx/x86_32/exits.S       Fri Feb  3 18:45:14 2006
+++ b/xen/arch/x86/hvm/vmx/x86_32/exits.S       Fri Feb  3 19:30:54 2006
@@ -61,7 +61,6 @@
         pushl $HVM_MONITOR_EFLAGS; \
         popf; \
         subl $(NR_SKIPPED_REGS*4), %esp; \
-        movl $0, 0xc(%esp); /* eflags==0 identifies cpu_user_regs as HVM guest 
*/ \
         pushl %eax; \
         pushl %ebp; \
         pushl %edi; \
diff -r 57e6d7218427 -r 6f7c5439a6c4 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Fri Feb  3 18:45:14 2006
+++ b/xen/arch/x86/traps.c      Fri Feb  3 19:30:54 2006
@@ -132,6 +132,9 @@
     int i;
     unsigned long *stack, addr;
 
+    if ( HVM_DOMAIN(current) )
+        return;
+
     if ( VM86_MODE(regs) )
     {
         stack = (unsigned long *)((regs->ss << 4) + (regs->esp & 0xffff));
@@ -251,7 +254,7 @@
     unsigned long *stack = ESP_BEFORE_EXCEPTION(regs), addr;
     int i;
 
-    if ( GUEST_CONTEXT(current, regs) )
+    if ( GUEST_MODE(regs) )
         return show_guest_stack(regs);
 
     printk("Xen stack trace from "__OP"sp=%p:\n   ", stack);
@@ -498,7 +501,7 @@
 
     if ( unlikely(IN_HYPERVISOR_RANGE(addr)) )
     {
-        if ( shadow_mode_external(d) && GUEST_CONTEXT(v, regs) )
+        if ( shadow_mode_external(d) && GUEST_MODE(regs) )
             return shadow_fault(addr, regs);
         if ( (addr >= GDT_LDT_VIRT_START) && (addr < GDT_LDT_VIRT_END) )
             return handle_gdt_ldt_mapping_fault(
diff -r 57e6d7218427 -r 6f7c5439a6c4 xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c       Fri Feb  3 18:45:14 2006
+++ b/xen/arch/x86/x86_32/traps.c       Fri Feb  3 19:30:54 2006
@@ -18,57 +18,51 @@
 
 void show_registers(struct cpu_user_regs *regs)
 {
-    struct cpu_user_regs faultregs;
-    unsigned long faultcrs[8];
+    struct cpu_user_regs fault_regs = *regs;
+    unsigned long fault_crs[8];
     const char *context;
 
-    if ( HVM_DOMAIN(current) && regs->eflags == 0 )
-    {
-       context = "hvm";
-       hvm_load_cpu_guest_regs(current, &faultregs);
-       hvm_store_cpu_guest_ctrl_regs(current, faultcrs);
+    if ( HVM_DOMAIN(current) && GUEST_MODE(regs) )
+    {
+        context = "hvm";
+        hvm_store_cpu_guest_regs(current, &fault_regs);
+        hvm_store_cpu_guest_ctrl_regs(current, fault_crs);
     }
     else
     {
-       faultregs = *regs;
-        if ( GUEST_MODE(regs) )
+        context = GUEST_MODE(regs) ? "guest" : "hypervisor";
+
+        if ( !GUEST_MODE(regs) )
         {
-            context = "guest";
-            faultregs.ss &= 0xFFFF;
-            faultregs.ds &= 0xFFFF;
-            faultregs.es &= 0xFFFF;
-            faultregs.cs &= 0xFFFF;
-       }
-       else 
-       {
-            context = "hypervisor";
-            faultregs.esp = (unsigned long)&regs->esp;
-            faultregs.ss = __HYPERVISOR_DS;
-            faultregs.ds = __HYPERVISOR_DS;
-            faultregs.es = __HYPERVISOR_DS;
-            faultregs.cs = __HYPERVISOR_CS;
-       }
-        __asm__ ("movw %%fs,%0 ; movw %%gs,%1"
-                : "=r" (faultregs.fs), "=r" (faultregs.gs) );
-
-       faultcrs[0] = read_cr0();
-       faultcrs[3] = read_cr3();
+            fault_regs.esp = (unsigned long)&regs->esp;
+            fault_regs.ss = __HYPERVISOR_DS;
+            fault_regs.ds = __HYPERVISOR_DS;
+            fault_regs.es = __HYPERVISOR_DS;
+            fault_regs.cs = __HYPERVISOR_CS;
+        }
+
+        __asm__ (
+            "movw %%fs,%0 ; movw %%gs,%1"
+            : "=r" (fault_regs.fs), "=r" (fault_regs.gs) );
+        
+        fault_crs[0] = read_cr0();
+        fault_crs[3] = read_cr3();
     }
 
     printk("CPU:    %d\nEIP:    %04x:[<%08x>]",
-           smp_processor_id(), faultregs.cs, faultregs.eip);
-    if ( !HVM_DOMAIN(current) && !GUEST_MODE(regs) )
-        print_symbol(" %s", faultregs.eip);
-    printk("\nEFLAGS: %08x   CONTEXT: %s\n", faultregs.eflags, context);
+           smp_processor_id(), fault_regs.cs, fault_regs.eip);
+    if ( !GUEST_MODE(regs) )
+        print_symbol(" %s", fault_regs.eip);
+    printk("\nEFLAGS: %08x   CONTEXT: %s\n", fault_regs.eflags, context);
     printk("eax: %08x   ebx: %08x   ecx: %08x   edx: %08x\n",
-           regs->eax, regs->ebx, regs->ecx, regs->edx);
+           fault_regs.eax, fault_regs.ebx, fault_regs.ecx, fault_regs.edx);
     printk("esi: %08x   edi: %08x   ebp: %08x   esp: %08x\n",
-           regs->esi, regs->edi, regs->ebp, faultregs.esp);
-    printk("cr0: %08lx   cr3: %08lx\n", faultcrs[0], faultcrs[3]);
+           fault_regs.esi, fault_regs.edi, fault_regs.ebp, fault_regs.esp);
+    printk("cr0: %08lx   cr3: %08lx\n", fault_crs[0], fault_crs[3]);
     printk("ds: %04x   es: %04x   fs: %04x   gs: %04x   "
            "ss: %04x   cs: %04x\n",
-           faultregs.ds, faultregs.es, faultregs.fs,
-          faultregs.gs, faultregs.ss, faultregs.cs);
+           fault_regs.ds, fault_regs.es, fault_regs.fs,
+           fault_regs.gs, fault_regs.ss, fault_regs.cs);
 
     show_stack(regs);
 }
diff -r 57e6d7218427 -r 6f7c5439a6c4 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S       Fri Feb  3 18:45:14 2006
+++ b/xen/arch/x86/x86_64/entry.S       Fri Feb  3 19:30:54 2006
@@ -311,8 +311,15 @@
         .asciz "domain_crash_sync called from entry.S\n"
 
 domain_crash_synchronous:
-        leaq domain_crash_synchronous_string(%rip),%rdi
-        call printf
+        # Get out of the guest-save area of the stack.
+        GET_GUEST_REGS(%rax)
+        movq  %rax,%rsp
+        # create_bounce_frame() temporarily clobbers CS.RPL. Fix up.
+        orb   $3,UREGS_cs(%rsp)
+        # printk(domain_crash_synchronous_string)
+        leaq  domain_crash_synchronous_string(%rip),%rdi
+        xorl  %eax,%eax
+        call  printf
         jmp  __domain_crash_synchronous
 
         ALIGN
@@ -468,6 +475,18 @@
 ENTRY(nmi)
         pushq $0
         SAVE_ALL
+        testb $3,UREGS_cs(%rsp)
+        jz    nmi_in_hypervisor_mode
+        /* Interrupted guest context. Copy the context to stack bottom. */
+        GET_GUEST_REGS(%rbx)
+        addq  $UREGS_kernel_sizeof,%rbx
+        movl  $UREGS_kernel_sizeof/8,%ecx
+1:      popq  %rax
+        subq  $8,%rbx
+        movq  %rax,(%rbx)
+        loop  1b
+        movq  %rbx,%rsp
+nmi_in_hypervisor_mode:
         movq  %rsp,%rdi
         call  do_nmi
         jmp   ret_from_intr
diff -r 57e6d7218427 -r 6f7c5439a6c4 xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c       Fri Feb  3 18:45:14 2006
+++ b/xen/arch/x86/x86_64/traps.c       Fri Feb  3 19:30:54 2006
@@ -18,52 +18,40 @@
 
 void show_registers(struct cpu_user_regs *regs)
 {
-    struct cpu_user_regs faultregs;
-    unsigned long faultcrs[8];
+    struct cpu_user_regs fault_regs = *regs;
+    unsigned long fault_crs[8];
     const char *context;
 
-    if ( HVM_DOMAIN(current) && regs->eflags == 0 )
-    {
-       context = "hvm";
-       hvm_load_cpu_guest_regs(current, &faultregs);
-       hvm_store_cpu_guest_ctrl_regs(current, faultcrs);
+    if ( HVM_DOMAIN(current) && GUEST_MODE(regs) )
+    {
+        context = "hvm";
+        hvm_store_cpu_guest_regs(current, &fault_regs);
+        hvm_store_cpu_guest_ctrl_regs(current, fault_crs);
     }
     else
     {
-       faultregs = *regs;
-
-        if ( GUEST_MODE(regs) )
-        {
-            context = "guest";
-       }
-       else 
-       {
-            context = "hypervisor";
-            faultregs.esp = (unsigned long)&regs->esp;
-       }
-
-       faultcrs[0] = read_cr0();
-       faultcrs[3] = read_cr3();
+        context = GUEST_MODE(regs) ? "guest" : "hypervisor";
+        fault_crs[0] = read_cr0();
+        fault_crs[3] = read_cr3();
     }
 
     printk("CPU:    %d\nRIP:    %04x:[<%016lx>]",
-           smp_processor_id(), faultregs.cs, faultregs.rip);
-    if ( !HVM_DOMAIN(current) && !GUEST_MODE(regs) )
-        print_symbol(" %s", faultregs.rip);
-
-    printk("\nRFLAGS: %016lx   CONTEXT: %s\n", faultregs.rflags, context);
+           smp_processor_id(), fault_regs.cs, fault_regs.rip);
+    if ( !GUEST_MODE(regs) )
+        print_symbol(" %s", fault_regs.rip);
+    printk("\nRFLAGS: %016lx   CONTEXT: %s\n", fault_regs.rflags, context);
     printk("rax: %016lx   rbx: %016lx   rcx: %016lx\n",
-           regs->rax, regs->rbx, regs->rcx);
+           fault_regs.rax, fault_regs.rbx, fault_regs.rcx);
     printk("rdx: %016lx   rsi: %016lx   rdi: %016lx\n",
-           regs->rdx, regs->rsi, regs->rdi);
+           fault_regs.rdx, fault_regs.rsi, fault_regs.rdi);
     printk("rbp: %016lx   rsp: %016lx   r8:  %016lx\n",
-           regs->rbp, faultregs.rsp, regs->r8);
+           fault_regs.rbp, fault_regs.rsp, fault_regs.r8);
     printk("r9:  %016lx   r10: %016lx   r11: %016lx\n",
-           regs->r9,  regs->r10, regs->r11);
+           fault_regs.r9,  fault_regs.r10, fault_regs.r11);
     printk("r12: %016lx   r13: %016lx   r14: %016lx\n",
-           regs->r12, regs->r13, regs->r14);
+           fault_regs.r12, fault_regs.r13, fault_regs.r14);
     printk("r15: %016lx   cr0: %016lx   cr3: %016lx\n",
-           regs->r15, faultcrs[0], faultcrs[3]);
+           fault_regs.r15, fault_crs[0], fault_crs[3]);
 
     show_stack(regs);
 }
diff -r 57e6d7218427 -r 6f7c5439a6c4 xen/include/asm-x86/regs.h
--- a/xen/include/asm-x86/regs.h        Fri Feb  3 18:45:14 2006
+++ b/xen/include/asm-x86/regs.h        Fri Feb  3 19:30:54 2006
@@ -31,8 +31,17 @@
     EF_ID   = 0x00200000,   /* id */
 };
 
-#define GUEST_MODE(_r) (likely(VM86_MODE(_r) || !RING_0(_r)))
-
-#define GUEST_CONTEXT(_ed, _r) ((HVM_DOMAIN(_ed) && ((_r)->eflags == 0)) || 
GUEST_MODE(_r))
+#define GUEST_MODE(r)                                                         \
+({                                                                            \
+    unsigned long diff = (char *)guest_cpu_user_regs() - (char *)(r);         \
+    /* Frame pointer must point into current CPU stack. */                    \
+    ASSERT(diff < STACK_SIZE);                                                \
+    /* If a guest frame, it must not be a ring 0 frame (unless HVM guest). */ \
+    ASSERT((diff != 0) || VM86_MODE(r) || !RING_0(r) || HVM_DOMAIN(current)); \
+    /* If not a guest frame, it must be a ring 0 frame. */                    \
+    ASSERT((diff == 0) || (!VM86_MODE(r) && RING_0(r)));                      \
+    /* Return TRUE if it's a guest frame. */                                  \
+    (diff == 0);                                                              \
+})
 
 #endif /* __X86_REGS_H__ */

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


 


Rackspace

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