NOVA: Fix cleanup of received capabilities, #268

MsgBuf has to keep the number of received capabilities in order
to free/know correctly unused and unwanted capabilities. Explicitly
call rcv_msg->post_ipc to store this information in a MsgBuf.

Don't reset rcv_msg in ipc.cc, since this is used during
un-marshalling of caps in ipc.h afterwards. The MsgBuf is reseted when its
de-constructor is called.
This commit is contained in:
Alexander Boettcher 2012-08-07 13:19:28 +02:00 committed by Norman Feske
parent e829288069
commit 998ebfc01b
3 changed files with 18 additions and 10 deletions

View File

@ -50,7 +50,7 @@ namespace Genode {
/**
* Base of portal receive window
*/
int _rcv_pt_base;
addr_t _rcv_pt_base;
struct {
addr_t sel;
@ -64,9 +64,9 @@ namespace Genode {
unsigned _rcv_pt_sel_max;
/**
* Flag set to true if receive window must be re-initialized
* Number of capabilities which has been received, reported by the kernel.
*/
bool _rcv_dirty;
unsigned _rcv_items;
char _msg_start[]; /* symbol marks start of message */
@ -75,12 +75,17 @@ namespace Genode {
/**
* Constructor
*/
Msgbuf_base() : _rcv_dirty(true)
Msgbuf_base() : _rcv_pt_base(~0UL), _rcv_items(0)
{
rcv_reset();
snd_reset();
}
~Msgbuf_base()
{
rcv_reset();
}
/*
* Begin of actual message buffer
*/
@ -156,11 +161,16 @@ namespace Genode {
return 0;
}
/**
* Return true if receive window must be re-initialized
*/
bool rcv_invalid() { return _rcv_pt_base == ~0UL; }
/**
* Return true if receive window must be re-initialized
*
* After reading portal selectors from the message buffer using
* 'rcv_pt_sel()', we assume that the IDC call populared the
* 'rcv_pt_sel()', we assume that the IDC call populated the
* current receive window with one or more portal capabilities.
* To enable the reception of portal capability selectors for the
* next IDC, we need a fresh receive window.
@ -231,10 +241,8 @@ namespace Genode {
*/
void rcv_prepare_pt_sel_window(Nova::Utcb *utcb)
{
if (rcv_dirty()) {
if (rcv_invalid() || rcv_cleanup(true))
_rcv_pt_base = cap_selector_allocator()->alloc(MAX_CAP_ARGS_LOG2);
_rcv_dirty = false;
}
/* register receive window at the UTCB */
utcb->crd_rcv = Nova::Obj_crd(rcv_pt_base(),MAX_CAP_ARGS_LOG2);

View File

@ -49,8 +49,6 @@ static void copy_utcb_to_msgbuf(Nova::Utcb *utcb, Msgbuf_base *rcv_msg)
mword_t *dst = (mword_t *)&msg_buf[0];
for (unsigned i = 0; i < num_msg_words; i++)
*dst++ = *src++;
rcv_msg->rcv_reset();
}
@ -151,6 +149,7 @@ void Ipc_client::_call()
PERR("call returned %u", res);
}
_rcv_msg->post_ipc(utcb);
copy_utcb_to_msgbuf(utcb, _rcv_msg);
_snd_msg->snd_reset();

View File

@ -133,6 +133,7 @@ void Rpc_entrypoint::_activation_entry()
Rpc_entrypoint *ep = static_cast<Rpc_entrypoint *>(Thread_base::myself());
Ipc_server srv(&ep->_snd_buf, &ep->_rcv_buf);
ep->_rcv_buf.post_ipc(reinterpret_cast<Nova::Utcb *>(ep->utcb()));
/* destination of next reply */
srv.dst(Native_capability(id_pt, srv.badge()));