mirror of
https://github.com/genodelabs/genode.git
synced 2025-03-03 21:20:41 +00:00
parent
76a4253132
commit
d71ddeb983
@ -135,6 +135,12 @@ struct Genode::Receive_window
|
|||||||
|
|
||||||
unsigned num_received_caps() const { return _rcv_pt_sel_max; }
|
unsigned num_received_caps() const { return _rcv_pt_sel_max; }
|
||||||
|
|
||||||
|
enum Receive_cleanup_result {
|
||||||
|
SELECTORS_KEPT = 0,
|
||||||
|
REINIT_REQUIRED = 1,
|
||||||
|
OUT_OF_BOUNDS = 2
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if receive window must be re-initialized
|
* Return true if receive window must be re-initialized
|
||||||
*
|
*
|
||||||
@ -152,10 +158,12 @@ struct Genode::Receive_window
|
|||||||
* because object is freed
|
* because object is freed
|
||||||
* afterwards.
|
* afterwards.
|
||||||
*
|
*
|
||||||
* \result 'true' - receive window must be re-initialized
|
* \result Receive_cleanup_result:
|
||||||
* 'false' - portal selectors has been kept
|
* REINIT_REQUIRED - receive window must be re-initialized
|
||||||
|
* SELECTORS_KEPT - portal selectors has been kept
|
||||||
|
* OUT_OF_BOUNDS - invalid internal state which would lead to out of bounds access
|
||||||
*/
|
*/
|
||||||
bool rcv_cleanup(bool keep, unsigned short const new_max = MAX_CAP_ARGS);
|
Receive_cleanup_result rcv_cleanup(bool keep, uint16_t new_max = MAX_CAP_ARGS);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize receive window for portal capability
|
* Initialize receive window for portal capability
|
||||||
|
@ -116,7 +116,8 @@ bool Receive_window::rcv_invalid() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Receive_window::rcv_cleanup(bool keep, unsigned short const new_max)
|
Receive_window::Receive_cleanup_result Receive_window::rcv_cleanup(bool const keep,
|
||||||
|
uint16_t const new_max)
|
||||||
{
|
{
|
||||||
/* mark used mapped capabilities as used to prevent freeing */
|
/* mark used mapped capabilities as used to prevent freeing */
|
||||||
bool reinit = false;
|
bool reinit = false;
|
||||||
@ -127,7 +128,7 @@ bool Receive_window::rcv_cleanup(bool keep, unsigned short const new_max)
|
|||||||
/* should never happen */
|
/* should never happen */
|
||||||
if (_rcv_pt_sel[i].sel < _rcv_pt_base ||
|
if (_rcv_pt_sel[i].sel < _rcv_pt_base ||
|
||||||
(_rcv_pt_sel[i].sel >= _rcv_pt_base + MAX_CAP_ARGS))
|
(_rcv_pt_sel[i].sel >= _rcv_pt_base + MAX_CAP_ARGS))
|
||||||
nova_die();
|
return Receive_cleanup_result::OUT_OF_BOUNDS;
|
||||||
|
|
||||||
_rcv_pt_cap_free [_rcv_pt_sel[i].sel - _rcv_pt_base] = USED_CAP;
|
_rcv_pt_cap_free [_rcv_pt_sel[i].sel - _rcv_pt_base] = USED_CAP;
|
||||||
|
|
||||||
@ -154,7 +155,7 @@ bool Receive_window::rcv_cleanup(bool keep, unsigned short const new_max)
|
|||||||
cap_map().remove(_rcv_pt_base + i, 0, false);
|
cap_map().remove(_rcv_pt_base + i, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return Receive_cleanup_result::SELECTORS_KEPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* decrease ref count if valid selector */
|
/* decrease ref count if valid selector */
|
||||||
@ -164,7 +165,7 @@ bool Receive_window::rcv_cleanup(bool keep, unsigned short const new_max)
|
|||||||
cap_map().remove(_rcv_pt_base + i, 0, _rcv_pt_cap_free[i] != FREE_SEL);
|
cap_map().remove(_rcv_pt_base + i, 0, _rcv_pt_cap_free[i] != FREE_SEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return Receive_cleanup_result::REINIT_REQUIRED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -186,8 +187,22 @@ bool Receive_window::prepare_rcv_window(Nova::Utcb &utcb, addr_t rcv_window)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* allocate receive window if necessary, otherwise use old one */
|
/* allocate receive window if necessary, otherwise use old one */
|
||||||
if (rcv_invalid() || rcv_cleanup(true, 1U << _rcv_wnd_log2))
|
bool reinit_required = rcv_invalid();
|
||||||
{
|
|
||||||
|
if (!reinit_required) {
|
||||||
|
auto const rcv_result = rcv_cleanup(true, 1U << _rcv_wnd_log2);
|
||||||
|
|
||||||
|
if (rcv_result == Receive_cleanup_result::OUT_OF_BOUNDS) {
|
||||||
|
_rcv_pt_base = INVALID_INDEX;
|
||||||
|
/* no mappings can be received */
|
||||||
|
utcb.crd_rcv = Nova::Obj_crd();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
reinit_required = rcv_result == Receive_cleanup_result::REINIT_REQUIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reinit_required) {
|
||||||
_rcv_pt_base = cap_map().insert(_rcv_wnd_log2);
|
_rcv_pt_base = cap_map().insert(_rcv_wnd_log2);
|
||||||
|
|
||||||
if (_rcv_pt_base == INVALID_INDEX) {
|
if (_rcv_pt_base == INVALID_INDEX) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user