# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1226404023 0
# Node ID 07d0be88571fa4dfbf3449069c78c08acc09b2da
# Parent 7be8e7eefbd79e7bb823b20eadfbdd1fec483d93
hvm: fix single stepping on debugger
The debuggee domain will die with unexpected trap
on single stepping of emulated instruction.
Signed-off-by: Kouya Shimura <kouya@xxxxxxxxxxxxxx>
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
xen/arch/x86/hvm/svm/svm.c | 24 +++++++++++++++++-------
xen/arch/x86/hvm/vmx/realmode.c | 20 ++++++++++++++------
xen/arch/x86/hvm/vmx/vmx.c | 25 ++++++++++++++++++-------
3 files changed, 49 insertions(+), 20 deletions(-)
diff -r 7be8e7eefbd7 -r 07d0be88571f xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Tue Nov 11 11:35:00 2008 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c Tue Nov 11 11:47:03 2008 +0000
@@ -739,6 +739,23 @@ static void svm_inject_exception(
struct vmcb_struct *vmcb = curr->arch.hvm_svm.vmcb;
eventinj_t event = vmcb->eventinj;
+ switch ( trapnr )
+ {
+ case TRAP_debug:
+ if ( guest_cpu_user_regs()->eflags & X86_EFLAGS_TF )
+ {
+ __restore_debug_registers(curr);
+ vmcb->dr6 |= 0x4000;
+ }
+ case TRAP_int3:
+ if ( curr->domain->debugger_attached )
+ {
+ /* Debug/Int3: Trap to debugger. */
+ domain_pause_for_debugger();
+ return;
+ }
+ }
+
if ( unlikely(event.fields.v) &&
(event.fields.type == X86_EVENTTYPE_HW_EXCEPTION) )
{
@@ -764,13 +781,6 @@ static void svm_inject_exception(
else
{
HVMTRACE_2D(INJ_EXC, trapnr, errcode);
- }
-
- if ( (trapnr == TRAP_debug) &&
- (guest_cpu_user_regs()->eflags & X86_EFLAGS_TF) )
- {
- __restore_debug_registers(curr);
- vmcb->dr6 |= 0x4000;
}
}
diff -r 7be8e7eefbd7 -r 07d0be88571f xen/arch/x86/hvm/vmx/realmode.c
--- a/xen/arch/x86/hvm/vmx/realmode.c Tue Nov 11 11:35:00 2008 +0000
+++ b/xen/arch/x86/hvm/vmx/realmode.c Tue Nov 11 11:47:03 2008 +0000
@@ -149,17 +149,25 @@ static void realmode_emulate_one(struct
hvmemul_ctxt->exn_insn_len = 0;
}
- if ( curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE )
+ if ( unlikely(curr->domain->debugger_attached) &&
+ ((hvmemul_ctxt->exn_vector == TRAP_debug) ||
+ (hvmemul_ctxt->exn_vector == TRAP_int3)) )
+ {
+ domain_pause_for_debugger();
+ }
+ else if ( curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE )
{
gdprintk(XENLOG_ERR, "Exception %02x in protected mode.\n",
hvmemul_ctxt->exn_vector);
goto fail;
}
-
- realmode_deliver_exception(
- hvmemul_ctxt->exn_vector,
- hvmemul_ctxt->exn_insn_len,
- hvmemul_ctxt);
+ else
+ {
+ realmode_deliver_exception(
+ hvmemul_ctxt->exn_vector,
+ hvmemul_ctxt->exn_insn_len,
+ hvmemul_ctxt);
+ }
}
return;
diff -r 7be8e7eefbd7 -r 07d0be88571f xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Tue Nov 11 11:35:00 2008 +0000
+++ b/xen/arch/x86/hvm/vmx/vmx.c Tue Nov 11 11:47:03 2008 +0000
@@ -1118,6 +1118,24 @@ void vmx_inject_hw_exception(int trap, i
void vmx_inject_hw_exception(int trap, int error_code)
{
unsigned long intr_info = __vmread(VM_ENTRY_INTR_INFO);
+ struct vcpu *curr = current;
+
+ switch ( trap )
+ {
+ case TRAP_debug:
+ if ( guest_cpu_user_regs()->eflags & X86_EFLAGS_TF )
+ {
+ __restore_debug_registers(curr);
+ write_debugreg(6, read_debugreg(6) | 0x4000);
+ }
+ case TRAP_int3:
+ if ( curr->domain->debugger_attached )
+ {
+ /* Debug/Int3: Trap to debugger. */
+ domain_pause_for_debugger();
+ return;
+ }
+ }
if ( unlikely(intr_info & INTR_INFO_VALID_MASK) &&
(((intr_info >> 8) & 7) == X86_EVENTTYPE_HW_EXCEPTION) )
@@ -1134,13 +1152,6 @@ void vmx_inject_hw_exception(int trap, i
TRC_PAR_LONG(current->arch.hvm_vcpu.guest_cr[2]));
else
HVMTRACE_2D(INJ_EXC, trap, error_code);
-
- if ( (trap == TRAP_debug) &&
- (guest_cpu_user_regs()->eflags & X86_EFLAGS_TF) )
- {
- __restore_debug_registers(current);
- write_debugreg(6, read_debugreg(6) | 0x4000);
- }
}
void vmx_inject_extint(int trap)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|