mirror of
https://github.com/genodelabs/genode.git
synced 2025-03-25 13:28:28 +00:00
hw: fix race on pager-object dissolve
The HW-kernel, in contrast to other kernels, provides a direct reference to the pager object with the fault signal that is send to the pager activation. When accessing this reference directly we may fall into the time span where the root parent-entrypoint of the faulter has alredy dissolved the pager object from the pager entrypoint, but not yet silenced the according signal context. To avoid this we issue an additional 'lookup_and_lock' with the received pager object. This isn't optimal as we don't need the potentially cost-intensive lookup but only the synchronization. Fixes #1311. Fixes #1332.
This commit is contained in:
parent
a59cf9f557
commit
d31492040c
@ -96,19 +96,26 @@ void Pager_activation_base::entry()
|
||||
_cap_valid.unlock();
|
||||
while (1)
|
||||
{
|
||||
/* await fault */
|
||||
Pager_object * o;
|
||||
while (1) {
|
||||
Signal s = Signal_receiver::wait_for_signal();
|
||||
o = dynamic_cast<Pager_object *>(s.context());
|
||||
if (o) {
|
||||
o->fault_occured(s);
|
||||
break;
|
||||
}
|
||||
PWRN("unknown pager object");
|
||||
/* receive fault */
|
||||
Signal s = Signal_receiver::wait_for_signal();
|
||||
Pager_object * po = static_cast<Pager_object *>(s.context());
|
||||
|
||||
/*
|
||||
* Synchronize access and ensure that the object is still managed
|
||||
*
|
||||
* FIXME: The implicit lookup of the oject isn't needed.
|
||||
*/
|
||||
unsigned const pon = po->cap().local_name();
|
||||
Object_pool<Pager_object>::Guard pog(_ep->lookup_and_lock(pon));
|
||||
if (!pog) {
|
||||
PWRN("failed to lookup pager object");
|
||||
continue;
|
||||
}
|
||||
/* let pager object go to fault state */
|
||||
pog->fault_occured(s);
|
||||
|
||||
/* fetch fault data */
|
||||
Platform_thread * const pt = (Platform_thread *)o->badge();
|
||||
Platform_thread * const pt = (Platform_thread *)pog->badge();
|
||||
if (!pt) {
|
||||
PWRN("failed to get platform thread of faulter");
|
||||
continue;
|
||||
@ -126,12 +133,15 @@ void Pager_activation_base::entry()
|
||||
PWRN("failed to read fault data");
|
||||
continue;
|
||||
}
|
||||
/* handle fault */
|
||||
if (o->pager(*this)) { continue; }
|
||||
/* try to resolve fault directly via local region managers */
|
||||
if (pog->pager(*this)) { continue; }
|
||||
|
||||
/* apply mapping that was determined by the local region managers */
|
||||
if (apply_mapping()) {
|
||||
PWRN("failed to apply mapping");
|
||||
continue;
|
||||
}
|
||||
o->fault_resolved();
|
||||
/* let pager object go back to no-fault state */
|
||||
pog->fault_resolved();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user