ia64/xen-unstable

changeset 8759:6f7c5439a6c4

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@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri Feb 03 20:30:54 2006 +0100 (2006-02-03)
parents 57e6d7218427
children bf176086255b
files xen/arch/x86/boot/x86_64.S xen/arch/x86/domain.c xen/arch/x86/hvm/svm/x86_32/exits.S xen/arch/x86/hvm/vmx/x86_32/exits.S xen/arch/x86/traps.c xen/arch/x86/x86_32/traps.c xen/arch/x86/x86_64/entry.S xen/arch/x86/x86_64/traps.c xen/include/asm-x86/regs.h
line diff
     1.1 --- a/xen/arch/x86/boot/x86_64.S	Fri Feb 03 18:45:14 2006 +0000
     1.2 +++ b/xen/arch/x86/boot/x86_64.S	Fri Feb 03 20:30:54 2006 +0100
     1.3 @@ -185,6 +185,7 @@ int_msg:
     1.4  ignore_int:
     1.5          cld
     1.6          leaq    int_msg(%rip),%rdi
     1.7 +        xorl    %eax,%eax
     1.8          call    printf
     1.9  1:      jmp     1b
    1.10  
     2.1 --- a/xen/arch/x86/domain.c	Fri Feb 03 18:45:14 2006 +0000
     2.2 +++ b/xen/arch/x86/domain.c	Fri Feb 03 20:30:54 2006 +0100
     2.3 @@ -384,7 +384,7 @@ int arch_set_info_guest(
     2.4      }
     2.5      else if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
     2.6      {
     2.7 -	hvm_modify_guest_state(v);
     2.8 +        hvm_modify_guest_state(v);
     2.9      }
    2.10  
    2.11      if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
    2.12 @@ -433,10 +433,10 @@ int arch_set_info_guest(
    2.13              d->arch.phys_table = v->arch.guest_table;
    2.14          v->arch.guest_table = mk_pagetable(0);
    2.15  
    2.16 -	if (!hvm_initialize_guest_resources(v))
    2.17 +        if ( !hvm_initialize_guest_resources(v) )
    2.18              return -EINVAL;
    2.19 -	   
    2.20 -	hvm_switch_on = 1;
    2.21 +
    2.22 +        hvm_switch_on = 1;
    2.23      }
    2.24  
    2.25      update_pagetables(v);
    2.26 @@ -613,7 +613,7 @@ static void save_segments(struct vcpu *v
    2.27      unsigned int dirty_segment_mask = 0;
    2.28  
    2.29      if ( HVM_DOMAIN(v) )
    2.30 -	hvm_save_segments(v);
    2.31 +        hvm_save_segments(v);
    2.32  
    2.33      __asm__ __volatile__ ( "mov %%ds,%0" : "=m" (regs->ds) );
    2.34      __asm__ __volatile__ ( "mov %%es,%0" : "=m" (regs->es) );
    2.35 @@ -773,7 +773,7 @@ void context_switch(struct vcpu *prev, s
    2.36          {
    2.37              load_LDT(next);
    2.38              load_segments(next);
    2.39 -	    if ( HVM_DOMAIN(next) )
    2.40 +            if ( HVM_DOMAIN(next) )
    2.41                  hvm_load_msrs(next);
    2.42          }
    2.43      }
    2.44 @@ -964,7 +964,7 @@ void domain_relinquish_resources(struct 
    2.45              v->arch.guest_table_user = mk_pagetable(0);
    2.46          }
    2.47  
    2.48 -	if ( HVM_DOMAIN(v) )
    2.49 +        if ( HVM_DOMAIN(v) )
    2.50              hvm_relinquish_guest_resources(v);
    2.51      }
    2.52  
     3.1 --- a/xen/arch/x86/hvm/svm/x86_32/exits.S	Fri Feb 03 18:45:14 2006 +0000
     3.2 +++ b/xen/arch/x86/hvm/svm/x86_32/exits.S	Fri Feb 03 20:30:54 2006 +0100
     3.3 @@ -62,7 +62,6 @@
     3.4          pushl $HVM_MONITOR_EFLAGS; \
     3.5          popf; \
     3.6          subl $(NR_SKIPPED_REGS*4), %esp; \
     3.7 -        movl $0, 0xc(%esp); /* eflags==0 identifies cpu_user_regs as HVM guest */ \
     3.8          pushl %eax; \
     3.9          pushl %ebp; \
    3.10          pushl %edi; \
     4.1 --- a/xen/arch/x86/hvm/vmx/x86_32/exits.S	Fri Feb 03 18:45:14 2006 +0000
     4.2 +++ b/xen/arch/x86/hvm/vmx/x86_32/exits.S	Fri Feb 03 20:30:54 2006 +0100
     4.3 @@ -61,7 +61,6 @@
     4.4          pushl $HVM_MONITOR_EFLAGS; \
     4.5          popf; \
     4.6          subl $(NR_SKIPPED_REGS*4), %esp; \
     4.7 -        movl $0, 0xc(%esp); /* eflags==0 identifies cpu_user_regs as HVM guest */ \
     4.8          pushl %eax; \
     4.9          pushl %ebp; \
    4.10          pushl %edi; \
     5.1 --- a/xen/arch/x86/traps.c	Fri Feb 03 18:45:14 2006 +0000
     5.2 +++ b/xen/arch/x86/traps.c	Fri Feb 03 20:30:54 2006 +0100
     5.3 @@ -132,6 +132,9 @@ static void show_guest_stack(struct cpu_
     5.4      int i;
     5.5      unsigned long *stack, addr;
     5.6  
     5.7 +    if ( HVM_DOMAIN(current) )
     5.8 +        return;
     5.9 +
    5.10      if ( VM86_MODE(regs) )
    5.11      {
    5.12          stack = (unsigned long *)((regs->ss << 4) + (regs->esp & 0xffff));
    5.13 @@ -251,7 +254,7 @@ void show_stack(struct cpu_user_regs *re
    5.14      unsigned long *stack = ESP_BEFORE_EXCEPTION(regs), addr;
    5.15      int i;
    5.16  
    5.17 -    if ( GUEST_CONTEXT(current, regs) )
    5.18 +    if ( GUEST_MODE(regs) )
    5.19          return show_guest_stack(regs);
    5.20  
    5.21      printk("Xen stack trace from "__OP"sp=%p:\n   ", stack);
    5.22 @@ -498,7 +501,7 @@ static int fixup_page_fault(unsigned lon
    5.23  
    5.24      if ( unlikely(IN_HYPERVISOR_RANGE(addr)) )
    5.25      {
    5.26 -        if ( shadow_mode_external(d) && GUEST_CONTEXT(v, regs) )
    5.27 +        if ( shadow_mode_external(d) && GUEST_MODE(regs) )
    5.28              return shadow_fault(addr, regs);
    5.29          if ( (addr >= GDT_LDT_VIRT_START) && (addr < GDT_LDT_VIRT_END) )
    5.30              return handle_gdt_ldt_mapping_fault(
     6.1 --- a/xen/arch/x86/x86_32/traps.c	Fri Feb 03 18:45:14 2006 +0000
     6.2 +++ b/xen/arch/x86/x86_32/traps.c	Fri Feb 03 20:30:54 2006 +0100
     6.3 @@ -18,57 +18,51 @@ idt_entry_t *idt_tables[NR_CPUS] = { 0 }
     6.4  
     6.5  void show_registers(struct cpu_user_regs *regs)
     6.6  {
     6.7 -    struct cpu_user_regs faultregs;
     6.8 -    unsigned long faultcrs[8];
     6.9 +    struct cpu_user_regs fault_regs = *regs;
    6.10 +    unsigned long fault_crs[8];
    6.11      const char *context;
    6.12  
    6.13 -    if ( HVM_DOMAIN(current) && regs->eflags == 0 )
    6.14 +    if ( HVM_DOMAIN(current) && GUEST_MODE(regs) )
    6.15      {
    6.16 -	context = "hvm";
    6.17 -	hvm_load_cpu_guest_regs(current, &faultregs);
    6.18 -	hvm_store_cpu_guest_ctrl_regs(current, faultcrs);
    6.19 +        context = "hvm";
    6.20 +        hvm_store_cpu_guest_regs(current, &fault_regs);
    6.21 +        hvm_store_cpu_guest_ctrl_regs(current, fault_crs);
    6.22      }
    6.23      else
    6.24      {
    6.25 -    	faultregs = *regs;
    6.26 -        if ( GUEST_MODE(regs) )
    6.27 +        context = GUEST_MODE(regs) ? "guest" : "hypervisor";
    6.28 +
    6.29 +        if ( !GUEST_MODE(regs) )
    6.30          {
    6.31 -            context = "guest";
    6.32 -            faultregs.ss &= 0xFFFF;
    6.33 -            faultregs.ds &= 0xFFFF;
    6.34 -            faultregs.es &= 0xFFFF;
    6.35 -            faultregs.cs &= 0xFFFF;
    6.36 -	}
    6.37 -	else 
    6.38 -	{
    6.39 -            context = "hypervisor";
    6.40 -            faultregs.esp = (unsigned long)&regs->esp;
    6.41 -            faultregs.ss = __HYPERVISOR_DS;
    6.42 -            faultregs.ds = __HYPERVISOR_DS;
    6.43 -            faultregs.es = __HYPERVISOR_DS;
    6.44 -            faultregs.cs = __HYPERVISOR_CS;
    6.45 -	}
    6.46 -        __asm__ ("movw %%fs,%0 ; movw %%gs,%1"
    6.47 -	         : "=r" (faultregs.fs), "=r" (faultregs.gs) );
    6.48 +            fault_regs.esp = (unsigned long)&regs->esp;
    6.49 +            fault_regs.ss = __HYPERVISOR_DS;
    6.50 +            fault_regs.ds = __HYPERVISOR_DS;
    6.51 +            fault_regs.es = __HYPERVISOR_DS;
    6.52 +            fault_regs.cs = __HYPERVISOR_CS;
    6.53 +        }
    6.54  
    6.55 -	faultcrs[0] = read_cr0();
    6.56 -	faultcrs[3] = read_cr3();
    6.57 +        __asm__ (
    6.58 +            "movw %%fs,%0 ; movw %%gs,%1"
    6.59 +            : "=r" (fault_regs.fs), "=r" (fault_regs.gs) );
    6.60 +        
    6.61 +        fault_crs[0] = read_cr0();
    6.62 +        fault_crs[3] = read_cr3();
    6.63      }
    6.64  
    6.65      printk("CPU:    %d\nEIP:    %04x:[<%08x>]",
    6.66 -           smp_processor_id(), faultregs.cs, faultregs.eip);
    6.67 -    if ( !HVM_DOMAIN(current) && !GUEST_MODE(regs) )
    6.68 -        print_symbol(" %s", faultregs.eip);
    6.69 -    printk("\nEFLAGS: %08x   CONTEXT: %s\n", faultregs.eflags, context);
    6.70 +           smp_processor_id(), fault_regs.cs, fault_regs.eip);
    6.71 +    if ( !GUEST_MODE(regs) )
    6.72 +        print_symbol(" %s", fault_regs.eip);
    6.73 +    printk("\nEFLAGS: %08x   CONTEXT: %s\n", fault_regs.eflags, context);
    6.74      printk("eax: %08x   ebx: %08x   ecx: %08x   edx: %08x\n",
    6.75 -           regs->eax, regs->ebx, regs->ecx, regs->edx);
    6.76 +           fault_regs.eax, fault_regs.ebx, fault_regs.ecx, fault_regs.edx);
    6.77      printk("esi: %08x   edi: %08x   ebp: %08x   esp: %08x\n",
    6.78 -           regs->esi, regs->edi, regs->ebp, faultregs.esp);
    6.79 -    printk("cr0: %08lx   cr3: %08lx\n", faultcrs[0], faultcrs[3]);
    6.80 +           fault_regs.esi, fault_regs.edi, fault_regs.ebp, fault_regs.esp);
    6.81 +    printk("cr0: %08lx   cr3: %08lx\n", fault_crs[0], fault_crs[3]);
    6.82      printk("ds: %04x   es: %04x   fs: %04x   gs: %04x   "
    6.83             "ss: %04x   cs: %04x\n",
    6.84 -           faultregs.ds, faultregs.es, faultregs.fs,
    6.85 -	   faultregs.gs, faultregs.ss, faultregs.cs);
    6.86 +           fault_regs.ds, fault_regs.es, fault_regs.fs,
    6.87 +           fault_regs.gs, fault_regs.ss, fault_regs.cs);
    6.88  
    6.89      show_stack(regs);
    6.90  }
     7.1 --- a/xen/arch/x86/x86_64/entry.S	Fri Feb 03 18:45:14 2006 +0000
     7.2 +++ b/xen/arch/x86/x86_64/entry.S	Fri Feb 03 20:30:54 2006 +0100
     7.3 @@ -311,8 +311,15 @@ domain_crash_synchronous_string:
     7.4          .asciz "domain_crash_sync called from entry.S\n"
     7.5  
     7.6  domain_crash_synchronous:
     7.7 -        leaq domain_crash_synchronous_string(%rip),%rdi
     7.8 -        call printf
     7.9 +        # Get out of the guest-save area of the stack.
    7.10 +        GET_GUEST_REGS(%rax)
    7.11 +        movq  %rax,%rsp
    7.12 +        # create_bounce_frame() temporarily clobbers CS.RPL. Fix up.
    7.13 +        orb   $3,UREGS_cs(%rsp)
    7.14 +        # printk(domain_crash_synchronous_string)
    7.15 +        leaq  domain_crash_synchronous_string(%rip),%rdi
    7.16 +        xorl  %eax,%eax
    7.17 +        call  printf
    7.18          jmp  __domain_crash_synchronous
    7.19  
    7.20          ALIGN
    7.21 @@ -468,6 +475,18 @@ ENTRY(double_fault)
    7.22  ENTRY(nmi)
    7.23          pushq $0
    7.24          SAVE_ALL
    7.25 +        testb $3,UREGS_cs(%rsp)
    7.26 +        jz    nmi_in_hypervisor_mode
    7.27 +        /* Interrupted guest context. Copy the context to stack bottom. */
    7.28 +        GET_GUEST_REGS(%rbx)
    7.29 +        addq  $UREGS_kernel_sizeof,%rbx
    7.30 +        movl  $UREGS_kernel_sizeof/8,%ecx
    7.31 +1:      popq  %rax
    7.32 +        subq  $8,%rbx
    7.33 +        movq  %rax,(%rbx)
    7.34 +        loop  1b
    7.35 +        movq  %rbx,%rsp
    7.36 +nmi_in_hypervisor_mode:
    7.37          movq  %rsp,%rdi
    7.38          call  do_nmi
    7.39          jmp   ret_from_intr
     8.1 --- a/xen/arch/x86/x86_64/traps.c	Fri Feb 03 18:45:14 2006 +0000
     8.2 +++ b/xen/arch/x86/x86_64/traps.c	Fri Feb 03 20:30:54 2006 +0100
     8.3 @@ -18,52 +18,40 @@
     8.4  
     8.5  void show_registers(struct cpu_user_regs *regs)
     8.6  {
     8.7 -    struct cpu_user_regs faultregs;
     8.8 -    unsigned long faultcrs[8];
     8.9 +    struct cpu_user_regs fault_regs = *regs;
    8.10 +    unsigned long fault_crs[8];
    8.11      const char *context;
    8.12  
    8.13 -    if ( HVM_DOMAIN(current) && regs->eflags == 0 )
    8.14 +    if ( HVM_DOMAIN(current) && GUEST_MODE(regs) )
    8.15      {
    8.16 -	context = "hvm";
    8.17 -	hvm_load_cpu_guest_regs(current, &faultregs);
    8.18 -	hvm_store_cpu_guest_ctrl_regs(current, faultcrs);
    8.19 +        context = "hvm";
    8.20 +        hvm_store_cpu_guest_regs(current, &fault_regs);
    8.21 +        hvm_store_cpu_guest_ctrl_regs(current, fault_crs);
    8.22      }
    8.23      else
    8.24      {
    8.25 -    	faultregs = *regs;
    8.26 -
    8.27 -        if ( GUEST_MODE(regs) )
    8.28 -        {
    8.29 -            context = "guest";
    8.30 -	}
    8.31 -	else 
    8.32 -	{
    8.33 -            context = "hypervisor";
    8.34 -            faultregs.esp = (unsigned long)&regs->esp;
    8.35 -	}
    8.36 -
    8.37 -	faultcrs[0] = read_cr0();
    8.38 -	faultcrs[3] = read_cr3();
    8.39 +        context = GUEST_MODE(regs) ? "guest" : "hypervisor";
    8.40 +        fault_crs[0] = read_cr0();
    8.41 +        fault_crs[3] = read_cr3();
    8.42      }
    8.43  
    8.44      printk("CPU:    %d\nRIP:    %04x:[<%016lx>]",
    8.45 -           smp_processor_id(), faultregs.cs, faultregs.rip);
    8.46 -    if ( !HVM_DOMAIN(current) && !GUEST_MODE(regs) )
    8.47 -        print_symbol(" %s", faultregs.rip);
    8.48 -
    8.49 -    printk("\nRFLAGS: %016lx   CONTEXT: %s\n", faultregs.rflags, context);
    8.50 +           smp_processor_id(), fault_regs.cs, fault_regs.rip);
    8.51 +    if ( !GUEST_MODE(regs) )
    8.52 +        print_symbol(" %s", fault_regs.rip);
    8.53 +    printk("\nRFLAGS: %016lx   CONTEXT: %s\n", fault_regs.rflags, context);
    8.54      printk("rax: %016lx   rbx: %016lx   rcx: %016lx\n",
    8.55 -           regs->rax, regs->rbx, regs->rcx);
    8.56 +           fault_regs.rax, fault_regs.rbx, fault_regs.rcx);
    8.57      printk("rdx: %016lx   rsi: %016lx   rdi: %016lx\n",
    8.58 -           regs->rdx, regs->rsi, regs->rdi);
    8.59 +           fault_regs.rdx, fault_regs.rsi, fault_regs.rdi);
    8.60      printk("rbp: %016lx   rsp: %016lx   r8:  %016lx\n",
    8.61 -           regs->rbp, faultregs.rsp, regs->r8);
    8.62 +           fault_regs.rbp, fault_regs.rsp, fault_regs.r8);
    8.63      printk("r9:  %016lx   r10: %016lx   r11: %016lx\n",
    8.64 -           regs->r9,  regs->r10, regs->r11);
    8.65 +           fault_regs.r9,  fault_regs.r10, fault_regs.r11);
    8.66      printk("r12: %016lx   r13: %016lx   r14: %016lx\n",
    8.67 -           regs->r12, regs->r13, regs->r14);
    8.68 +           fault_regs.r12, fault_regs.r13, fault_regs.r14);
    8.69      printk("r15: %016lx   cr0: %016lx   cr3: %016lx\n",
    8.70 -           regs->r15, faultcrs[0], faultcrs[3]);
    8.71 +           fault_regs.r15, fault_crs[0], fault_crs[3]);
    8.72  
    8.73      show_stack(regs);
    8.74  }
     9.1 --- a/xen/include/asm-x86/regs.h	Fri Feb 03 18:45:14 2006 +0000
     9.2 +++ b/xen/include/asm-x86/regs.h	Fri Feb 03 20:30:54 2006 +0100
     9.3 @@ -31,8 +31,17 @@ enum EFLAGS {
     9.4      EF_ID   = 0x00200000,   /* id */
     9.5  };
     9.6  
     9.7 -#define GUEST_MODE(_r) (likely(VM86_MODE(_r) || !RING_0(_r)))
     9.8 -
     9.9 -#define GUEST_CONTEXT(_ed, _r) ((HVM_DOMAIN(_ed) && ((_r)->eflags == 0)) || GUEST_MODE(_r))
    9.10 +#define GUEST_MODE(r)                                                         \
    9.11 +({                                                                            \
    9.12 +    unsigned long diff = (char *)guest_cpu_user_regs() - (char *)(r);         \
    9.13 +    /* Frame pointer must point into current CPU stack. */                    \
    9.14 +    ASSERT(diff < STACK_SIZE);                                                \
    9.15 +    /* If a guest frame, it must not be a ring 0 frame (unless HVM guest). */ \
    9.16 +    ASSERT((diff != 0) || VM86_MODE(r) || !RING_0(r) || HVM_DOMAIN(current)); \
    9.17 +    /* If not a guest frame, it must be a ring 0 frame. */                    \
    9.18 +    ASSERT((diff == 0) || (!VM86_MODE(r) && RING_0(r)));                      \
    9.19 +    /* Return TRUE if it's a guest frame. */                                  \
    9.20 +    (diff == 0);                                                              \
    9.21 +})
    9.22  
    9.23  #endif /* __X86_REGS_H__ */