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.
This commit is contained in:
Christian Helmuth 2014-01-17 17:22:32 +01:00
parent 6ec36350d6
commit 7e517179c9
18 changed files with 52 additions and 56 deletions

View File

@ -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());
}

View File

@ -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);

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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();

View File

@ -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();
}

View File

@ -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<Affinity::Location *>(stack_top())[-1] = location;
reinterpret_cast<Affinity::Location *>(stack_base())[0] = location;
/* creates local EC */
Thread_base::start();

View File

@ -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<Affinity::Location *>(stack_top())[-1] = location;
reinterpret_cast<Affinity::Location *>(stack_base())[0] = location;
}
/* required to create a 'local' EC */

View File

@ -142,9 +142,6 @@ void Thread_base::start()
throw Cpu_session::Thread_creation_failed();
/* create EC at core */
addr_t thread_sp = reinterpret_cast<addr_t>(&_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 */

View File

@ -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<addr_t *>(_context->stack - sizeof(addr_t));
addr_t *sp = reinterpret_cast<addr_t *>(_context->stack_top() - sizeof(addr_t));
*sp = reinterpret_cast<addr_t>(_thread_start);
/* create global EC */
enum { GLOBAL = true };
uint8_t res = create_ec(_tid.ec_sel, pd_sel, boot_cpu(),

View File

@ -73,14 +73,17 @@ void Thread_base::start()
*/
using namespace Nova;
addr_t sp = reinterpret_cast<addr_t>(&_context->stack[-4]);
sp &= ~0xFUL; /* align initial stack to 16 byte boundary */
addr_t utcb = reinterpret_cast<addr_t>(&_context->utcb);
Utcb * utcb_obj = reinterpret_cast<Utcb *>(&_context->utcb);
addr_t pd_sel = Platform_pd::pd_core_sel();
Affinity::Location location = reinterpret_cast<Affinity::Location *>(stack_top())[-1];
addr_t sp = _context->stack_top();
addr_t utcb = reinterpret_cast<addr_t>(&_context->utcb);
Utcb * utcb_obj = reinterpret_cast<Utcb *>(&_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<Affinity::Location *>(stack_base())[0];
/* server code sets this value */
if (!location.valid())
location = Affinity::Location(boot_cpu(), 0);

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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

View File

@ -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());
}

View File

@ -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; }