diff --git a/base-nova/include/base/ipc_msgbuf.h b/base-nova/include/base/ipc_msgbuf.h index 20aa037ea..c351a6838 100644 --- a/base-nova/include/base/ipc_msgbuf.h +++ b/base-nova/include/base/ipc_msgbuf.h @@ -54,7 +54,7 @@ namespace Genode { struct { addr_t sel; unsigned rights; - bool trans_map; + bool trans_map; } _snd_pt_sel [MAX_CAP_ARGS]; /** @@ -280,32 +280,43 @@ namespace Genode { * rcv_window parameter, this function allocates a * fresh receive window and clears 'rcv_invalid'. */ - void rcv_prepare_pt_sel_window(Nova::Utcb *utcb, + bool rcv_prepare_pt_sel_window(Nova::Utcb *utcb, addr_t rcv_window = INVALID_INDEX) { - /* - * If a rcv_window was specified use solely - * the selector specified by rcv_window. - */ - if (rcv_window != INVALID_INDEX) { - /* cleanup if this msgbuf was already used */ - if (!rcv_invalid()) rcv_cleanup(false); + try { + /* + * If a rcv_window was specified use solely + * the selector specified by rcv_window. + */ + if (rcv_window != INVALID_INDEX) { + /* cleanup if this msgbuf was already used */ + if (!rcv_invalid()) rcv_cleanup(false); - _rcv_pt_base = rcv_window; - } else { - if (rcv_invalid() || rcv_cleanup(true)) - _rcv_pt_base = cap_selector_allocator()->alloc(MAX_CAP_ARGS_LOG2); + _rcv_pt_base = rcv_window; + } else { + if (rcv_invalid() || rcv_cleanup(true)) + _rcv_pt_base = cap_selector_allocator()->alloc(MAX_CAP_ARGS_LOG2); + } + + addr_t max = 0; + if (rcv_window == INVALID_INDEX) + max = MAX_CAP_ARGS_LOG2; + + using namespace Nova; + /* setup receive window */ + utcb->crd_rcv = Obj_crd(rcv_pt_base(), max); + /* open maximal translate window */ + utcb->crd_xlt = Obj_crd(0, ~0UL); + + return true; + } catch (Bit_array_out_of_indexes) { + using namespace Nova; + /* setup receive window */ + utcb->crd_rcv = Obj_crd(); + /* open maximal translate window */ + utcb->crd_xlt = Obj_crd(0, ~0UL); + return false; } - - addr_t max = 0; - if (rcv_window == INVALID_INDEX) - max = MAX_CAP_ARGS_LOG2; - - using namespace Nova; - /* setup receive window */ - utcb->crd_rcv = Obj_crd(rcv_pt_base(), max); - /* open maximal translate window */ - utcb->crd_xlt = Obj_crd(0, ~0UL); } /** @@ -346,7 +357,7 @@ namespace Genode { _rcv_pt_cap_free [cap.base() - rcv_pt_base()] = UNUSED_CAP; } - if (_rcv_pt_sel_max >= max) continue; + if (_rcv_pt_sel_max >= max) continue; /* track the order of mapped and translated items */ if (cap.is_null()) { @@ -368,7 +379,6 @@ namespace Genode { if (max != MAX_CAP_ARGS) _rcv_pt_base = INVALID_INDEX; } - }; diff --git a/base-nova/src/base/ipc/ipc.cc b/base-nova/src/base/ipc/ipc.cc index 5aad04878..077184c82 100644 --- a/base-nova/src/base/ipc/ipc.cc +++ b/base-nova/src/base/ipc/ipc.cc @@ -140,7 +140,11 @@ void Ipc_client::_call() PERR("could not setup IPC"); return; } - _rcv_msg->rcv_prepare_pt_sel_window(utcb, Ipc_ostream::_dst.rcv_window()); + + /* if we can't setup receive window, die in order to recognize the issue */ + if (!_rcv_msg->rcv_prepare_pt_sel_window(utcb, Ipc_ostream::_dst.rcv_window())) + /* printf doesn't work here since for IPC also rcv_prepare* is used */ + nova_die(); /* establish the mapping via a portal traversal */ uint8_t res = Nova::call(Ipc_ostream::_dst.local_name()); diff --git a/base-nova/src/base/server/server.cc b/base-nova/src/base/server/server.cc index 170175857..d973c48b4 100644 --- a/base-nova/src/base/server/server.cc +++ b/base-nova/src/base/server/server.cc @@ -105,7 +105,7 @@ void Rpc_entrypoint::_activation_entry() Ipc_server srv(&ep->_snd_buf, &ep->_rcv_buf); ep->_rcv_buf.post_ipc(reinterpret_cast(ep->utcb())); - /* destination of next reply */ + /* destination of next reply - no effect on nova */ srv.dst(Native_capability(id_pt)); int opcode = 0; @@ -116,11 +116,7 @@ void Rpc_entrypoint::_activation_entry() srv.ret(ERR_INVALID_OBJECT); /* atomically lookup and lock referenced object */ - Rpc_object_base * curr_obj = ep->lookup_and_lock(id_pt); - { - Lock::Guard lock_guard(ep->_curr_obj_lock); - ep->_curr_obj = curr_obj; - } + ep->_curr_obj = ep->lookup_and_lock(id_pt); if (!ep->_curr_obj) { /* @@ -133,21 +129,23 @@ void Rpc_entrypoint::_activation_entry() " return from call id_pt=%lx", id_pt); - srv << IPC_REPLY; - } + } else { - /* dispatch request */ - try { srv.ret(ep->_curr_obj->dispatch(opcode, srv, srv)); } - catch (Blocking_canceled) { } + /* dispatch request */ + try { srv.ret(ep->_curr_obj->dispatch(opcode, srv, srv)); } + catch (Blocking_canceled) { } - Rpc_object_base * tmp = ep->_curr_obj; - { - Lock::Guard lock_guard(ep->_curr_obj_lock); + Rpc_object_base * tmp = ep->_curr_obj; ep->_curr_obj = 0; - } - tmp->release(); - ep->_rcv_buf.rcv_prepare_pt_sel_window((Nova::Utcb *)ep->utcb()); + tmp->release(); + } + + /* if we can't setup receive window, die in order to recognize the issue */ + if (!ep->_rcv_buf.rcv_prepare_pt_sel_window((Nova::Utcb *)ep->utcb())) + /* printf doesn't work here since for IPC also rcv_prepare* is used */ + nova_die(); + srv << IPC_REPLY; }