diff --git a/base-nova/include/nova/util.h b/base-nova/include/nova/util.h index 9c1df028c9..7483af3c96 100644 --- a/base-nova/include/nova/util.h +++ b/base-nova/include/nova/util.h @@ -23,8 +23,8 @@ inline void nova_die(const char * text = 0) /* * If thread is de-constructed the sessions are already gone. * Be careful when enabling printf here. - */ - while (1) + */ + while (1) asm volatile ("ud2a" : : "a"(text)); } diff --git a/base-nova/patches/del_able_utcb.patch b/base-nova/patches/del_able_utcb.patch new file mode 100644 index 0000000000..c9f24528e5 --- /dev/null +++ b/base-nova/patches/del_able_utcb.patch @@ -0,0 +1,45 @@ +diff --git a/src/ec.cpp b/src/ec.cpp +index 5d5a66c..a69cfef 100644 +--- a/src/ec.cpp ++++ b/src/ec.cpp +@@ -64,6 +64,8 @@ Ec::Ec (Pd *own, mword sel, Pd *p, void (*f)(), unsigned c, unsigned e, mword u, + + trace (TRACE_SYSCALL, "EC:%p created (PD:%p CPU:%#x UTCB:%#lx ESP:%lx EVT:%#x)", this, p, c, u, s, e); + ++ pd->insert_utcb (u, Buddy::ptr_to_phys(utcb) >> 12); ++ + } else { + + regs.dst_portal = NUM_VMI - 2; +diff --git a/src/space_mem.cpp b/src/space_mem.cpp +index 5341836..60e2fdc 100644 +--- a/src/space_mem.cpp ++++ b/src/space_mem.cpp +@@ -132,12 +132,12 @@ void Space_mem::insert_root (uint64 s, uint64 e, mword a) + } + } + +-bool Space_mem::insert_utcb (mword b) ++bool Space_mem::insert_utcb (mword b, mword phys) + { + if (!b) + return true; + +- Mdb *mdb = new Mdb (this, 0, b >> PAGE_BITS, 0); ++ Mdb *mdb = new Mdb (this, phys, b >> PAGE_BITS, 0, 0x3); + + if (tree_insert (mdb)) + return true; +diff --git a/include/space_mem.h b/include/space_mem.h +index e155dad..1584395 100644 +--- a/include/space_mem.h ++++ b/include/space_mem.h +@@ -68,7 +68,7 @@ class Space_mem : public Space + INIT + void insert_root (uint64, uint64, mword = 0x7); + +- bool insert_utcb (mword); ++ bool insert_utcb (mword, mword = 0); + + void update (Mdb *, mword = 0); + diff --git a/base-nova/src/base/env/main_thread.cc b/base-nova/src/base/env/main_thread.cc index 3570a204ba..33a4787d4b 100644 --- a/base-nova/src/base/env/main_thread.cc +++ b/base-nova/src/base/env/main_thread.cc @@ -20,13 +20,12 @@ using namespace Genode; -/** - * Location of the main thread's UTCB, initialized by the startup code - */ -Nova::mword_t __main_thread_utcb; - - -Native_utcb *main_thread_utcb() { return (Native_utcb *)__main_thread_utcb; } +Native_utcb *main_thread_utcb() +{ + return reinterpret_cast( + Native_config::context_area_virtual_base() + + Native_config::context_area_virtual_size() - Nova::PAGE_SIZE_BYTE); +} addr_t main_thread_running_semaphore() { return Nova::SM_SEL_EC; } diff --git a/base-nova/src/core/include/nova_util.h b/base-nova/src/core/include/nova_util.h index 514068103c..d3c479b501 100644 --- a/base-nova/src/core/include/nova_util.h +++ b/base-nova/src/core/include/nova_util.h @@ -56,11 +56,12 @@ static int map_local(Nova::Utcb *utcb, Nova::Crd src_crd, Nova::Crd dst_crd, /* establish the mapping via a portal traversal during reply phase */ Nova::uint8_t res = Nova::call(echo()->pt_sel()); - if (res != 0 || utcb->msg_words() != 1 || !utcb->msg[0]) { - PERR("Failure - map_local 0x%lx:%lu:%u->0x%lx:%lu:%u - call result=%x utcb=%x:%lx !!!", + if (res != Nova::NOVA_OK || utcb->msg_words() != 1 || !utcb->msg[0]) { + PERR("Failure - map_local 0x%lx:%lu:%u->0x%lx:%lu:%u - call result=%x" + " utcb=%x:%lx !!! %p %u", src_crd.addr(), src_crd.order(), src_crd.type(), dst_crd.addr(), dst_crd.order(), dst_crd.type(), - res, utcb->msg_words(), utcb->msg[0]); + res, utcb->msg_words(), utcb->msg[0], utcb, kern_pd); return res > 0 ? res : -1; } /* clear receive window */ diff --git a/base-nova/src/core/platform.cc b/base-nova/src/core/platform.cc index b594964a92..f2c54c8f39 100644 --- a/base-nova/src/core/platform.cc +++ b/base-nova/src/core/platform.cc @@ -34,6 +34,7 @@ using namespace Nova; enum { verbose_boot_info = true }; +Native_utcb *main_thread_utcb(); /** * Initial value of esp register, saved by the crt0 startup code @@ -52,7 +53,7 @@ extern int __first_free_cap_selector; /** * Pointer to the UTCB of the main thread */ -extern Utcb *__main_thread_utcb; +Utcb *__main_thread_utcb; /** @@ -384,6 +385,13 @@ Platform::Platform() : _irq_alloc.add_range(0, hip->sel_gsi - 1); _gsi_base_sel = (hip->mem_desc_offset - hip->cpu_desc_offset) / hip->cpu_desc_size; + /* remap main utcb to default utbc address */ + if (map_local(__main_thread_utcb, (addr_t)__main_thread_utcb, + (addr_t)main_thread_utcb(), 1)) { + PERR("could not remap main threads utcb"); + nova_die(); + } + if (verbose_boot_info) { printf(":virt_alloc: "); _core_mem_alloc.virt_alloc()->raw()->dump_addr_tree(); printf(":phys_alloc: "); _core_mem_alloc.phys_alloc()->raw()->dump_addr_tree(); diff --git a/base-nova/src/core/platform_thread.cc b/base-nova/src/core/platform_thread.cc index 719a363a0c..7b3cc0a7d7 100644 --- a/base-nova/src/core/platform_thread.cc +++ b/base-nova/src/core/platform_thread.cc @@ -55,12 +55,10 @@ int Platform_thread::start(void *ip, void *sp) return -2; } - _pager->initial_eip((addr_t)ip); if (!_is_main_thread) { addr_t initial_sp = reinterpret_cast(sp); addr_t utcb = _is_vcpu ? 0 : round_page(initial_sp); - _pager->initial_esp(initial_sp); if (_sel_exc_base == Native_thread::INVALID_INDEX) { PERR("exception base not specified"); return -3; @@ -72,12 +70,10 @@ int Platform_thread::start(void *ip, void *sp) * SM_SEL_EC_CLIENT and can be later on requested by the thread * the same way as STARTUP and PAGEFAULT portal. */ - uint8_t res = Nova::create_sm(_pager->exc_pt_sel() + - SM_SEL_EC_CLIENT, - _pd->pd_sel(), 0); + addr_t sm = _pager->exc_pt_sel() + SM_SEL_EC_CLIENT; + uint8_t res = Nova::create_sm(sm, _pd->pd_sel(), 0); if (res != Nova::NOVA_OK) { - PERR("creation of semaphore for new thread failed %u", - res); + PERR("creation of semaphore for new thread failed %u", res); return -4; } @@ -86,12 +82,17 @@ int Platform_thread::start(void *ip, void *sp) res = create_ec(_sel_ec(), _pd->pd_sel(), _cpu_no, utcb, initial_sp, _sel_exc_base, thread_global); - if (res) + if (res != Nova::NOVA_OK) { + revoke(Obj_crd(sm, 0)); PERR("creation of new thread failed %u", res); + return -5; + } + _pager->initial_eip((addr_t)ip); + _pager->initial_esp(initial_sp); _pager->client_set_ec(_sel_ec()); - return res ? -5 : 0; + return 0; } if (_sel_exc_base != Native_thread::INVALID_INDEX) { @@ -107,8 +108,6 @@ int Platform_thread::start(void *ip, void *sp) Native_config::context_area_virtual_size() - get_page_size(); - _pager->initial_esp(pd_utcb + get_page_size()); - _sel_exc_base = cap_selector_allocator()->alloc(NUM_INITIAL_PT_LOG2); addr_t pd_core_sel = Platform_pd::pd_core_sel(); @@ -176,7 +175,7 @@ int Platform_thread::start(void *ip, void *sp) /* create task */ res = create_pd(pd_sel, pd_core_sel, initial_pts); - if (res) { + if (res != NOVA_OK) { PERR("create_pd returned %d", res); goto cleanup_pd; } @@ -185,7 +184,7 @@ int Platform_thread::start(void *ip, void *sp) enum { THREAD_GLOBAL = true }; res = create_ec(_sel_ec(), pd_sel, _cpu_no, pd_utcb, 0, 0, THREAD_GLOBAL); - if (res) { + if (res != NOVA_OK) { PERR("create_ec returned %d", res); goto cleanup_pd; } @@ -196,16 +195,20 @@ int Platform_thread::start(void *ip, void *sp) */ _pd->assign_pd(pd_sel); _pager->client_set_ec(_sel_ec()); + _pager->initial_eip((addr_t)ip); + _pager->initial_esp((addr_t)sp); /* Let the thread run */ res = create_sc(_sel_sc(), pd_sel, _sel_ec(), Qpd()); - if (res) { + if (res != NOVA_OK) { /** * Reset pd cap since thread got not running and pd cap will * be revoked during cleanup. */ _pd->assign_pd(Native_thread::INVALID_INDEX); _pager->client_set_ec(Native_thread::INVALID_INDEX); + _pager->initial_eip(0); + _pager->initial_esp(0); PERR("create_sc returned %d", res); goto cleanup_ec; diff --git a/base-nova/src/platform/_main_helper.h b/base-nova/src/platform/_main_helper.h index f65a9845e5..b781791c97 100644 --- a/base-nova/src/platform/_main_helper.h +++ b/base-nova/src/platform/_main_helper.h @@ -18,11 +18,6 @@ #include #include -/** - * Location of the main thread's UTCB, initialized by the startup code - */ -extern Nova::mword_t __main_thread_utcb; - /** * Initial value of esp register, saved by the crt0 startup code * @@ -37,9 +32,6 @@ extern int __first_free_cap_selector; static void main_thread_bootstrap() { - /* register UTCB of main thread */ - __main_thread_utcb = __initial_sp - Nova::PAGE_SIZE_BYTE; - /* register start of usable capability range */ enum { FIRST_FREE_PORTAL = 0x1000 }; diff --git a/os/src/lib/ldso/symbol.map b/os/src/lib/ldso/symbol.map index c674d440d8..5f5df8097b 100644 --- a/os/src/lib/ldso/symbol.map +++ b/os/src/lib/ldso/symbol.map @@ -76,9 +76,7 @@ l4_atomic_cmpxchg; /* Nova */ - __main_thread_utcb; __first_free_cap_selector; - __local_pd_sel; extern "C++" { main_thread_utcb*;