记一次TEE reserved memory调整

发布时间 2023-08-23 17:14:13作者: xiululu

问题背景:

基于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             0x915fffff

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的配置之后,再次编译版本测试就都正常了。

其他:

学习中:https://aijishu.com/a/1060000000206679