diff --git a/base-nova/include/nova/syscall-generic.h b/base-nova/include/nova/syscall-generic.h index 9f75a86ad..9c11b080b 100644 --- a/base-nova/include/nova/syscall-generic.h +++ b/base-nova/include/nova/syscall-generic.h @@ -362,8 +362,10 @@ namespace Nova { enum { RIGHT_EC_RECALL = 0x1U, - RIGHT_PT_CTRL = 0x1U, - RIGHT_PT_CALL = 0x2U + RIGHT_PT_CALL = 0x1U, + RIGHT_PT_CTRL = 0x2U, + RIGHT_SM_UP = 0x1U, + RIGHT_SM_DOWN = 0x2U }; Obj_crd() : Crd(0, 0) @@ -575,6 +577,8 @@ namespace Nova { enum { PT_SEL_PAGE_FAULT = 0xe, PT_SEL_PARENT = 0x1a, /* convention on Genode */ + PT_SEL_MAIN_PAGER = 0x1b, /* convention on Genode */ + PT_SEL_MAIN_EC = 0x1c, /* convention on Genode */ PT_SEL_STARTUP = 0x1e, PT_SEL_RECALL = 0x1f, SM_SEL_EC = 0x1d, /* convention on Genode */ diff --git a/base-nova/include/nova/util.h b/base-nova/include/nova/util.h index a9093dbf9..211021cdd 100644 --- a/base-nova/include/nova/util.h +++ b/base-nova/include/nova/util.h @@ -56,8 +56,8 @@ inline void request_event_portal(Genode::Native_capability const &cap, inline void request_native_ec_cap(Genode::Native_capability const &cap, - Genode::addr_t sel) { - request_event_portal(cap, sel , ~0UL, 1); } + Genode::addr_t sel, unsigned pager_cap = 1) { + request_event_portal(cap, sel , ~0UL, pager_cap); } inline void request_signal_sm_cap(Genode::Native_capability const &cap, diff --git a/base-nova/src/base/pager/pager.cc b/base-nova/src/base/pager/pager.cc index 1d921aad7..1b1b04ce4 100644 --- a/base-nova/src/base/pager/pager.cc +++ b/base-nova/src/base/pager/pager.cc @@ -224,7 +224,9 @@ void Pager_object::_invoke_handler() */ bool res = utcb->append_item(Obj_crd(obj->_state.sel_client_ec, 0, Obj_crd::RIGHT_EC_RECALL), 0); - res = utcb->append_item(Obj_crd(obj->Object_pool::Entry::cap().local_name(), 0), 1); + /* if logcount > 0 then the pager cap should also be mapped */ + if (logcount) + res = utcb->append_item(Obj_crd(obj->Object_pool::Entry::cap().local_name(), 0), 1); (void)res; reply(myself->stack_top()); diff --git a/base-nova/src/base/thread/thread_nova.cc b/base-nova/src/base/thread/thread_nova.cc index a65f46c9b..de509f099 100644 --- a/base-nova/src/base/thread/thread_nova.cc +++ b/base-nova/src/base/thread/thread_nova.cc @@ -79,7 +79,15 @@ void Thread_base::_init_platform_thread(Type type) /* for main threads the member initialization differs */ if (type == MAIN || type == REINITIALIZED_MAIN) { _thread_cap = env()->parent()->main_thread_cap(); + + Genode::Native_capability pager_cap(Nova::PT_SEL_MAIN_PAGER); + _pager_cap = reinterpret_cap_cast(pager_cap); + _tid.exc_pt_sel = 0; + _tid.ec_sel = Nova::PT_SEL_MAIN_EC; + + enum { DONT_MAP_PAGER_CAP = 0 }; + request_native_ec_cap(_pager_cap, _tid.ec_sel, DONT_MAP_PAGER_CAP); return; } diff --git a/base-nova/src/core/platform_thread.cc b/base-nova/src/core/platform_thread.cc index 0bff9627a..dae419408 100644 --- a/base-nova/src/core/platform_thread.cc +++ b/base-nova/src/core/platform_thread.cc @@ -108,8 +108,9 @@ int Platform_thread::start(void *ip, void *sp) pd_utcb = Native_config::context_area_virtual_base() + Native_config::context_virtual_size() - get_page_size(); - addr_t remap_src[] = { _pd->parent_pt_sel() }; - addr_t remap_dst[] = { PT_SEL_PARENT }; + addr_t remap_src[] = { _pd->parent_pt_sel(), + _pager->Object_pool::Entry::cap().local_name() }; + addr_t remap_dst[] = { PT_SEL_PARENT, PT_SEL_MAIN_PAGER }; /* remap exception portals for first thread */ for (unsigned i = 0; i < sizeof(remap_dst)/sizeof(remap_dst[0]); i++) { @@ -120,11 +121,14 @@ int Platform_thread::start(void *ip, void *sp) } } - addr_t pd_sel = cap_map()->insert(); - /* create task */ - Obj_crd initial_pts(_sel_exc_base, is_vcpu() ? - NUM_INITIAL_VCPU_PT_LOG2 : NUM_INITIAL_PT_LOG2); + addr_t const pd_sel = cap_map()->insert(); + addr_t const rights = Obj_crd::RIGHT_EC_RECALL | + Obj_crd::RIGHT_PT_CTRL | Obj_crd::RIGHT_PT_CALL | + Obj_crd::RIGHT_SM_UP | Obj_crd::RIGHT_SM_DOWN; + unsigned pts = is_vcpu() ? NUM_INITIAL_VCPU_PT_LOG2 : NUM_INITIAL_PT_LOG2; + + Obj_crd initial_pts(_sel_exc_base, pts, rights); uint8_t res = create_pd(pd_sel, pd_core_sel, initial_pts); if (res != NOVA_OK) { PERR("create_pd returned %d", res);