diff --git a/repos/base-hw/src/core/rm_session_support.cc b/repos/base-hw/src/core/rm_session_support.cc index 78e0141d61..fa38b108be 100644 --- a/repos/base-hw/src/core/rm_session_support.cc +++ b/repos/base-hw/src/core/rm_session_support.cc @@ -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(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(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::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(); } }