summaryrefslogtreecommitdiff
path: root/meta-arm/meta-arm/recipes-security/optee/optee-os-3.20.0/0008-core-spmc-configure-SP-s-NS-interrupt-action-based-o.patch
diff options
context:
space:
mode:
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.patch150
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