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;
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.


More information about the users mailing list