mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-08 05:43:53 +00:00
feat(pie/por): support permission indirection and overlay
Arm v8.9 introduces a series of features providing a new way to set memory permissions. Instead of directly encoding the permissions in the page tables the PTEs contain indexes into an array of permissions stored in system registers, allowing greater flexibility and density of encoding. Enable access to these features for EL2 and below, context switching the newly added EL2 registers as appropriate. Since all of FEAT_S[12]P[IO]E are separately discoverable we have separate build time options for enabling them, but note that there is overlap in the registers that they implement and the enable bit required for lower EL access. Change the FVP platform to default to handling them as dynamic options so the right decision can be made by the code at runtime. Signed-off-by: Mark Brown <broonie@kernel.org> Change-Id: Icf89e444e39e1af768739668b505661df18fb234
This commit is contained in:
parent
2237e562fd
commit
062b6c6bf2
10 changed files with 197 additions and 1 deletions
8
Makefile
8
Makefile
|
@ -1185,6 +1185,10 @@ $(eval $(call assert_numerics,\
|
|||
ENABLE_FEAT_RNG_TRAP \
|
||||
ENABLE_FEAT_SEL2 \
|
||||
ENABLE_FEAT_TCR2 \
|
||||
ENABLE_FEAT_S2PIE \
|
||||
ENABLE_FEAT_S1PIE \
|
||||
ENABLE_FEAT_S2POE \
|
||||
ENABLE_FEAT_S1POE \
|
||||
ENABLE_FEAT_VHE \
|
||||
ENABLE_MPAM_FOR_LOWER_ELS \
|
||||
ENABLE_RME \
|
||||
|
@ -1321,6 +1325,10 @@ $(eval $(call add_defines,\
|
|||
ENABLE_FEAT_CSV2_2 \
|
||||
ENABLE_FEAT_PAN \
|
||||
ENABLE_FEAT_TCR2 \
|
||||
ENABLE_FEAT_S2PIE \
|
||||
ENABLE_FEAT_S1PIE \
|
||||
ENABLE_FEAT_S2POE \
|
||||
ENABLE_FEAT_S1POE \
|
||||
FEATURE_DETECTION \
|
||||
TWED_DELAY \
|
||||
ENABLE_FEAT_TWED \
|
||||
|
|
|
@ -210,6 +210,14 @@ void detect_arch_features(void)
|
|||
/* v8.9 features */
|
||||
check_feature(ENABLE_FEAT_TCR2, read_feat_tcrx_id_field(),
|
||||
"TCR2", 1, 1);
|
||||
check_feature(ENABLE_FEAT_S2PIE, read_feat_s2pie_id_field(),
|
||||
"S2PIE", 1, 1);
|
||||
check_feature(ENABLE_FEAT_S1PIE, read_feat_s1pie_id_field(),
|
||||
"S1PIE", 1, 1);
|
||||
check_feature(ENABLE_FEAT_S2POE, read_feat_s2poe_id_field(),
|
||||
"S2POE", 1, 1);
|
||||
check_feature(ENABLE_FEAT_S1POE, read_feat_s1poe_id_field(),
|
||||
"S1POE", 1, 1);
|
||||
|
||||
/* v9.0 features */
|
||||
check_feature(ENABLE_BRBE_FOR_NS, read_feat_brbe_id_field(),
|
||||
|
|
|
@ -354,6 +354,26 @@ Common build options
|
|||
flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION``
|
||||
mechanism. Default value is ``0``.
|
||||
|
||||
- ``ENABLE_FEAT_S2PIE``: Numeric value to enable support for FEAT_S2PIE
|
||||
at EL2 and below, and context switch relevant registers. This flag
|
||||
can take the values 0 to 2, to align with the ``FEATURE_DETECTION``
|
||||
mechanism. Default value is ``0``.
|
||||
|
||||
- ``ENABLE_FEAT_S1PIE``: Numeric value to enable support for FEAT_S1PIE
|
||||
at EL2 and below, and context switch relevant registers. This flag
|
||||
can take the values 0 to 2, to align with the ``FEATURE_DETECTION``
|
||||
mechanism. Default value is ``0``.
|
||||
|
||||
- ``ENABLE_FEAT_S2POE``: Numeric value to enable support for FEAT_S2POE
|
||||
at EL2 and below, and context switch relevant registers. This flag
|
||||
can take the values 0 to 2, to align with the ``FEATURE_DETECTION``
|
||||
mechanism. Default value is ``0``.
|
||||
|
||||
- ``ENABLE_FEAT_S1POE``: Numeric value to enable support for FEAT_S1POE
|
||||
at EL2 and below, and context switch relevant registers. This flag
|
||||
can take the values 0 to 2, to align with the ``FEATURE_DETECTION``
|
||||
mechanism. Default value is ``0``.
|
||||
|
||||
- ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO)
|
||||
support in GCC for TF-A. This option is currently only supported for
|
||||
AArch64. Default is 0.
|
||||
|
|
|
@ -355,6 +355,18 @@
|
|||
/* ID_AA64MMFR3_EL1 definitions */
|
||||
#define ID_AA64MMFR3_EL1 S3_0_C0_C7_3
|
||||
|
||||
#define ID_AA64MMFR3_EL1_S2POE_SHIFT U(20)
|
||||
#define ID_AA64MMFR3_EL1_S2POE_MASK ULL(0xf)
|
||||
|
||||
#define ID_AA64MMFR3_EL1_S1POE_SHIFT U(16)
|
||||
#define ID_AA64MMFR3_EL1_S1POE_MASK ULL(0xf)
|
||||
|
||||
#define ID_AA64MMFR3_EL1_S2PIE_SHIFT U(12)
|
||||
#define ID_AA64MMFR3_EL1_S2PIE_MASK ULL(0xf)
|
||||
|
||||
#define ID_AA64MMFR3_EL1_S1PIE_SHIFT U(8)
|
||||
#define ID_AA64MMFR3_EL1_S1PIE_MASK ULL(0xf)
|
||||
|
||||
#define ID_AA64MMFR3_EL1_TCRX_SHIFT U(0)
|
||||
#define ID_AA64MMFR3_EL1_TCRX_MASK ULL(0xf)
|
||||
|
||||
|
@ -512,6 +524,7 @@
|
|||
#define SCR_GPF_BIT (UL(1) << 48)
|
||||
#define SCR_TWEDEL_SHIFT U(30)
|
||||
#define SCR_TWEDEL_MASK ULL(0xf)
|
||||
#define SCR_PIEN_BIT (UL(1) << 45)
|
||||
#define SCR_TCR2EN_BIT (UL(1) << 43)
|
||||
#define SCR_TRNDR_BIT (UL(1) << 40)
|
||||
#define SCR_HXEn_BIT (UL(1) << 38)
|
||||
|
@ -1320,6 +1333,15 @@
|
|||
******************************************************************************/
|
||||
#define TCR2_EL2 S3_4_C2_C0_3
|
||||
|
||||
/*******************************************************************************
|
||||
* Permission indirection and overlay
|
||||
******************************************************************************/
|
||||
|
||||
#define PIRE0_EL2 S3_4_C10_C2_2
|
||||
#define PIR_EL2 S3_4_C10_C2_3
|
||||
#define POR_EL2 S3_4_C10_C2_4
|
||||
#define S2PIR_EL2 S3_4_C10_C2_5
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions for DynamicIQ Shared Unit registers
|
||||
******************************************************************************/
|
||||
|
|
|
@ -234,6 +234,88 @@ static inline bool is_feat_tcr2_supported(void)
|
|||
return read_feat_tcrx_id_field() != 0U;
|
||||
}
|
||||
|
||||
static unsigned int read_feat_s2poe_id_field(void)
|
||||
{
|
||||
return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S2POE);
|
||||
}
|
||||
|
||||
static inline bool is_feat_s2poe_supported(void)
|
||||
{
|
||||
if (ENABLE_FEAT_S2POE == FEAT_STATE_DISABLED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ENABLE_FEAT_S2POE == FEAT_STATE_ALWAYS) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return read_feat_s2poe_id_field() != 0U;
|
||||
}
|
||||
|
||||
static unsigned int read_feat_s1poe_id_field(void)
|
||||
{
|
||||
return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S1POE);
|
||||
}
|
||||
|
||||
static inline bool is_feat_s1poe_supported(void)
|
||||
{
|
||||
if (ENABLE_FEAT_S1POE == FEAT_STATE_DISABLED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ENABLE_FEAT_S1POE == FEAT_STATE_ALWAYS) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return read_feat_s1poe_id_field() != 0U;
|
||||
}
|
||||
|
||||
static inline bool is_feat_sxpoe_supported(void)
|
||||
{
|
||||
return is_feat_s1poe_supported() || is_feat_s2poe_supported();
|
||||
}
|
||||
|
||||
static unsigned int read_feat_s2pie_id_field(void)
|
||||
{
|
||||
return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S2PIE);
|
||||
}
|
||||
|
||||
static inline bool is_feat_s2pie_supported(void)
|
||||
{
|
||||
if (ENABLE_FEAT_S2PIE == FEAT_STATE_DISABLED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ENABLE_FEAT_S2PIE == FEAT_STATE_ALWAYS) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return read_feat_s2pie_id_field() != 0U;
|
||||
}
|
||||
|
||||
static unsigned int read_feat_s1pie_id_field(void)
|
||||
{
|
||||
return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S1PIE);
|
||||
}
|
||||
|
||||
static inline bool is_feat_s1pie_supported(void)
|
||||
{
|
||||
if (ENABLE_FEAT_S1PIE == FEAT_STATE_DISABLED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ENABLE_FEAT_S1PIE == FEAT_STATE_ALWAYS) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return read_feat_s1pie_id_field() != 0U;
|
||||
}
|
||||
|
||||
static inline bool is_feat_sxpie_supported(void)
|
||||
{
|
||||
return is_feat_s1pie_supported() || is_feat_s2pie_supported();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Functions to identify the presence of the Activity Monitors Extension
|
||||
******************************************************************************/
|
||||
|
|
|
@ -605,6 +605,14 @@ DEFINE_RENAME_IDREG_READ_FUNC(id_aa64mmfr3_el1, ID_AA64MMFR3_EL1)
|
|||
/* FEAT_TCR2 Register */
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(tcr2_el2, TCR2_EL2)
|
||||
|
||||
/* FEAT_SxPIE Registers */
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(pire0_el2, PIRE0_EL2)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(pir_el2, PIR_EL2)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(s2pir_el2, S2PIR_EL2)
|
||||
|
||||
/* FEAT_SxPOE Registers */
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(por_el2, POR_EL2)
|
||||
|
||||
/* DynamIQ Shared Unit power management */
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1)
|
||||
|
||||
|
|
|
@ -230,9 +230,13 @@
|
|||
|
||||
// Starting with Armv8.9
|
||||
#define CTX_TCR2_EL2 U(0x1d8)
|
||||
#define CTX_POR_EL2 U(0x1e0)
|
||||
#define CTX_PIRE0_EL2 U(0x1e8)
|
||||
#define CTX_PIR_EL2 U(0x1f0)
|
||||
#define CTX_S2PIR_EL2 U(0x1f8)
|
||||
|
||||
/* Align to the next 16 byte boundary */
|
||||
#define CTX_EL2_SYSREGS_END U(0x1e0)
|
||||
#define CTX_EL2_SYSREGS_END U(0x200)
|
||||
|
||||
#endif /* CTX_INCLUDE_EL2_REGS */
|
||||
|
||||
|
|
|
@ -354,6 +354,14 @@ static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *e
|
|||
scr_el3 |= SCR_TCR2EN_BIT;
|
||||
}
|
||||
|
||||
/*
|
||||
* SCR_EL3.PIEN: Enable permission indirection and overlay
|
||||
* registers for AArch64 if present.
|
||||
*/
|
||||
if (is_feat_sxpie_supported() || is_feat_sxpoe_supported()) {
|
||||
scr_el3 |= SCR_PIEN_BIT;
|
||||
}
|
||||
|
||||
/*
|
||||
* CPTR_EL3 was initialized out of reset, copy that value to the
|
||||
* context register.
|
||||
|
@ -994,6 +1002,16 @@ void cm_el2_sysregs_context_save(uint32_t security_state)
|
|||
if (is_feat_tcr2_supported()) {
|
||||
write_ctx_reg(el2_sysregs_ctx, CTX_TCR2_EL2, read_tcr2_el2());
|
||||
}
|
||||
if (is_feat_sxpie_supported()) {
|
||||
write_ctx_reg(el2_sysregs_ctx, CTX_PIRE0_EL2, read_pire0_el2());
|
||||
write_ctx_reg(el2_sysregs_ctx, CTX_PIR_EL2, read_pir_el2());
|
||||
}
|
||||
if (is_feat_s2pie_supported()) {
|
||||
write_ctx_reg(el2_sysregs_ctx, CTX_S2PIR_EL2, read_s2pir_el2());
|
||||
}
|
||||
if (is_feat_sxpoe_supported()) {
|
||||
write_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2, read_por_el2());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1061,6 +1079,16 @@ void cm_el2_sysregs_context_restore(uint32_t security_state)
|
|||
if (is_feat_tcr2_supported()) {
|
||||
write_tcr2_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TCR2_EL2));
|
||||
}
|
||||
if (is_feat_sxpie_supported()) {
|
||||
write_pire0_el2(read_ctx_reg(el2_sysregs_ctx, CTX_PIRE0_EL2));
|
||||
write_pir_el2(read_ctx_reg(el2_sysregs_ctx, CTX_PIR_EL2));
|
||||
}
|
||||
if (is_feat_s2pie_supported()) {
|
||||
write_s2pir_el2(read_ctx_reg(el2_sysregs_ctx, CTX_S2PIR_EL2));
|
||||
}
|
||||
if (is_feat_sxpoe_supported()) {
|
||||
write_por_el2(read_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* CTX_INCLUDE_EL2_REGS */
|
||||
|
|
|
@ -176,6 +176,18 @@ ENABLE_FEAT_TWED := 0
|
|||
# Flag to enable access to TCR2 (FEAT_TCR2)
|
||||
ENABLE_FEAT_TCR2 := 0
|
||||
|
||||
# Flag to enable access to Stage 2 Permission Indirection (FEAT_S2PIE)
|
||||
ENABLE_FEAT_S2PIE := 0
|
||||
|
||||
# Flag to enable access to Stage 1 Permission Indirection (FEAT_S1PIE)
|
||||
ENABLE_FEAT_S1PIE := 0
|
||||
|
||||
# Flag to enable access to Stage 2 Permission Overlay (FEAT_S2POE)
|
||||
ENABLE_FEAT_S2POE := 0
|
||||
|
||||
# Flag to enable access to Stage 1 Permission Overlay (FEAT_S1POE)
|
||||
ENABLE_FEAT_S1POE := 0
|
||||
|
||||
# By default BL31 encryption disabled
|
||||
ENCRYPT_BL31 := 0
|
||||
|
||||
|
|
|
@ -77,6 +77,10 @@ ENABLE_TRF_FOR_NS := 2
|
|||
ENABLE_FEAT_ECV := 2
|
||||
ENABLE_FEAT_FGT := 2
|
||||
ENABLE_FEAT_TCR2 := 2
|
||||
ENABLE_FEAT_S2PIE := 2
|
||||
ENABLE_FEAT_S1PIE := 2
|
||||
ENABLE_FEAT_S2POE := 2
|
||||
ENABLE_FEAT_S1POE := 2
|
||||
endif
|
||||
|
||||
# The FVP platform depends on this macro to build with correct GIC driver.
|
||||
|
|
Loading…
Add table
Reference in a new issue