From 7e517179c9ac1aa11cd3501299634675f48932d1 Mon Sep 17 00:00:00 2001 From: Christian Helmuth Date: Fri, 17 Jan 2014 17:22:32 +0100 Subject: [PATCH] Unify stack alignment among all platforms The alignment is now done in Thread_base::Context. Implementations are forced to use Context::stack_top(), which aligns the stack top. --- base-codezero/src/base/thread/thread_start.cc | 4 +--- base-codezero/src/core/thread_start.cc | 2 +- base-fiasco/src/core/thread_start.cc | 2 +- base-foc/src/base/thread/thread_start.cc | 4 +--- base-foc/src/core/thread_start.cc | 2 +- base-hw/src/base/thread_support.cc | 4 +--- base-linux/src/base/thread/thread_linux.cc | 2 +- base-linux/src/core/thread_linux.cc | 4 +--- base-nova/src/base/pager/pager.cc | 2 +- base-nova/src/base/server/server.cc | 2 +- base-nova/src/base/thread/thread_nova.cc | 5 +--- base-nova/src/core/irq_session_component.cc | 4 ++-- base-nova/src/core/thread_start.cc | 17 ++++++++------ base-okl4/src/core/thread_start.cc | 2 +- base-pistachio/src/core/thread_start.cc | 2 +- base/include/base/thread.h | 23 ++++++++++++------- base/src/base/thread/thread_start.cc | 4 +--- ports-foc/src/lib/l4lx/include/vcpu.h | 23 +++++++++---------- 18 files changed, 52 insertions(+), 56 deletions(-) diff --git a/base-codezero/src/base/thread/thread_start.cc b/base-codezero/src/base/thread/thread_start.cc index 9802132908..44c42df9c6 100644 --- a/base-codezero/src/base/thread/thread_start.cc +++ b/base-codezero/src/base/thread/thread_start.cc @@ -64,9 +64,7 @@ void Thread_base::start() env()->cpu_session()->set_pager(_thread_cap, _pager_cap); /* register initial IP and SP at core */ - addr_t thread_sp = (addr_t)&_context->stack[-4]; - thread_sp &= ~0xf; /* align initial stack to 16 byte boundary */ - env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start, thread_sp); + env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start, _context->stack_top()); } diff --git a/base-codezero/src/core/thread_start.cc b/base-codezero/src/core/thread_start.cc index caf06a596f..af14b81509 100644 --- a/base-codezero/src/core/thread_start.cc +++ b/base-codezero/src/core/thread_start.cc @@ -104,7 +104,7 @@ void Thread_base::start() /* create and start platform thread */ _tid.pt = new(platform()->core_mem_alloc()) Platform_thread(_context->name); - _tid.l4id = create_thread(1, &_context->stack[-4], (void *)&_thread_start); + _tid.l4id = create_thread(1, stack_top(), (void *)&_thread_start); if (_tid.l4id < 0) PERR("create_thread returned %d", _tid.l4id); diff --git a/base-fiasco/src/core/thread_start.cc b/base-fiasco/src/core/thread_start.cc index 3709570891..b2d065e7f3 100644 --- a/base-fiasco/src/core/thread_start.cc +++ b/base-fiasco/src/core/thread_start.cc @@ -41,7 +41,7 @@ void Thread_base::start() _tid.pt->pager(platform_specific()->core_pager()); _tid.l4id = _tid.pt->native_thread_id(); - _tid.pt->start((void *)_thread_start, _context->stack); + _tid.pt->start((void *)_thread_start, stack_top()); } diff --git a/base-foc/src/base/thread/thread_start.cc b/base-foc/src/base/thread/thread_start.cc index 023fc29ef7..041512155b 100644 --- a/base-foc/src/base/thread/thread_start.cc +++ b/base-foc/src/base/thread/thread_start.cc @@ -70,9 +70,7 @@ void Thread_base::start() l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this; /* register initial IP and SP at core */ - addr_t thread_sp = (addr_t)&_context->stack[-4]; - thread_sp &= ~0xf; /* align initial stack to 16 byte boundary */ - env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start, thread_sp); + env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start, _context->stack_top()); } diff --git a/base-foc/src/core/thread_start.cc b/base-foc/src/core/thread_start.cc index 7d69f7faca..6f865fcedc 100644 --- a/base-foc/src/core/thread_start.cc +++ b/base-foc/src/core/thread_start.cc @@ -56,7 +56,7 @@ void Thread_base::start() l4_utcb_tcr_u(pt->utcb())->user[UTCB_TCR_BADGE] = (unsigned long) pt->gate().local.idx(); l4_utcb_tcr_u(pt->utcb())->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this; - pt->start((void *)_thread_start, _context->stack); + pt->start((void *)_thread_start, stack_top()); } diff --git a/base-hw/src/base/thread_support.cc b/base-hw/src/base/thread_support.cc index c958723bad..226e4f3d2b 100644 --- a/base-hw/src/base/thread_support.cc +++ b/base-hw/src/base/thread_support.cc @@ -90,9 +90,7 @@ void Thread_base::start() sleep_forever(); } /* start thread with its initial IP and aligned SP */ - addr_t thread_sp = (addr_t)&_context->stack[-4]; - thread_sp &= ~0xf; - env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start, thread_sp); + env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start, _context->stack_top()); } diff --git a/base-linux/src/base/thread/thread_linux.cc b/base-linux/src/base/thread/thread_linux.cc index 81b09dadfc..d28cd76b18 100644 --- a/base-linux/src/base/thread/thread_linux.cc +++ b/base-linux/src/base/thread/thread_linux.cc @@ -123,7 +123,7 @@ void Thread_base::start() } /* align initial stack to 16 byte boundary */ - void *thread_sp = (void *)((addr_t)(_context->stack) & ~0xf); + void *thread_sp = (void *)((addr_t)(stack_top()) & ~0xf); _tid.tid = lx_create_thread(Thread_base::_thread_start, thread_sp, this); _tid.pid = lx_getpid(); diff --git a/base-linux/src/core/thread_linux.cc b/base-linux/src/core/thread_linux.cc index 47f41d0c05..8e1ddcc94d 100644 --- a/base-linux/src/core/thread_linux.cc +++ b/base-linux/src/core/thread_linux.cc @@ -54,9 +54,7 @@ void Thread_base::_deinit_platform_thread() { } void Thread_base::start() { - /* align initial stack to 16 byte boundary */ - void *thread_sp = (void *)((addr_t)(_context->stack) & ~0xf); - _tid.tid = lx_create_thread(Thread_base::_thread_start, thread_sp, this); + _tid.tid = lx_create_thread(Thread_base::_thread_start, stack_top(), this); _tid.pid = lx_getpid(); } diff --git a/base-nova/src/base/pager/pager.cc b/base-nova/src/base/pager/pager.cc index 8616673daf..0b55e4e829 100644 --- a/base-nova/src/base/pager/pager.cc +++ b/base-nova/src/base/pager/pager.cc @@ -354,7 +354,7 @@ Pager_object::Pager_object(unsigned long badge, Affinity::Location location) throw Create_exception_pt_failed(); /* tell thread starting code on which CPU to let run the pager */ - reinterpret_cast(stack_top())[-1] = location; + reinterpret_cast(stack_base())[0] = location; /* creates local EC */ Thread_base::start(); diff --git a/base-nova/src/base/server/server.cc b/base-nova/src/base/server/server.cc index cb0b98f1bd..ea001a3334 100644 --- a/base-nova/src/base/server/server.cc +++ b/base-nova/src/base/server/server.cc @@ -212,7 +212,7 @@ Rpc_entrypoint::Rpc_entrypoint(Cap_session *cap_session, size_t stack_size, _tid.ec_sel = Native_thread::INVALID_INDEX - 1; } else { /* tell affinity CPU in 'core' via stack */ - reinterpret_cast(stack_top())[-1] = location; + reinterpret_cast(stack_base())[0] = location; } /* required to create a 'local' EC */ diff --git a/base-nova/src/base/thread/thread_nova.cc b/base-nova/src/base/thread/thread_nova.cc index a0f30ed3e8..9aff42922a 100644 --- a/base-nova/src/base/thread/thread_nova.cc +++ b/base-nova/src/base/thread/thread_nova.cc @@ -142,9 +142,6 @@ void Thread_base::start() throw Cpu_session::Thread_creation_failed(); /* create EC at core */ - addr_t thread_sp = reinterpret_cast(&_context->stack[-4]); - thread_sp &= ~0xfUL; /* align initial stack to 16 byte boundary */ - Thread_state state; state.sel_exc_base = _tid.exc_pt_sel; state.is_vcpu = _tid.is_vcpu; @@ -155,7 +152,7 @@ void Thread_base::start() try { env()->cpu_session()->state(_thread_cap, state); } catch (...) { throw Cpu_session::Thread_creation_failed(); } - if (env()->cpu_session()->start(_thread_cap, thread_ip, thread_sp)) + if (env()->cpu_session()->start(_thread_cap, thread_ip, _context->stack_top())) throw Cpu_session::Thread_creation_failed(); /* request native EC thread cap */ diff --git a/base-nova/src/core/irq_session_component.cc b/base-nova/src/core/irq_session_component.cc index 23e3ab14c1..f5b96c4ae7 100644 --- a/base-nova/src/core/irq_session_component.cc +++ b/base-nova/src/core/irq_session_component.cc @@ -63,9 +63,9 @@ class Irq_thread : public Thread_base /* * Put IP on stack, it will be read from core pager in platform.cc */ - addr_t *sp = reinterpret_cast(_context->stack - sizeof(addr_t)); + addr_t *sp = reinterpret_cast(_context->stack_top() - sizeof(addr_t)); *sp = reinterpret_cast(_thread_start); - + /* create global EC */ enum { GLOBAL = true }; uint8_t res = create_ec(_tid.ec_sel, pd_sel, boot_cpu(), diff --git a/base-nova/src/core/thread_start.cc b/base-nova/src/core/thread_start.cc index d5437921b9..631af0fdea 100644 --- a/base-nova/src/core/thread_start.cc +++ b/base-nova/src/core/thread_start.cc @@ -73,14 +73,17 @@ void Thread_base::start() */ using namespace Nova; - addr_t sp = reinterpret_cast(&_context->stack[-4]); - sp &= ~0xFUL; /* align initial stack to 16 byte boundary */ - addr_t utcb = reinterpret_cast(&_context->utcb); - Utcb * utcb_obj = reinterpret_cast(&_context->utcb); - addr_t pd_sel = Platform_pd::pd_core_sel(); - Affinity::Location location = reinterpret_cast(stack_top())[-1]; + addr_t sp = _context->stack_top(); + addr_t utcb = reinterpret_cast(&_context->utcb); + Utcb * utcb_obj = reinterpret_cast(&_context->utcb); + addr_t pd_sel = Platform_pd::pd_core_sel(); + + /* + * In core, the affinity location was write to the stack base by the server + * code. So, thry to read the value from there. + */ + Affinity::Location location = reinterpret_cast(stack_base())[0]; - /* server code sets this value */ if (!location.valid()) location = Affinity::Location(boot_cpu(), 0); diff --git a/base-okl4/src/core/thread_start.cc b/base-okl4/src/core/thread_start.cc index f4129a7cf2..7649b24f3a 100644 --- a/base-okl4/src/core/thread_start.cc +++ b/base-okl4/src/core/thread_start.cc @@ -38,7 +38,7 @@ void Thread_base::start() platform_specific()->core_pd()->bind_thread(_tid.pt); - _tid.pt->start((void *)_thread_start, _context->stack); + _tid.pt->start((void *)_thread_start, stack_top()); } diff --git a/base-pistachio/src/core/thread_start.cc b/base-pistachio/src/core/thread_start.cc index 3709570891..b2d065e7f3 100644 --- a/base-pistachio/src/core/thread_start.cc +++ b/base-pistachio/src/core/thread_start.cc @@ -41,7 +41,7 @@ void Thread_base::start() _tid.pt->pager(platform_specific()->core_pager()); _tid.l4id = _tid.pt->native_thread_id(); - _tid.pt->start((void *)_thread_start, _context->stack); + _tid.pt->start((void *)_thread_start, stack_top()); } diff --git a/base/include/base/thread.h b/base/include/base/thread.h index caa93ca99b..be2ed7ea02 100644 --- a/base/include/base/thread.h +++ b/base/include/base/thread.h @@ -96,10 +96,21 @@ namespace Genode { */ struct Context { + private: + + /** + * Top of the stack is accessible via stack_top() + */ + long _stack[]; + + public: + /** - * Top of the stack + * Top of stack aligned to 16 byte + * + * The alignment is also sufficient for the AMD64 ABI. */ - long stack[]; + addr_t stack_top() const { return (addr_t)_stack & ~0xf; } /** * Virtual address of the start of the stack @@ -333,13 +344,9 @@ namespace Genode { /** * Return top of stack * - * \return pointer to first stack element + * \return pointer just after first stack element */ - void *stack_top() - { - return (void *)((addr_t)_context->stack - - sizeof(_context->stack[0])); - } + void *stack_top() const { return (void *)_context->stack_top(); } /** * Return base of stack diff --git a/base/src/base/thread/thread_start.cc b/base/src/base/thread/thread_start.cc index 6681e725f9..d17363d47f 100644 --- a/base/src/base/thread/thread_start.cc +++ b/base/src/base/thread/thread_start.cc @@ -61,9 +61,7 @@ void Thread_base::start() env()->cpu_session()->set_pager(_thread_cap, pager_cap); /* register initial IP and SP at core */ - addr_t thread_sp = (addr_t)&_context->stack[-4]; - thread_sp &= ~0xf; /* align initial stack to 16 byte boundary */ - env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start, thread_sp); + env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start, _context->stack_top()); } diff --git a/ports-foc/src/lib/l4lx/include/vcpu.h b/ports-foc/src/lib/l4lx/include/vcpu.h index 0b4422e512..02e8981978 100644 --- a/ports-foc/src/lib/l4lx/include/vcpu.h +++ b/ports-foc/src/lib/l4lx/include/vcpu.h @@ -56,19 +56,19 @@ namespace L4lx { _data(data ? *data : 0), _vcpu_state(vcpu_state), _cpu_nr(cpu_nr) - { - start(); + { + start(); - /* set l4linux specific utcb entry: L4X_UTCB_TCR_ID */ - l4_utcb_tcr_u(utcb())->user[0] = tid(); + /* set l4linux specific utcb entry: L4X_UTCB_TCR_ID */ + l4_utcb_tcr_u(utcb())->user[0] = tid(); - /* enable vcpu functionality respectively */ - if (_vcpu_state) - vcpu_connection()->enable_vcpu(_thread_cap, _vcpu_state); + /* enable vcpu functionality respectively */ + if (_vcpu_state) + vcpu_connection()->enable_vcpu(_thread_cap, _vcpu_state); - /* set cpu affinity */ - set_affinity(_cpu_nr); - } + /* set cpu affinity */ + set_affinity(_cpu_nr); + } void entry() { @@ -79,8 +79,7 @@ namespace L4lx { void unblock() { _lock.unlock(); } - Genode::addr_t sp() { - return ((Genode::addr_t)&_context->stack[-4]) & ~0xf; } + Genode::addr_t sp() { return _context->stack_top(); } Genode::addr_t ip() { return (Genode::addr_t)_func; }