[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 6/6] x86/debug: actually plumb pending_dbg through the monitor and devicemodel interfaces
Commit 21867648033d ("x86/debug: Plumb pending_dbg through the monitor and devicemodel interfaces") introduced pending_dbg, but did not actually populate or use the field. Signed-off-by: Jinoh Kang <jinoh.kang.kr@xxxxxxxxx> --- xen/arch/x86/hvm/svm/svm.c | 34 +++++++++++++++++++++++++++++++--- xen/arch/x86/hvm/vmx/vmx.c | 32 ++++++++++++++++++++++++-------- 2 files changed, 55 insertions(+), 11 deletions(-) diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index f25d6a53f092..139be9902dae 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -2422,6 +2422,14 @@ static bool cf_check svm_get_pending_event( info->type = vmcb->event_inj.type; info->error_code = vmcb->event_inj.ec; + if ( info->type == X86_EVENTTYPE_HW_EXCEPTION && + info->vector == X86_EXC_DB ) + { + unsigned long dr6 = v->arch.hvm.flag_dr_dirty ? + vmcb_get_dr6(vmcb) : v->arch.dr6; + info->extra = dr6 & ~DR_STATUS_RESERVED_ONE; + } + return true; } @@ -2733,16 +2741,28 @@ void svm_vmexit_handler(void) if ( !v->domain->debugger_attached ) { unsigned int trap_type; + unsigned long exit_pending_dbg; if ( likely(exit_reason != VMEXIT_ICEBP) ) { trap_type = X86_EVENTTYPE_HW_EXCEPTION; insn_len = 0; + + __restore_debug_registers(vmcb, v); + + /* + * NOTE: This is slightly wrong; old bits in dr6 are not + * automatically cleared by CPU on #DB, so it's not exactly + * equivalent to PENDING_DBG_EXCEPTIONS in semantics. + */ + exit_pending_dbg = vmcb_get_dr6(vmcb) & ~DR_STATUS_RESERVED_ONE; + vmcb_set_dr6(vmcb, DR_STATUS_RESERVED_ONE); } else { trap_type = X86_EVENTTYPE_PRI_SW_EXCEPTION; insn_len = svm_get_insn_len(v, INSTR_ICEBP); + exit_pending_dbg = 0; if ( !insn_len ) break; @@ -2750,12 +2770,20 @@ void svm_vmexit_handler(void) rc = hvm_monitor_debug(regs->rip, HVM_MONITOR_DEBUG_EXCEPTION, - trap_type, insn_len, 0); + trap_type, insn_len, exit_pending_dbg); if ( rc < 0 ) goto unexpected_exit_type; if ( !rc ) - hvm_inject_exception(X86_EXC_DB, - trap_type, insn_len, X86_EVENT_NO_EC); + { + if (trap_type == X86_EVENTTYPE_HW_EXCEPTION) + { + /* Updates DR6 where debugger can peek. */ + hvm_inject_debug_exception(exit_pending_dbg); + } + else + hvm_inject_exception(X86_EXC_DB, + trap_type, insn_len, X86_EVENT_NO_EC); + } } else domain_pause_for_debugger(); diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 1795b9479cf9..63411b62cb94 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -2469,6 +2469,14 @@ static bool cf_check vmx_get_pending_event( info->type = MASK_EXTR(intr_info, INTR_INFO_INTR_TYPE_MASK); info->error_code = error_code; + if ( info->type == X86_EVENTTYPE_HW_EXCEPTION && + info->vector == X86_EXC_DB ) + { + unsigned long dr6 = v->arch.hvm.flag_dr_dirty ? + read_debugreg(6) : v->arch.dr6; + info->extra = dr6 & ~DR_STATUS_RESERVED_ONE; + } + return true; } @@ -4240,13 +4248,11 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) { case X86_EXC_DB: /* - * Updates DR6 where debugger can peek (See 3B 23.2.1, - * Table 23-1, "Exit Qualification for Debug Exceptions"). + * See 3B 23.2.1, Table 23-1, "Exit Qualification for Debug + * Exceptions". */ __vmread(EXIT_QUALIFICATION, &exit_qualification); HVMTRACE_1D(TRAP_DEBUG, exit_qualification); - __restore_debug_registers(v); - write_debugreg(6, exit_qualification | DR_STATUS_RESERVED_ONE); /* * Work around SingleStep + STI/MovSS VMEntry failures. @@ -4285,22 +4291,32 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) if ( !v->domain->debugger_attached ) { - unsigned long insn_len = 0; + unsigned long exit_pending_dbg = 0, insn_len = 0; int rc; unsigned long trap_type = MASK_EXTR(intr_info, INTR_INFO_INTR_TYPE_MASK); - if ( trap_type >= X86_EVENTTYPE_SW_INTERRUPT ) + if ( trap_type == X86_EVENTTYPE_HW_EXCEPTION ) + exit_pending_dbg = exit_qualification; + else if ( trap_type >= X86_EVENTTYPE_SW_INTERRUPT ) __vmread(VM_EXIT_INSTRUCTION_LEN, &insn_len); rc = hvm_monitor_debug(regs->rip, HVM_MONITOR_DEBUG_EXCEPTION, - trap_type, insn_len, 0); + trap_type, insn_len, exit_pending_dbg); if ( rc < 0 ) goto exit_and_crash; if ( !rc ) - vmx_propagate_intr(intr_info); + { + if ( trap_type == X86_EVENTTYPE_HW_EXCEPTION ) + { + /* Updates DR6 where debugger can peek. */ + hvm_inject_debug_exception(exit_pending_dbg); + } + else + vmx_propagate_intr(intr_info); + } } else domain_pause_for_debugger(); -- 2.41.0
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |