Hi,
On 06/22/2017 07:02 PM, rijurekha@...71... wrote:
Thanks a lot Stefan! base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc and base-hw/src/core/spec/arm_v7/trustzone/mode_transition.s makes the memory sharing and register read/write between vmm and vm clearer.
Further doubts: (1)We put three print statements: (a) In os/src/server/tz_vmm/spec/imx53/main.cc, printf1 Signal s = _sig_rcv.wait_for_signal() printf3
(b) In base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc, printf2 mtc()->switch_to(reinterpret_castCpu::Context*(_state), cpu, (addr_t)&_mt_nonsecure_entry_pic, (addr_t)&_tz_client_context);
printf1 prints once. printf2 prints multiple times, followed by printf3 (we make uart secure in csu_config.h, so we hit printf3 followed by the register dumps). Why do we switch from secure to normal world so many times (indicated by multiple printf2), while _sig_rcv.wait_for_signal()? What causes a switch back from normal to secure, before the UART related abort?
Secure interrupts. Please keep in mind that in your scenario there is more than the VMM component and the VM. The kernel schedules different entities, thereby it uses its schedule clock. Probably you also have a user-land timer for all other components, and maybe additional drivers, which can use secure interrupts. Each secure interrupt hits the fast-interrupt exception vector of the monitor mode, and thereby initiates a world-switch.
(2) Every time we switch from secure to normal world, .macro _secure_to_nonsecure does mov lr, #13 mcr p15, 0, lr, c1, c1, 0 /* enable EA, FIQ, and NS bit in SCTRL */ So a csu based uart abort in normal world is expected to trap to monitor?
correct.
Are you saying this behavior is something peripheral/vendor specific?
No, I don't meant that whether an external data abort hits the monitor mode is peripheral/vendor specific, like it is configured above. What I meant is how a peripheral (e.g.: the CSU) signals a security violation or error condition is not necessarily determined, and might differ from peripheral to peripheral. I also said the update of the DFAR and DFSR register is nothing I would count on. I only observed in my experiments that DFAR was set to the correct value when the CSU signaled a data-abort. Therefore, the kernel saved that register to the VM state, and the VMM dumped it for debugging purposes.
(3) We suspect that the csu based uart abort doesn't trap to monitor handler. If it came to the handler with a DABT excpetion, DFAR would be copied to r3 and saved in the memory shared with _state at .macro _nonsecure_to_secure In that case _state->dfar would give the same value, with and without the explicit read in base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc case Genode::Cpu_state::DATA_ABORT: state->dfar = Cpu::Dfar::read(); But we see without this read, _state->dfar prints all zeros, and with this read it gives a uart address. So dfar is not saved in the monitor handler, and therefore no other register would be saved. Is this understanding correct?
No. The DFAR register simply is not saved within the assembler path, but at a later point using the "read" you refered to. All other relevant registers are already saved in the assembler path. As I said, reading out the DFAR was done for debugging purposes only, and enabled at a later point in time. There was no need to read its value within the assembler path.
(4) What does Signal s = _sig_rcv.wait_for_signal(); do in os/src/server/tz_vmm/spec/imx53/main.cc? If the uart abort doesn't trap to the monitor, what raises the signal so that we come to this main.cc and execute the subsequent code like _handle_vm() that calls _vm->dump()? Is vmm doing some sort of polling to check cpu exception states in normal world?
It waits for all signals registered at the signal receiver. It does not poll at all. It blocks until a signal arrives. The VM session's signal context is definitely connected to that signal receiver, so that whenever the VM produced an exception, e.g. an abort, or smc call, the VMM gets unblocked. But the signal receiver can be attached to other signal sources too, e.g.: para-virtual driver backends like a block session. So in general the VMM can also be woken up by another signal source, as long as you use para-virtual devices in your scenario, which is probably not the case if you use the tz_vmm example for the Quickstart board.
(5) If abort doesn't trap to monitor, then only dfar and dfsr will hold the normal world relevant values, as that was the last abort? The other registers will be over-written, as normal world continued to execute, until vmm polled it? So emulating the abort causing instruction in secure world looks infeasible?
as being said, just do not uncomment DFAR saving, and it will work again.
(6) Is there a way to print something from base-hw/src/core/spec/arm_v7/trustzone/mode_transition.s? Most of the actions happen here, but we are not able to trace when those macros are executed.
Not easily, you can write your own assembler macro that writes to the UART directly. But changing anything there is very much error-prone. If you have a JTAG adapter you should use that instead.
Regards Stefan
Thanks for your constant assistance.
Riju
Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ genode-main mailing list genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main