Ejemplo n.º 1
0
void
retrieve_result__rx(struct intermon_binding *b, errval_t status,
                    uint8_t relations, genvaddr_t st)
{
    errval_t err;
    struct retrieve_rpc_st *rst = (struct retrieve_rpc_st*)(lvaddr_t)st;

    if (err_is_fail(status)) {
        err = status;
        goto report_error;
    }

    err = monitor_domcap_remote_relations(rst->cap.croot, rst->cap.cptr,
                                          rst->cap.bits, relations, 0xFF,
                                          NULL);
    PANIC_IF_ERR(err, "setting rrels for retrieved cap");

    struct event_closure updated_cont
        = MKCONT(retrieve_ownership_update__fin, rst);
    err = capsend_update_owner(rst->cap, updated_cont);
    PANIC_IF_ERR(err, "updating retrieve ownership");

report_error:
    retrieve_ownership__rx(err, rst);
}
Ejemplo n.º 2
0
static void
revoke_no_remote(struct revoke_master_st *st)
{
    assert(num_monitors_online() == 1);

    if (!delete_steps_get_waitset()) {
        delete_steps_init(get_default_waitset());
    }

    errval_t err;
    DEBUG_CAPOPS("%s\n", __FUNCTION__);

    // pause deletion steps
    DEBUG_CAPOPS("%s: delete_steps_pause()\n", __FUNCTION__);
    delete_steps_pause();

    // mark target of revoke
    DEBUG_CAPOPS("%s: mon_revoke_mark_tgt()\n", __FUNCTION__);
    err = monitor_revoke_mark_target(st->cap.croot,
                                     st->cap.cptr,
                                     st->cap.bits);
    PANIC_IF_ERR(err, "marking revoke");


    // resume delete steps
    DEBUG_CAPOPS("%s: delete_steps_resume()\n", __FUNCTION__);
    delete_steps_resume();

    // wait on delete queue, marking that remote cores are done
    st->remote_fin = true;
    DEBUG_CAPOPS("%s: delete_queue_wait()\n", __FUNCTION__);
    struct event_closure steps_fin_cont
        = MKCLOSURE(revoke_master_steps__fin, st);
    delete_queue_wait(&st->del_qn, steps_fin_cont);
}
Ejemplo n.º 3
0
void
revoke_mark__rx(struct intermon_binding *b,
                intermon_caprep_t caprep,
                genvaddr_t st)
{
    DEBUG_CAPOPS("%s\n", __FUNCTION__);
    errval_t err;
    struct intermon_state *inter_st = (struct intermon_state*)b->st;

    struct revoke_slave_st *rvk_st;
    err = calloce(1, sizeof(*rvk_st), &rvk_st);
    PANIC_IF_ERR(err, "allocating revoke slave state");

    rvk_st->from = inter_st->core_id;
    rvk_st->st = st;
    caprep_to_capability(&caprep, &rvk_st->rawcap);

    if (!slaves_head) {
        assert(!slaves_tail);
        slaves_head = slaves_tail = rvk_st;
    }
    else {
        assert(slaves_tail);
        assert(!slaves_tail->next);
        slaves_tail->next = rvk_st;
        slaves_tail = rvk_st;
    }

    // pause any ongoing "delete stepping" as mark phases on other nodes need
    // to delete all foreign copies before we can delete locally owned caps
    delete_steps_pause();

    // XXX: this invocation could create a scheduling hole that could be
    // problematic in RT systems and should probably be done in a loop.
    err = monitor_revoke_mark_relations(&rvk_st->rawcap);
    if (err_no(err) == SYS_ERR_CAP_NOT_FOUND) {
        // found no copies or descendants of capability on this core,
        // do nothing. -SG
        DEBUG_CAPOPS("no copies on core %d\n", disp_get_core_id());
    } else if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "marking revoke");
    }

    rvk_st->im_qn.cont = revoke_ready__send;
    err = capsend_target(rvk_st->from, (struct msg_queue_elem*)rvk_st);
    PANIC_IF_ERR(err, "enqueing revoke_ready");
}
Ejemplo n.º 4
0
static void
revoke_ready__send(struct intermon_binding *b,
                   struct intermon_msg_queue_elem *e)
{
    errval_t err;
    struct revoke_slave_st *rvk_st = (struct revoke_slave_st*)e;
    err = intermon_capops_revoke_ready__tx(b, NOP_CONT, rvk_st->st);
    PANIC_IF_ERR(err, "sending revoke_ready");
}
Ejemplo n.º 5
0
static void
retrieve_result__enq(errval_t status, struct retrieve_response_st *st)
{
    errval_t err;
    st->status = status;
    st->iqn.cont = retrieve_result__send;

    err = capsend_target(st->from, (struct msg_queue_elem*)st);
    PANIC_IF_ERR(err, "enqueing retrieve result");
}
Ejemplo n.º 6
0
static void
revoke_slave_steps__fin(void *st)
{
    errval_t err;
    struct revoke_slave_st *rvk_st = (struct revoke_slave_st*)st;

    rvk_st->im_qn.cont = revoke_done__send;
    err = capsend_target(rvk_st->from, (struct msg_queue_elem*)rvk_st);
    PANIC_IF_ERR(err, "enqueueing revoke_done");
}
Ejemplo n.º 7
0
static void
revoke_done__send(struct intermon_binding *b,
                  struct intermon_msg_queue_elem *e)
{
    errval_t err;
    struct revoke_slave_st *rvk_st = (struct revoke_slave_st*)e;
    err = intermon_capops_revoke_done__tx(b, NOP_CONT, rvk_st->st);
    PANIC_IF_ERR(err, "sending revoke_done");
    remove_slave_from_list(rvk_st);
    free(rvk_st);
}
Ejemplo n.º 8
0
static void
retrieve_result__send(struct intermon_binding *b,
                      struct intermon_msg_queue_elem *e)
{
    errval_t err;
    struct retrieve_response_st *st = (struct retrieve_response_st*)e;

    err = intermon_capops_retrieve_result__tx(b, NOP_CONT, st->status,
                                              st->relations, st->st);
    PANIC_IF_ERR(err, "sending retrieve result");
    free(st);
}
Ejemplo n.º 9
0
static void
revoke_local(struct revoke_master_st *st)
{
    DEBUG_CAPOPS("%s: called from %p\n", __FUNCTION__,
            __builtin_return_address(0));
    errval_t err;

    delete_steps_pause();

    err = monitor_revoke_mark_target(st->cap.croot,
                                     st->cap.cptr,
                                     st->cap.bits);
    PANIC_IF_ERR(err, "marking revoke");


    DEBUG_CAPOPS("%s ## revocation: mark phase\n", __FUNCTION__);
    // XXX: could check whether remote copies exist here(?), -SG, 2014-11-05
    err = capsend_relations(&st->rawcap, revoke_mark__send,
            &st->revoke_mc_st, &st->dests);
    PANIC_IF_ERR(err, "initiating revoke mark multicast");
}
Ejemplo n.º 10
0
static void
revoke_retrieve__rx(errval_t result, void *st_)
{
    struct revoke_master_st *st = (struct revoke_master_st*)st_;

    if (err_is_fail(result)) {
        revoke_result__rx(result, st, false);
    }
    else {

#ifndef NDEBUG
        distcap_state_t state;
        errval_t err = dom_cnode_get_state(st->cap, &state);
        PANIC_IF_ERR(err, "dom_cnode_get_state");
        assert(!distcap_state_is_foreign(state));
#endif
        revoke_local(st);
    }
}
Ejemplo n.º 11
0
void
revoke_ready__rx(struct intermon_binding *b, genvaddr_t st)
{
    DEBUG_CAPOPS("%s\n", __FUNCTION__);
    errval_t err;

    struct revoke_master_st *rvk_st = (struct revoke_master_st*)(lvaddr_t)st;
    if (!capsend_handle_mc_reply(&rvk_st->revoke_mc_st)) {
        DEBUG_CAPOPS("%s: waiting for remote cores\n", __FUNCTION__);
        // multicast not complete
        return;
    }

    DEBUG_CAPOPS("%s ## revocation: commit phase\n", __FUNCTION__);
    err = capsend_relations(&rvk_st->rawcap, revoke_commit__send,
            &rvk_st->revoke_mc_st, &rvk_st->dests);
    PANIC_IF_ERR(err, "enqueing revoke_commit multicast");

    delete_steps_resume();

    struct event_closure steps_fin_cont
        = MKCLOSURE(revoke_master_steps__fin, rvk_st);
    delete_queue_wait(&rvk_st->del_qn, steps_fin_cont);
}
Ejemplo n.º 12
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);
}