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@jp.fujitsu.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
This commit is contained in:
Keir Fraser committed 2008-11-11 11:47:03 +00:00
1 parent ef755ee444
commit 98cb2ef797
3 files changed
+49 -20

No files matched your search

+17 -7
View File
@@ -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) )
{
@@ -765,13 +782,6 @@ static void svm_inject_exception(
{
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;
}
}
static int svm_event_pending(struct vcpu *v)
+14 -6
View File
@@ -149,17 +149,25 @@ static void realmode_emulate_one(struct hvm_emulate_ctxt *hvmemul_ctxt)
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;
+18 -7
View File
@@ -1118,6 +1118,24 @@ static void __vmx_inject_exception(int trap, int type, int error_code)
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, int error_code)
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)
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.