最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

arm - ARMv8-m TrustZone crashes with INVTRAN after call to non-secure code - Stack Overflow

programmeradmin1浏览0评论

I'm using TrustZone on RP2350 microcontroller. After setting up SAU to define secure and non-secure memory areas, I'm jumping to non-secure code with bxns instruction.

The non-secure part of the firmware is compiled has its own vector table and I'm taking the entry addresses from it:

uint32_t *image_base = ...;
uint32_t sp = image_base[0];
uint32_t pc = image_base[1];
__asm__(
    "msr msp_ns, %0\n\t"
    "bxns %1" : : "r" (sp), "r" (pc) : "memory"); 

After the bxns instruction executes, the CPU jumps to crash handler. The SFSR (secure fault status register) shows value 0x00000010, indicating the INVTRAN error:

Invalid transition flag. Sticky flag indicating that an exception was raised due to a branch that was not flagged as being domain crossing causing a transition from Secure to Non-secure memory.

How should I "flag" the branch?

I'm using TrustZone on RP2350 microcontroller. After setting up SAU to define secure and non-secure memory areas, I'm jumping to non-secure code with bxns instruction.

The non-secure part of the firmware is compiled has its own vector table and I'm taking the entry addresses from it:

uint32_t *image_base = ...;
uint32_t sp = image_base[0];
uint32_t pc = image_base[1];
__asm__(
    "msr msp_ns, %0\n\t"
    "bxns %1" : : "r" (sp), "r" (pc) : "memory"); 

After the bxns instruction executes, the CPU jumps to crash handler. The SFSR (secure fault status register) shows value 0x00000010, indicating the INVTRAN error:

Invalid transition flag. Sticky flag indicating that an exception was raised due to a branch that was not flagged as being domain crossing causing a transition from Secure to Non-secure memory.

How should I "flag" the branch?

Share Improve this question asked Mar 19 at 19:07 jpajpa 12.2k1 gold badge37 silver badges55 bronze badges 2
  • Hopefully you've left out the part of your code where registers are sanitized before transitioning to non-secure state...? – Nate Eldredge Commented Mar 19 at 19:36
  • @NateEldredge Yes, and a lot of other init stuff. Maybe eventually I'll post something more complete, but that's a bit lot for a single question. – jpa Commented Mar 19 at 20:07
Add a comment  | 

1 Answer 1

Reset to default 0

From description of the bxns instruction in Armv8-M Architecture Reference Manual:

Branch and Exchange Non-secure causes a branch to an address specified by a register. If bit[0] of the target address is 0, and the target address is not FNC_RETURN or EXC_RETURN, then the instruction causes a transition from Secure to Non-secure state. This variant of the instruction must only be used when the additional steps required to make such a transition safe have been taken.

Normally in ARMv8-m, the lowest bit of a branch address must be 1, to indicate the thumb instruction mode. This applies also to the reset vector in the vector table. However, in the specific case of bxns, it transfers to non-secure state only when the bottom bit is set to 0.

The target memory area has been configured as non-secure in SAU but because the bottom bit is set, the processor stays in secure mode. This triggers the fault, as secure mode cannot execute instructions from non-secure memory.

To properly execute the jump, the address must be modified:

__asm__(
    "msr msp_ns, %0\n\t"
    "bxns %1" : : "r" (sp), "r" (pc & ~1) : "memory"); 
发布评论

评论列表(0)

  1. 暂无评论