static void cap_set_remote(struct monitor_blocking_binding *b,
                           struct capref cap, bool remote)
{
    errval_t err, reterr;

    reterr = monitor_remote_relations(cap, RRELS_COPY_BIT, RRELS_COPY_BIT, NULL);

    err = b->tx_vtbl.cap_set_remote_response(b, NOP_CONT, reterr);
    if(err_is_fail(err)) {
        if(err_no(err) == FLOUNDER_ERR_TX_BUSY) {
            struct pending_reply *r = malloc(sizeof(struct pending_reply));
            assert(r != NULL);
            r->b = b;
            r->err = reterr;
            err = b->register_send(b, get_default_waitset(), MKCONT(retry_reply, r));
            assert(err_is_ok(err));
        } else {
            USER_PANIC_ERR(err, "cap_set_remote_response");
        }
    }
}
Beispiel #2
0
static void span_domain_request(struct monitor_binding *mb,
                                uintptr_t domain_id, uint8_t core_id,
                                struct capref vroot, struct capref disp)
{
    errval_t err, err2;

    trace_event(TRACE_SUBSYS_MONITOR, TRACE_EVENT_MONITOR_SPAN0, core_id);

    struct span_state *state;
    uintptr_t state_id;

    err = span_state_alloc(&state, &state_id);
    if (err_is_fail(err)) {
        err_push(err, MON_ERR_SPAN_STATE_ALLOC);
        goto reply;
    }

    state->core_id   = core_id;
    state->vroot     = vroot;
    state->mb        = mb;
    state->domain_id = domain_id;

    trace_event(TRACE_SUBSYS_MONITOR, TRACE_EVENT_MONITOR_SPAN1, core_id);

    /* Look up the destination monitor */
    struct intermon_binding *ib;
    err = intermon_binding_get(core_id, &ib);
    if (err_is_fail(err)) {
        goto reply;
    }

    /* Idenfity vroot */
    struct capability vroot_cap;
    err = monitor_cap_identify(vroot, &vroot_cap);
    if (err_is_fail(err)) {
        err_push(err, MON_ERR_CAP_IDENTIFY);
        goto reply;
    }
    if (vroot_cap.type != ObjType_VNode_x86_64_pml4) { /* Check type */
        err = MON_ERR_WRONG_CAP_TYPE;
        goto reply;
    }

    /* Identify the dispatcher frame */
    struct frame_identity frameid;
    err = invoke_frame_identify(disp, &frameid);
    if (err_is_fail(err)) {
        err_push(err, LIB_ERR_FRAME_IDENTIFY);
        goto reply;
    }

    err = monitor_remote_relations(disp, RRELS_COPY_BIT, RRELS_COPY_BIT, NULL);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "monitor_remote_relations failed");
        return;
    }
    err = monitor_remote_relations(vroot, RRELS_COPY_BIT, RRELS_COPY_BIT, NULL);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "monitor_remote_relations failed");
        return;
    }

    /* Send msg to destination monitor */
    err = ib->tx_vtbl.span_domain_request(ib, NOP_CONT, state_id,
                                          vroot_cap.u.vnode_x86_64_pml4.base,
                                          frameid.base, frameid.bits);

    if (err_is_fail(err)) {
        err_push(err, MON_ERR_SEND_REMOTE_MSG);
        goto reply;
    }
    goto cleanup;

 reply:
    err2 = mb->tx_vtbl.span_domain_reply(mb, NOP_CONT, err, domain_id);
    if (err_is_fail(err2)) {
        // XXX: Cleanup?
        USER_PANIC_ERR(err2, "Failed to reply to the user domain");
    }
    if(state_id != 0) {
        err2 = span_state_free(state_id);
        if (err_is_fail(err2)) {
            USER_PANIC_ERR(err2, "Failed to free span state");
        }
    }

 cleanup:
    err2 = cap_destroy(vroot);
    if (err_is_fail(err2)) {
        USER_PANIC_ERR(err2, "Failed to destroy span_vroot cap");
    }
    err2 = cap_destroy(disp);
    if (err_is_fail(err2)) {
        USER_PANIC_ERR(err2, "Failed to destroy disp cap");
    }
}
Beispiel #3
0
void
retrieve_request__rx(struct intermon_binding *b,
                     intermon_caprep_t caprep,
                     genvaddr_t st)
{
    errval_t err, err2;
    struct intermon_state *inter_st = (struct intermon_state*)b->st;

    struct retrieve_response_st *rst;
    err = calloce(1, sizeof(*rst), &rst);
    PANIC_IF_ERR(err, "allocating retrieve respones state");
    rst->st = st;
    rst->from = inter_st->core_id;

    struct capability rawcap;
    caprep_to_capability(&caprep, &rawcap);

    struct capref cap;
    err = slot_alloc(&cap);
    GOTO_IF_ERR(err, respond_err);

    err = monitor_copy_if_exists(&rawcap, cap);
    GOTO_IF_ERR(err, free_slot);

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

    if (distcap_state_is_busy(state)) {
        err = MON_ERR_REMOTE_CAP_RETRY;
        goto delete_cap;
    }
    if (distcap_state_is_foreign(state)) {
        err = MON_ERR_CAP_FOREIGN;
        goto delete_cap;
    }

    uint8_t relations, remote_relations;
    err = monitor_cap_has_relations(cap, 0xFF, &relations);
    GOTO_IF_ERR(err, delete_cap);

    err = monitor_remote_relations(cap, 0, 0, &remote_relations);
    GOTO_IF_ERR(err, delete_cap);

    rst->relations = relations | remote_relations | RRELS_COPY_BIT;

    err = monitor_set_cap_owner(cap_root, get_cap_addr(cap),
                                get_cap_valid_bits(cap),
                                rst->from);

delete_cap:
    err2 = cap_delete(cap);
    DEBUG_IF_ERR(err2, "while deleting temp cap for retrieve");

free_slot:
    err2 = slot_free(cap);
    DEBUG_IF_ERR(err2, "freeing temp cap slot for retrieve");

respond_err:
    retrieve_result__enq(err, rst);
}