MAKE_INSTR(CLTS, 2, 0x0f, 0x06);
MAKE_INSTR(LMSW, 3, 0x0f, 0x01, 0x00);
MAKE_INSTR(SMSW, 3, 0x0f, 0x01, 0x00);
+MAKE_INSTR(INT3, 1, 0xcc);
static const u8 *opc_bytes[INSTR_MAX_COUNT] =
{
[INSTR_CLTS] = OPCODE_CLTS,
[INSTR_HLT] = OPCODE_HLT,
[INSTR_LMSW] = OPCODE_LMSW,
- [INSTR_SMSW] = OPCODE_SMSW
+ [INSTR_SMSW] = OPCODE_SMSW,
+ [INSTR_INT3] = OPCODE_INT3
};
/*
unsigned long eip;
struct vcpu *v = current;
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+ int inst_len;
exit_reason = vmcb->exitcode;
save_svm_cpu_user_regs(v, regs);
break;
case VMEXIT_EXCEPTION_DB:
- if ( v->domain->debugger_attached )
- domain_pause_for_debugger();
- else
- svm_inject_exception(v, TRAP_debug, 0, 0);
+ if ( !v->domain->debugger_attached )
+ goto exit_and_crash;
+ domain_pause_for_debugger();
break;
case VMEXIT_EXCEPTION_BP:
- if ( v->domain->debugger_attached )
- domain_pause_for_debugger();
- else
- svm_inject_exception(v, TRAP_int3, 0, 0);
+ if ( !v->domain->debugger_attached )
+ goto exit_and_crash;
+ /* AMD Vol2, 15.11: INT3, INTO, BOUND intercepts do not update RIP. */
+ inst_len = __get_instruction_length(v, INSTR_INT3, NULL);
+ __update_guest_eip(vmcb, inst_len);
+ domain_pause_for_debugger();
break;
case VMEXIT_EXCEPTION_NM:
svm_handle_invlpg(1, regs);
break;
- case VMEXIT_VMMCALL: {
- int inst_len = __get_instruction_length(v, INSTR_VMCALL, NULL);
+ case VMEXIT_VMMCALL:
+ inst_len = __get_instruction_length(v, INSTR_VMCALL, NULL);
ASSERT(inst_len > 0);
HVMTRACE_1D(VMMCALL, v, regs->eax);
__update_guest_eip(vmcb, inst_len);
hvm_do_hypercall(regs);
break;
- }
case VMEXIT_CR0_READ:
svm_cr_access(v, 0, TYPE_MOV_FROM_CR, regs);
switch ( vector )
{
case TRAP_debug:
- if ( v->domain->debugger_attached )
- domain_pause_for_debugger();
- else
- vmx_reflect_exception(v);
- break;
case TRAP_int3:
- if ( v->domain->debugger_attached )
- domain_pause_for_debugger();
- else
- vmx_reflect_exception(v);
+ if ( !v->domain->debugger_attached )
+ goto exit_and_crash;
+ domain_pause_for_debugger();
break;
case TRAP_no_device:
vmx_do_no_device_fault();
vmx_reflect_exception(v);
break;
default:
- vmx_reflect_exception(v);
- break;
+ goto exit_and_crash;
}
break;
}