Merge branch 'fix/esp_tee_int_wdt_v5.5' into 'release/v5.5'

fix(esp_tee): Sync M-U interrupt thresholds during service calls from critical sections (v5.5)

See merge request espressif/esp-idf!42720
This commit is contained in:
Mahavir Jain
2025-10-20 14:43:02 +05:30
2 changed files with 59 additions and 0 deletions

View File

@@ -25,6 +25,7 @@
.equ ECALL_U_MODE, 0x8
.equ ECALL_M_MODE, 0xb
.equ CSR_UINTTHRESH, 0x047
.equ CSR_MINTTHRESH, 0x347
.global esp_tee_global_interrupt_handler
.global esp_tee_service_dispatcher
@@ -42,6 +43,11 @@ _ns_sp:
_s_sp:
.word 0
.align 4
.global _s_intr_thresh
_s_intr_thresh:
.word 0
/* 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
@@ -285,6 +291,16 @@ _1:
lui t0, ESP_TEE_M2U_SWITCH_MAGIC
beq a1, t0, _skip_ctx_restore
/* Check if we need to restore the MINTTHRESH register */
la t0, _s_intr_thresh
lw t1, 0(t0)
beqz t1, _skip_thresh_restore # if saved threshold == 0, skip
/* Restore CSR_MINTTHRESH */
sw zero, 0(t0)
csrw CSR_MINTTHRESH, t1
_skip_thresh_restore:
/* Switching back to the saved REE stack */
la t0, _ns_sp
lw sp, 0(t0)
@@ -322,6 +338,17 @@ _user_ecall:
save_general_regs
save_mepc
# Check if REE is in a critical section
csrr t0, CSR_UINTTHRESH # t0 = current UINTTHRESH
beqz t0, _process_ecall # if threshold == 0 -> continue
# Save current MINTTHRESH and mirror UINTTHRESH into MINTTHRESH
csrr t1, CSR_MINTTHRESH # t1 = current MINTTHRESH
la t2, _s_intr_thresh
sw t1, 0(t2) # save old MINTTHRESH
csrw CSR_MINTTHRESH, t0 # set MINTTHRESH = UINTTHRESH
_process_ecall:
/* Save the U-mode (i.e. REE) stack pointer */
la t0, _ns_sp
sw sp, 0(t0)

View File

@@ -6,6 +6,7 @@
#include "soc/soc.h"
#include "soc/soc_caps.h"
#include "soc/plic_reg.h"
#include "riscv/encoding.h"
#include "riscv/rvruntime-frames.h"
@@ -43,6 +44,11 @@ _ns_sp:
_s_sp:
.word 0
.align 4
.global _s_intr_thresh
_s_intr_thresh:
.word 0
/* 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
@@ -272,6 +278,17 @@ _machine_ecall:
lui t0, ESP_TEE_M2U_SWITCH_MAGIC
beq a1, t0, _skip_ctx_restore
/* Check if we need to restore the MXINT threshold register */
la t0, _s_intr_thresh
lw t1, 0(t0)
beqz t1, _skip_thresh_restore # if saved threshold == 0, skip
/* Restore PLIC_MXINT_THRESH_REG */
sw zero, 0(t0)
li t0, PLIC_MXINT_THRESH_REG
sw t1, 0(t0)
_skip_thresh_restore:
/* Switching back to the saved REE stack */
la t0, _ns_sp
lw sp, 0(t0)
@@ -309,6 +326,20 @@ _user_ecall:
save_general_regs
save_mepc
# Check if REE is in a critical section
li t0, PLIC_UXINT_THRESH_REG
lw t1, 0(t0) # t1 = current UXINT threshold
li t2, 1
ble t1, t2, _process_ecall # if threshold <= 1 -> continue
# Save current MXINT threshold and mirror UXINT threshold into MXINT
li t0, PLIC_MXINT_THRESH_REG
lw t2, 0(t0) # t3 = current MXINT threshold
la t3, _s_intr_thresh
sw t2, 0(t3) # save old MXINT threshold
sw t1, 0(t0)
_process_ecall:
/* Save the U-mode (i.e. REE) stack pointer */
la t0, _ns_sp
sw sp, 0(t0)
@@ -319,6 +350,7 @@ _user_ecall:
/* 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