feat(fpmr): disable FPMR trap

This patch enables support of FEAT_FPMR by enabling access
to FPMR register. It achieves it by setting the EnFPM bit of
SCR_EL3. This feature is currently enabled for NS world only.

Reference:
https://developer.arm.com/documentation/109697/2024_09/
Feature-descriptions/The-Armv9-5-architecture-extension?lang=en

Change-Id: I580c409b9b22f8ead0737502280fb9093a3d5dd2
Signed-off-by: Arvind Ram Prakash <arvind.ramprakash@arm.com>
This commit is contained in:
Arvind Ram Prakash 2024-11-11 14:32:37 -06:00
parent e372c29153
commit a57e18e433
12 changed files with 110 additions and 0 deletions

View file

@ -951,8 +951,21 @@ ifeq (${ARCH},aarch32)
ifeq (${ENABLE_FEAT_RNG_TRAP},1)
$(error "ENABLE_FEAT_RNG_TRAP cannot be used with ARCH=aarch32")
endif
ifneq (${ENABLE_FEAT_FPMR},0)
$(error "ENABLE_FEAT_FPMR cannot be used with ARCH=aarch32")
endif
endif #(ARCH=aarch32)
ifneq (${ENABLE_FEAT_FPMR},0)
ifeq (${ENABLE_FEAT_FGT},0)
$(error "ENABLE_FEAT_FPMR requires ENABLE_FEAT_FGT")
endif
ifeq (${ENABLE_FEAT_HCX},0)
$(error "ENABLE_FEAT_FPMR requires ENABLE_FEAT_HCX")
endif
endif #(ENABLE_FEAT_FPMR)
ifneq (${ENABLE_SME_FOR_NS},0)
ifeq (${ENABLE_SVE_FOR_NS},0)
$(error "ENABLE_SME_FOR_NS requires ENABLE_SVE_FOR_NS")
@ -1264,6 +1277,7 @@ $(eval $(call assert_numerics,\
ENABLE_FEAT_ECV \
ENABLE_FEAT_FGT \
ENABLE_FEAT_FGT2 \
ENABLE_FEAT_FPMR \
ENABLE_FEAT_HCX \
ENABLE_FEAT_LS64_ACCDATA \
ENABLE_FEAT_MTE2 \
@ -1425,6 +1439,7 @@ $(eval $(call add_defines,\
ENABLE_MPMM_FCONF \
ENABLE_FEAT_FGT \
ENABLE_FEAT_FGT2 \
ENABLE_FEAT_FPMR \
ENABLE_FEAT_ECV \
ENABLE_FEAT_AMUv1p1 \
ENABLE_FEAT_SEL2 \

View file

@ -150,6 +150,10 @@ ifneq (${ENABLE_TRF_FOR_NS},0)
BL31_SOURCES += lib/extensions/trf/aarch64/trf.c
endif
ifneq (${ENABLE_FEAT_FPMR},0)
BL31_SOURCES += lib/extensions/fpmr/fpmr.c
endif
ifeq (${WORKAROUND_CVE_2017_5715},1)
BL31_SOURCES += lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S \
lib/cpus/aarch64/wa_cve_2017_5715_mmu.S

View file

@ -280,6 +280,12 @@ static unsigned int read_feat_d128_id_field(void)
ID_AA64MMFR3_EL1_D128_MASK);
}
static unsigned int read_feat_fpmr_id_field(void)
{
return ISOLATE_FIELD(read_id_aa64pfr2_el1(), ID_AA64PFR2_EL1_FPMR_SHIFT,
ID_AA64PFR2_EL1_FPMR_MASK);
}
/***********************************************************************************
* TF-A supports many Arm architectural features starting from arch version
* (8.0 till 8.7+). These features are mostly enabled through build flags. This
@ -405,6 +411,8 @@ void detect_arch_features(void)
"SME", 1, 2);
check_feature(ENABLE_SME2_FOR_NS, read_feat_sme_id_field(),
"SME2", 2, 2);
check_feature(ENABLE_FEAT_FPMR, read_feat_fpmr_id_field(),
"FPMR", 1, 1);
/* v9.3 features */
check_feature(ENABLE_FEAT_D128, read_feat_d128_id_field(),

View file

@ -351,6 +351,12 @@ Common build options
This flag can take the values 0 to 2, to align with the ``ENABLE_FEAT``
mechanism. Default value is ``0``.
- ``ENABLE_FEAT_FPMR``: Numerical value to enable support for Floating Point
Mode Register feature, allowing access to the FPMR register. FPMR register
controls the behaviors of FP8 instructions. It is an optional architectural
feature from v9.2 and upwards. This flag can take value of 0 to 2, to align
with the ``FEATURE_DETECTION`` mechanism. Default value is ``0``.
- ``ENABLE_FEAT_FGT``: Numeric value to enable support for FGT (Fine Grain Traps)
feature allowing for access to the HDFGRTR_EL2 (Hypervisor Debug Fine-Grained
Read Trap Register) during EL2 to EL3 context save/restore operations.

View file

@ -465,6 +465,11 @@
#define ID_AA64PFR2_EL1_MTEFAR_SHIFT U(8)
#define ID_AA64PFR2_EL1_MTEFAR_MASK ULL(0xf)
#define ID_AA64PFR2_EL1_FPMR_SHIFT U(32)
#define ID_AA64PFR2_EL1_FPMR_MASK ULL(0xf)
#define FPMR_IMPLEMENTED ULL(0x1)
#define VDISR_EL2 S3_4_C12_C1_1
#define VSESR_EL2 S3_4_C5_C2_3
@ -605,6 +610,7 @@
#define SCR_NSE_SHIFT U(62)
#define SCR_FGTEN2_BIT (UL(1) << 59)
#define SCR_NSE_BIT (ULL(1) << SCR_NSE_SHIFT)
#define SCR_EnFPM_BIT (ULL(1) << 50)
#define SCR_GPF_BIT (UL(1) << 48)
#define SCR_D128En_BIT (UL(1) << 47)
#define SCR_TWEDEL_SHIFT U(30)
@ -1522,6 +1528,11 @@
******************************************************************************/
#define CLUSTERPWRDN_EL1 S3_0_c15_c3_6
/*******************************************************************************
* FEAT_FPMR - Floating point Mode Register
******************************************************************************/
#define FPMR S3_3_C4_C4_2
/* CLUSTERPWRDN_EL1 register definitions */
#define DSU_CLUSTER_PWR_OFF 0
#define DSU_CLUSTER_PWR_ON 1

View file

@ -142,6 +142,8 @@ CREATE_FEATURE_SUPPORTED(name, is_ ## name ## _present, guard)
* +----------------------------+
* | FEAT_LS64_ACCDATA |
* +----------------------------+
* | FEAT_FPMR |
* +----------------------------+
*/
__attribute__((always_inline))
@ -284,6 +286,12 @@ CREATE_FEATURE_FUNCS(feat_d128, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_D128_SHIFT,
ID_AA64MMFR3_EL1_D128_MASK, D128_IMPLEMENTED,
ENABLE_FEAT_D128)
/* FEAT_FPMR */
CREATE_FEATURE_FUNCS(feat_fpmr, id_aa64pfr2_el1, ID_AA64PFR2_EL1_FPMR_SHIFT,
ID_AA64PFR2_EL1_FPMR_MASK, FPMR_IMPLEMENTED,
ENABLE_FEAT_FPMR)
__attribute__((always_inline))
static inline bool is_feat_sxpie_supported(void)
{

View file

@ -718,6 +718,8 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(cpumpmmcr_el3, CPUMPMMCR_EL3)
DEFINE_RENAME_SYSREG_RW_FUNCS(gptbr_el3, GPTBR_EL3)
DEFINE_RENAME_SYSREG_RW_FUNCS(gpccr_el3, GPCCR_EL3)
DEFINE_RENAME_SYSREG_RW_FUNCS(fpmr, FPMR)
#define IS_IN_EL(x) \
(GET_EL(read_CurrentEl()) == MODE_EL##x)

View file

@ -0,0 +1,20 @@
/*
* Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef FPMR_H
#define FPMR_H
#include <context.h>
#if ENABLE_FEAT_FPMR
void fpmr_enable_per_world(per_world_context_t *per_world_ctx);
#else
static inline void fpmr_enable_per_world(per_world_context_t *per_world_ctx)
{
}
#endif /* ENABLE_FEAT_FPMR */
#endif /* FPMR_H */

View file

@ -28,6 +28,7 @@
#include <lib/extensions/brbe.h>
#include <lib/extensions/debug_v8p9.h>
#include <lib/extensions/fgt2.h>
#include <lib/extensions/fpmr.h>
#include <lib/extensions/mpam.h>
#include <lib/extensions/pmuv3.h>
#include <lib/extensions/sme.h>
@ -291,6 +292,13 @@ static void setup_ns_context(cpu_context_t *ctx, const struct entry_point_info *
scr_el3 |= SCR_D128En_BIT;
}
if (is_feat_fpmr_supported()) {
/* Set the EnFPM bit in SCR_EL3 to enable access to FPMR
* register.
*/
scr_el3 |= SCR_EnFPM_BIT;
}
write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
/* Initialize EL2 context registers */
@ -714,6 +722,10 @@ void manage_extensions_nonsecure_per_world(void)
if (is_feat_mpam_supported()) {
mpam_enable_per_world(&per_world_context[CPU_CONTEXT_NS]);
}
if (is_feat_fpmr_supported()) {
fpmr_enable_per_world(&per_world_context[CPU_CONTEXT_NS]);
}
}
#endif /* IMAGE_BL31 */

View file

@ -0,0 +1,20 @@
/*
* Copyright (c) 2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <arch_features.h>
#include <arch_helpers.h>
#include <lib/extensions/fpmr.h>
void fpmr_enable_per_world(per_world_context_t *per_world_ctx)
{
u_register_t reg;
/* Disable Floating point Trap in CPTR_EL3. */
reg = per_world_ctx->ctx_cptr_el3;
reg &= ~TFP_BIT;
per_world_ctx->ctx_cptr_el3 = reg;
}

View file

@ -408,6 +408,9 @@ ENABLE_SME_FOR_SWD ?= 0
# if FEAT_BRBE is implemented.
ENABLE_BRBE_FOR_NS ?= 0
# Flag to enable Floating point exception Mode Register Feature (FEAT_FPMR)
ENABLE_FEAT_FPMR ?= 0
#----
# 9.3
#----

View file

@ -57,6 +57,7 @@ endif
ENABLE_BRBE_FOR_NS := 2
ENABLE_TRBE_FOR_NS := 2
ENABLE_FEAT_D128 := 2
ENABLE_FEAT_FPMR := 2
endif
ENABLE_SYS_REG_TRACE_FOR_NS := 2