记一次TEE reserved memory调整
问题背景:
基于Android R版本来使能go版本。
产品要求将原先TEE reserved memory规划的80M尽可能缩减。
80M是第三方TEE方案要求的,集成了多个指纹以及支付相关的较多TA,我们自研方案是OPTEE,集成的TA不多,所以这里还是有一些裁剪空间的。
修改点:
之前有过一次调整ATF内存大小的经验,所以这次以为轻车熟路,一上来咔咔咔改了3处,多次开机正常,配置密码也正常,就以为万事大吉了。
UEFI中BL32 size大小调整:
头文件:
#define BL32_BASE» » CONFIG_BL32_ADDRESS #define BL32_SIZE» » 0x05000000 --> #define BL32_SIZE» » 0x01400000
mk文件:
PLATFORM_BUILD_FLAGS += -DBL32_SIZE=0x5000000 --> PLATFORM_BUILD_FLAGS += -DBL32_SIZE=0x1400000
TZC中TEE区域:
LoaderPkg/Library/PlatformLib/Source/bl2_early_setup.c
#define DDR_TEE_REGION_START 0x90200000 #define DDR_TEE_REGION_END 0x94dfffff --> #define DDR_TEE_REGION_END 0x911fffff
TZC中安全内存不包含SHM部分。所以要剔除SHM的4M。
kernel dts调整:
tee_region@0x90200000 { reg = <0 0x90200000 0 0x5000000>; --> reg = <0 0x90200000 0 0x1400000>; no-map; };
以上改动完成之后,编译版本,开关机及基本功能测试,cat /sys/kernel/debug/memblock/memory查看内存信息,都正常,搞定。
出现问题:
开关机挂测偶尔会起不来。测试锁屏密码时会有奇奇怪怪的错误,比如设置不成功,比如settings意外停止。
关键log:
TC:? 0 ldelf_init_with_ldelf:126 ldelf failed with res: 0xffff000c
错误码对应定义:
./optee_client/public/tee_client_api.h:181:#define TEEC_ERROR_OUT_OF_MEMORY 0xFFFF000C
妥妥改出来的。
最开始以为是内存改太小导致的,从80M改到20M,缩减幅度确实有点大。
但实际这个20M是有理论依据的。
本地统计了所有TA大致需要的内存大小。
TA所占内存大致分布:TA文件大小 + stack 大小 + heap 大小。
栈和堆的大小都是TA代码中(user_ta_header_defines.h)配置的:
如:
#define TA_STACK_SIZE (32 * 1024) #define TA_DATA_SIZE (256 * 1024)
所以所有的TA所占内存可以有个大致的估算,另外core+pta给了2M,4M给了SHM。所以私以为这20M够用。
既然出现OOM,那么着手对前期配置的值进行调整。
这么测试下来,本地将值调整为60M都还会出现问题。(之前为什么不出现呢?我后来回想了一下,我们本地的版本分为emmc和emmc32G,当时刷的emmc版本,也许版本都弄错了)
这一轮测试下来,我觉得之前的调整可能还有漏洞。应该是某个地方没有改全导致的。
请教了部门的大牛,再参考官网的说明:
https://optee.readthedocs.io/en/latest/architecture/porting_guidelines.html#add-a-new-platform
以及代码中的定义:
https://github.com/OP-TEE/optee_os/blob/master/core/arch/arm/include/mm/generic_ram_layout.h
/* SPDX-License-Identifier: BSD-2-Clause */ /* * Copyright (c) 2018, Linaro Limited */ #ifndef __MM_GENERIC_RAM_LAYOUT_H #define __MM_GENERIC_RAM_LAYOUT_H #include <util.h> /* * Generic RAM layout configuration directives * * Mandatory directives: * CFG_TZDRAM_START * CFG_TZDRAM_SIZE * CFG_SHMEM_START * CFG_SHMEM_SIZE * * Optional directives: * CFG_TEE_LOAD_ADDR If defined sets TEE_LOAD_ADDR. If not, TEE_LOAD_ADDR * is set by the platform or defaults to TEE_RAM_START. * CFG_TEE_RAM_VA_SIZE Some platforms may have specific needs * * Optional directives when pager is enabled: * CFG_TZSRAM_START If no set, emulated at CFG_TZDRAM_START * CFG_TZSRAM_SIZE Default to CFG_CORE_TZSRAM_EMUL_SIZE * * Optional directive when CFG_SECURE_DATA_PATH is enabled: * CFG_TEE_SDP_MEM_SIZE If CFG_TEE_SDP_MEM_BASE is not defined, SDP test * memory byte size can be set by CFG_TEE_SDP_MEM_SIZE. * * This header file produces the following generic macros upon the mandatory * and optional configuration directives listed above: * * TEE_RAM_START TEE core RAM physical base address * TEE_RAM_VA_SIZE TEE core virtual memory address range size * TEE_RAM_PH_SIZE TEE core physical RAM byte size * TA_RAM_START TA contexts/pagestore RAM physical base address * TA_RAM_SIZE TA contexts/pagestore RAM byte size * TEE_SHMEM_START Non-secure static shared memory physical base address * TEE_SHMEM_SIZE Non-secure static shared memory byte size * * TZDRAM_BASE Main/external secure RAM base address * TZDRAM_SIZE Main/external secure RAM byte size * TZSRAM_BASE On-chip secure RAM base address, required by pager. * TZSRAM_SIZE On-chip secure RAM byte size, required by pager. * * TEE_LOAD_ADDR Only defined here if CFG_TEE_LOAD_ADDR is defined. * Otherwise we expect the platform_config.h to define it * unless which LEE_LOAD_ADDR defaults to TEE_RAM_START. * * TEE_RAM_VA_SIZE Set to CFG_TEE_RAM_VA_SIZE or defaults to * CORE_MMU_PGDIR_SIZE. * * TEE_SDP_TEST_MEM_BASE Define if a SDP memory pool is required and none set. * Always defined in the inner top (high addresses) * of CFG_TZDRAM_START/_SIZE. * TEE_SDP_TEST_MEM_SIZE Set to CFG_TEE_SDP_MEM_SIZE or a default size. * * ---------------------------------------------------------------------------- * TEE RAM layout without CFG_WITH_PAGER *_ * +----------------------------------+ <-- CFG_TZDRAM_START * | TEE core secure RAM (TEE_RAM) | * +----------------------------------+ * | Trusted Application RAM (TA_RAM) | * +----------------------------------+ * | SDP test memory (optional) | * +----------------------------------+ <-- CFG_TZDRAM_START + CFG_TZDRAM_SIZE * * +----------------------------------+ <-- CFG_SHMEM_START * | Non-secure static SHM | * +----------------------------------+ <-- CFG_SHMEM_START + CFG_SHMEM_SIZE * * ---------------------------------------------------------------------------- * TEE RAM layout with CFG_WITH_PAGER=y and undefined CFG_TZSRAM_START/_SIZE * * +----------------------------------+ <-- CFG_TZDRAM_START * | TEE core secure RAM (TEE_RAM) | | | CFG_CORE_TZSRAM_EMUL_SIZE * +----------------------------------+ --|-' * | reserved (for kasan) | | TEE_RAM_VA_SIZE * +----------------------------------+ --' * | TA RAM / Pagestore (TA_RAM) | * +----------------------------------+ <---- align with CORE_MMU_PGDIR_SIZE * +----------------------------------+ <-- * | SDP test memory (optional) | | CFG_TEE_SDP_MEM_SIZE * +----------------------------------+ <-+ CFG_TZDRAM_START + CFG_TZDRAM_SIZE * * +----------------------------------+ <-- CFG_SHMEM_START * | Non-secure static SHM | | * +----------------------------------+ v CFG_SHMEM_SIZE * * ---------------------------------------------------------------------------- * TEE RAM layout with CFG_WITH_PAGER=y and define CFG_TZSRAM_START/_SIZE * * +----------------------------------+ <-- CFG_TZSRAM_START * | TEE core secure RAM (TEE_RAM) | | CFG_TZSRAM_SIZE * +----------------------------------+ --' * * +----------------------------------+ <- CFG_TZDRAM_START * | TA RAM / Pagestore (TA_RAM) | * |----------------------------------+ <---- align with CORE_MMU_PGDIR_SIZE * |----------------------------------+ <-- * | SDP test memory (optional) | | CFG_TEE_SDP_MEM_SIZE * +----------------------------------+ <-+ CFG_TZDRAM_START + CFG_TZDRAM_SIZE * * +----------------------------------+ <-- CFG_SHMEM_START * | Non-secure static SHM | | * +----------------------------------+ v CFG_SHMEM_SIZE */ #ifdef CFG_TEE_LOAD_ADDR #define TEE_LOAD_ADDR CFG_TEE_LOAD_ADDR #else /* Platform specific platform_config.h may set TEE_LOAD_ADDR */ #endif #ifdef CFG_TEE_RAM_VA_SIZE #define TEE_RAM_VA_SIZE CFG_TEE_RAM_VA_SIZE #else #define TEE_RAM_VA_SIZE CORE_MMU_PGDIR_SIZE #endif #ifdef CFG_SHMEM_SIZE #define TEE_SHMEM_SIZE CFG_SHMEM_SIZE #endif #ifdef CFG_SHMEM_START #define TEE_SHMEM_START CFG_SHMEM_START #ifndef CFG_SHMEM_SIZE #error CFG_SHMEM_START mandates CFG_SHMEM_SIZE #endif #endif #if defined(CFG_TZSRAM_START) #define TZSRAM_BASE CFG_TZSRAM_START #define TZSRAM_SIZE CFG_TZSRAM_SIZE #endif #ifdef CFG_TZDRAM_START #if !defined(CFG_WITH_PAGER) || defined(CFG_TZSRAM_START) #define TZDRAM_BASE CFG_TZDRAM_START #define TZDRAM_SIZE CFG_TZDRAM_SIZE #else #define TZSRAM_BASE CFG_TZDRAM_START #define TZSRAM_SIZE CFG_CORE_TZSRAM_EMUL_SIZE #define TZDRAM_BASE ROUNDUP(TZSRAM_BASE + TZSRAM_SIZE, \ TEE_RAM_VA_SIZE) #define TZDRAM_SIZE (CFG_TZDRAM_START + (CFG_TZDRAM_SIZE - \ TZDRAM_BASE)) #endif #ifdef CFG_WITH_PAGER #define TEE_RAM_START TZSRAM_BASE #define TEE_RAM_PH_SIZE TZSRAM_SIZE #define TA_RAM_START ROUNDUP(TZDRAM_BASE, CORE_MMU_PGDIR_SIZE) #else #define TEE_RAM_START TZDRAM_BASE #define TEE_RAM_PH_SIZE TEE_RAM_VA_SIZE #define TA_RAM_START ROUNDUP(TZDRAM_BASE + TEE_RAM_VA_SIZE, \ SMALL_PAGE_SIZE) #endif /*CFG_WITH_PAGER*/ #define TA_RAM_SIZE (ROUNDDOWN(TZDRAM_BASE + (TZDRAM_SIZE - \ TEE_SDP_TEST_MEM_SIZE), \ SMALL_PAGE_SIZE) - TA_RAM_START) #endif /*CFG_TZDRAM_START*/ /* * Secure data path test memory pool * - If SDP is disabled, no SDP test memory needed. * - If SDP is enabled, if CFG_TEE_SDP_MEM_BASE, SDP test pool is not needed. * - If SDP is enabled and CFG_TEE_SDP_MEM_BASE not defined, a SDP test pool * is defined at the end of the secure RAM. CFG_TEE_SDP_MEM_SIZE can set * its size otherwise it defaults to 4MB. */ #if !defined(CFG_SECURE_DATA_PATH) || defined(CFG_TEE_SDP_MEM_BASE) #define TEE_SDP_TEST_MEM_SIZE 0 #else #ifdef CFG_TEE_SDP_MEM_SIZE #define TEE_SDP_TEST_MEM_SIZE CFG_TEE_SDP_MEM_SIZE #else #define TEE_SDP_TEST_MEM_SIZE SIZE_4M #endif #define TEE_SDP_TEST_MEM_BASE (CFG_TZDRAM_START + (CFG_TZDRAM_SIZE - \ TEE_SDP_TEST_MEM_SIZE)) #endif #endif /*__MM_GENERIC_RAM_LAYOUT_H*/
最终是同步修改CFG_TZDRAM_SIZE的配置之后,同时将CFG_SHMEM_START地址往前挪,另外uefi中BL32_SHMEM_BASE同步修改,再次编译版本测试就都正常了。