示例#1
0
static void
cap_send_request_tx_cont(errval_t err, struct captx_prepare_state *captx_st,
                         intermon_captx_t *captx, void *st_)
{
    DEBUG_CAPOPS("%s: %s [%p]\n", __FUNCTION__, err_getstring(err), __builtin_return_address(0));
    errval_t queue_err;
    struct send_cap_st *send_st = (struct send_cap_st*)st_;

    if (err_is_fail(err)) {
        // XXX: should forward error here
        DEBUG_ERR(err, "preparing cap tx failed");
        free(send_st);
        return;
    }

    send_st->captx = *captx;

    DEBUG_CAPOPS("%s: enqueueing send\n", __FUNCTION__);
    send_st->qe.cont = cap_send_tx_cont;
    struct remote_conn_state *conn = remote_conn_lookup(send_st->my_mon_id);
    struct intermon_binding *binding = conn->mon_binding;
    struct intermon_state *inter_st = (struct intermon_state*)binding->st;
    queue_err = intermon_enqueue_send(binding, &inter_st->queue,
                                      binding->waitset,
                                      (struct msg_queue_elem*)send_st);
    if (err_is_fail(queue_err)) {
        DEBUG_ERR(queue_err, "enqueuing cap_send_request failed");
        free(send_st);
    }
}
示例#2
0
static void
cap_send_tx_cont(struct intermon_binding *b,
                 struct intermon_msg_queue_elem *e)
{
    DEBUG_CAPOPS("%s: %p %p\n", __FUNCTION__, b, e);
    errval_t send_err;
    struct send_cap_st *st = (struct send_cap_st*)e;
    struct remote_conn_state *conn = remote_conn_lookup(st->my_mon_id);
    send_err = intermon_cap_send_request__tx(b, NOP_CONT, conn->mon_id,
                                                st->capid, st->captx);
    if (err_is_fail(send_err)) {
        DEBUG_ERR(send_err, "sending cap_send_request failed");
    }
    free(st);
}
示例#3
0
static void monitor_bind_ump_reply(struct monitor_binding *dom_binding,
                                   uintptr_t my_mon_id, uintptr_t domain_id,
                                   errval_t msgerr, struct capref notify)
{
    errval_t err;

    struct remote_conn_state *conn = remote_conn_lookup(my_mon_id);
    if (conn == NULL) {
        USER_PANIC("invalid mon_id in UMP bind reply");
        return;
    }

    uintptr_t your_mon_id = conn->mon_id;
    struct intermon_binding *mon_binding = conn->mon_binding;

    if (err_is_ok(msgerr)) {
        /* Connection accepted */
        conn->domain_id = domain_id;
        conn->domain_binding = dom_binding;
    } else {
//error:
        /* Free the cap */
        err = cap_destroy(conn->x.ump.frame);
        assert(err_is_ok(err));

        err = remote_conn_free(my_mon_id);
        assert(err_is_ok(err));
    }

    // Identify notify cap
    struct capability capability;
    err = monitor_cap_identify(notify, &capability);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "monitor_cap_identify failed, ignored");
        return;
    }
    assert(capability.type == ObjType_Notify_RCK
           || capability.type == ObjType_Notify_IPI
           || capability.type == ObjType_Null);
    /* assert(capability.u.notify.coreid == my_core_id); */

    bind_ump_reply_cont(mon_binding, your_mon_id, my_mon_id, msgerr, capability);
}
示例#4
0
static void
cap_send_request(struct monitor_binding *b, uintptr_t my_mon_id,
                 struct capref cap, uint32_t capid)
{
    DEBUG_CAPOPS("cap_send_request\n");
    errval_t err;
    struct remote_conn_state *conn = remote_conn_lookup(my_mon_id);

    struct send_cap_st *st;
    st = calloc(1, sizeof(*st));
    if (!st) {
        err = LIB_ERR_MALLOC_FAIL;
        DEBUG_ERR(err, "Failed to allocate cap_send_request state");
        // XXX: should forward error here
        return;
    }
    st->my_mon_id = my_mon_id;
    st->cap = cap;
    st->capid = capid;

    captx_prepare_send(cap, conn->core_id, true, &st->captx_state,
                       cap_send_request_tx_cont, st);
}
示例#5
0
static void intermon_bind_ump_reply(struct intermon_binding *ib, 
                                    uint64_t my_mon_id, uint64_t your_mon_id,
                                    errval_t msgerr, 
                                    intermon_caprep_t caprep)
{
    errval_t err;
    struct remote_conn_state *con = remote_conn_lookup(my_mon_id);
    if (con == NULL) {
        USER_PANIC_ERR(0, "unknown mon_id in UMP bind reply");
        return;
    }

    uintptr_t domain_id = con->domain_id;
    struct monitor_binding *domain_binding = con->domain_binding;
    struct capref notify_cap = NULL_CAP;

    if (err_is_ok(msgerr)) { /* bind succeeded */
        con->mon_id = your_mon_id;
        con->mon_binding = ib;

#if 0
        /* map in UMP channel state */
        void *buf;
        err = vspace_map_one_frame_attr(&buf,
              2 * (UMP_CHANNEL_SIZE + con->localchan.size * sizeof(uintptr_t)),
                                        con->frame, VREGION_FLAGS_READ,
                                        NULL, NULL);
        if (err_is_fail(err)) {
            USER_PANIC_ERR(err, "vspace_map_one_frame failed");
            // XXX: should not be an assert, but we don't have any way to do
            // connection teardown here!
            assert(buf != NULL);
        }
        con->sharedchan = buf;
        con->localchan.buf = buf + 2 * UMP_CHANNEL_SIZE;

        // XXX: Put frame cap on a separate allocator as it is not deleted anymore
        struct capref frame_copy;
        err = slot_alloc(&frame_copy);
        if (err_is_fail(err)) {
            USER_PANIC_ERR(err, "Failed to allocator slot from channel_alloc");
        }
        err = cap_copy(frame_copy, con->frame);
        if (err_is_fail(err)) {
            USER_PANIC_ERR(err, "Failed create copy of frame cap");
        }
        err = cap_destroy(con->frame);
        if (err_is_fail(err)) {
            USER_PANIC_ERR(err, "cap_destroy_default failed");
        }
        con->frame = frame_copy;
#endif

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

        if(capability.type != ObjType_Null) {
            // Get core id of sender
            coreid_t core_id = ((struct intermon_state *)ib->st)->core_id;

            // Construct the notify cap
            err = slot_alloc(&notify_cap);
            if (err_is_fail(err)) {
                USER_PANIC_ERR(err, "Failed to allocate slot from channel_alloc");
            }

            err = monitor_cap_create(notify_cap, &capability, core_id);
            if (err_is_fail(err)) {
                USER_PANIC_ERR(err, "monitor_cap_create failed");
            }
        }
    } else { /* bind refused */
        err = cap_destroy(con->x.ump.frame);
        if (err_is_fail(err)) {
            USER_PANIC_ERR(err, "cap_destroy_default failed");
        }
        err = remote_conn_free(my_mon_id);
        assert(err_is_ok(err));
    }

    bind_ump_reply_client_cont(domain_binding, my_mon_id, domain_id, msgerr,
                               notify_cap);
}