Hi Josef,
El 12/01/18 a las 16:51, Stark, Josef escribió:
Step 4 is relatively easy and already working, so I now have an app that pagefaults and gets resumed repeatedly at the same address and ip since I couldn't implement the rest of the steps so far. The reason is that I can't figure out how to access the Thread_state of the thread causing the pagefault. The Vinit uses an imprint written into the State that can be used to correlate an RM client to the pagefault State. I'm trying to integrate this imprint as well, but I'm struggling because obviously since the creation of Vinit the genode architecture has changed quite a bit (at least for a newcomer like me). E.g. I'm having trouble corresponding the required changes from [3] to add_client() to the 16.08 version (it exists in a different place with a different signature and a much smaller body).
So I'm wondering if maybe in the meantime there exists an easier way to access the IP (and other registers) of a pagefaulting thread from within the fault-handler (in my example _handle_fault in [4])? Especially considering that my parent task has only this one child (with currently only 1 thread), if that makes it easier.
As you should be the parent of the traced component, you can intercept the CPU session and remember all thread capabilities created by the component. On a fault you iterate through all threads to select those that are currently in a page fault. A good example for this is the GDB monitor [1]. Now you want to select from the remaining threads those that are in a fault on your specific address. This can't be done with the current Genode API, but an easy way to achieve it would be to expand the Cpu_state [2] to deliver also the value of the ARM Data Fault Address Register or DFAR when calling Cpu_thread_client::state (make sure to update the dfar member in [4] as is done in [3]).
Now you can arbitrarily choose one of the remaining threads, read its IP from the Cpu_state, emulate its instruction, and write back results via Cpu_thread_client::state. Then, you would have to continue execution of the thread. Unfortunately, this is normally done automatically by Genodes Core when it sees a new mapping that matches the fault address. You don't want to do such a mapping, but there is no explicit "resume this faulter". So, you have might add such an RPC call [5] and its back end [6] to the RM interface. This shouldn't be much invasive.
If there are further questions please do not hesitate to ask ;)
Cheers, Martin
[1] ports/src/app/gdb_monitor/cpu_session_component.cc: Cpu_session_component::handle_unresolved_page_fault
[2] base/include/spec/arm/cpu/cpu_state.h
[3] base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc: Vm::exception
[4] base-hw/src/core/spec/arm/kernel/thread.cc: Thread::exception
[5] base/include/region_map/region_map.h
[6] base/src/core/region_map_component.cc