int xendevicemodel_inject_event(
xendevicemodel_handle *dmod, domid_t domid, int vcpu, uint8_t vector,
- uint8_t type, uint32_t error_code, uint8_t insn_len, uint64_t cr2)
+ uint8_t type, uint32_t error_code, uint8_t insn_len, uint64_t extra)
{
struct xen_dm_op op;
struct xen_dm_op_inject_event *data;
data->type = type;
data->error_code = error_code;
data->insn_len = insn_len;
- data->cr2 = cr2;
+ data->cr2 = extra;
return xendevicemodel_op(dmod, domid, 1, &op, sizeof(op));
}
* @parm type the event type (see the definition of enum x86_event_type)
* @parm error_code the error code or ~0 to skip
* @parm insn_len the instruction length
- * @parm cr2 the value of CR2 for page faults
+ * @parm extra type-specific extra data (%cr2 for #PF, pending_dbg for #DB)
* @return 0 on success, -1 on failure.
*/
int xendevicemodel_inject_event(
xendevicemodel_handle *dmod, domid_t domid, int vcpu, uint8_t vector,
- uint8_t type, uint32_t error_code, uint8_t insn_len, uint64_t cr2);
+ uint8_t type, uint32_t error_code, uint8_t insn_len, uint64_t extra);
/**
* Shuts the domain down.
break;
case VM_EVENT_REASON_DEBUG_EXCEPTION:
- printf("Debug exception: rip=%016"PRIx64", vcpu %d. Type: %u. Length: %u\n",
+ printf("Debug exception: rip=%016"PRIx64", vcpu %d. Type: %u. Length: %u. Pending dbg 0x%08"PRIx64"\n",
req.data.regs.x86.rip,
req.vcpu_id,
req.u.debug_exception.type,
- req.u.debug_exception.insn_length);
+ req.u.debug_exception.insn_length,
+ req.u.debug_exception.pending_dbg);
/* Reinject */
rc = xc_hvm_inject_trap(xch, domain_id, req.vcpu_id,
X86_TRAP_DEBUG,
req.u.debug_exception.type, -1,
req.u.debug_exception.insn_length,
- req.data.regs.x86.cr2);
+ req.u.debug_exception.pending_dbg);
if (rc < 0)
{
ERROR("Error %d injecting breakpoint\n", rc);
}
int hvm_monitor_debug(unsigned long rip, enum hvm_monitor_debug_type type,
- unsigned long trap_type, unsigned long insn_length)
+ unsigned int trap_type, unsigned int insn_length,
+ unsigned int pending_dbg)
{
/*
* rc < 0 error in monitor/vm_event, crash
return 0;
req.reason = VM_EVENT_REASON_DEBUG_EXCEPTION;
req.u.debug_exception.gfn = gfn_of_rip(rip);
+ req.u.debug_exception.pending_dbg = pending_dbg;
req.u.debug_exception.type = trap_type;
req.u.debug_exception.insn_length = insn_length;
sync = !!ad->monitor.debug_exception_sync;
rc = hvm_monitor_debug(regs->rip,
HVM_MONITOR_DEBUG_EXCEPTION,
- trap_type, insn_len);
+ trap_type, insn_len, 0);
if ( rc < 0 )
goto unexpected_exit_type;
if ( !rc )
rc = hvm_monitor_debug(regs->rip,
HVM_MONITOR_SOFTWARE_BREAKPOINT,
X86_EVENTTYPE_SW_EXCEPTION,
- insn_len);
+ insn_len, 0);
if ( rc < 0 )
goto unexpected_exit_type;
if ( !rc )
rc = hvm_monitor_debug(regs->rip,
HVM_MONITOR_DEBUG_EXCEPTION,
- trap_type, insn_len);
+ trap_type, insn_len, 0);
if ( rc < 0 )
goto exit_and_crash;
rc = hvm_monitor_debug(regs->rip,
HVM_MONITOR_SOFTWARE_BREAKPOINT,
X86_EVENTTYPE_SW_EXCEPTION,
- insn_len);
+ insn_len, 0);
if ( rc < 0 )
goto exit_and_crash;
{
hvm_monitor_debug(regs->rip,
HVM_MONITOR_SINGLESTEP_BREAKPOINT,
- 0, 0);
+ 0, 0, 0);
if ( v->domain->debugger_attached )
domain_pause_for_debugger();
uint64_t vmx_exit_qualification,
uint8_t descriptor, bool is_write);
int hvm_monitor_debug(unsigned long rip, enum hvm_monitor_debug_type type,
- unsigned long trap_type, unsigned long insn_length);
+ unsigned int trap_type, unsigned int insn_length,
+ unsigned int pending_dbg);
int hvm_monitor_cpuid(unsigned long insn_length, unsigned int leaf,
unsigned int subleaf);
void hvm_monitor_interrupt(unsigned int vector, unsigned int type,
/* IN - error code (or ~0 to skip) */
uint32_t error_code;
uint32_t pad1;
- /* IN - CR2 for page faults */
+ /* IN - type-specific extra data (%cr2 for #PF, pending_dbg for #DB) */
uint64_aligned_t cr2;
};
struct vm_event_debug {
uint64_t gfn;
+ uint64_t pending_dbg; /* Behaves like the VT-x PENDING_DBG field. */
uint32_t insn_length;
uint8_t type; /* HVMOP_TRAP_* */
uint8_t _pad[3];