Reading thread registers
Christian Prochaska
christian.prochaska at ...1...
Tue Mar 7 20:57:26 CET 2017
Hi Denis,
On 03.03.2017 08:35, Denis Huber wrote:
> Hallo Christian, and hallo Genode community.
>
> Preliminary: I want to read the registers of a thread A from a task from
> another thread B on another task. I am using Genode 16.08 on Fiasco.OC.
> I am also using the Genode mechanism of Cpu_thread::pause() before
> Cpu_thread::state(), but do not receive the any register values beside
> zeros. Christina told me that this problem comes from thread A being in
> a syscall during the pausing. His suggestion was to extend
> l4_thread_ex_regs_ret() to return the missing registers from the UTCB in
> a non-blocking fashion.
>
> I am trying to do this, but I do not understand the syscall mechanism
> fully. Am I correct with the following understanding:
>
> * Thread A is in a syscall: It is waiting for the answer of its IPC call.
> * The answer will be stored in the UTCB.
> * While the thread is waiting, another thread B tries to pause thread A.
> * The pause mechanism wants to put thread A into an artifical-exception
> state and additionally writes the register data to the UTCB of thread A.
> * The pause and syscall mechanism both need the UTCB for themselves.
> * To guarantee consistency of the UTCB, the pause method is not allowed
> to be executed while thread A is in a syscall. Otherwise the syscall
> could overrite the pause data (i.e. register values), if it
> spontaneously returns.
And there would also be the problem of how to restart an interrupted syscall in thread A.
> Assumed my understanding is correct (please tell me, if it is not), I
> have to wait (i.e. block execution) until the syscall finishes and the
> pause mechanism can write the register data to the UTCB. Christian
> wrote, it is possible to return the missing registers from the UTCB
> without blocking until the syscall finishes. How is it possible, if the
> register data is not in the UTCB?
The general idea is that when thread B calls l4_thread_ex_regs_ret() to find out the register state of thread A, the kernel could
copy the complete register state of thread A into the UTCB of thread B. So, when l4_thread_ex_regs_ret() returns, thread B would
find the complete register state of thread A in its own UTCB. Currently, only the flags, ip and sp are copied into the UTCB of
thread B. So, when extending the implementation of the l4_thread_ex_regs_ret() syscall, you would need to find out where the kernel
has stored the register state of thread A and then copy it completely into the UTCB of thread B and then, when
l4_thread_ex_regs_ret() returns, read the additional registers from the UTCB of thread B. On the user side this could probably look
something like:
...
ip = ~0UL;
sp = ~0UL;
flags = L4_THREAD_EX_REGS_TRIGGER_EXCEPTION;
l4_thread_ex_regs_ret(kcap, &ip, &sp, &flags);
l4_utcb_t *utcb = l4_utcb();
r0 = utcb->mr[3];
r1 = utcb->mr[4];
...
where, according to the implementation of l4_thread_ex_regs_ret_u() in
'contrib/foc-xxx/src/kernel/foc/l4/pkg/l4sys/include/thread.h', mr[0], mr[1] and mr[2] are currently used to transfer the flags, ip
and sp.
Christian
More information about the users
mailing list