OP-TEE / optee_os

Trusted side of the TEE
Other
1.54k stars 1.04k forks source link

tzc400.c violation non-secure privileged write AXI ID 480 #6306

Closed symdeb closed 10 months ago

symdeb commented 11 months ago

Attempts for support from ST failed so far hence an attempt here. This issue concern an STM32MP157AAA3 custom board using STM ECO 5.0 sources. As you can see below, OPTEE runs with BL32 Extra 2 paging in DDR. The boot from SD shows the following error (with additional "DEBUG" messages added). The board only uses the debug UART4 and SD card configured on EMMC1 . The rest of peripherals were not enabled in CubeMX (such as I2C). power is form regulators and PMIC is not used. Clock and power rail settings should be correct. This panic is in tzc400.c even though it shows and u-boot sign on, I just guess this error is u-boot running code attempting to access memory managed by OP-TEE on the secure side (apologies if wrong). Hence posting it here.

1 What is AXI and ID 480 ? How to find out ?

  1. What does this error means ?
  2. How to find out what causes this. 4 .What things to try ?
  3. What does "non-secure" but still "privileged" mean in this context ?
  4. Why would u-boot try to access an write an area that is firewalled for secure access only ? The ST docs state: 0xDE00 0000: 30-Mbyte region where only secure accesses are allowed The violation added was firewalled in TF-A stm32mp15-fw-config.dtsi but removing it does not have effect either. DDR_SEC_BASE = 0xDE000000 and DDR_SEC_SIZE - 0x02000000

    ifdef AARCH32_SP_OPTEE

    memory-ranges = < DDR_NS_BASE DDR_NS_SIZE TZC_REGION_S_NONE TZC_REGION_NSEC_ALL_ACCESS_RDWR DDR_SEC_BASE DDR_SEC_SIZE TZC_REGION_S_RDWR 0 0xdfe00000 0x00200000 TZC_REGION_S_NONE TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID)

    ;

NOTICE: CPU: STM32MP157AAA Rev.B NOTICE: Model: STMicroelectronics custom STM32CubeMX board - openstlinux-6.1-yocto-mickledore-mp1-v23.06.21 NOTICE: DEBUG: stm32_print_boardinfo NOTICE: DEBUG: stm32mp_is_closed_device NOTICE: HELLO: fixed_regulator_register NOTICE: DEBUG: fdt_get_address NOTICE: DEBUG: fdt_for_each_compatible_node NOTICE: DEBUG: fdt_get_name NOTICE: DEBUG: fixed_regulator_register:80 regulator_register vin NOTICE: DEBUG:: register vin NOTICE: DEBUG: parse_dt NOTICE: DEBUG @ parse_dt: vin: parse dt NOTICE: DEBUG:fdt_get_phandle NOTICE: DEBUG:fdt_getprop NOTICE: DEBUG:fdt32_to_cpu NOTICE: DEBUG: vin: min_mv=5000 NOTICE: DEBUG:fdt_getprop NOTICE: DEBUG:fdt32_to_cpu NOTICE: DEBUG: vin: max_mv=5000 NOTICE: DEBUG: regulator_list_voltages NOTICE: DEBUG: parse_propterties NOTICE: DEBUG: regulator_register done NOTICE: DEBUG: assert NOTICE: DEBUG: fdt_get_name NOTICE: DEBUG: fixed_regulator_register:80 regulator_register vdd NOTICE: DEBUG:: register vdd NOTICE: DEBUG: parse_dt NOTICE: DEBUG @ parse_dt: vdd: parse dt NOTICE: DEBUG:fdt_get_phandle NOTICE: DEBUG:fdt_getprop NOTICE: DEBUG:fdt32_to_cpu NOTICE: DEBUG: vdd: min_mv=3300 NOTICE: DEBUG:fdt_getprop NOTICE: DEBUG:fdt32_to_cpu NOTICE: DEBUG: vdd: max_mv=3300 NOTICE: DEBUG: regulator_list_voltages NOTICE: DEBUG: parse_propterties NOTICE: DEBUG: regulator_register done NOTICE: DEBUG: assert NOTICE: DEBUG: dt_pmic_status NOTICE: DEBUG: stm32mp1_syscfg_init NOTICE: DEBUG: stm32mp1_iwdg_init NOTICE: DEBUG: stm32mp1_iwdg_refresh NOTICE: DEBUG: bsec_read_debug_conf NOTICE: DEBUG: stm32mp1_arch_security_setup NOTICE: DEBUG: print_reset_reason NOTICE: DEBUG: stm32mp1_syscfg_enable_io_compensation_finish NOTICE: DEBUG: fconf_populate NOTICE: DEBUG: stm32_skip_boot_device_after_standby NOTICE: DEBUG: stm32mp_io_setup NOTICE: BL2: v2.8-stm32mp1-r1.0(release):() NOTICE: BL2: Built : 06:06:12, Sep 20 2023 NOTICE: DEBUG: parse optee image #0 NOTICE: DEBUG: header->optee_image_list[num].image_id=0x0 NOTICE: DEBUG: OPTEE_PAGER_IMAGE_ID=0 NOTICE: DEBUG: OPTEE_PAGED_IMAGE_ID=1 NOTICE: DEBUG: init_load_addr=0x2ffc0000 NOTICE: DEBUG: init_size=0x13800 NOTICE: DEBUG: image_info->image_base=0x2ffc0000 NOTICE: DEBUG: image_info->image_max_size=0x22000 NOTICE: DEBUG: parse optee image https://github.com/OP-TEE/optee_docs/pull/1 NOTICE: DEBUG: header->optee_image_list[num].image_id=0x1 NOTICE: DEBUG: OPTEE_PAGER_IMAGE_ID=0 NOTICE: DEBUG: OPTEE_PAGED_IMAGE_ID=1 NOTICE: DEBUG: parse_optee_imageNOTICE: DEBUG: init_load_addr=0xde000000 NOTICE: DEBUG: init_size=0x56000 NOTICE: DEBUG: image_info->image_base=0xde000000 NOTICE: DEBUG: image_info->image_max_size=0x2000000 NOTICE: BL2: Booting BL32 I/TC: Early console on UART#4 I/TC: I/TC: Pager is enabled. Hashes: 2848 bytes I/TC: Pager pool size: 92kB I/TC: Embedded DTB found I/TC: OP-TEE version: Unknown_3.19 (gcc version 12.2.0 (GCC)) https://github.com/OP-TEE/optee_docs/pull/1 Wed Sep 20 06:07:36 UTC 2023 arm I/TC: WARNING: This OP-TEE configuration might be insecure! I/TC: WARNING: Please check https://optee.readthedocs.io/en/latest/architecture/porting_guidelines.html I/TC: Primary CPU initializing I/TC: Platform stm32mp1: flavor PLATFORM_FLAVOR - DT stm32mp157a-board-mx.dts I/TC: DTB enables console (non-secure) I/TC: HUK unlocked I/TC: No power configuration found in DT I/TC: Primary CPU switching to normal world boot optee optee: OP-TEE: revision 3.19

U-Boot 2022.10-stm32mp-r1 (Sep 20 2023 - 14:07:55 +0800)

CPU: STM32MP157AAA Rev.B Model: STMicroelectronics STM32MP157C eval daughter on eval mother Board: stm32mp1 in trusted mode (st,stm32mp157c-ev1) DRAM: 512 MiB E/TC:0 tzc_it_handler:79 TZC permission failure E/TC:0 dump_fail_filter:420 Permission violation on filter 0 E/TC:0 dump_fail_filter:425 DEBUG: status = 0x1 E/TC:0 dump_fail_filter:426 DEBUG: IT_STATUS = 0x10 E/TC:0 dump_fail_filter:427 DEBUG: filter = 0x0 E/TC:0 dump_fail_filter:428 DEBUG: tzc.base = 0x34806000 E/TC:0 dump_fail_filter:429 DEBUG: FAIL_ID(filter) = 0x2c E/TC:0 dump_fail_filter:431 Violation @0xdfb19000, non-secure privileged write, AXI ID 480 E/TC:0 Panic

etienne-lms commented 10 months ago

Hello @symdeb,

1 What is AXI and ID 480 ? How to find out ?

See STM32MP157 ref manual, Rev6, table 20 "NSAID and AXI_ID mapping". Here 480 (1E0h) is in CA7 (CPU0 and 1) range, hence a Cortex-A7 unauthorized access.

  1. What does this error means ?

"Violation @0xdfb19000, non-secure privileged write, AXI ID 480" means a non-secure Cortext-A7 privileged access to physical memory address 0xdfb19000.

"Privileged" here means Cortex-A7 CPU in "kernel land", not in "userland".

  1. How to find out what causes this.
  2. What things to try ?

Warning: this answer is does not relate to OP-TEE/optee_os Github source tree. With STM ECO 5.0 sources, there are means to dump CA-7 non-secure registers state at the time the TZC interrupt occur. Maybe that would help. See stm32mp_dump_core_registers().

  1. What does "non-secure" but still "privileged" mean in this context ?

See above.

  1. Why would u-boot try to access an write an area that is firewalled for secure access only ? The ST docs state: 0xDE00 0000: 30-Mbyte region where only secure accesses are allowed The violation added was firewalled in TF-A stm32mp15-fw-config.dtsi but removing it does not have effect either. DDR_SEC_BASE = 0xDE000000 and DDR_SEC_SIZE - 0x02000000

Indeed U-Boot should not access his area. Please check wether CFG_CORE_RESERVED_SHM is enabled or not in your OP-TEE config. If it is, then the DDR last 32MB are made of 30MB secure DDR followed by 2MB non-secure DDR. If it is not, the last 32MB DDR is secure access only. When so, TF-A is expected to set the firewall accordingly. Latest ST ECO has removed this old 2MB non-secure static shared memory, both in OP-TEE and TF-A components.

symdeb commented 10 months ago

Thank you very much to clarify the origins of ID 480 ! Was not aware of the deprecation of the 2MB area, That was one of the things I noticed. The 2MB area is not in fwconfig generate files anymore and any references to SHMEM were removed by a patch in the ECO repo. This deprecation is not mentioned anywhere on ST site/WIKIsm moreover this region is mentioned in several (recent published) WIKI's on ST STM32MP1 site https://wiki.st.com/stm32mpu wiki/How_to_configure_a_256MB_DDR_mapping_from_STM32_MPU_Distribution_Package and here https://wiki.st.com/stm32mpu/wiki/How_to_configure_TF-A_FW_CONFIG . I added this region in the firewall based on the assumption that this was a required area.

Why was this are removed ?

P.S the OP-TEE conf .mk sets the flag to n: ifeq ($(CFG_STM32MP15),y) $(call force,CFG_BOOT_SECONDARY_REQUEST,y) $(call force,CFG_CORE_RESERVED_SHM,n)

After more than a week not being able to fix this error, it suddenly went away and I could to reproduce it anymore even trying to reverse all the changes. Likely one was missed, but will keep trying to find the culprit.

This is the default firewall: memory-ranges = <0xc0000000 0x1e000000 0x00000000 0x87fb87fb 0xde000000 0x02000000 0x00000003 0x00000000>; and the one modified with the 2MB area at 0xdfe00000 memory-ranges = <0xc0000000 0x1e000000 0x00000000 0x87fb87fb 0xde000000 0x01e00000 0x00000003 0x00000000 0xdfe00000 0x00200000 0x00000000 0x00010001>;

I did recall the AXI 480 error occured in both instances.

P.S There is a related post here https://github.com/OP-TEE/optee_os/issues/6141, though CFG_CORE_DYN_SHM is not in the OP-TEE conf.mk .

etienne-lms commented 10 months ago

This deprecation is not mentioned anywhere on ST site/WIKIsm moreover this region is mentioned

Thanks, I'll report this. Note that ST ECO release for stm32mp15 is rather to be discussed in the ST forum for STM32MPU embedded software.

P.S There is a related post here https://github.com/OP-TEE/optee_os/issues/6141, though CFG_CORE_DYN_SHM is not in the OP-TEE conf.mk .

CFG_CORE_DYN_SHM is enable by default from mk/config.mk.

symdeb commented 10 months ago

I assumed OP-TEE only used the conf.mk from /core/arch/plat-stm32mp1/conf.mk Attached is that file. There isn't CFG_CORE_DYN_SHM defined. Does OPT-EE build also use mk/config.mk ? Does that mean changing mk.config.mk is also required for OP-TEE build ? conf.zip Note that ST ECO release for stm32mp15 is rather to be discussed in the ST forum for [STM32MPU embedded software](https://community.st.com/t5/stm32-mpus-embedded-software/bd-p/mpu-embedded-software-forum).. The reason for this post. In the community no reactions.

image P.S How to read 1E0 from this format ?

jforissier commented 10 months ago

Not speaking about the ST fork of OP-TEE specifically, but in general, several configuration files are included in the build. See https://github.com/OP-TEE/optee_os/blob/master/mk/config.mk#L1-L17.

symdeb commented 10 months ago

Thus:

  1. The Linux kernel OP-TEE driver will first try dynamic shared memory (CFG_CORE_DYN_SHM=y) and if that fails try static shared memory(CFG_CORE_RESERVED_SHM=y) (see link above)
  2. Platform-specific overrides are in core/arch/arm32/plat-*/conf.mk.

Thus: 1.mk/config.mk : CFG_CORE_DYN_SHM=y (default)

  1. stm's conf.mk does not contain CFG_CORE_DYN_SHM=y but has CFG_CORE_RESERVED_SHM=n for STM32MP15 Does this mean CFG_CORE_DYN_SHM=y takes priority so that the SHM area always is enabled or does CFG_CORE_RESERVED overrule CFG_CORE_DYN_SHM ? If it does not override it, 2MB SHM would/should always enabled, and if it is deprecated that wouldn't be correct.
jforissier commented 10 months ago

Reserved and dynamic shared memory can be independently enabled and disabled. In your case I understand you should end up with CFG_CORE_DYN_SHM=y and CFG_CORE_RESERVED_SHM=n, which you can check in $(out-dir)/conf.mk.

symdeb commented 10 months ago

After starting from scratch with CubeMX files, not adding 2MB firewall entry in TF-A fw-config , restarting from a clean set of ST's ECO 5.0 sources ,adding the custom board CubeMX DT's and applying all needed DT changes, an similar AXI 480 error was encountered (though at a different address). It could be resolved by adding the optee reserved memory area in the uboot.dts. Perhaps the previous sources were not clean anymore (after lots of debug, trial and error changes) and the u-boot change did not have the desired effect.

stm32mp1_ddr ddr@5a003000: set_state_simple op missing size=20, ptr=21098, limit=80000: c00a1078 RAM init base=c0000000, size=20000000 size=18, ptr=210b0, limit=80000: c00a1098 size=4, ptr=210b4, limit=80000: c00a10b0 512 MiB E/TC:0 tzc_it_handler:79 TZC permission failure E/TC:0 dump_fail_filter:420 Permission violation on filter 0 E/TC:0 dump_fail_filter:425 Violation @0xdff01000, non-secure privileged write, AXI ID 480 E/TC:0 Panic

etienne-lms commented 10 months ago

U-boot machine implements board_get_usable_ram_top() (_arch/arm/mach-stm32mp/draminit.c). This function is expected to carveout DDR top (that is secure) thanks to a reserved-memory node from the board DT. Maybe there is also a CONFIG_TOP_UNMAPPED_SIZE config switch in your U-Boot source tree that can be used to tell the 32MB top DDR cannot be reached by U-Boot.