コード例 #1
0
static void forward_kcb_rm_request(struct monitor_blocking_binding *b,
                                   coreid_t destination, struct capref kcb)
{
    errval_t err = SYS_ERR_OK;

    // can't move ourselves
    assert(destination != my_core_id);

    struct capability kcb_cap;
    err = monitor_cap_identify(kcb, &kcb_cap);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "monitor_cap_identify failed");
        err = b->tx_vtbl.forward_kcb_request_response(b, NOP_CONT, err);
        assert(err_is_ok(err));
        return;
    }

    struct intermon_binding *ib;
    err = intermon_binding_get(destination, &ib);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "intermon_binding_get failed");
        err = b->tx_vtbl.forward_kcb_request_response(b, NOP_CONT, err);
        assert(err_is_ok(err));
        return;
    }
    uintptr_t kcb_base = (uintptr_t )kcb_cap.u.kernelcontrolblock.kcb;

    // send request to other monitor
    // remember monitor binding to send answer
    struct intermon_state *ist = (struct intermon_state*)ib->st;
    ist->originating_client = (struct monitor_binding*)b; //XXX: HACK
    err = ib->tx_vtbl.forward_kcb_rm_request(ib, NOP_CONT, kcb_base);
    assert(err_is_ok(err));
}
コード例 #2
0
// XXX: these look suspicious in combination with distops!
static void forward_kcb_request(struct monitor_blocking_binding *b,
                                coreid_t destination, struct capref kcb)
{
    printf("%s:%s:%d: forward_kcb_request in monitor\n",
           __FILE__, __FUNCTION__, __LINE__);

    errval_t err = SYS_ERR_OK;

    struct capability kcb_cap;
    err = monitor_cap_identify(kcb, &kcb_cap);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "monitor_cap_identify failed");
        err = b->tx_vtbl.forward_kcb_request_response(b, NOP_CONT, err);
        assert(err_is_ok(err));
        return;
    }

    if (destination == my_core_id) {
        uintptr_t kcb_base = (uintptr_t)kcb_cap.u.kernelcontrolblock.kcb;
        printf("%s:%s:%d: Invoke syscall directly, destination==my_core_id; kcb_base = 0x%"PRIxPTR"\n",
               __FILE__, __FUNCTION__, __LINE__, kcb_base);
        err = invoke_monitor_add_kcb(kcb_base);
        if (err_is_fail(err)) {
            USER_PANIC_ERR(err, "invoke_montitor_add_kcb failed.");
        }

        err = b->tx_vtbl.forward_kcb_request_response(b, NOP_CONT, err);
        assert(err_is_ok(err));
        return;
    }

    struct intermon_binding *ib;
    err = intermon_binding_get(destination, &ib);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "intermon_binding_get failed");
        err = b->tx_vtbl.forward_kcb_request_response(b, NOP_CONT, err);
        assert(err_is_ok(err));
        return;
    }

    intermon_caprep_t kcb_rep;
    capability_to_caprep(&kcb_cap, &kcb_rep);

    ib->st = b;
    err = ib->tx_vtbl.give_kcb_request(ib, NOP_CONT, kcb_rep);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "give_kcb send failed");
        err = b->tx_vtbl.forward_kcb_request_response(b, NOP_CONT, err);
        assert(err_is_ok(err));
        return;
    }
}
コード例 #3
0
ファイル: ump_support.c プロジェクト: CoryXie/BarrelfishOS
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_identify(struct monitor_blocking_binding *b,
                         struct capref cap)
{
    errval_t err, reterr;

    union capability_caprep_u u;
    reterr = monitor_cap_identify(cap, &u.cap);

    /* XXX: shouldn't we skip this if we're being called from the monitor?
     * apparently not: we make a copy of the cap on LMP to self?!?! */
    err = cap_destroy(cap);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "cap_destroy failed");
    }

    err = b->tx_vtbl.cap_identify_response(b, NOP_CONT, reterr, u.caprepb);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "reply failed");
    }
}
コード例 #5
0
ファイル: monitor_server.c プロジェクト: XuNazgul/cmpe295A
static void span_domain_request(struct monitor_binding *mb,
                                uintptr_t domain_id, uint8_t core_id,
                                struct capref vroot, struct capref disp)
{
    errval_t err, err2;

    trace_event(TRACE_SUBSYS_MONITOR, TRACE_EVENT_MONITOR_SPAN0, core_id);

    struct span_state *state;
    uintptr_t state_id;

    err = span_state_alloc(&state, &state_id);
    if (err_is_fail(err)) {
        err_push(err, MON_ERR_SPAN_STATE_ALLOC);
        goto reply;
    }

    state->core_id   = core_id;
    state->vroot     = vroot;
    state->mb        = mb;
    state->domain_id = domain_id;

    trace_event(TRACE_SUBSYS_MONITOR, TRACE_EVENT_MONITOR_SPAN1, core_id);

    /* Look up the destination monitor */
    struct intermon_binding *ib;
    err = intermon_binding_get(core_id, &ib);
    if (err_is_fail(err)) {
        goto reply;
    }

    /* Idenfity vroot */
    struct capability vroot_cap;
    err = monitor_cap_identify(vroot, &vroot_cap);
    if (err_is_fail(err)) {
        err_push(err, MON_ERR_CAP_IDENTIFY);
        goto reply;
    }
    if (vroot_cap.type != ObjType_VNode_x86_64_pml4) { /* Check type */
        err = MON_ERR_WRONG_CAP_TYPE;
        goto reply;
    }

    /* Identify the dispatcher frame */
    struct frame_identity frameid;
    err = invoke_frame_identify(disp, &frameid);
    if (err_is_fail(err)) {
        err_push(err, LIB_ERR_FRAME_IDENTIFY);
        goto reply;
    }

    err = monitor_remote_relations(disp, RRELS_COPY_BIT, RRELS_COPY_BIT, NULL);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "monitor_remote_relations failed");
        return;
    }
    err = monitor_remote_relations(vroot, RRELS_COPY_BIT, RRELS_COPY_BIT, NULL);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "monitor_remote_relations failed");
        return;
    }

    /* Send msg to destination monitor */
    err = ib->tx_vtbl.span_domain_request(ib, NOP_CONT, state_id,
                                          vroot_cap.u.vnode_x86_64_pml4.base,
                                          frameid.base, frameid.bits);

    if (err_is_fail(err)) {
        err_push(err, MON_ERR_SEND_REMOTE_MSG);
        goto reply;
    }
    goto cleanup;

 reply:
    err2 = mb->tx_vtbl.span_domain_reply(mb, NOP_CONT, err, domain_id);
    if (err_is_fail(err2)) {
        // XXX: Cleanup?
        USER_PANIC_ERR(err2, "Failed to reply to the user domain");
    }
    if(state_id != 0) {
        err2 = span_state_free(state_id);
        if (err_is_fail(err2)) {
            USER_PANIC_ERR(err2, "Failed to free span state");
        }
    }

 cleanup:
    err2 = cap_destroy(vroot);
    if (err_is_fail(err2)) {
        USER_PANIC_ERR(err2, "Failed to destroy span_vroot cap");
    }
    err2 = cap_destroy(disp);
    if (err_is_fail(err2)) {
        USER_PANIC_ERR(err2, "Failed to destroy disp cap");
    }
}
コード例 #6
0
ファイル: inter.c プロジェクト: huiweics/arrakis
/**
 * \brief Notification of a newly booted monitor.
 *  Setup our connection and request the sender to proxy
 *  the bind request to the monitor
 */
static void new_monitor_notify(struct intermon_binding *b,
                               coreid_t core_id)
{
    errval_t err;

    /* Setup the connection */
    ram_set_affinity(SHARED_MEM_MIN + (PERCORE_MEM_SIZE * my_core_id),
                     SHARED_MEM_MIN + (PERCORE_MEM_SIZE * (my_core_id + 1)));
    struct capref frame;
    err = frame_alloc(&frame, MON_URPC_SIZE, NULL);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "frame_alloc failed");
        return; // FIXME: cleanup
    }
    ram_set_affinity(0, 0);     // Reset affinity

    void *buf;
    err = vspace_map_one_frame_attr(&buf, MON_URPC_SIZE, frame, VREGION_FLAGS_READ_WRITE_NOCACHE, NULL, NULL);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "vspace_map_one_frame failed");
        assert(buf); // XXX
    }
    // XXX: Clear the frame (kernel can't do it for us)
    memset(buf, 0, MON_URPC_SIZE);

    // Allocate my own notification caps
    struct capref ep, my_notify_cap;
    struct lmp_endpoint *iep;
    int chanid;
    err = endpoint_create(LMP_RECV_LENGTH, &ep, &iep);
    assert(err_is_ok(err));
    err = notification_allocate(ep, &chanid);
    assert(err == SYS_ERR_OK);
    err = notification_create_cap(chanid, my_core_id, &my_notify_cap);
    assert(err == SYS_ERR_OK);

    // init our end of the binding and channel
    struct intermon_ump_ipi_binding *ump_binding =
        malloc(sizeof(struct intermon_ump_ipi_binding));
    assert(ump_binding != NULL);
    err = intermon_ump_ipi_init(ump_binding, get_default_waitset(),
                                buf, MON_URPC_CHANNEL_LEN,
                                buf + MON_URPC_CHANNEL_LEN,
                                MON_URPC_CHANNEL_LEN, NULL_CAP, my_notify_cap,
                                ep, iep);
    assert(err_is_ok(err));
    /* if (err_is_fail(err)) { */
    /*     cap_destroy(frame); */
    /*     return err_push(err, LIB_ERR_UMP_CHAN_BIND); */
    /* } */

    // Identify UMP frame for tracing
    struct frame_identity umpid = { .base = 0, .bits = 0 };
    err = invoke_frame_identify(frame, &umpid);
    assert(err_is_ok(err));
    ump_binding->ump_state.chan.recvid = (uintptr_t)umpid.base;
    ump_binding->ump_state.chan.sendid =
        (uintptr_t)(umpid.base + MON_URPC_CHANNEL_LEN);

    err = intermon_init(&ump_binding->b, core_id);
    assert(err_is_ok(err));

    /* Identify the frame cap */
    struct capability frame_cap;
    err = monitor_cap_identify(frame, &frame_cap);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "monitor_cap_identify failed");
        return; // FIXME: cleanup
    }

    intermon_caprep_t caprep;
    capability_to_caprep(&frame_cap, &caprep);

    /* reply to the sending monitor to proxy request */
    err = b->tx_vtbl.bind_monitor_proxy_scc(b, NOP_CONT, core_id,
                                            caprep, chanid, my_core_id);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "bind proxy request failed");
    }
}

errval_t arch_intermon_init(struct intermon_binding *b)
{
    b->rx_vtbl.bind_monitor_request_scc = bind_monitor_request_scc;
    b->rx_vtbl.bind_monitor_reply_scc = bind_monitor_reply_scc;
    b->rx_vtbl.bind_monitor_proxy_scc = bind_monitor_proxy_scc;
    b->rx_vtbl.new_monitor_notify = new_monitor_notify;

    return SYS_ERR_OK;
}
コード例 #7
0
ファイル: ump_support.c プロジェクト: CoryXie/BarrelfishOS
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);
}