[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2] vmx: Restore debug registers when injecting #DB traps
Commit a929bee0e652 ("x86/vmx: Fix injection of #DB traps following XSA-156") prevents an infinite loop in certain #DB traps. However, it changed the behavior to not call hvm_hw_inject_trap() for #DB and #AC traps which which means that the debug registers are not restored correctly and nullified commit b56ae5b48c38 ("VMX: fix/adjust trap injection"). To fix this, restore the original code path through hvm_inject_trap(), but ensure that the struct hvm_trap is populated with all the required data. Signed-off-by: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx> --- Changed in v2: Use MASK_EXTR. Only set instruction length for certain event types. xen/arch/x86/hvm/vmx/vmx.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 9c5a388..bc4410f 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -3091,24 +3091,31 @@ static int vmx_handle_eoi_write(void) * It is the callers responsibility to ensure that this function is only used * in the context of an appropriate vmexit. */ -static void vmx_propagate_intr(void) +static void vmx_propagate_intr(unsigned long intr) { - unsigned long intr, tmp; - - __vmread(VM_EXIT_INTR_INFO, &intr); - - ASSERT(intr & INTR_INFO_VALID_MASK); - - __vmwrite(VM_ENTRY_INTR_INFO, intr); + struct hvm_trap trap = { + .vector = MASK_EXTR(intr, INTR_INFO_VECTOR_MASK), + .type = MASK_EXTR(intr, INTR_INFO_INTR_TYPE_MASK), + }; + unsigned long tmp; if ( intr & INTR_INFO_DELIVER_CODE_MASK ) { __vmread(VM_EXIT_INTR_ERROR_CODE, &tmp); - __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, tmp); + trap.error_code = tmp; } + else + trap.error_code = HVM_DELIVER_NO_ERROR_CODE; + + if ( trap.type >= X86_EVENTTYPE_SW_INTERRUPT ) + { + __vmread(VM_EXIT_INSTRUCTION_LEN, &tmp); + trap.insn_len = tmp; + } + else + trap.insn_len = 0; - __vmread(VM_EXIT_INSTRUCTION_LEN, &tmp); - __vmwrite(VM_ENTRY_INSTRUCTION_LEN, tmp); + hvm_inject_trap(&trap); } static void vmx_idtv_reinject(unsigned long idtv_info) @@ -3366,7 +3373,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) HVMTRACE_1D(TRAP_DEBUG, exit_qualification); write_debugreg(6, exit_qualification | DR_STATUS_RESERVED_ONE); if ( !v->domain->debugger_attached ) - vmx_propagate_intr(); + vmx_propagate_intr(intr_info); else domain_pause_for_debugger(); break; @@ -3437,7 +3444,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) break; case TRAP_alignment_check: HVMTRACE_1D(TRAP, vector); - vmx_propagate_intr(); + vmx_propagate_intr(intr_info); break; case TRAP_nmi: if ( MASK_EXTR(intr_info, INTR_INFO_INTR_TYPE_MASK) != -- 2.4.3 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |