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); } }
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); }
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); }
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); }
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(¬ify_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); }