Hi Josef,
El 12/03/18 a las 18:19, Josef Stark escribió:
I experimented a bit and after comparing the actual register contents of R0-R15 inside the child application with the contents of the Thread_state register backup (R0-R15) that is delivered to my fault handler, it seems like Genode (or Fiasco.OC or the glue code) delivers the registers in a strange mapping, where some original regs are mapped to different regs in the backup, and some do not appear at all. The mapping is like this:
Thread_state   | Child   | Child - Alternative Possibility
R0Â Â Â Â Â Â Â | R9Â Â Â | R7 R1Â Â Â Â Â Â Â | R10Â Â Â | R4 R2Â Â Â Â Â Â Â | R11Â Â Â | R3Â Â Â Â Â Â Â |Â Â Â | R4Â Â Â Â Â Â Â |Â Â Â | R5Â Â Â Â Â Â Â |Â Â Â | R6Â Â Â Â Â Â Â |Â Â Â | R7Â Â Â Â Â Â Â |Â Â Â | R8Â Â Â Â Â Â Â | R0Â Â Â | R9Â Â Â Â Â Â Â | R1Â Â Â | R10Â Â Â Â Â Â Â | R2Â Â Â | R11Â Â Â Â Â Â Â | R3Â Â Â | R12Â Â Â Â Â Â Â | R12Â Â Â | R5 R13Â Â Â Â Â Â Â | R13Â Â Â | R14Â Â Â Â Â Â Â | R14Â Â Â | R15Â Â Â Â Â Â Â | R15Â Â Â | Â Â Â Â Â Â Â | R6Â Â Â | Â Â Â Â Â Â Â | R8Â Â Â |
(Alternative Possibility means I couldn't tell which of the two is actually correct due to equal values. The Thread_state registers that have no mapping contained values that did not match any of the original register contents; some of those values appeared in two distinct Thread_state registers. I assured myself that the child didn't modify the registers before dumping the contents.) While this looks pretty strange, I verified the 'mapping' on a few occasions and after incorporating the mapping into the instruction emulator/the redundant memory writer, it does what it should, at least for a limited test case (which doesn't access one of the unmapped registers).
I should mention that we use a slightly modified Fiasco.OC kernel and kernel interface, since in the unmodified Genode 16.08/Fiasco.OC, calling Cpu_thread_component::state() [1] internally calls Platform_thread::state(), which does not return the contents of all registers. Instead our modified Platform_thread::state() calls our own method all_regs() [2] which does that. The modified Fiasco.OC kernel source files are [3] and [4] with modifications marked with a comment mentioning "rtcr". But no remapping or other strange things are done there.
My guess is that this register magic is not happening in the base-hw version of Genode (since Vinit instruction emulation is not using any remapping and still works), but maybe you still have a clue of what is going on there.
Sorry, but I don't have a glue what the problem is. It looks as if there are issues with your all_regs syscall. Maybe the regs array layout is not as you expect it to be, or the v->mr array gets modified afterwards in the kernel? In your position, I would look into what really happens during the syscall, which values get written to the v->mr and what is done with them.
In contrast to FOC, the base-hw kernel was written with the sole purpose to fullfill the requieremts of Genodes Core/Userland in the simplest manner possible and thus, the kernel had support for returning all regs of a thread right from the beginning.
Cheers, Martin