diff options
Diffstat (limited to 'meta-arm/meta-arm/recipes-security/optee/optee-os-3.20.0/0008-core-spmc-configure-SP-s-NS-interrupt-action-based-o.patch')
-rw-r--r-- | meta-arm/meta-arm/recipes-security/optee/optee-os-3.20.0/0008-core-spmc-configure-SP-s-NS-interrupt-action-based-o.patch | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/meta-arm/meta-arm/recipes-security/optee/optee-os-3.20.0/0008-core-spmc-configure-SP-s-NS-interrupt-action-based-o.patch b/meta-arm/meta-arm/recipes-security/optee/optee-os-3.20.0/0008-core-spmc-configure-SP-s-NS-interrupt-action-based-o.patch new file mode 100644 index 0000000000..32e560689f --- /dev/null +++ b/meta-arm/meta-arm/recipes-security/optee/optee-os-3.20.0/0008-core-spmc-configure-SP-s-NS-interrupt-action-based-o.patch @@ -0,0 +1,150 @@ +From cad33cffb5be17fc0654aaf03c4d5227ae682e7a Mon Sep 17 00:00:00 2001 +From: Imre Kis <imre.kis@arm.com> +Date: Tue, 25 Apr 2023 14:19:14 +0200 +Subject: [PATCH] core: spmc: configure SP's NS interrupt action based on + the manifest + +Used mandatory ns-interrupts-action SP manifest property to configure +signaled or queued non-secure interrupt handling. + +Upstream-Status: Pending + +Signed-off-by: Imre Kis <imre.kis@arm.com> +Change-Id: I843e69e5dbb9613ecd8b95654e8ca1730a594ca6 +--- + .../arm/include/kernel/secure_partition.h | 2 + + core/arch/arm/kernel/secure_partition.c | 66 +++++++++++++++++-- + 2 files changed, 63 insertions(+), 5 deletions(-) + +diff --git a/core/arch/arm/include/kernel/secure_partition.h b/core/arch/arm/include/kernel/secure_partition.h +index 290750936..3bf339d3c 100644 +--- a/core/arch/arm/include/kernel/secure_partition.h ++++ b/core/arch/arm/include/kernel/secure_partition.h +@@ -43,6 +43,8 @@ struct sp_session { + unsigned int spinlock; + const void *fdt; + bool is_initialized; ++ uint32_t ns_interrupts_action; ++ uint32_t ns_interrupts_action_inherited; + TAILQ_ENTRY(sp_session) link; + }; + +diff --git a/core/arch/arm/kernel/secure_partition.c b/core/arch/arm/kernel/secure_partition.c +index 52365553b..e54069c17 100644 +--- a/core/arch/arm/kernel/secure_partition.c ++++ b/core/arch/arm/kernel/secure_partition.c +@@ -46,6 +46,10 @@ + SP_MANIFEST_ATTR_WRITE | \ + SP_MANIFEST_ATTR_EXEC) + ++#define SP_MANIFEST_NS_INT_QUEUED (0x0) ++#define SP_MANIFEST_NS_INT_MANAGED_EXIT (0x1) ++#define SP_MANIFEST_NS_INT_SIGNALED (0x2) ++ + #define SP_PKG_HEADER_MAGIC (0x474b5053) + #define SP_PKG_HEADER_VERSION_V1 (0x1) + #define SP_PKG_HEADER_VERSION_V2 (0x2) +@@ -907,6 +911,30 @@ static TEE_Result sp_init_uuid(const TEE_UUID *uuid, const void * const fdt) + return res; + DMSG("endpoint is 0x%"PRIx16, sess->endpoint_id); + ++ res = sp_dt_get_u32(fdt, 0, "ns-interrupts-action", ++ &sess->ns_interrupts_action); ++ ++ if (res) { ++ EMSG("Mandatory property is missing: ns-interrupts-action"); ++ return res; ++ } ++ ++ switch (sess->ns_interrupts_action) { ++ case SP_MANIFEST_NS_INT_QUEUED: ++ case SP_MANIFEST_NS_INT_SIGNALED: ++ /* OK */ ++ break; ++ ++ case SP_MANIFEST_NS_INT_MANAGED_EXIT: ++ EMSG("Managed exit is not implemented"); ++ return TEE_ERROR_NOT_IMPLEMENTED; ++ ++ default: ++ EMSG("Invalid ns-interrupts-action value: %d", ++ sess->ns_interrupts_action); ++ return TEE_ERROR_BAD_PARAMETERS; ++ } ++ + return TEE_SUCCESS; + } + +@@ -989,17 +1017,45 @@ TEE_Result sp_enter(struct thread_smc_args *args, struct sp_session *sp) + return res; + } + ++/* ++ * According to FF-A v1.1 section 8.3.1.4 if a caller requires less permissive ++ * active on NS interrupt than the callee, the callee must inherit the caller's ++ * configuration. ++ * Each SP's own NS action setting is stored in ns_interrupts_action. The ++ * effective action will be MIN([self action], [caller's action]) which is ++ * stored in the ns_interrupts_action_inherited field. ++ */ ++static void sp_cpsr_configure_foreing_interrupts(struct sp_session *s, ++ struct ts_session *caller, ++ uint64_t *cpsr) ++{ ++ if (caller) { ++ struct sp_session *caller_sp = to_sp_session(caller); ++ ++ s->ns_interrupts_action_inherited = ++ MIN(caller_sp->ns_interrupts_action_inherited, ++ s->ns_interrupts_action); ++ } else { ++ s->ns_interrupts_action_inherited = s->ns_interrupts_action; ++ } ++ ++ if (s->ns_interrupts_action_inherited == SP_MANIFEST_NS_INT_QUEUED) ++ *cpsr |= (THREAD_EXCP_FOREIGN_INTR << ARM32_CPSR_F_SHIFT); ++ else ++ *cpsr &= ~(THREAD_EXCP_FOREIGN_INTR << ARM32_CPSR_F_SHIFT); ++} ++ + static TEE_Result sp_enter_invoke_cmd(struct ts_session *s, + uint32_t cmd __unused) + { + struct sp_ctx *ctx = to_sp_ctx(s->ctx); + TEE_Result res = TEE_SUCCESS; + uint32_t exceptions = 0; +- uint64_t cpsr = 0; + struct sp_session *sp_s = to_sp_session(s); + struct ts_session *sess = NULL; + struct thread_ctx_regs *sp_regs = NULL; + uint32_t thread_id = THREAD_ID_INVALID; ++ struct ts_session *caller = NULL; + uint32_t rpc_target_info = 0; + uint32_t panicked = false; + uint32_t panic_code = 0; +@@ -1009,11 +1065,12 @@ static TEE_Result sp_enter_invoke_cmd(struct ts_session *s, + sp_regs = &ctx->sp_regs; + ts_push_current_session(s); + +- cpsr = sp_regs->cpsr; +- sp_regs->cpsr = read_daif() & (SPSR_64_DAIF_MASK << SPSR_64_DAIF_SHIFT); +- + exceptions = thread_mask_exceptions(THREAD_EXCP_ALL); + ++ /* Enable/disable foreign interrupts in CPSR/SPSR */ ++ caller = ts_get_calling_session(); ++ sp_cpsr_configure_foreing_interrupts(sp_s, caller, &sp_regs->cpsr); ++ + /* + * Store endpoint ID and thread ID in rpc_target_info. This will be used + * as w1 in FFA_INTERRUPT in case of a NWd interrupt. +@@ -1026,7 +1083,6 @@ static TEE_Result sp_enter_invoke_cmd(struct ts_session *s, + + __thread_enter_user_mode(sp_regs, &panicked, &panic_code); + +- sp_regs->cpsr = cpsr; + /* Restore rpc_target_info */ + thread_get_tsd()->rpc_target_info = rpc_target_info; + +-- +2.17.1 |