From 7c246826436779cc2137d8adf21893ff7d8002cb Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Mon, 17 Nov 2025 16:00:58 +0530 Subject: [PATCH] feat(esp_tee): Add support for the RISC-V H/W stack guard mechanism --- components/esp_system/CMakeLists.txt | 12 +- components/esp_system/Kconfig | 3 +- .../private/esp_private/hw_stack_guard.h | 72 ++++++-- .../tee_sec_storage/tee_sec_storage.c | 6 +- .../arch/riscv/esp_tee_vector_table_clic.S | 18 +- .../arch/riscv/esp_tee_vector_table_plic.S | 19 +- .../main/arch/riscv/esp_tee_vectors_clic.S | 153 +++++++++++++++- .../main/arch/riscv/esp_tee_vectors_plic.S | 168 ++++++++++++++++-- .../main/common/panic/panic_helper_riscv.c | 3 + .../subproject/main/core/esp_tee_intr.c | 2 +- .../tee_cli_app/sdkconfig.ci.release | 4 +- .../test_sec_srv/sec_srv_tbl_test.yml | 8 + .../components/test_sec_srv/src/test_panic.c | 41 ++++- .../tee_test_fw/main/test_esp_tee_panic.c | 54 ++++++ .../tee_test_fw/pytest_esp_tee_ut.py | 31 ++-- .../portable/riscv/portasm.S | 4 +- .../FreeRTOS-Kernel/portable/riscv/portasm.S | 4 +- 17 files changed, 523 insertions(+), 79 deletions(-) diff --git a/components/esp_system/CMakeLists.txt b/components/esp_system/CMakeLists.txt index 98340aa9306..dc6f7f1927a 100644 --- a/components/esp_system/CMakeLists.txt +++ b/components/esp_system/CMakeLists.txt @@ -24,10 +24,14 @@ if(CONFIG_IDF_ENV_FPGA OR CONFIG_ESP_BRINGUP_BYPASS_RANDOM_SETTING) endif() if(BOOTLOADER_BUILD OR esp_tee_build) - # "_esp_error_check_failed()" requires spi_flash module - # Bootloader relies on some Kconfig options defined in esp_system. - idf_component_register(SRCS "${srcs}" REQUIRES spi_flash - INCLUDE_DIRS include) + set(include_dirs "include") + if(esp_tee_build) + list(APPEND include_dirs "port/include/private") + endif() + # "_esp_error_check_failed()" requires spi_flash module + # Bootloader relies on some Kconfig options defined in esp_system. + idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "${include_dirs}" + REQUIRES spi_flash) else() list(APPEND srcs "crosscore_int.c" "esp_ipc.c" diff --git a/components/esp_system/Kconfig b/components/esp_system/Kconfig index db830d7aa30..5288080acc8 100644 --- a/components/esp_system/Kconfig +++ b/components/esp_system/Kconfig @@ -447,8 +447,7 @@ menu "ESP System Settings" config ESP_SYSTEM_HW_STACK_GUARD bool "Hardware stack guard" - # TODO: [ESP-TEE] IDF-10770 - depends on SOC_ASSIST_DEBUG_SUPPORTED && !SECURE_ENABLE_TEE + depends on SOC_ASSIST_DEBUG_SUPPORTED default y help This config allows to trigger a panic interrupt when Stack Pointer register goes out of allocated stack diff --git a/components/esp_system/port/include/private/esp_private/hw_stack_guard.h b/components/esp_system/port/include/private/esp_private/hw_stack_guard.h index cb60b989ea2..70a522d14cc 100644 --- a/components/esp_system/port/include/private/esp_private/hw_stack_guard.h +++ b/components/esp_system/port/include/private/esp_private/hw_stack_guard.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -39,10 +39,10 @@ uint32_t esp_hw_stack_guard_get_pc(uint32_t core_id); #define ASSIST_DEBUG_CORE_0_SP_MAX_OFFSET (ASSIST_DEBUG_CORE_0_SP_MAX_REG - DR_REG_ASSIST_DEBUG_BASE) #define ASSIST_DEBUG_CORE_0_SP_SPILL_OFFSET (ASSIST_DEBUG_CORE_0_MONITOR_REG - DR_REG_ASSIST_DEBUG_BASE) -.macro ESP_HW_STACK_GUARD_SET_BOUNDS_CPU0 reg1 +.macro ESP_HW_STACK_GUARD_SET_BOUNDS_CPU0 reg1 sp_min sp_max lui \reg1, ASSIST_DEBUG_CORE_0_MONITOR_REG_IMM -sw a0, ASSIST_DEBUG_CORE_0_SP_MIN_OFFSET(\reg1) -sw a1, ASSIST_DEBUG_CORE_0_SP_MAX_OFFSET(\reg1) +sw \sp_min, ASSIST_DEBUG_CORE_0_SP_MIN_OFFSET(\reg1) +sw \sp_max, ASSIST_DEBUG_CORE_0_SP_MAX_OFFSET(\reg1) .endm .macro ESP_HW_STACK_GUARD_MONITOR_STOP_CPU0 reg1 reg2 @@ -59,6 +59,18 @@ ori \reg2, \reg2, ASSIST_DEBUG_SP_SPILL_BITS sw \reg2, ASSIST_DEBUG_CORE_0_SP_SPILL_OFFSET(\reg1) .endm +.macro ESP_HW_STACK_GUARD_GET_BOUNDS_CPU0 reg1 sp_min sp_max +lui \reg1, ASSIST_DEBUG_CORE_0_MONITOR_REG_IMM +lw \sp_min, ASSIST_DEBUG_CORE_0_SP_MIN_OFFSET(\reg1) +lw \sp_max, ASSIST_DEBUG_CORE_0_SP_MAX_OFFSET(\reg1) +.endm + +.macro ESP_HW_STACK_GUARD_MONITOR_QUERY_CPU0 reg1 reg2 +lui \reg1, ASSIST_DEBUG_CORE_0_MONITOR_REG_IMM +lw \reg2, ASSIST_DEBUG_CORE_0_SP_SPILL_OFFSET(\reg1) +andi \reg2, \reg2, ASSIST_DEBUG_SP_SPILL_BITS +.endm + #if SOC_CPU_CORES_NUM > 1 #define ASSIST_DEBUG_CORE_1_MONITOR_REG_IMM (ASSIST_DEBUG_CORE_1_MONITOR_REG >> 12) @@ -66,10 +78,10 @@ sw \reg2, ASSIST_DEBUG_CORE_0_SP_SPILL_OFFSET(\reg1) #define ASSIST_DEBUG_CORE_1_SP_MAX_OFFSET (ASSIST_DEBUG_CORE_1_SP_MAX_REG - DR_REG_ASSIST_DEBUG_BASE) #define ASSIST_DEBUG_CORE_1_SP_SPILL_OFFSET (ASSIST_DEBUG_CORE_1_MONITOR_REG - DR_REG_ASSIST_DEBUG_BASE) -.macro ESP_HW_STACK_GUARD_SET_BOUNDS_CPU1 reg1 +.macro ESP_HW_STACK_GUARD_SET_BOUNDS_CPU1 reg1 sp_min sp_max lui \reg1, ASSIST_DEBUG_CORE_1_MONITOR_REG_IMM -sw a0, ASSIST_DEBUG_CORE_1_SP_MIN_OFFSET(\reg1) -sw a1, ASSIST_DEBUG_CORE_1_SP_MAX_OFFSET(\reg1) +sw \sp_min, ASSIST_DEBUG_CORE_1_SP_MIN_OFFSET(\reg1) +sw \sp_max, ASSIST_DEBUG_CORE_1_SP_MAX_OFFSET(\reg1) .endm .macro ESP_HW_STACK_GUARD_MONITOR_STOP_CPU1 reg1 reg2 @@ -86,16 +98,28 @@ ori \reg2, \reg2, ASSIST_DEBUG_SP_SPILL_BITS sw \reg2, ASSIST_DEBUG_CORE_1_SP_SPILL_OFFSET(\reg1) .endm -.macro ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE reg1 +.macro ESP_HW_STACK_GUARD_GET_BOUNDS_CPU1 reg1 sp_min sp_max +lui \reg1, ASSIST_DEBUG_CORE_1_MONITOR_REG_IMM +lw \sp_min, ASSIST_DEBUG_CORE_1_SP_MIN_OFFSET(\reg1) +lw \sp_max, ASSIST_DEBUG_CORE_1_SP_MAX_OFFSET(\reg1) +.endm + +.macro ESP_HW_STACK_GUARD_MONITOR_QUERY_CPU1 reg1 reg2 +lui \reg1, ASSIST_DEBUG_CORE_1_MONITOR_REG_IMM +lw \reg2, ASSIST_DEBUG_CORE_1_SP_SPILL_OFFSET(\reg1) +andi \reg2, \reg2, ASSIST_DEBUG_SP_SPILL_BITS +.endm + +.macro ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE reg1 sp_min sp_max /* Check the current core ID */ csrr \reg1, mhartid beqz \reg1, 1f /* Core 1 */ -ESP_HW_STACK_GUARD_SET_BOUNDS_CPU1 \reg1 +ESP_HW_STACK_GUARD_SET_BOUNDS_CPU1 \reg1 \sp_min \sp_max j 2f 1: /* Core 0 */ -ESP_HW_STACK_GUARD_SET_BOUNDS_CPU0 \reg1 +ESP_HW_STACK_GUARD_SET_BOUNDS_CPU0 \reg1 \sp_min \sp_max 2: .endm @@ -125,11 +149,39 @@ ESP_HW_STACK_GUARD_MONITOR_STOP_CPU0 \reg1 \reg2 2: .endm +.macro ESP_HW_STACK_GUARD_GET_BOUNDS_CUR_CORE reg1 sp_min sp_max +/* Check the current core ID */ +csrr \reg1, mhartid +beqz \reg1, 1f +/* Core 1 */ +ESP_HW_STACK_GUARD_GET_BOUNDS_CPU1 \reg1 \sp_min \sp_max +j 2f +1: +/* Core 0 */ +ESP_HW_STACK_GUARD_GET_BOUNDS_CPU0 \reg1 \sp_min \sp_max +2: +.endm + +.macro ESP_HW_STACK_GUARD_MONITOR_QUERY_CUR_CORE reg1 reg2 +/* Check the current core ID */ +csrr \reg1, mhartid +beqz \reg1, 1f +/* Core 1 */ +ESP_HW_STACK_GUARD_MONITOR_QUERY_CPU1 \reg1 \reg2 +j 2f +1: +/* Core 0 */ +ESP_HW_STACK_GUARD_MONITOR_QUERY_CPU0 \reg1 \reg2 +2: +.endm + #else // SOC_CPU_CORES_NUM <= 1 #define ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE ESP_HW_STACK_GUARD_SET_BOUNDS_CPU0 #define ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE ESP_HW_STACK_GUARD_MONITOR_START_CPU0 #define ESP_HW_STACK_GUARD_MONITOR_STOP_CUR_CORE ESP_HW_STACK_GUARD_MONITOR_STOP_CPU0 +#define ESP_HW_STACK_GUARD_GET_BOUNDS_CUR_CORE ESP_HW_STACK_GUARD_GET_BOUNDS_CPU0 +#define ESP_HW_STACK_GUARD_MONITOR_QUERY_CUR_CORE ESP_HW_STACK_GUARD_MONITOR_QUERY_CPU0 #endif // SOC_CPU_CORES_NUM > 1 diff --git a/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c b/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c index 0ad68fd8699..c3c4afbf377 100644 --- a/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c +++ b/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c @@ -688,7 +688,11 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign_pbkdf2(const esp_tee_sec_storage_pbkdf2 } int cfg_key_id = (int)CONFIG_SECURE_TEE_PBKDF2_EFUSE_HMAC_KEY_ID; - if (cfg_key_id < 0 || cfg_key_id >= HMAC_KEY_MAX) { + /* Split the checks to keep Coverity happy */ + if (cfg_key_id < 0) { + return ESP_ERR_INVALID_ARG; + } + if (cfg_key_id >= HMAC_KEY_MAX) { return ESP_ERR_INVALID_ARG; } diff --git a/components/esp_tee/subproject/main/arch/riscv/esp_tee_vector_table_clic.S b/components/esp_tee/subproject/main/arch/riscv/esp_tee_vector_table_clic.S index 98e728dab8b..30e4804fbb5 100644 --- a/components/esp_tee/subproject/main/arch/riscv/esp_tee_vector_table_clic.S +++ b/components/esp_tee/subproject/main/arch/riscv/esp_tee_vector_table_clic.S @@ -9,9 +9,13 @@ /* The system interrupts are not used for now, so trigger a panic every time one occurs. */ #define _system_int_handler _tee_panic_handler - /* Handlers defined in the `vector.S` file, common to all RISC-V targets */ - .global _tee_ns_intr_handler - .global _tee_panic_handler +#define MEMPROT_ISR _tee_ns_intr_handler + +#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD + #define ASTDBG_ISR _tee_panic_handler +#else + #define ASTDBG_ISR _tee_ns_intr_handler +#endif // CONFIG_ESP_SYSTEM_HW_STACK_GUARD .section .exception_vectors_table.text @@ -32,7 +36,7 @@ .type _vector_table, @function .balign 0x40 _vector_table: - j _tee_panic_handler + j _tee_exception_handler .size _vector_table, .-_vector_table @@ -94,10 +98,8 @@ _mtvt_table: .word _tee_ns_intr_handler /* 39: Free interrupt number */ .word _tee_panic_handler /* 40: ETS_INT_WDT_INUM (+16) panic-interrupt (soc-level panic) */ .word _tee_panic_handler /* 41: ETS_CACHEERR_INUM (+16) panic-interrupt (soc-level panic) */ - /* NOTE: Triggers panic irrespective of the Kconfig setting with ESP-TEE */ - .word _tee_panic_handler /* 42: ETS_MEMPROT_ERR_INUM (+16) handler (soc-level panic) */ - /* TODO: [IDF-10770] Not supported yet with ESP-TEE */ - .word _tee_panic_handler /* 43: ETS_ASSIST_DEBUG_INUM (+16) handler (soc-level panic) */ + .word MEMPROT_ISR /* 42: ETS_MEMPROT_ERR_INUM (+16) handler (soc-level panic) */ + .word ASTDBG_ISR /* 43: ETS_ASSIST_DEBUG_INUM (+16) handler (soc-level panic) */ .word _tee_ns_intr_handler /* 44: ETS_IPC_ISR_INUM (+16) handler*/ .word _tee_ns_intr_handler /* 45: Free interrupt number */ .word _tee_ns_intr_handler /* 46: ESP-TEE: U-mode interrupt delegation entry */ diff --git a/components/esp_tee/subproject/main/arch/riscv/esp_tee_vector_table_plic.S b/components/esp_tee/subproject/main/arch/riscv/esp_tee_vector_table_plic.S index 6067d80eb79..8197ab70e6d 100644 --- a/components/esp_tee/subproject/main/arch/riscv/esp_tee_vector_table_plic.S +++ b/components/esp_tee/subproject/main/arch/riscv/esp_tee_vector_table_plic.S @@ -10,10 +10,13 @@ #error "ETS_INT_WDT_INUM expected to be 24" #endif - /* Handlers defined in the `esp_tee_vectors.S` file */ - .global _tee_panic_handler - .global _tee_ns_intr_handler - .global _tee_s_intr_handler +#define MEMPROT_ISR _tee_ns_intr_handler + +#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD + #define ASTDBG_ISR _tee_panic_handler +#else + #define ASTDBG_ISR _tee_ns_intr_handler +#endif // CONFIG_ESP_SYSTEM_HW_STACK_GUARD .section .exception_vectors_table.text, "ax" @@ -36,7 +39,7 @@ .global _vector_table .type _vector_table, @function _vector_table: - j _tee_panic_handler /* 0: Exception entry */ + j _tee_exception_handler /* 0: Exception entry */ /* NOTE: All of the free interrupts are used by the REE */ j _tee_ns_intr_handler /* 1: Free interrupt number */ j _tee_ns_intr_handler /* 2: Free interrupt number */ @@ -63,10 +66,8 @@ _vector_table: j _tee_ns_intr_handler /* 23: Free interrupt number */ j _tee_panic_handler /* 24: ETS_INT_WDT_INUM panic-interrupt (soc-level panic) */ j _tee_panic_handler /* 25: ETS_CACHEERR_INUM panic-interrupt (soc-level panic) */ - /* NOTE: Triggers panic irrespective of the Kconfig setting with ESP-TEE */ - j _tee_panic_handler /* 26: ETS_MEMPROT_ERR_INUM handler (soc-level panic) */ - /* TODO: [IDF-10770] Not supported yet with ESP-TEE */ - j _tee_panic_handler /* 27: ETS_ASSIST_DEBUG_INUM handler (soc-level panic) */ + j MEMPROT_ISR /* 26: ETS_MEMPROT_ERR_INUM handler (soc-level panic) */ + j ASTDBG_ISR /* 27: ETS_ASSIST_DEBUG_INUM handler (soc-level panic) */ j _tee_ns_intr_handler /* 28: Free interrupt number */ j _tee_ns_intr_handler /* 29: Free interrupt number */ j _tee_ns_intr_handler /* 30: Free interrupt number */ diff --git a/components/esp_tee/subproject/main/arch/riscv/esp_tee_vectors_clic.S b/components/esp_tee/subproject/main/arch/riscv/esp_tee_vectors_clic.S index 9a24713640a..789188e2cb4 100644 --- a/components/esp_tee/subproject/main/arch/riscv/esp_tee_vectors_clic.S +++ b/components/esp_tee/subproject/main/arch/riscv/esp_tee_vectors_clic.S @@ -16,6 +16,10 @@ #include "esp_tee_intr_defs.h" #include "sdkconfig.h" +#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD +#include "esp_private/hw_stack_guard.h" +#endif + .equ SAVE_REGS, 32 .equ CONTEXT_SIZE, (SAVE_REGS * 4) .equ panic_from_exception, tee_panic_from_exc @@ -32,22 +36,99 @@ .global _tee_s_entry .section .data + .balign 4 - .align 4 .global _ns_sp _ns_sp: .word 0 - .align 4 .global _s_sp _s_sp: .word 0 - .align 4 .global _s_intr_thresh _s_intr_thresh: .word 0 + .global _ns_sp_min +_ns_sp_min: + .word 0 + + .global _ns_sp_max +_ns_sp_max: + .word 0 + +/** + * STACK_GUARD_PRE_SWITCH + * Stops HW stack-guard monitoring and optionally saves current bounds. + * + * Args: + * op_reg – output register for “monitoring enabled” state (must be reused) + * to_save – 1=save bounds to memory, 0=skip saving + * sp_min – symbol to store lower bound (if to_save=1) + * sp_max – symbol to store upper bound (if to_save=1) + * + * Clobbers: t0, t1, t2, op_reg + */ +.macro STACK_GUARD_PRE_SWITCH op_reg, to_save, sp_min, sp_max +#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD + /* Query if monitoring is enabled: result goes into \op_reg */ + ESP_HW_STACK_GUARD_MONITOR_QUERY_CUR_CORE t2 \op_reg + beqz \op_reg, 1f + + .if \to_save + /* Save current REE/U-mode stack bounds */ + ESP_HW_STACK_GUARD_GET_BOUNDS_CUR_CORE t2 t0 t1 + la t2, \sp_min + sw t0, 0(t2) + la t2, \sp_max + sw t1, 0(t2) + .endif + + /* Stop monitoring */ + ESP_HW_STACK_GUARD_MONITOR_STOP_CUR_CORE t0 t1 + fence +1: +#endif +.endm + +/** + * STACK_GUARD_POST_SWITCH + * Restores or applies new bounds after switching stacks, then restarts monitoring. + * + * Args: + * op_reg – saved monitoring state from PRE_SWITCH + * to_restore – 1=restore from memory, 0=set static bounds + * sp_min – saved bound (restore) or static lower bound (S-mode) + * sp_max – saved bound (restore) or static upper bound (S-mode) + * + * Clobbers: t0, t1, t2 + */ +.macro STACK_GUARD_POST_SWITCH op_reg, to_restore, sp_min, sp_max +#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD + /* Check if monitoring was enabled (using saved state from op_reg) */ + beqz \op_reg, 1f + + .if \to_restore + /* Restore saved REE/U-mode bounds from memory */ + la t2, \sp_min + lw t0, 0(t2) + la t2, \sp_max + lw t1, 0(t2) + .else + /* Use new TEE/S-mode stack bounds (static symbols) */ + la t0, \sp_min + la t1, \sp_max + .endif + + /* Apply bounds to hardware stack guard */ + ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE t2 t0 t1 + /* Restart monitoring */ + ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE t0 t1 +1: +#endif +.endm + /* Macro which first allocates space on the stack to save general * purpose registers, and then save them. GP register is excluded. * The default size allocated on the stack is CONTEXT_SIZE, but it @@ -179,9 +260,10 @@ _s_intr_thresh: .section .exception_vectors.text, "ax" /* Exception handler. */ + .global _tee_exception_handler .global _tee_panic_handler .type _tee_panic_handler, @function -_tee_panic_handler: +_tee_exception_handler: /* Backup t0, t1 on the stack before using it */ addi sp, sp, -16 sw t0, 0(sp) @@ -205,7 +287,7 @@ _tee_panic_handler: lw t1, 4(sp) addi sp, sp, 16 -_actual_panic: +_tee_panic_handler: /* Not an ecall, proceed to the panic handler */ /* Allocate space on the stack and store general purpose registers */ save_general_regs RV_STK_FRMSZ @@ -267,7 +349,7 @@ _return_from_exception: restore_general_regs RV_STK_FRMSZ mret - .size _tee_panic_handler, .-_tee_panic_handler + .size _tee_exception_handler, .-_tee_exception_handler /* ECALL handler. */ .type _ecall_handler, @function @@ -301,9 +383,13 @@ _1: csrw CSR_MINTTHRESH, t1 _skip_thresh_restore: + STACK_GUARD_PRE_SWITCH t3 0 + /* Switching back to the saved REE stack */ la t0, _ns_sp lw sp, 0(t0) + + STACK_GUARD_POST_SWITCH t3 1 _ns_sp_min _ns_sp_max fence /* Backup the A0 register @@ -353,9 +439,13 @@ _process_ecall: la t0, _ns_sp sw sp, 0(t0) + STACK_GUARD_PRE_SWITCH t3 1 _ns_sp_min _ns_sp_max + /* Switch to the M-mode (i.e. TEE) stack */ la sp, _tee_stack + STACK_GUARD_POST_SWITCH t3 0 _tee_stack_bottom _tee_stack + /* Load the TEE entry point (see _tee_s_entry) in the mepc */ la t0, _tee_s_entry csrw mepc, t0 @@ -389,10 +479,14 @@ _3: lw t2, 0(t0) bne t2, t1, _3 + STACK_GUARD_PRE_SWITCH t3 0 + /* Restore the secure stack pointer */ la t0, _s_sp lw sp, 0(t0) + STACK_GUARD_POST_SWITCH t3 0 _tee_stack_bottom _tee_stack + /* Set the privilege mode to transition to after mret to M-mode */ li t0, MSTATUS_MPP csrs mstatus, t0 @@ -504,17 +598,23 @@ _4: li t1, MSTATUS_MPP csrc mstatus, t1 - /* Save the current secure stack pointer and switch to the U-mode interrupt stack - * saved while entering the secure service call routine (see `_tee_s_entry`) */ + /* Save the current secure stack pointer */ la t0, _s_sp sw sp, 0(t0) + + STACK_GUARD_PRE_SWITCH t3 0 + + /* Switch to the saved U-mode stack */ la t1, _ns_sp lw sp, 0(t1) + fence /* Set a flag to identify the next U2M switch would be after handling a U-mode interrupt */ lui t0, RTNVAL csrw mscratch, t0 + STACK_GUARD_POST_SWITCH t3 1 _ns_sp_min _ns_sp_max + /* Place magic bytes in all the general registers */ store_magic_general_regs @@ -577,8 +677,28 @@ _save_reg_ctx: _continue: /* Before doing anything preserve the stack pointer */ mv s11, sp + + /* NOTE: Cannot use the stack-guard macros here because they expect + * static symbols, not register-based bounds. */ +#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD + /* Check if stack monitoring is enabled */ + ESP_HW_STACK_GUARD_MONITOR_QUERY_CUR_CORE t2 t3 + beqz t3, 1f + + /* Save the REE stack guard bounds in s9/s10 (callee-saved registers) */ + ESP_HW_STACK_GUARD_GET_BOUNDS_CUR_CORE t2 s9 s10 + /* Stop the stack monitoring */ + ESP_HW_STACK_GUARD_MONITOR_STOP_CUR_CORE t0 t1 + fence +1: +#endif + /* Switch to the TEE interrupt stack */ la sp, _tee_intr_stack + + STACK_GUARD_POST_SWITCH t3 0 _tee_intr_stack_bottom _tee_intr_stack + fence + /* If this is a non-nested interrupt, SP now points to the interrupt stack */ /* Before dispatch c handler, restore interrupt to enable nested intr */ @@ -623,9 +743,24 @@ _intr_hdlr_exec: csrw mcause, s1 csrw mstatus, s2 + STACK_GUARD_PRE_SWITCH t3 0 + /* Restoring the stack pointer */ mv sp, s11 + /* NOTE: Cannot use the stack-guard macros here because they expect + * static symbols, not register-based bounds. */ +#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD + /* Check if stack monitoring was enabled (using saved state from t3) */ + beqz t3, 2f # Skip if monitoring was not enabled + + /* Restore the REE stack bounds from s9/s10 (callee-saved registers) */ + ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE t2 s9 s10 + /* Resume stack monitoring */ + ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE t0 t1 +2: +#endif + restore_mepc restore_general_regs RV_STK_FRMSZ /* exit, this will also re-enable the interrupts */ @@ -635,7 +770,7 @@ _intr_hdlr_exec: .section .text, "ax" - .align 4 + .balign 4 .type _tee_s_entry, @function _tee_s_entry: /* Jump to the secure service dispatcher */ diff --git a/components/esp_tee/subproject/main/arch/riscv/esp_tee_vectors_plic.S b/components/esp_tee/subproject/main/arch/riscv/esp_tee_vectors_plic.S index 48385df4167..9fd6f5ec983 100644 --- a/components/esp_tee/subproject/main/arch/riscv/esp_tee_vectors_plic.S +++ b/components/esp_tee/subproject/main/arch/riscv/esp_tee_vectors_plic.S @@ -16,6 +16,10 @@ #include "esp_tee_intr_defs.h" #include "sdkconfig.h" +#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD +#include "esp_private/hw_stack_guard.h" +#endif + .equ SAVE_REGS, 32 .equ CONTEXT_SIZE, (SAVE_REGS * 4) .equ panic_from_exception, tee_panic_from_exc @@ -24,31 +28,112 @@ .equ RTNVAL, 0xc0de .equ ECALL_U_MODE, 0x8 .equ ECALL_M_MODE, 0xb - /* NOTE: INTWDT timeout and Cache error interrupts trigger the panic - * handler before reset, so they don’t need to be delegated. */ - .equ TEE_INTR_DELEG_MASK, ~((1U << TEE_SECURE_INUM) | (1U << ETS_INT_WDT_INUM) | (1U << ETS_CACHEERR_INUM)) - + /* NOTE: INTWDT timeout, Cache error and Stack protection interrupts + * trigger the panic handler before reset, so they don't need to be delegated. */ + .equ TEE_INTR_DELEG_BASE, ((1U << TEE_SECURE_INUM) | (1U << ETS_INT_WDT_INUM) | (1U << ETS_CACHEERR_INUM)) +#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD + .equ TEE_INTR_DELEG_MASK, ~(TEE_INTR_DELEG_BASE | (1U << ETS_ASSIST_DEBUG_INUM)) +#else + .equ TEE_INTR_DELEG_MASK, ~(TEE_INTR_DELEG_BASE) +#endif .global esp_tee_global_interrupt_handler .global esp_tee_service_dispatcher .global _tee_s_entry .section .data + .balign 4 - .align 4 .global _ns_sp _ns_sp: .word 0 - .align 4 .global _s_sp _s_sp: .word 0 - .align 4 .global _s_intr_thresh _s_intr_thresh: .word 0 + .global _ns_sp_min +_ns_sp_min: + .word 0 + + .global _ns_sp_max +_ns_sp_max: + .word 0 + +/** + * STACK_GUARD_PRE_SWITCH + * Stops HW stack-guard monitoring and optionally saves current bounds. + * + * Args: + * op_reg – output register for “monitoring enabled” state (must be reused) + * to_save – 1=save bounds to memory, 0=skip saving + * sp_min – symbol to store lower bound (if to_save=1) + * sp_max – symbol to store upper bound (if to_save=1) + * + * Clobbers: t0, t1, t2, op_reg + */ +.macro STACK_GUARD_PRE_SWITCH op_reg, to_save, sp_min, sp_max +#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD + /* Query if monitoring is enabled: result goes into \op_reg */ + ESP_HW_STACK_GUARD_MONITOR_QUERY_CUR_CORE t2 \op_reg + beqz \op_reg, 1f + + .if \to_save + /* Save current REE/U-mode stack bounds */ + ESP_HW_STACK_GUARD_GET_BOUNDS_CUR_CORE t2 t0 t1 + la t2, \sp_min + sw t0, 0(t2) + la t2, \sp_max + sw t1, 0(t2) + .endif + + /* Stop monitoring */ + ESP_HW_STACK_GUARD_MONITOR_STOP_CUR_CORE t0 t1 + fence +1: +#endif +.endm + +/** + * STACK_GUARD_POST_SWITCH + * Restores or applies new bounds after switching stacks, then restarts monitoring. + * + * Args: + * op_reg – saved monitoring state from PRE_SWITCH + * to_restore – 1=restore from memory, 0=set static bounds + * sp_min – saved bound (restore) or static lower bound (S-mode) + * sp_max – saved bound (restore) or static upper bound (S-mode) + * + * Clobbers: t0, t1, t2 + */ +.macro STACK_GUARD_POST_SWITCH op_reg, to_restore, sp_min, sp_max +#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD + /* Check if monitoring was enabled (using saved state from op_reg) */ + beqz \op_reg, 1f + + .if \to_restore + /* Restore saved REE/U-mode bounds from memory */ + la t2, \sp_min + lw t0, 0(t2) + la t2, \sp_max + lw t1, 0(t2) + .else + /* Use new TEE/S-mode stack bounds (static symbols) */ + la t0, \sp_min + la t1, \sp_max + .endif + + /* Apply bounds to hardware stack guard */ + ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE t2 t0 t1 + /* Restart monitoring */ + ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE t0 t1 +1: +#endif +.endm + /* Macro which first allocates space on the stack to save general * purpose registers, and then save them. GP register is excluded. * The default size allocated on the stack is CONTEXT_SIZE, but it @@ -180,9 +265,10 @@ _s_intr_thresh: .section .exception_vectors.text, "ax" /* Exception handler. */ + .global _tee_exception_handler .global _tee_panic_handler - .type _tee_panic_handler, @function -_tee_panic_handler: + .type _tee_exception_handler, @function +_tee_exception_handler: /* Backup t0, t1 on the stack before using it */ addi sp, sp, -16 sw t0, 0(sp) @@ -206,7 +292,7 @@ _tee_panic_handler: lw t1, 4(sp) addi sp, sp, 16 -_actual_panic: +_tee_panic_handler: /* Not an ecall, proceed to the panic handler */ /* Allocate space on the stack and store general purpose registers */ save_general_regs RV_STK_FRMSZ @@ -259,7 +345,7 @@ _return_from_exception: restore_general_regs RV_STK_FRMSZ mret - .size _tee_panic_handler, .-_tee_panic_handler + .size _tee_exception_handler, .-_tee_exception_handler /* ECALL handler. */ .type _ecall_handler, @function @@ -289,9 +375,13 @@ _machine_ecall: sw t1, 0(t0) _skip_thresh_restore: + STACK_GUARD_PRE_SWITCH t3 0 + /* Switching back to the saved REE stack */ la t0, _ns_sp lw sp, 0(t0) + + STACK_GUARD_POST_SWITCH t3 1 _ns_sp_min _ns_sp_max fence /* Backup the A0 register @@ -344,13 +434,16 @@ _process_ecall: la t0, _ns_sp sw sp, 0(t0) + STACK_GUARD_PRE_SWITCH t3 1 _ns_sp_min _ns_sp_max + /* Switch to the M-mode (i.e. TEE) stack */ la sp, _tee_stack + STACK_GUARD_POST_SWITCH t3 0 _tee_stack_bottom _tee_stack + /* Load the TEE entry point (see _tee_s_entry) in the mepc */ la t0, _tee_s_entry csrw mepc, t0 - fence /* Disable the U-mode delegation of all interrupts */ csrwi mideleg, 0 @@ -367,10 +460,14 @@ _rtn_from_ns_int: /* Disable the U-mode interrupt delegation */ csrwi mideleg, 0 + STACK_GUARD_PRE_SWITCH t3 0 + /* Restore the secure stack pointer */ la t0, _s_sp lw sp, 0(t0) + STACK_GUARD_POST_SWITCH t3 0 _tee_stack_bottom _tee_stack + /* Set the privilege mode to transition to after mret to M-mode */ li t0, MSTATUS_MPP csrs mstatus, t0 @@ -427,12 +524,16 @@ _tee_ns_intr_handler: li t1, MSTATUS_MPP csrc mstatus, t1 - /* Save the current secure stack pointer and switch to the U-mode interrupt stack - * saved while entering the secure service call routine (see `_tee_s_entry`) */ + /* Save the current secure stack pointer */ la t0, _s_sp sw sp, 0(t0) + + STACK_GUARD_PRE_SWITCH t3 0 + + /* Switch to the saved U-mode stack */ la t1, _ns_sp lw sp, 0(t1) + fence /* Set a flag to identify the next U2M switch would be after handling a U-mode interrupt */ lui t0, RTNVAL @@ -442,6 +543,8 @@ _tee_ns_intr_handler: li t0, TEE_INTR_DELEG_MASK csrs mideleg, t0 + STACK_GUARD_POST_SWITCH t3 1 _ns_sp_min _ns_sp_max + /* Place magic bytes in all the general registers */ store_magic_general_regs @@ -506,8 +609,28 @@ _save_reg_ctx: _continue: /* Before doing anything preserve the stack pointer */ mv s11, sp + + /* NOTE: Cannot use the stack-guard macros here because they expect + * static symbols, not register-based bounds. */ +#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD + /* Check if stack monitoring is enabled */ + ESP_HW_STACK_GUARD_MONITOR_QUERY_CUR_CORE t2 t3 + beqz t3, 1f + + /* Save the REE stack guard bounds in s9/s10 (callee-saved registers) */ + ESP_HW_STACK_GUARD_GET_BOUNDS_CUR_CORE t2 s9 s10 + /* Stop the stack monitoring */ + ESP_HW_STACK_GUARD_MONITOR_STOP_CUR_CORE t0 t1 + fence +1: +#endif + /* Switch to the TEE interrupt stack */ la sp, _tee_intr_stack + + STACK_GUARD_POST_SWITCH t3 0 _tee_intr_stack_bottom _tee_intr_stack + fence + /* If this is a non-nested interrupt, SP now points to the interrupt stack */ /* Before dispatch c handler, restore interrupt to enable nested intr */ @@ -572,9 +695,24 @@ _intr_hdlr_exec: csrw mcause, s1 csrw mstatus, s2 + STACK_GUARD_PRE_SWITCH t3 0 + /* Restoring the stack pointer */ mv sp, s11 + /* NOTE: Cannot use the stack-guard macros here because they expect + * static symbols, not register-based bounds. */ +#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD + /* Check if stack monitoring was enabled (using saved state from t3) */ + beqz t3, 2f # Skip if monitoring was not enabled + + /* Restore the REE stack bounds from s9/s10 (callee-saved registers) */ + ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE t2 s9 s10 + /* Resume stack monitoring */ + ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE t0 t1 +2: +#endif + restore_mepc restore_general_regs RV_STK_FRMSZ /* exit, this will also re-enable the interrupts */ @@ -584,7 +722,7 @@ _intr_hdlr_exec: .section .text, "ax" - .align 4 + .balign 4 .type _tee_s_entry, @function _tee_s_entry: /* Jump to the secure service dispatcher */ diff --git a/components/esp_tee/subproject/main/common/panic/panic_helper_riscv.c b/components/esp_tee/subproject/main/common/panic/panic_helper_riscv.c index 7dc31388248..462cd95956c 100644 --- a/components/esp_tee/subproject/main/common/panic/panic_helper_riscv.c +++ b/components/esp_tee/subproject/main/common/panic/panic_helper_riscv.c @@ -154,6 +154,9 @@ void panic_print_isrcause(const void *f, int core) rsn = "Interrupt wdt timeout on CPU1"; break; #endif + case ETS_ASSIST_DEBUG_INUM: + rsn = "Stack protection fault"; + break; } panic_print_rsn(f, core, rsn); diff --git a/components/esp_tee/subproject/main/core/esp_tee_intr.c b/components/esp_tee/subproject/main/core/esp_tee_intr.c index 27eac49e555..db5a8f59154 100644 --- a/components/esp_tee/subproject/main/core/esp_tee_intr.c +++ b/components/esp_tee/subproject/main/core/esp_tee_intr.c @@ -70,7 +70,7 @@ void esp_tee_route_intr_matrix(int cpu_no, uint32_t model_num, uint32_t intr_num ESP_LOGV(TAG, "Connected src %d to int %d (cpu %d)", model_num, intr_num, cpu_no); #if SOC_INT_CLIC_SUPPORTED - if (intr_num != ETS_T1_WDT_INUM && intr_num != ETS_CACHEERR_INUM) { + if (intr_num != ETS_T1_WDT_INUM && intr_num != ETS_CACHEERR_INUM && intr_num != ETS_ASSIST_DEBUG_INUM) { /* Configure interrupts to be visible in the TEE (M-mode) */ REG_SET_BIT(DR_REG_INTMTX_BASE + 4 * model_num, BIT(8)); /* Configure interrupts to be serviced in the REE (U-mode) */ diff --git a/components/esp_tee/test_apps/tee_cli_app/sdkconfig.ci.release b/components/esp_tee/test_apps/tee_cli_app/sdkconfig.ci.release index e96f96e949c..84a31ced197 100644 --- a/components/esp_tee/test_apps/tee_cli_app/sdkconfig.ci.release +++ b/components/esp_tee/test_apps/tee_cli_app/sdkconfig.ci.release @@ -1,6 +1,6 @@ # Reducing TEE I/DRAM sizes -# 28KB -CONFIG_SECURE_TEE_IRAM_SIZE=0x7000 +# 29KB +CONFIG_SECURE_TEE_IRAM_SIZE=0x7400 # TEE Secure Storage: Release mode CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE=y diff --git a/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/sec_srv_tbl_test.yml b/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/sec_srv_tbl_test.yml index 98d7001ffac..f0adf8dcad1 100644 --- a/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/sec_srv_tbl_test.yml +++ b/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/sec_srv_tbl_test.yml @@ -69,3 +69,11 @@ secure_services: type: custom function: esp_tee_test_heap_malloc_write_free args: 0 + - id: 217 + type: custom + function: esp_tee_test_stack_overflow + args: 0 + - id: 218 + type: custom + function: esp_tee_test_stack_underflow + args: 0 diff --git a/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/src/test_panic.c b/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/src/test_panic.c index e159106cb9a..4c0f2f32ba2 100644 --- a/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/src/test_panic.c +++ b/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/src/test_panic.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -46,6 +46,45 @@ void _ss_esp_tee_test_iram_reg2_write_violation(void) *test_addr = RND_VAL; } +static void do_stack_smash(bool underflow, int depth, volatile uint8_t *sink) +{ + /* Overflow path */ + if (!underflow) { + if (depth == -1) { + return; // unreachable + } + + uint8_t buffer[1024]; + buffer[0] = (uint8_t)depth; + *sink = buffer[0]; + + do_stack_smash(false, depth + 1, sink); + return; + } + + /* Underflow path */ + asm volatile( + "li t0, 2048\n" + "add sp, sp, t0\n" + ); + + volatile uint8_t a = 1; + volatile uint8_t b = a; + (void)b; +} + +void _ss_esp_tee_test_stack_overflow(void) +{ + volatile uint8_t sink = 0; + do_stack_smash(false, 1, &sink); +} + +void _ss_esp_tee_test_stack_underflow(void) +{ + volatile uint8_t sink = 0; + do_stack_smash(true, 0, &sink); +} + #pragma GCC pop_options static void foo_d(void) diff --git a/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_panic.c b/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_panic.c index cb058018bce..198b81ef6c6 100644 --- a/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_panic.c +++ b/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_panic.c @@ -5,6 +5,7 @@ */ #include "soc/soc_caps.h" +#include "esp_attr.h" #if SOC_AES_SUPPORTED #include "soc/aes_reg.h" @@ -21,6 +22,7 @@ #include "soc/lp_wdt_reg.h" #include "soc/spi_mem_reg.h" #include "soc/ext_mem_defs.h" +#include "soc/assist_debug_reg.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -226,3 +228,55 @@ TEST_CASE("Test REE-TEE isolation: DROM-W1", "[exception]") *(uint32_t *)(test_addr - 0x04) = 0xbadc0de; TEST_FAIL_MESSAGE("Exception should have been generated"); } + +static void do_stack_smash(bool underflow, int depth, volatile uint8_t *sink) +{ + /* Overflow path */ + if (!underflow) { + if (depth == -1) { + return; // unreachable + } + + uint8_t buffer[1024]; + buffer[0] = (uint8_t)depth; + *sink = buffer[0]; + + do_stack_smash(false, depth + 1, sink); + return; + } + + /* Underflow path */ + asm volatile( + "li t0, 4096\n" + "add sp, sp, t0\n" + ); + + volatile uint8_t temp = 1; + (void)temp; +} + +TEST_CASE("Test REE stack overflow", "[exception]") +{ + volatile uint8_t sink = 0; + do_stack_smash(false, 1, &sink); + TEST_FAIL_MESSAGE("Exception should have been generated"); +} + +TEST_CASE("Test REE stack underflow", "[exception]") +{ + volatile uint8_t sink = 0; + do_stack_smash(true, 0, &sink); + TEST_FAIL_MESSAGE("Exception should have been generated"); +} + +TEST_CASE("Test TEE stack overflow", "[exception]") +{ + esp_tee_service_call(1, SS_ESP_TEE_TEST_STACK_OVERFLOW); + TEST_FAIL_MESSAGE("Exception should have been generated"); +} + +TEST_CASE("Test TEE stack underflow", "[exception]") +{ + esp_tee_service_call(1, SS_ESP_TEE_TEST_STACK_UNDERFLOW); + TEST_FAIL_MESSAGE("Exception should have been generated"); +} diff --git a/components/esp_tee/test_apps/tee_test_fw/pytest_esp_tee_ut.py b/components/esp_tee/test_apps/tee_test_fw/pytest_esp_tee_ut.py index 71b48221646..d0a8432f13a 100644 --- a/components/esp_tee/test_apps/tee_test_fw/pytest_esp_tee_ut.py +++ b/components/esp_tee/test_apps/tee_test_fw/pytest_esp_tee_ut.py @@ -39,6 +39,7 @@ TEE_VIOLATION_TEST_EXC_RSN: dict[str, str] = { ('IRAM-W2'): 'Store access fault', ('DRAM-X1'): 'Instruction access fault', ('DRAM-X2'): 'Instruction access fault', + ('Illegal Instruction'): 'Illegal instruction', } REE_ISOLATION_TEST_EXC_RSN: dict[str, str] = { @@ -128,19 +129,6 @@ def test_esp_tee_apm_violation(dut: IdfDut) -> None: raise RuntimeError('Incorrect exception received!') -@idf_parametrize( - 'config, target, markers', - CONFIG_DEFAULT, - indirect=['config', 'target'], -) -def test_esp_tee_illegal_instruction(dut: IdfDut) -> None: - dut.expect_exact('Press ENTER to see the list of tests') - dut.write('"Test TEE-TEE violation: Illegal Instruction"') - exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=30).group(2).decode() - if exc != 'Illegal instruction': - raise RuntimeError('Incorrect exception received!') - - @idf_parametrize( 'config, target, markers', CONFIG_DEFAULT, @@ -183,6 +171,23 @@ def test_esp_tee_isolation_checks(dut: IdfDut) -> None: dut.expect('Origin: U-mode') +@idf_parametrize( + 'config, target, markers', + CONFIG_DEFAULT, + indirect=['config', 'target'], +) +def test_esp_tee_stack_smashing(dut: IdfDut) -> None: + for env in ('REE', 'TEE'): + for case in ('overflow', 'underflow'): + dut.expect_exact('Press ENTER to see the list of tests') + dut.write(f'"Test {env} stack {case}"') + + match = dut.expect(r"Core ([01]) panic'ed \(([^)]+)\)", timeout=30) + exc = match.group(2).decode() + if exc != 'Stack protection fault': + raise RuntimeError('Incorrect exception received!') + + # ---------------- TEE Flash Protection Tests ---------------- diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/portasm.S b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/portasm.S index e3b4ccc59dd..f68adf012d7 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/portasm.S +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/portasm.S @@ -66,7 +66,7 @@ rtos_int_enter: /* esp_hw_stack_guard_set_bounds(xIsrStack, xIsrStackTop); */ la a0, xIsrStack mv a1, sp - ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE a2 + ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE a2 a0 a1 /* esp_hw_stack_guard_monitor_start(); */ ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE a0 a1 #endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */ @@ -143,7 +143,7 @@ no_switch: */ lw a0, PORT_OFFSET_PX_STACK(t0) lw a1, PORT_OFFSET_PX_END_OF_STACK(t0) - ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE a2 + ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE a2 a0 a1 /* esp_hw_stack_guard_monitor_start(); */ ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE a0 a1 #endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */ diff --git a/components/freertos/FreeRTOS-Kernel/portable/riscv/portasm.S b/components/freertos/FreeRTOS-Kernel/portable/riscv/portasm.S index e761b8d09f2..84ddaa303af 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/riscv/portasm.S +++ b/components/freertos/FreeRTOS-Kernel/portable/riscv/portasm.S @@ -684,7 +684,7 @@ rtos_int_enter: mv a1, sp /* esp_hw_stack_guard_set_bounds(xIsrStackBottom[coreID], xIsrStackTop[coreID]); */ - ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE a2 + ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE a2 a0 a1 ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE a0 a1 #endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */ @@ -841,7 +841,7 @@ restore_stack_pointer: */ lw a1, PORT_OFFSET_PX_END_OF_STACK(a0) lw a0, PORT_OFFSET_PX_STACK(a0) - ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE a2 + ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE a2 a0 a1 /* esp_hw_stack_guard_monitor_start(); */ ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE a0 a1 #endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */