Hi,
On Friday, 26. January 2018, 14:34:29 Stark, Josef wrote:
Hey,
I did this now, we already had a custom function that reads all the general purpose registers, and IP and SP (by calling Thread::user_ip() and Thread::user_sp()) so there I inserted my assembler call. Now the call doesn't freeze the system anymore and it returns a value. But the strange thing is that when I have 3 threads in a process and only 1 is faulting and I call this function for all of them, they all return the same value from their DFAR (0xe07c). When I instead read the DFSR (c5 instead of c6), they all return 0x7. But I'm thinking that when only one of the threads is faulting, their DFSRs or DFARs should return different values. What am I missing? The IP and SP registers appear to be read correctly and with different values.
The DFAR/DFSR registers are CPU registers. They are not specific to a thread. When a thread faults, DFAR/DFSR get set in hardware on the CPU. Now when the OS switches contexts on the CPU these registers are unaffected. Your solution only ever sees the last fault address on the CPU. And that might not even need to be a userland address either.
I have a userspace application that has registered itself as fault handler for its child. Now, when a page fault arrives, I want to identify the faulting thread by comparing the page fault address from the pf-report with the DFAR registers of each of the threads. I'm using Genode on top of Fiasco.OC, and Genode's pagefault report doesn't include a direct way to identify/access the faulting thread.
Maybe a way forward is to register different page fault handlers for your threads in question? So each handler knows which thread(s) it serves already.
Hope that helps a bit.
- Christian