Hi,
I want to implement a new syscall for getting/setting stored register values of a specific thread (identified by its cap).
Why not use ex_regs() on the thread to trigger an exception. That way, the attached userland exception handler can introspect the thread's complete register set. It can also alter the registers, so that the thread continues to run with the modified register set.
Is there anything more you need?
Before implementing the syscall, I need to better understand the kernel-part of Fiasco.OC. Can you help me answer the following questions and point me to the source code regarding each question:
- Where (in the source code) are threads preempted and their register
state stored?
A thread's userland registers are stored on every entry to the kernel. The class in Fiasco is called Entry_frame.
The userland exception handler mentioned above modifies that Entry_frame.
- Where is the register state of a thread loaded to the CPU and the
thread started (e.g. after a preempt)?
When the scheduler selects a thread, its userland state (Entry_frame) is restored on exit from kernel mode.
- How can I introspect the stored thread register of a thread in the
kernel debugger JDB? ** My thoughts: Is it K<kobj_ptr> with kobj_ptr of the thread and the 3 lines beginning with PC=...? e.g. " PC=010579cc USP=200ffdb0 smlatbeq r9, r0, r2, r5 [0] 00000003 000010c0 00218003 00000000 tsteq000r5, ip, rrx [8] 200ffdb0 200ffe40 01086ef0 200ffe98 [c] 200ffef8 010579cc fffffff8 20000010 "
Yes, that PC line is the userland program counter. the USP is the userland stack pointer. All userland registers are located at the top of kernel stack for a particular thread.
I also have another, short, off-topic question:
- How can I introspect the capability space of a task inside the kernel
debugger?
In short mode, press 's' for a list of all tasks. Select the task in question and the press 'o' to see the capability space for that task.
Hope that helps,
- Christian
Hello Ludwig,
Why not use ex_regs() on the thread to trigger an exception. That way, the attached userland exception handler can introspect the thread's complete register set. It can also alter the registers, so that the thread continues to run with the modified register set.
Is there anything more you need?
I already tried ex_regs(). The problem with this function is, that it does not return all registers, if the thread is in a syscall. It only returns the PC and SP registers.
A thread's userland registers are stored on every entry to the kernel. The class in Fiasco is called Entry_frame.
The userland exception handler mentioned above modifies that Entry_frame.
Where does the kernel store the Entry_frame object for each thread? Is it the location where Context::regs() points to?
When the scheduler selects a thread, its userland state (Entry_frame) is restored on exit from kernel mode.
Can you point to the function that executes this code?
Yes, that PC line is the userland program counter. the USP is the userland stack pointer. All userland registers are located at the top of kernel stack for a particular thread.
In short mode, press 's' for a list of all tasks. Select the task in question and the press 'o' to see the capability space for that task.
Hope that helps,
- Christian
Thanks for your answer.
Kind regards, Denis
On Thu Mar 16, 2017 at 13:33:18 +0100, Denis Huber wrote:
Why not use ex_regs() on the thread to trigger an exception. That way, the attached userland exception handler can introspect the thread's complete register set. It can also alter the registers, so that the thread continues to run with the modified register set.
Is there anything more you need?
I already tried ex_regs(). The problem with this function is, that it does not return all registers, if the thread is in a syscall. It only returns the PC and SP registers.
I think Christian wants to point you to the L4_THREAD_EX_REGS_TRIGGER_EXCEPTION flag that one can give to ex_regs() that triggers an exception for the thread. With this exception all the CPU state will be delivered.
A thread's userland registers are stored on every entry to the kernel. The class in Fiasco is called Entry_frame.
The userland exception handler mentioned above modifies that Entry_frame.
Where does the kernel store the Entry_frame object for each thread? Is it the location where Context::regs() points to?
Yes.
When the scheduler selects a thread, its userland state (Entry_frame) is restored on exit from kernel mode.
Can you point to the function that executes this code?
There are several places, for all architectures in the assembly paths. For x86 in entry.S, look for code paths with 'iret' in them. For ARM in ivt.S, look for return_from_exception.
Adam
l4-hackers@os.inf.tu-dresden.de