Hi Daniel, On 03/25/2011 06:12 PM, Daniel Waddington wrote: > the registers and changing the ip/sp. I think the main issue is that > in our first attempt we did not copy the "additional context members" > and "UTCB" to the new stack frame. The thread switching works until you > try to access the utcb.
I suspect that the culprit here is the 'Thread_base::myself()' function, which is used by the callee to determine it's 'Thread_base' object. This function uses the stack pointer as key to find the callee's 'Thread_base::Context'. The stack pointer is expected to reside within the so-called thread-context area. Each thread owns a slot within this virtual address range (currently a slot is 1MB - details can be found in 'base/include/base/thread.h'). Within each slot, there resides the thread's stack and the its 'Thread_base::Context' object. Now, if you switch the stack pointer to an address allocated somewhere outside the thread-context area, the 'Thread_base::myself()' function will assume that the callee is the main thread (the main thread has no slot in the thread-context area, its stack is located within the BSS segment). Consequently, functionality that relies on the thread context (such as locking) is going to fail. To overcome this problem, I see three possible solutions: First, the 'Thread_base' class could be extended by a hook for considering additional stack ranges when 'Thread_base::myself()' is called. This hook would by able to tell 'Thread_base::myself()' about the physical thread context belonging to stack ranges allocated by a user-level threading library. Alternatively, you might try placing the stack of the user-level thread within the same context-area slot as used by the physical thread so that 'Thread_base::myself()' will always return the correct physical 'Thread_base' object. To see how to directly interact with the thread-context area, please have a look at 'base/src/base/thread/thread.cc', in particular '_alloc_context()'. As a third approach, you might consider adding support for user-level threads in a way that each user-level thread uses a real 'Thread_base' context but not a physical thread. Each thread context of a user-level thread would have a reference to the physical 'Thread_base' object used for its execution. This way, when 'Thread_base::myself()' is called, the 'myself()' function would first look whether the callee is a user-level thread. If so, it would return the referenced physical 'Thread_base' object. I think, this approach would be the most elegant one, mostly because it would allow the detection of stack overflows of user-level threads as each user-level thread would be subject to the overflow protection provided by the thread-context mechanism. Best regards Norman -- Dr.-Ing. Norman Feske Genode Labs http://www.genode-labs.com · http://genode.org Genode Labs GmbH · Amtsgericht Dresden · HRB 28424 · Sitz Dresden Geschäftsführer: Dr.-Ing. Norman Feske, Christian Helmuth ------------------------------------------------------------------------------ Enable your software for Intel(R) Active Management Technology to meet the growing manageability and security demands of your customers. Businesses are taking advantage of Intel(R) vPro (TM) technology - will your software be a part of the solution? Download the Intel(R) Manageability Checker today! http://p.sf.net/sfu/intel-dev2devmar _______________________________________________ Genode-main mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/genode-main
