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 * Base of portal receive window
*/ */
int _rcv_pt_base; addr_t _rcv_pt_base;
struct { struct {
addr_t sel; addr_t sel;
@ -64,9 +64,9 @@ namespace Genode {
unsigned _rcv_pt_sel_max; 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 */ char _msg_start[]; /* symbol marks start of message */
@ -75,12 +75,17 @@ namespace Genode {
/** /**
* Constructor * Constructor
*/ */
Msgbuf_base() : _rcv_dirty(true) Msgbuf_base() : _rcv_pt_base(~0UL), _rcv_items(0)
{ {
rcv_reset(); rcv_reset();
snd_reset(); snd_reset();
} }
~Msgbuf_base()
{
rcv_reset();
}
/* /*
* Begin of actual message buffer * Begin of actual message buffer
*/ */
@ -156,11 +161,16 @@ namespace Genode {
return 0; 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 * Return true if receive window must be re-initialized
* *
* After reading portal selectors from the message buffer using * 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. * current receive window with one or more portal capabilities.
* To enable the reception of portal capability selectors for the * To enable the reception of portal capability selectors for the
* next IDC, we need a fresh receive window. * next IDC, we need a fresh receive window.
@ -231,10 +241,8 @@ namespace Genode {
*/ */
void rcv_prepare_pt_sel_window(Nova::Utcb *utcb) 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_pt_base = cap_selector_allocator()->alloc(MAX_CAP_ARGS_LOG2);
_rcv_dirty = false;
}
/* register receive window at the UTCB */ /* register receive window at the UTCB */
utcb->crd_rcv = Nova::Obj_crd(rcv_pt_base(),MAX_CAP_ARGS_LOG2); 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]; mword_t *dst = (mword_t *)&msg_buf[0];
for (unsigned i = 0; i < num_msg_words; i++) for (unsigned i = 0; i < num_msg_words; i++)
*dst++ = *src++; *dst++ = *src++;
rcv_msg->rcv_reset();
} }
@ -151,6 +149,7 @@ void Ipc_client::_call()
PERR("call returned %u", res); PERR("call returned %u", res);
} }
_rcv_msg->post_ipc(utcb);
copy_utcb_to_msgbuf(utcb, _rcv_msg); copy_utcb_to_msgbuf(utcb, _rcv_msg);
_snd_msg->snd_reset(); _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()); Rpc_entrypoint *ep = static_cast<Rpc_entrypoint *>(Thread_base::myself());
Ipc_server srv(&ep->_snd_buf, &ep->_rcv_buf); Ipc_server srv(&ep->_snd_buf, &ep->_rcv_buf);
ep->_rcv_buf.post_ipc(reinterpret_cast<Nova::Utcb *>(ep->utcb()));
/* destination of next reply */ /* destination of next reply */
srv.dst(Native_capability(id_pt, srv.badge())); srv.dst(Native_capability(id_pt, srv.badge()));