This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Cannot access EL1 resources from EL3 or secure world on armv8.

The working secerio is that I'm testing OP-TEE on a Hikey board(Cortex-A53, armv8), and they use arm-trusted-firmware(see https://github.com/linaro-swg/arm-trusted-firmware) to be the monitor running in EL3.

I'm trying to access some resources in EL1 by specifying an virtual memory that would work in EL1, for example, if the address of sys_call_table in EL1 is whatever_the_addr, then I try to access the addr in EL3 directly by using

memcpy(dest, whatever_the_addr, size);   //where dest is an array allocated in EL3.

I do the access in the beginning `smc_handler` working in EL3, so that when the EL1 linux kernel launches an SMC instruction(which would be routed to EL3), I do the access.

However, the system just hung up and I couldn't figure out why. I have put the value of TTBR0_EL1 into TTBR0_EL3(which means that their page base registers are the same now), why would the access still fail? Would the SMC call cause some context changes? But I didn't find relevant information in the ARM SMC calling conventions(see http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0028a/index.html).

If I'm not supposed to access it directly, how could I access these memories exactly? Could anyone please give me some clues? I'd appreciate it very much if anyone could help me with it.

BTW, when I decide to access some memory in EL1, the EL1 normal world system has already been running.

Thanks a lot.
Tgn

Parents
  • I'm not an expert on OP-TEE, so will stick to the architectural side.

    The translation tables are bit patterns in memory, pointed at by the relevant TTBR.  However, how you interpret those tables is determined by set of configurations stored in other registers.  For example:

    • TCR - size of address space, translation granule, location of ASID
    • MAIR - index to type mapping
    • SCTLR - MMU enable, and whether write-able regions are executable

    Just copying TTBR0_EL1 to TTBR0_EL3 is unlikely to work, as unless all these other settings are the same, the tables will be interpreted differently.  And hence give different results.

    Then there is the question of which TTBR0_EL1 value you copied.  In ARMv8-A, when EL3 uses AArch64, there is only a single copy of TTBR0_EL1 used by both S.EL1 and NS.EL1.  It's up to the EL3 software to perform the context switch.  If you've just taken the SMC from Non-secure state, it's probably the NS.EL1 value of TTBR0_EL1 you copied.  Is that what you wanted?

    There is also the issue of the TLBs, which cache recently used translations.  Unless you invalidated the TLBs after writing TTBR0_EL3, it's possible it's still using an old cached translation.  Assuming you put the value of TTBR0_EL3 back afterwards, there is also the risk that when you restart execution you'll have corrupt TLB entries.

Reply
  • I'm not an expert on OP-TEE, so will stick to the architectural side.

    The translation tables are bit patterns in memory, pointed at by the relevant TTBR.  However, how you interpret those tables is determined by set of configurations stored in other registers.  For example:

    • TCR - size of address space, translation granule, location of ASID
    • MAIR - index to type mapping
    • SCTLR - MMU enable, and whether write-able regions are executable

    Just copying TTBR0_EL1 to TTBR0_EL3 is unlikely to work, as unless all these other settings are the same, the tables will be interpreted differently.  And hence give different results.

    Then there is the question of which TTBR0_EL1 value you copied.  In ARMv8-A, when EL3 uses AArch64, there is only a single copy of TTBR0_EL1 used by both S.EL1 and NS.EL1.  It's up to the EL3 software to perform the context switch.  If you've just taken the SMC from Non-secure state, it's probably the NS.EL1 value of TTBR0_EL1 you copied.  Is that what you wanted?

    There is also the issue of the TLBs, which cache recently used translations.  Unless you invalidated the TLBs after writing TTBR0_EL3, it's possible it's still using an old cached translation.  Assuming you put the value of TTBR0_EL3 back afterwards, there is also the risk that when you restart execution you'll have corrupt TLB entries.

Children