Пример #1
0
/*
 * Resume the domain if no pending events. If there are pending events, like
 * another vcpu in a BP, report it. Otherwise, continue, and wait till an 
 * event, like bp or user doing xm pause, occurs.
 *
 * Returns: vcpuid : if a vcpu hits a breakpoint or end of step
 *              -1 : either an error (msg printed on terminal), or non-bp 
 *                   event, like "xm pause domid", to enter debugger
 */
vcpuid_t
xg_resume_n_wait(int guest_bitness)
{
    vcpuid_t vcpu;

    XGTRC("E:\n");
    assert(_domain_is_paused());

    if ((vcpu=_vcpu_in_bp()) != -1) {
        /* another vcpu in breakpoint. return it's id */
        return vcpu;
    }
    XGTRC("unpausing domain\n");
    if (_unpause_domain())
        return -1;
         
    /* now wait for domain to pause */
    _wait_domain_pause();

    /* check again if any vcpu in BP, or user thru "xm pause" */
    vcpu = _vcpu_in_bp(); 

    XGTRC("X:vcpu:%d\n", vcpu);
    return vcpu;
}
Пример #2
0
/*
 * Single step the given vcpu. This is achieved by pausing all but given vcpus,
 * setting the TF flag, let the domain run and pause, unpause all vcpus, and 
 * clear TF flag on given vcpu.
 * Returns: 0 success
 */
int 
xg_step(vcpuid_t which_vcpu, int guest_bitness)
{
    int rc;

    XGTRC("E:vcpu:%d\n", (int)which_vcpu);

    if (_allbutone_vcpu(XEN_DOMCTL_gdbsx_pausevcpu, which_vcpu))
        return 1;

    if ((rc=_change_TF(which_vcpu, guest_bitness, 1)))
        return rc;

    XGTRC("unpausing domain\n");

    /* now unpause the domain so our vcpu can execute */
    if (_unpause_domain())
        return 1;
         
    /* wait for our vcpu to finish step */
    _wait_domain_pause();

    _allbutone_vcpu(XEN_DOMCTL_gdbsx_unpausevcpu, which_vcpu);
    rc = _change_TF(which_vcpu, guest_bitness, 0);

    return rc;
}
Пример #3
0
/*
 * Attach to the given domid for debugging.
 * Returns: max vcpu id : Success
 *                   -1 : Failure
 */
int 
xg_attach(int domid, int guest_bitness)
{
    XGTRC("E:domid:%d\n", domid);

    _dom_id = domctl.domain = domid;
    domctl.interface_version = XEN_DOMCTL_INTERFACE_VERSION;

    if (mlock(&domctl, sizeof(domctl))) {
        XGERR("Unable to pin domctl in memory. errno:%d\n", errno);
        return -1;
    }
    if (_check_hyp(guest_bitness))
        return -1;

    if (_domctl_hcall(XEN_DOMCTL_pausedomain, NULL, 0)) {
        XGERR("Unable to pause domain:%d\n", _dom_id);
        return -1;
    } 

    memset(&domctl.u, 0, sizeof(domctl.u));
    domctl.u.setdebugging.enable = 1;
    if (_domctl_hcall(XEN_DOMCTL_setdebugging, NULL, 0)) {
        XGERR("Unable to set domain to debug mode: errno:%d\n", errno);
        _unpause_domain();
        return -1;
    }

    memset(&domctl.u, 0, sizeof(domctl.u));
    if (_domctl_hcall(XEN_DOMCTL_getdomaininfo, NULL, 0)) {
        XGERR("Unable to get domain info: domid:%d errno:%d\n", 
              domid, errno);
        _unpause_domain();
        return -1;
    }
    if (!_domain_ok(&domctl.u.getdomaininfo)) {
        _unpause_domain();
        return -1;
    }

    _max_vcpu_id = domctl.u.getdomaininfo.max_vcpu_id;
    _hvm_guest = (domctl.u.getdomaininfo.flags & XEN_DOMINF_hvm_guest);
    _pvh_guest = (domctl.u.getdomaininfo.flags & XEN_DOMINF_pvh_guest);
    return _max_vcpu_id;
}
Пример #4
0
/* Detach from guest for debugger exit */
void
xg_detach_deinit(void)
{
    memset(&domctl.u, 0, sizeof(domctl.u));
    domctl.u.setdebugging.enable = 0;
    if (_domctl_hcall(XEN_DOMCTL_setdebugging, NULL, 0)) {
        XGERR("Unable to reset domain debug mode: errno:%d\n", errno);
    }
    if (_domain_is_paused()) 
        _unpause_domain();
        
    close(_dom0_fd);
}