Пример #1
0
static errval_t reclaim_memory(genpaddr_t base, uint8_t bits)
{
    /* XXX: mem client is only defined for the bsp core.
     * For app cores, just return */
    if (get_mem_client() == NULL) {
        return SYS_ERR_OK;
    }

    // Fabricate new RAM cap and hand back to mem_serv
    struct capability c = {
        .type = ObjType_RAM,
        .u.ram = {
            .base = base,
            .bits = bits,
        }
    };
    struct capref ramcap;
    errval_t err = slot_alloc(&ramcap);
    if(err_is_fail(err)) {
        return err;
    }

    err = monitor_cap_create(ramcap, &c, my_core_id);
    if(err_is_fail(err)) {
        return err;
    }

    struct ram_alloc_state *ram_alloc_state = get_ram_alloc_state();
    errval_t result;
    thread_mutex_lock(&ram_alloc_state->ram_alloc_lock);
    struct mem_rpc_client *b = get_mem_client();
    // XXX: This should not be an RPC! It could stall the monitor, but
    // we trust mem_serv for the moment.
    err = b->vtbl.free_monitor(b, ramcap, base, bits, &result);
    thread_mutex_unlock(&ram_alloc_state->ram_alloc_lock);
    if(err_is_fail(err)) {
        return err;
    }
    if(err_is_fail(result)) {
        return result;
    }

    // XXX: this shouldn't be necessary as free_monitor uses give_away_cap
    err = cap_destroy(ramcap);
    if (err_no(err) == SYS_ERR_CAP_NOT_FOUND) {
        err = SYS_ERR_OK;
    }
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "destroying reclaimed cap");
    }
    return err;
}
Пример #2
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);
}
Пример #3
0
static void intermon_bind_ump_request(struct intermon_binding *ib,
                                      iref_t iref, con_id_t your_mon_id,
                                      uint32_t channel_length_in,
                                      uint32_t channel_length_out,
                                      genpaddr_t framebase, uint8_t framebits,
                                      intermon_caprep_t caprep)
{
    errval_t err;

    /* Get client's core_id */
    struct intermon_state *ist = ib->st;
    assert(ist != NULL);
    coreid_t core_id = ist->core_id;

    /* Construct the frame capability */
    struct capability frame_cap = {
        .type = ObjType_Frame,
        .rights = CAPRIGHTS_READ_WRITE, // XXX
        .u.frame = {
            .base = framebase,
            .bits = framebits
        }
    };

    // Construct the notify cap
    struct capref notify_cap = NULL_CAP;
    struct capability capability;
    caprep_to_capability(&caprep, &capability);
    if(capability.type != ObjType_Null) {
        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");
        }
    }

    // XXX: Put frame cap on a separate allocator as it is not deleted anymore
    struct capref frame;
    err = slot_alloc(&frame);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "Failed to allocate slot from channel_alloc");
    }
    err = monitor_cap_create(frame, &frame_cap, core_id);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "monitor_cap_create failed");
    }

    /* Get the server's connection */
    struct monitor_binding *domain_binding = NULL;
    err = iref_get_binding(iref, &domain_binding);
    assert(err_is_ok(err));

    /* Get the service id */
    uintptr_t service_id = 0;
    err = iref_get_service_id(iref, &service_id);
    assert(err_is_ok(err));

    /* Create a new connection state */
    uintptr_t my_mon_id;
    struct remote_conn_state *con;
    err = remote_conn_alloc(&con, &my_mon_id, REMOTE_CONN_UMP);
    assert(err_is_ok(err));

    // Set the monitor portion of it
    con->mon_id = your_mon_id;
    con->mon_binding = ib;
    con->x.ump.frame = frame;
    con->core_id = core_id;

    bind_ump_service_request_cont(domain_binding, service_id, my_mon_id,
                                  frame, channel_length_in, channel_length_out,
                                  notify_cap, ib, your_mon_id);
}