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 monitor_bind_ump_client_request(struct monitor_binding *mb,
                                            iref_t iref, uintptr_t domain_id,
                                            struct capref frame,
                                            size_t channel_length_in,
                                            size_t channel_length_out,
                                            struct capref notify)
{
    uint8_t core_id;
    uintptr_t conn_id = 0;
    errval_t err;
    struct remote_conn_state *conn = NULL;

    // Get the core id
    err = iref_get_core_id(iref, &core_id);
    if (err_is_fail(err)) {
        debug_err(__FILE__, __func__, __LINE__, err, "iref_get_core_id failed");
        monitor_bind_ump_client_request_error(mb, frame, conn_id, domain_id, err);
        return;
    }

    if (core_id == my_core_id) {
        USER_PANIC("Same-core UMP binding NYI");
    }

    /* Identify frame */
    struct frame_identity frameid;
    err = invoke_frame_identify(frame, &frameid);
    if (err_is_fail(err)) {
        debug_err(__FILE__, __func__, __LINE__, err, "frame_identify failed");
        monitor_bind_ump_client_request_error(mb, frame, conn_id, domain_id, err);
        return;
    }

    // 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); */

    /* Forward request to the corresponding monitor */
    // Create local state
    err = remote_conn_alloc(&conn, &conn_id, REMOTE_CONN_UMP);
    if (err_is_fail(err)) {
        debug_err(__FILE__, __func__, __LINE__, err, "remote_conn_alloc failed");
        monitor_bind_ump_client_request_error(mb, frame, conn_id, domain_id, err);
        return;
    }

    // Track data
    conn->domain_id = domain_id;
    conn->domain_binding = mb;
    conn->x.ump.frame = frame;
    conn->core_id = core_id;

    // Get connection to the monitor to forward request to
    struct intermon_binding *intermon_binding;
    err = intermon_binding_get(core_id, &intermon_binding);
    if (err_is_fail(err)) {
        debug_err(__FILE__, __func__, __LINE__, err, "intermon_binding_get failed");
        monitor_bind_ump_client_request_error(mb, frame, conn_id, domain_id, err);
        return;
    }

    bind_ump_request_cont(intermon_binding, iref, conn_id, channel_length_in,
                          channel_length_out, frameid, capability, mb, frame,
                          domain_id);
}