feat(sve): add support for FPU usage in REL2
With SVE enabled for Realms, this change enables back FPU usage in
REL2.
RMM uses FPU in few RMI and RSI handlers when RMM_FPU_USE_AT_REL2=ON.
So a list is maintained to track which of these handlers needs FPU.
Currently attestation, measurement related services use FPU.
RMI Handlers:
SMC_RMM_REALM_CREATE, SMC_RMM_DATA_CREATE, SMC_RMM_REC_CREATE,
and SMC_RMM_RTT_INIT_RIPAS
For any of these RMI handlers, the NS SIMD state is actively saved
upon entering and restored on exit.
RSI Handlers:
SMC_RSI_ATTEST_TOKEN_CONTINUE and SMC_RSI_MEASUREMENT_EXTEND
For any of these RSI handlers, the REC or NS SIMD state is actively
saved upon entering and restored before exiting RSI handler.
These changes are under the build flag RMM_FPU_USE_AT_REL2. This allows
RMM to use FPU only for these RMI/RSI handlers when
RMM_FPU_USE_AT_REL2=ON.
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: Ibdaf54e3fb4884fd26245931010263091b5be0e7
diff --git a/runtime/core/handler.c b/runtime/core/handler.c
index 77c1517..0f16ae7 100644
--- a/runtime/core/handler.c
+++ b/runtime/core/handler.c
@@ -8,6 +8,7 @@
#include <assert.h>
#include <buffer.h>
#include <debug.h>
+#include <simd.h>
#include <sizes.h>
#include <smc-handler.h>
#include <smc-rmi.h>
@@ -141,6 +142,17 @@
static bool rmi_call_log_enabled = true;
+static inline bool rmi_handler_needs_fpu(unsigned long id)
+{
+#ifdef RMM_FPU_USE_AT_REL2
+ if (id == SMC_RMM_REALM_CREATE || id == SMC_RMM_DATA_CREATE ||
+ id == SMC_RMM_REC_CREATE || id == SMC_RMM_RTT_INIT_RIPAS) {
+ return true;
+ }
+#endif
+ return false;
+}
+
static void rmi_log_on_exit(unsigned long handler_id,
unsigned long args[],
struct smc_result *ret)
@@ -214,6 +226,7 @@
{
unsigned long handler_id;
const struct smc_handler *handler = NULL;
+ bool restore_ns_simd_state = false;
/* Ignore SVE hint bit, until RMM supports SVE hint bit */
function_id &= ~MASK(SMC_SVE_HINT);
@@ -238,6 +251,15 @@
assert_cpu_slots_empty();
+ /* Current CPU's SIMD state must not be saved when entering RMM */
+ assert(simd_is_state_saved() == false);
+
+ /* If the handler needs FPU, actively save NS simd context. */
+ if (rmi_handler_needs_fpu(function_id) == true) {
+ simd_save_ns_state();
+ restore_ns_simd_state = true;
+ }
+
switch (handler->type) {
case rmi_type_00:
ret->x[0] = handler->f_00();
@@ -273,6 +295,14 @@
rmi_log_on_exit(handler_id, args, ret);
}
+ /* If the handler uses FPU, restore the saved NS simd context. */
+ if (restore_ns_simd_state) {
+ simd_restore_ns_state();
+ }
+
+ /* Current CPU's SIMD state must not be saved when exiting RMM */
+ assert(simd_is_state_saved() == false);
+
assert_cpu_slots_empty();
}