mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 02:01:38 +00:00
hw: don't communicate main-thread UTCB via SP
When using the initial SP of a main thread for the UTCB startup-argument, fork_trampoline in libc_noux gets broken. The function expects the SP to be initialized already in contrast to the _start function in crt0.s that is called for processes that are not forked. As the main-thread UTCB is located at the same virtual address for every PD anyways, we can circumvent this problem by defining it statically. ref #964
This commit is contained in:
parent
2b8e5d7b19
commit
54610247ad
@ -277,5 +277,26 @@ class Genode::Native_utcb
|
||||
void * base() const { return (void *)_data; }
|
||||
};
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
enum {
|
||||
VIRT_ADDR_SPACE_START = 0x1000,
|
||||
VIRT_ADDR_SPACE_SIZE = 0xfffef000,
|
||||
};
|
||||
|
||||
/**
|
||||
* Return virtual UTCB location of main threads
|
||||
*/
|
||||
inline Native_utcb * main_thread_utcb()
|
||||
{
|
||||
enum {
|
||||
VAS_TOP = VIRT_ADDR_SPACE_START + VIRT_ADDR_SPACE_SIZE,
|
||||
UTCB = VAS_TOP - sizeof(Native_utcb),
|
||||
UTCB_ALIGNED = UTCB & ~((1 << MIN_MAPPING_SIZE_LOG2) - 1),
|
||||
};
|
||||
return (Native_utcb *)UTCB_ALIGNED;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _BASE__NATIVE_TYPES_H_ */
|
||||
|
||||
|
@ -19,8 +19,6 @@
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
extern Native_utcb * __initial_sp;
|
||||
|
||||
namespace Genode { Rm_session * env_context_area_rm_session(); }
|
||||
|
||||
|
||||
@ -34,7 +32,7 @@ void Thread_base::_init_platform_thread() { }
|
||||
Native_utcb * Thread_base::utcb()
|
||||
{
|
||||
if (this) { return &_context->utcb; }
|
||||
return __initial_sp;
|
||||
return main_thread_utcb();
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,8 +41,8 @@ namespace Genode {
|
||||
Phys_allocator _irq_alloc; /* IRQ allocator */
|
||||
Rom_fs _rom_fs; /* ROM file system */
|
||||
|
||||
addr_t _vm_base; /* base of virtual address space */
|
||||
size_t _vm_size; /* size of virtual address space */
|
||||
addr_t _vm_start; /* base of virtual address space */
|
||||
size_t _vm_size; /* size of virtual address space */
|
||||
|
||||
/**
|
||||
* Get one of the consecutively numbered available resource regions
|
||||
@ -101,7 +101,7 @@ namespace Genode {
|
||||
|
||||
inline Range_allocator * irq_alloc() { return &_irq_alloc; }
|
||||
|
||||
inline addr_t vm_start() const { return _vm_base; }
|
||||
inline addr_t vm_start() const { return _vm_start; }
|
||||
|
||||
inline size_t vm_size() const { return _vm_size; }
|
||||
|
||||
|
@ -109,10 +109,12 @@ Native_region * Platform::_core_only_ram_regions(unsigned const i)
|
||||
}
|
||||
|
||||
|
||||
Platform::Platform() :
|
||||
Platform::Platform()
|
||||
:
|
||||
_core_mem_alloc(0),
|
||||
_io_mem_alloc(core_mem_alloc()), _io_port_alloc(core_mem_alloc()),
|
||||
_irq_alloc(core_mem_alloc()), _vm_base(0x1000), _vm_size(0xfffef000)
|
||||
_irq_alloc(core_mem_alloc()),
|
||||
_vm_start(VIRT_ADDR_SPACE_START), _vm_size(VIRT_ADDR_SPACE_SIZE)
|
||||
{
|
||||
/*
|
||||
* Initialise platform resource allocators.
|
||||
|
@ -20,6 +20,8 @@ using namespace Genode;
|
||||
|
||||
namespace Kernel { unsigned core_id(); }
|
||||
|
||||
void Platform_thread::_init() { }
|
||||
|
||||
|
||||
bool Platform_thread::_attaches_utcb_by_itself()
|
||||
{
|
||||
@ -158,23 +160,12 @@ int Platform_thread::join_pd(unsigned const pd_id, bool const main_thread,
|
||||
}
|
||||
|
||||
|
||||
void Platform_thread::_init()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int Platform_thread::start(void * const ip, void * const sp,
|
||||
unsigned int const cpu_id)
|
||||
{
|
||||
/* attach UTCB if the thread can't do this by itself */
|
||||
if (!_attaches_utcb_by_itself())
|
||||
{
|
||||
/* declare page aligned virtual UTCB outside the context area */
|
||||
_utcb_virt = (Native_utcb *)((platform()->vm_start()
|
||||
+ platform()->vm_size() - sizeof(Native_utcb))
|
||||
& ~((1<<MIN_MAPPING_SIZE_LOG2)-1));
|
||||
|
||||
/* attach UTCB */
|
||||
/* attach UTCB in case of a main thread */
|
||||
if (_main_thread) {
|
||||
_utcb_virt = main_thread_utcb();
|
||||
if (!_rm_client) {
|
||||
PERR("invalid RM client");
|
||||
return -1;
|
||||
@ -186,16 +177,13 @@ int Platform_thread::start(void * const ip, void * const sp,
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/* initialize thread regisers */
|
||||
/* initialize thread registers */
|
||||
typedef Kernel::Thread_reg_id Reg_id;
|
||||
enum { WRITES = 2 };
|
||||
addr_t * write_regs = (addr_t *)Thread_base::myself()->utcb()->base();
|
||||
write_regs[0] = Reg_id::IP;
|
||||
write_regs[1] = Reg_id::SP;
|
||||
addr_t write_values[] = {
|
||||
(addr_t)ip,
|
||||
_main_thread ? (addr_t)_utcb_virt : (addr_t)sp
|
||||
};
|
||||
addr_t write_values[] = { (addr_t)ip, (addr_t)sp };
|
||||
if (Kernel::access_thread_regs(id(), 0, WRITES, 0, write_values)) {
|
||||
PERR("failed to initialize thread registers");
|
||||
return -1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user