Mailing List Archive

Fix show_registers() on x86/64. Get rid of
# HG changeset patch
# User kaf24@firebug.cl.cam.ac.uk
# 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@xensource.com>

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@lists.xensource.com
http://lists.xensource.com/xen-changelog