cancel
Showing results for 
Search instead for 
Did you mean: 

Cortex-M33/STM32U5 - unprivileged mode in secure not working?!

42Bastian Schick
Associate III

Ask this at arm.com, but maybe it is STM32U5 specific:

I try run an unprivileged application in secure mode and get a strange behavior:

STM32U5 has TZ enabled, all application runs in secure mode.

1) LR = 0xffff_fff9, CONTROL = 1 => BX LR increments the SP, but all registers become 0 (including PC and XPSR!)

2) When setting CONTROL = 1 and executing SVC, SP is decremented correctly, but nothing is stored on the stack?

I check all errata I could find, but no hint.

If TZ is disabled, the system behaves normal.

1 ACCEPTED SOLUTION

Accepted Solutions

I think this is STM32U5 specific. ST adds "Resource isolation improvements" on top of the ARMv8-M TrustZone. These improvements allow a block-based secure and privilege configuration for internal SRAM.

See page 8 on the STM32U5-Security-Overview (SECOVW) presentation.

View solution in original post

14 REPLIES 14
42Bastian Schick
Associate III

Dummy reply.

Pierre_Paris
ST Employee

Hello @42Bastian Schick ,

Thank you for your question.

Here is some guidance:

  • According to ARM documentation, you define the Thread mode with the MSP use in a unprivileged level. "After any Thread mode transition from privileged to unprivileged execution, software must issue an ISB instruction to ensure instruction fetch correctness." 
  • How are you executing SVC instruction ? Like this :

 

#define EnablePrivilegedMode() __asm("SVC #0") 

 

  • Most likely the problem can be because the MPU isolate the memory for unprivileged application. You can read more here (see table 13). What address are you trying to reach ?
  • GTZC can protect against non-secure and optionally unprivileged transactions initiated by masters other than
    the Cortex-M33. Here is a STM32U5-Security-Overview. Do you have any illegal access detected ?
  • Can you tell me more about the application ? Are you using any peripherals/external memories/DMA channel? For your information, when the TZ is activated, peripherals are set as non secure and unprivileged after reset.

Best Regards,

Pierre

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

42Bastian Schick
Associate III

The application is our RTOS.

The switch between kernel (privileged) and user process (unprivileged) works correct with TZ disabled on SoC level.

So MPU settings should be correct and there is no access violation directly after the return or after the "svc".

But since the "return" pops all 0 (that is r0..r3,r12,lr and xpsr), the next instruction will cause an invalidate instruction exception.

And since "svc" does not push anything onto the stack, the following code crashes, as the stack contains nonsense.

It is weird, that SP is correctly updated in both cases.

Whether I place my SP in 0x3000.0000 or 0x2000.0000 RAM does not change anything.

There is no change of security, so no "SG".

There is no MPU error.

 

42Bastian Schick
Associate III

I made an example, the absolute minimum which just runs.

Same behavior "svc" with CONTROL == 0 => registers pushed

CONTROL == 1 => SP reduced, no registers pushed.

The attached ELF can be flashed. Run until "HelloSciopta", single step "svc" => registers pushed and PC at sc_sysSVC.

Do it again, set CONTROL == 1 before step. Single step, PC at sc_sysSVC, but no registers pushed.

Pierre_Paris
ST Employee

Thank you for your ELF file @42Bastian Schick , I flashed it and get this error :

PierrePARIS_0-1695199590474.png

  • Can you please check your linker file ? That might be a memory zone definition overlap...
  • Also what are your OB configuration ? (RDP level? User config? and Write Protection with page size?)

Best Regards,

Pierre

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

42Bastian Schick
Associate III

Yes there are memory regions with the same start address, but of size 0. So you can ignore the warning.

OB:

42BastianSchick_0-1695200620593.png

I hope above makes sense. CubeProgrammer does not allow to "dump" the OB info nicely :(

42BastianSchick_1-1695201360427.png

WRP2 same, only 0x081...

I attached a new ELF which I flashed w/o error/warning with CubeProgrammer.

Cheers

42Bastian

 

Pierre_Paris
ST Employee

Hello @42Bastian Schick ,

Here is some remark, information demand :

  • What U5 are you using ?
  • In the .elf you gave me, CONTROL = 0. 
  • I am currently trying to reproduce your issue with & without TZEN. In both case, the first instruction is at the address 0x0C00 023A.
    • In case TZEN = 0, you finally stay stuck at the address 0x0C00 1830. According to the symbol table ( se_sciopta_ERRHOOK at the address 0x0C00 183C), it look like it's an error case... But what is the source of that, do you have an interrupt ? any peripherals accessing a wrong memory ? The PSR value is 0x6100000B so flags zero, carry or borrow, T bits are set...
    • In case TZEN = 1, I also stay stuck at the address 0x0C00 1830. So, I have the same behavior... What are you expected ?
  • Are you using the OCTOSPI ? According to the RM, 0x7FFF FFFE is the last address of OCTOSPI2 non-secure bank... 
     PierrePARIS_0-1695742342734.png

Best Regards,

Pierre

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Salut,

yes, this file is meant to be run with TZEN=1. It is tested on nucleo-u575zi-q.

If the system just runs it ends in an error condition, that is "wanted". At the label HelloSciopta is an "svc" instruction and the kernel detects that it is build w/o support for SVC.

Nevertheless, the issue happens when stepping through HelloSciopta function into "svc" opcode.

If CONTROL==0 (default), the step over SVC pushes the r0-r3,r12,lr and XPSR (you can see them on the stack).

If CONTROL==1 then the step over SVC only decrements the SP by the correct amount, but there is nothing stored on the stack.

Cheers

42Bastian

Hello @42Bastian Schick ,

I am currently using the same board.

Here is some remark :

  • "detects that it is build w/o support for SVC" : your sentence make me thing that it could be a declaration problem in c but I am really not sure about that. Have you any error/warning message at the compilation ? 
  • So to recap :
    • when CONTROL == 0 (Thread in Privileged level so Software has full access to system resources, subject to security restrictions), everything is running normally. It causes an exception and change to Supervisor mode.
    • when CONTROL == 1 (Thread in Unprivileged level so the software has limited access to system resources), Nothing is stored on the Stack, in the MSP ?
  • I am checking the SVCALLACT bit (CONTROL == 0 and CONTROL==1) and in both cases it's equal to 1 so SVC call is active. At the same time SVCALLPENDED bit stay to 0, so there is no exception pending. Can you confirm this behavior ? However, for some reason I am not seeing the SVC instruction in the disassembly...
  • Have you checked the GTZC, MPCBB & TZIC registers during your debug sessions ? 

Only privileged software can write to the CONTROL register to change the privilege level for software execution in
Thread mode. Unprivileged software can use the SVC instruction to make a Supervisor Call to transfer control to
privileged software. Here is the PM of the STM32 Cortex -M33 in case.

Best Regards,

Pierre

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.