I am trying to get working getcontext/setcontext/makecontext prototype on seL4/Genode (I can’t use anything except seL4 in this moment due to some reasons). I need both for x86_64 and aarm64 arch. I started from x86.
So, question one. May be someone know kind of rough implementation for user-space context switching? I read information that this is not implemented yet in the main genode - but may be some projects does this already?
Problem 2. When I start trying to make a fast solution and try to read registers and some info from low level physical seL4 thread using seL4_TCB_ReadRegisters I found that: In returned successfully data rip register is always 0 for current thread, tcb selector myself.native_thread().tcb_sel also 0, and rsp = 0x13! Probably I can’t read myself?
Problem 3. I try to take address of IPC buffer bounded to utcb() field of Genode::Thread using code below. It successfully compiled and linked. Anyway, in attempt to run the program I found the following error in log:
[init -> test-go] Error: LD: jump slot relocation failed for symbol: 'Genode::Thread::utcb()’
While access for similar fields in the same Thread structure successfully works! Eg Name name() const; can be printed, native_thread() also give results.
I even found in the .o file the name of field (function technically) marked as U , and literally the same name mangled in the sym file for ld.lib.so compiled: 000000000003a09a T _ZN6Genode6Thread4utcbEv
genode/repos/base/lib/symbols/ld:_ZN6Genode6Thread4utcbEv T How to fix this?
// take info about genode thread Thread &myself = *Thread::myself(); log("myself ", &myself, " size ", sizeof(myself)); addr_t const ipc_buffer = reinterpret_cast<addr_t>(myself.utcb()); log(" name ",myself.name(), " sb ", myself.stack_base(), " svb ", myself.stack_area_virtual_base(), " tcb ", (addr_t)myself.native_thread().tcb_sel);
seL4_IPCBuffer &ipc_buffer = *reinterpret_cast<seL4_IPCBuffer *>(myself.utcb());
Sincerely, Alexander Tormasov・
Problem 2. When I start trying to make a fast solution and try to read registers and some info from low level physical seL4 thread using seL4_TCB_ReadRegisters I found that: In returned successfully data rip register is always 0 for current thread, tcb selector myself.native_thread().tcb_sel also 0, and rsp = 0x13! Probably I can’t read myself?
Seems that I found answer in the seL4 code. They do not allow ReadReginster from myself:
In file object/tcb.c exception_t decodeReadRegisters(cap_t cap, word_t length, bool_t call, word_t *buffer) { … thread = TCB_PTR(cap_thread_cap_get_capTCBPtr(cap)); if (thread == NODE_STATE(ksCurThread)) { userError("TCB ReadRegisters: Attempted to read our own registers."); current_syscall_error.type = seL4_IllegalOperation; return EXCEPTION_SYSCALL_ERROR; }
Seems that this is my fault (while this is not anyhow specified in the docs, only some innuendo about stopped thread read)
So, the function used from library seL4_TCB_ReadRegisters incorrectly return 0 - everything is ok while it is not.
Also seems that seL4_TCB_WriteRegisters do not work in such conditions as well - it return without errors and not changing rip to new function specified in appropriate field …
Alex,
I would encourage passing what you found along (even the documentation improvement suggestion) to Data61. They are very open to any form of feedback with seL4.
On 9/26/2019 6:53 AM, Alexander Tormasov via users wrote:
Problem 2. When I start trying to make a fast solution and try to read registers and some info from low level physical seL4 thread using seL4_TCB_ReadRegisters I found that: In returned successfully data rip register is always 0 for current thread, tcb selector myself.native_thread().tcb_sel also 0, and rsp = 0x13! Probably I can’t read myself?
Seems that I found answer in the seL4 code. They do not allow ReadReginster from myself:
In file object/tcb.c exception_t decodeReadRegisters(cap_t cap, word_t length, bool_t call, word_t *buffer) { … thread = TCB_PTR(cap_thread_cap_get_capTCBPtr(cap)); if (thread == NODE_STATE(ksCurThread)) { userError("TCB ReadRegisters: Attempted to read our own registers."); current_syscall_error.type = seL4_IllegalOperation; return EXCEPTION_SYSCALL_ERROR; }
Seems that this is my fault (while this is not anyhow specified in the docs, only some innuendo about stopped thread read)
So, the function used from library seL4_TCB_ReadRegisters incorrectly return 0 - everything is ok while it is not.
Also seems that seL4_TCB_WriteRegisters do not work in such conditions as well - it return without errors and not changing rip to new function specified in appropriate field …
Genode users mailing list users@lists.genode.org https://lists.genode.org/listinfo/users
Thank you for suggestion! Will send them info that they need explicitly state that you can’t read local (own) thread registers in docs
While I I think that this is mostly bug in Genode - it return incorrect OK code (0) during such attempt while probably need to analyze response from seL4 more carefully
(May be this is seL4 library bug - it is still unclear for me why I haven’t the name used from seL4 documentation in the seL4 sources in Genode/contrib, suspect some linker tricks)
Отправлено с iPhone
27 сент. 2019 г., в 10:56, Adam Wiethuechter wiethuat@critical.com написал(а):
Alex,
I would encourage passing what you found along (even the documentation improvement suggestion) to Data61. They are very open to any form of feedback with seL4.
On 9/26/2019 6:53 AM, Alexander Tormasov via users wrote:
Problem 2. When I start trying to make a fast solution and try to read registers and some info from low level physical seL4 thread using seL4_TCB_ReadRegisters I found that: In returned successfully data rip register is always 0 for current thread, tcb selector myself.native_thread().tcb_sel also 0, and rsp = 0x13! Probably I can’t read myself?
Seems that I found answer in the seL4 code. They do not allow ReadReginster from myself:
In file object/tcb.c exception_t decodeReadRegisters(cap_t cap, word_t length, bool_t call, word_t *buffer) { … thread = TCB_PTR(cap_thread_cap_get_capTCBPtr(cap)); if (thread == NODE_STATE(ksCurThread)) { userError("TCB ReadRegisters: Attempted to read our own registers."); current_syscall_error.type = seL4_IllegalOperation; return EXCEPTION_SYSCALL_ERROR; }
Seems that this is my fault (while this is not anyhow specified in the docs, only some innuendo about stopped thread read)
So, the function used from library seL4_TCB_ReadRegisters incorrectly return 0 - everything is ok while it is not.
Also seems that seL4_TCB_WriteRegisters do not work in such conditions as well - it return without errors and not changing rip to new function specified in appropriate field …
_______________________________________________ Genode users mailing list users@lists.genode.orgmailto:users@lists.genode.org https://lists.genode.org/listinfo/users
-- 73's, Adam Wiethuechter, Junior Software Engineer Critical Technologies Inc. (CTI) Desk: (315)-793-0248 x157 Cell: (315)-552-4298 adam.wiethuechter@critical.commailto:adam.wiethuechter@critical.com
_______________________________________________ Genode users mailing list users@lists.genode.org https://lists.genode.org/listinfo/users
Hello Alexander,
I think we have to clarify a few things.
The direct invocation of kernel syscalls is not encouraged on Genode applications, since the whole point about Genode is to have a operating system framework running _portable code_ across more than 7 microkernels (seL4, Fiasco.OC, NOVA, Genode's hw-kernel and our retirees OKL4, Pistachio and Fiasco/L4) and even Linux (base-linux). It is a fundamental concern to be kernel-independent.
That being said, we avoid as far as possible to give Genode applications kernel specific capabilities at hand. For Genode/seL4 we intentionally don't give the seL4 thread capabilities to the applications. That means you can't succeed in invoking seL4_TCB_ReadRegisters or seL4_TCB_WriteRegisters syscalls directly. So, as pointed out above - it is a feature, not a bug.
Instead, please consider the usage of Genode interfaces [1] and more portable approaches [0] that work across kernels.
Best regards,
Alexander Boettcher.
[0] https://lists.genode.org/pipermail/users/2019-September/006931.html [1] https://lists.genode.org/pipermail/users/2019-September/006930.html
On 27.09.19 12:05, Alexander Tormasov via users wrote:
Thank you for suggestion! Will send them info that they need explicitly state that you can’t read local (own) thread registers in docs
While I I think that this is mostly bug in Genode - it return incorrect OK code (0) during such attempt while probably need to analyze response from seL4 more carefully
(May be this is seL4 library bug - it is still unclear for me why I haven’t the name used from seL4 documentation in the seL4 sources in Genode/contrib, suspect some linker tricks)
Отправлено с iPhone
27 сент. 2019 г., в 10:56, Adam Wiethuechter wiethuat@critical.com написал(а):
Alex,
I would encourage passing what you found along (even the documentation improvement suggestion) to Data61. They are very open to any form of feedback with seL4.
On 9/26/2019 6:53 AM, Alexander Tormasov via users wrote:
Problem 2. When I start trying to make a fast solution and try to read registers and some info from low level physical seL4 thread using seL4_TCB_ReadRegisters I found that: In returned successfully data rip register is always 0 for current thread, tcb selector myself.native_thread().tcb_sel also 0, and rsp = 0x13! Probably I can’t read myself?
Seems that I found answer in the seL4 code. They do not allow ReadReginster from myself:
In file object/tcb.c exception_t decodeReadRegisters(cap_t cap, word_t length, bool_t call, word_t *buffer) { … thread = TCB_PTR(cap_thread_cap_get_capTCBPtr(cap)); if (thread == NODE_STATE(ksCurThread)) { userError("TCB ReadRegisters: Attempted to read our own registers."); current_syscall_error.type = seL4_IllegalOperation; return EXCEPTION_SYSCALL_ERROR; }
Seems that this is my fault (while this is not anyhow specified in the docs, only some innuendo about stopped thread read)
So, the function used from library seL4_TCB_ReadRegisters incorrectly return 0 - everything is ok while it is not.
Also seems that seL4_TCB_WriteRegisters do not work in such conditions as well - it return without errors and not changing rip to new function specified in appropriate field …
Genode users mailing list users@lists.genode.orgmailto:users@lists.genode.org https://lists.genode.org/listinfo/users
-- 73's, Adam Wiethuechter, Junior Software Engineer Critical Technologies Inc. (CTI) Desk: (315)-793-0248 x157 Cell: (315)-552-4298 adam.wiethuechter@critical.commailto:adam.wiethuechter@critical.com
Genode users mailing list users@lists.genode.org https://lists.genode.org/listinfo/users
Genode users mailing list users@lists.genode.org https://lists.genode.org/listinfo/users
On 26.09.19 12:53, Alexander Tormasov via users wrote:
Problem 2. When I start trying to make a fast solution and try to read registers and some info from low level physical seL4 thread using seL4_TCB_ReadRegisters
On Genode you may request the thread state like the values of registers via Genode::Cpu_thread::state(). Example code you may find in our thread test, see [0]. The actual structure is platform depend, look into the respective cpu_state.h header file, see [1].
[0] https://github.com/genodelabs/genode/blob/master/repos/base/src/test/thread/...
[1] repos/base/include/spec/x86_32/cpu/cpu_state.h repos/base/include/spec/x86_64/cpu/cpu_state.h repos/base/include/spec/arm/cpu/cpu_state.h repos/base/include/spec/arm_64/cpu/cpu_state.h
Problem 2. When I start trying to make a fast solution and try to read registers and some info from low level physical seL4 thread using seL4_TCB_ReadRegisters
On Genode you may request the thread state like the values of registers via Genode::Cpu_thread::state(). Example code you may find in our thread test, see [0]. The actual structure is platform depend, look into the respective cpu_state.h header file, see [1].
Thank you for reference! Unfortunately, this function use the same seL4_TCB_ReadRegisters and can’t read our own registers (like setjmp/getcontext/etc) as I see in repos/base-sel4/src/core/spec/x86_64/thread.cc
And I still don’t have a «legal» way to read or set registers via Genode interface, need to use asm :(
On 27.09.19 01:21, Alexander Tormasov via users wrote:
Problem 2. When I start trying to make a fast solution and try to read registers and some info from low level physical seL4 thread using seL4_TCB_ReadRegisters
On Genode you may request the thread state like the values of registers via Genode::Cpu_thread::state(). Example code you may find in our thread test, see [0]. The actual structure is platform depend, look into the respective cpu_state.h header file, see [1].
Thank you for reference! Unfortunately, this function use the same seL4_TCB_ReadRegisters and can’t read our own registers (like setjmp/getcontext/etc) as I see in repos/base-sel4/src/core/spec/x86_64/thread.cc
This works for me without issues:
void Component::construct(Env &env)
{
log("--- thread test started ---");
Cpu_thread_client thread_client(Thread::myself()->cap());
Thread_state state = thread_client.state();
log("my ip=", Hex(state.ip), " sp=", Hex(state.sp), " - done");
return; }
[init -> test-thread] --- thread test started --- [init -> test-thread] my ip=0x837c2 sp=0x401fe4c0 - done
Alexander,
On Fri, Sep 27, 2019 at 01:21:25 CEST, Alexander Tormasov via users wrote:
Unfortunately, this function use the same seL4_TCB_ReadRegisters and can’t read our own registers (like setjmp/getcontext/etc) as I see in repos/base-sel4/src/core/spec/x86_64/thread.cc
And I still don’t have a «legal» way to read or set registers via Genode interface, need to use asm :(
Why don't you use setjmp/longjmp? Implementation are in the libc and repos/dde_linux/src/lx_kit/spec for our drivers.
Greets
And I still don’t have a «legal» way to read or set registers via Genode interface, need to use asm :(
Why don't you use setjmp/longjmp? Implementation are in the libc and repos/dde_linux/src/lx_kit/spec for our drivers.
Because golang runtime do use makecontext to replace addresses of functions and own stack, while jmpbuf is a kind of opaque structure... probably I have to manually select appropriate buf offsets and replace 2 out of 12 long int (while it is still unclear for me why there are 12 words in it while they use something like 9.5?)