mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-24 15:56:41 +00:00
nova: recall thread if exception can't be resolved
Recall faulting thread and block pager thread. The pager get resumed as soon as the fault gets resolved by the rm_session (or never ever). Fixes #621
This commit is contained in:
parent
ac5b814387
commit
6cc0d69aa7
@ -63,18 +63,7 @@ void Pager_object::_page_fault_handler()
|
||||
int ret = obj->pager(ipc_pager);
|
||||
|
||||
if (ret) {
|
||||
if (obj->submit_exception_signal())
|
||||
/* Somebody takes care don't die - just recall and block */
|
||||
obj->client_recall();
|
||||
else {
|
||||
PWRN("unresolvable page-fault at address 0x%lx, ip=0x%lx",
|
||||
ipc_pager.fault_addr(), ipc_pager.fault_ip());
|
||||
|
||||
/* revoke paging capability, let thread die in kernel */
|
||||
Nova::revoke(Obj_crd(obj->exc_pt_sel() + PT_SEL_PAGE_FAULT, 0));
|
||||
obj->_state.dead = true;
|
||||
}
|
||||
|
||||
utcb->set_msg_word(0);
|
||||
utcb->mtd = 0;
|
||||
}
|
||||
@ -88,11 +77,15 @@ void Pager_object::_exception_handler(addr_t portal_id)
|
||||
Thread_base *myself;
|
||||
Pager_object *obj;
|
||||
Utcb *utcb = _check_handler(myself, obj);
|
||||
addr_t fault_ip = utcb->ip;
|
||||
|
||||
if (obj->submit_exception_signal())
|
||||
/* Somebody takes care don't die - just recall and block */
|
||||
obj->client_recall();
|
||||
else {
|
||||
PWRN("unresolvable exception at ip 0x%lx, exception portal 0x%lx",
|
||||
fault_ip, portal_id);
|
||||
|
||||
Nova::revoke(Obj_crd(portal_id, 0));
|
||||
obj->_state.dead = true;
|
||||
}
|
||||
@ -303,13 +296,16 @@ Pager_object::~Pager_object()
|
||||
*/
|
||||
revoke(Obj_crd(exc_pt_sel(), NUM_INITIAL_PT_LOG2), false);
|
||||
|
||||
/* Revoke semaphore cap to signal valid state after recall */
|
||||
/* revoke semaphore cap to signal valid state after recall */
|
||||
addr_t sm_cap = _sm_state_notify;
|
||||
_sm_state_notify = Native_thread::INVALID_INDEX;
|
||||
/* If pager is blocked wake him up */
|
||||
/* wake up client blocked in a thread::pause call */
|
||||
sm_ctrl(sm_cap, SEMAPHORE_UP);
|
||||
revoke(Obj_crd(sm_cap, 0));
|
||||
|
||||
/* if pager is blocked wake him up */
|
||||
wake_up();
|
||||
|
||||
/*
|
||||
* Make sure nobody is in the handler anymore by doing an IPC to a
|
||||
* local cap pointing to same serving thread (if not running in the
|
||||
|
Loading…
Reference in New Issue
Block a user