static void remote_cap_revoke(struct monitor_blocking_binding *b,
                              struct capref croot, capaddr_t src, uint8_t vbits)
{
    errval_t err;
    /* Save state for stackripped reply */
    struct revoke_st * st = alloc_revoke_st(b, croot, src, vbits);

    /* Get the raw cap from the kernel */
    err = monitor_domains_cap_identify(croot, src, vbits,
                                       &(st->rcap_st.capability));
    if (err_is_fail(err)) {
        err_push(err, MON_ERR_CAP_REMOTE);
        goto reply;
    }

    /* request recursive lock on the cap and all of its descendants */
    err = rcap_db_acquire_recursive_lock(&(st->rcap_st.capability),
                                         (struct rcap_st*)st);
    if (err_is_fail(err)) {
        goto reply;
    }
    return;  // continues in remote_cap_retype_phase_2

reply:
    free_revoke_st(st);
    err = b->tx_vtbl.remote_cap_revoke_response(b, NOP_CONT, err);
    assert(err_is_ok(err));
}
Beispiel #2
0
void
capops_revoke(struct domcapref cap,
              revoke_result_handler_t result_handler,
              void *st)
{
    errval_t err;

    DEBUG_CAPOPS("%s ## start revocation protocol\n", __FUNCTION__);

    distcap_state_t state;
    err = dom_cnode_get_state(cap, &state);
    GOTO_IF_ERR(err, report_error);

    if (distcap_state_is_busy(state)) {
        err = MON_ERR_REMOTE_CAP_RETRY;
        goto report_error;
    }

    struct revoke_master_st *rst;
    err = calloce(1, sizeof(*rst), &rst);
    GOTO_IF_ERR(err, report_error);
    rst->cap = cap;
    err = monitor_domains_cap_identify(cap.croot, cap.cptr, cap.bits, &rst->rawcap);
    GOTO_IF_ERR(err, free_st);
    rst->result_handler = result_handler;
    rst->st = st;

    if (distcap_state_is_foreign(state)) {
        // need to retrieve ownership
        DEBUG_CAPOPS("%s getting cap ownership\n", __FUNCTION__);
        capops_retrieve(rst->cap, revoke_retrieve__rx, rst);
    }
    else {
        if (num_monitors_online() == 1) {
            DEBUG_CAPOPS("%s: only one monitor: do simpler revoke\n",
                    __FUNCTION__);
            // no remote monitors exist; do simplified revocation process
            revoke_no_remote(rst);
            // return here
            return;
        }
        // have ownership, initiate revoke
        revoke_local(rst);
    }

    return;

free_st:
    free(rst);

report_error:
    result_handler(err, st);
}
Beispiel #3
0
errval_t
capsend_update_owner(struct domcapref capref, struct event_closure completion_continuation)
{
    errval_t err;
    struct capability cap;
    err = monitor_domains_cap_identify(capref.croot, capref.cptr, capref.bits,
                                       &cap);
    if (err_is_fail(err)) {
        return err;
    }

    struct update_owner_broadcast_st *bc_st = calloc(1, sizeof(struct update_owner_broadcast_st));
    if (!bc_st) {
        return LIB_ERR_MALLOC_FAIL;
    }
    bc_st->completion_continuation = completion_continuation;

    return capsend_broadcast((struct capsend_mc_st*)bc_st, NULL, &cap, update_owner_broadcast_send_cont);
}
static void remote_cap_retype(struct monitor_blocking_binding *b,
                              struct capref croot, capaddr_t src,
                              uint64_t new_type, uint8_t size_bits,
                              capaddr_t to, capaddr_t slot, int32_t dcn_vbits)
{
    errval_t err;
    bool has_descendants;
    coremask_t on_cores;

    /* Save state for stackripped reply */
    struct retype_st * st = alloc_retype_st(b, croot, src, new_type, size_bits,
                                            to, slot, dcn_vbits);


    /* Get the raw cap from the kernel */
    err = monitor_domains_cap_identify(croot, src, CPTR_BITS,
                                       &(st->rcap_st.capability));
    if (err_is_fail(err)) {
        err_push(err, MON_ERR_CAP_REMOTE);
        goto reply;
    }

    /* Check if cap is retyped, if it is there is no point continuing,
       This will be checked again once we succeed in locking cap */
    err = rcap_db_get_info(&st->rcap_st.capability, &has_descendants, &on_cores);
    assert(err_is_ok(err));
    if (has_descendants) {
        err = MON_ERR_REMOTE_CAP_NEED_REVOKE;
        goto reply;
    }

    /* request lock */
    err = rcap_db_acquire_lock(&st->rcap_st.capability, (struct rcap_st*)st);
    if (err_is_fail(err)) {
        goto reply;
    }
    return;  // continues in remote_cap_retype_phase_2

reply:
    free_retype_st(st);
    err = b->tx_vtbl.remote_cap_retype_response(b, NOP_CONT, err);
    assert(err_is_ok(err));
}
Beispiel #5
0
errval_t
capsend_find_descendants(struct domcapref src, capsend_result_fn result_fn, void *st)
{
    errval_t err;

    struct capability cap;
    err = monitor_domains_cap_identify(src.croot, src.cptr, src.bits, &cap);
    if (err_is_fail(err)) {
        return err;
    }

    struct find_descendants_mc_st *mc_st;
    mc_st = malloc(sizeof(*mc_st));
    if (!mc_st) {
        return LIB_ERR_MALLOC_FAIL;
    }

    mc_st->result_fn = result_fn;
    mc_st->st = st;
    mc_st->have_result = false;
    return capsend_relations(&cap, find_descendants_send_cont,
            (struct capsend_mc_st*)mc_st, NULL);
}