Hi,
On 06/20/2017 02:12 PM, rijurekha@...71... wrote:
We read the dfsr value with changes in base-hw/include/spec/imx53/vm_state.h, base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc, and os/src/server/tz_vmm/include/vm_base.h dump() function.
We got dfsr = 00001008, which gives b101000 for the status bits, matching "bx01000 precise external abort, nontranslation" with "x=1=AXI Slave error caused the abort" (according to http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344k/Bgbiagh...).
Got dfar = 53fbc080 physical address, which is in the UART range, and we have made UART secure in csu_config.h, so makes sense that we get an AXI slave error.
Basic questions: (1) In base-hw/src/core/include/spec/arm/cpu_support.h, we see Cpu structs Dfsr and Dfar and the read functions, which read from the cp15 registers. This is what we explicitly read on a data abort and assign to _state variables. How do the other _state variables r0-r12, ip, lr, etc. defined in base/include/spec/arm/cpu/cpu_state.h get populated?
They are saved within the assembler path when switching from normal to secure mode within monitor mode. Have a look at file:
repos/base-hw/src/core/spec/arm_v7/trustzone/mode_transition.s
In os/src/server/tz_vmm/include/vm_base.h, constructor has this initialization for _state:
_state((Genode::Vm_state*)Genode::env()->rm_session()->attach(_vm_con.cpu_state()))
What does this do?
It initializes the pointer to the memory holding the normal world's register set. That memory is a dataspace returned by the VM service provided by core. The component attaches this dataspace to its region map (virtual memory), and assigns the resulting address to the _state pointer.
When we read or write from _state->ip or _state->r5, are we accessing an actual register or a memory location? Where does the memory read/write get translated to an actual register read/write?
When the kernel/core schedules the normal world after the VMM marked it to be runnable via run() of the VM service, the register state within the VM's dataspace is restored to the actual registers.
Like dfar and dfsr, do we need explicit assignment of the other _state variables in the data abort handler, so that in dump() function we get the correct _state->ip?
No.
(2) For precise data aborts, http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344f/Beiibjc... says the following.
After dealing with the cause of the abort, the handler executes the following return instruction, irrespective of the processor operating state at the point of entry: SUBS PC,R14_abt,#8 This restores both the PC and the CPSR, and retries the aborted instruction.
But as we discussed above in this thread, we need to see _state->ip and not _state->abt.lr, because this is an external abort on the AXI bus, and not an mmu based internal abort. Is this behavior (lr_abt not updated and ip needs to be read) something genode specific, or ARM specific? We see cpsr=0x93, which makes EA=0. So external aborts are not programmed to trap to monitor mode. So what is the flow when an imprecise external abort occurs in the normal world? Does it go to the normal world exception handler or comes to genode exception handler? What code can I look at to understand this flow?
The "_state" register set in memory is the information that our hypervisor (kernel/core) provides to the VMM component. It is typically the register state *before* the exception occurred resp. the instruction that triggered the exception. For instance in your case the kernel saves the lr register of the monitor mode to _state.ip. Therefore, you should have a look at that register. The _state->abt.lr value shows the last instruction pointer when the normal world's exception vector was hit by a data-abort exception. It has nothing to do with your observed exception. When the normal world's MMU/TLB can correctly translate a data access, but the bus or peripheral answers with an error due to a security violation, control is directly given to the monitor mode _not_ the normal world's exception vector. This is independent from the abort flag in the CPSR register, which is useful in this context only within the normal world (and its exception vector).
I hope this answers your questions.
Regards Stefan
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