Example #1
0
static void bind_lmp_client_request(struct monitor_binding *b,
                                    iref_t iref, uintptr_t domain_id,
                                    size_t buflen, struct capref ep)
{
    errval_t err;
    struct monitor_binding *serv_binding = NULL;

    /* Look up core_id from the iref */
    uint8_t core_id;
    err = iref_get_core_id(iref, &core_id);
    if (err_is_fail(err)) {
        bind_lmp_client_request_error(b, err, domain_id, serv_binding, ep);
        return;
    }

    // Return error if service on different core
    if (core_id != my_core_id) {
        err = MON_ERR_IDC_BIND_NOT_SAME_CORE;
        bind_lmp_client_request_error(b, err, domain_id, serv_binding, ep);
        return;
    }

    /* Lookup the server's connection to monitor */
    err = iref_get_binding(iref, &serv_binding);
    if (err_is_fail(err)) {
        bind_lmp_client_request_error(b, err, domain_id, serv_binding, ep);
        return;
    }

    /* Lookup the server's service_id */
    uintptr_t service_id;
    err = iref_get_service_id(iref, &service_id);
    if (err_is_fail(err)) {
        bind_lmp_client_request_error(b, err, domain_id, serv_binding, ep);
        return;
    }

    /* Allocate a new monitor connection */
    uintptr_t con_id;
    struct lmp_conn_state *conn;
    err = lmp_conn_alloc(&conn, &con_id);
    if (err_is_fail(err)) {
        bind_lmp_client_request_error(b, err, domain_id, serv_binding, ep);
        return;
    }

    conn->domain_id = domain_id;
    conn->domain_binding = b;

    /* Send request to the server */
    bind_lmp_service_request_cont(serv_binding, service_id, con_id, buflen, ep,
                                  b, domain_id);
}
Example #2
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);
}