From dc0ca64e4b6c86090eee025293e7ae7f1fe1cf12 Mon Sep 17 00:00:00 2001 From: Javier Almansa Sobrino Date: Thu, 1 Dec 2022 17:20:45 +0000 Subject: [PATCH] fix(rmmd): add missing padding to RMM Boot Manifest and initialize it This patch also: * Enforces the check of RES0 fields on EL3-RMM boot interface and manifest * Fixes a couple of nits on the EL3-RMM Boot Interface documentation. Signed-off-by: Javier Almansa Sobrino Change-Id: Idb9e38f9fcda2ba0655646a1e2c4fdbabd5cdc40 --- docs/components/rmm-el3-comms-spec.rst | 6 +++--- include/services/rmm_core_manifest.h | 1 + plat/arm/board/fvp/fvp_common.c | 1 + plat/arm/common/trp/arm_trp_setup.c | 3 +++ services/std_svc/rmmd/trp/trp_entry.S | 10 ++++++++++ services/std_svc/rmmd/trp/trp_main.c | 18 ++++++++++++++++++ services/std_svc/rmmd/trp/trp_private.h | 4 ++++ 7 files changed, 40 insertions(+), 3 deletions(-) diff --git a/docs/components/rmm-el3-comms-spec.rst b/docs/components/rmm-el3-comms-spec.rst index 8070ff446..25c426970 100644 --- a/docs/components/rmm-el3-comms-spec.rst +++ b/docs/components/rmm-el3-comms-spec.rst @@ -101,7 +101,7 @@ During cold boot RMM expects the following register values: x2,Maximum number of CPUs to be supported at runtime. RMM should ensure that it can support this maximum number. x3,Base address for the shared buffer used for communication between EL3 firmware and RMM. This buffer must be of 4KB size (1 page). The boot manifest must be present at the base of this shared buffer during cold boot. -During cold boot, EL3 firmware needs to allocate a 4K page that will be +During cold boot, EL3 firmware needs to allocate a 4KB page that will be passed to RMM in x3. This memory will be used as shared buffer for communication between EL3 and RMM. It must be assigned to Realm world and must be mapped with Normal memory attributes (IWB-OWB-ISH) at EL3. At boot, this memory will be @@ -522,8 +522,8 @@ _____ .. _rmm_el3_manifest_struct: -RMM-EL3 Boot Manifest Version -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +RMM-EL3 Boot Manifest structure +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The RMM-EL3 Boot Manifest structure contains platform boot information passed from EL3 to RMM. The width of the Boot Manifest is 128 bits diff --git a/include/services/rmm_core_manifest.h b/include/services/rmm_core_manifest.h index 2f2585860..7edef469b 100644 --- a/include/services/rmm_core_manifest.h +++ b/include/services/rmm_core_manifest.h @@ -38,6 +38,7 @@ /* Boot manifest core structure as per v0.1 */ typedef struct rmm_manifest { uint32_t version; /* Manifest version */ + uint32_t padding; /* RES0 */ uintptr_t plat_data; /* Manifest platform data */ } rmm_manifest_t; diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index f8463f14c..f5d9940f0 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -536,6 +536,7 @@ int plat_rmmd_load_manifest(rmm_manifest_t *manifest) assert(manifest != NULL); manifest->version = RMMD_MANIFEST_VERSION; + manifest->padding = 0U; /* RES0 */ manifest->plat_data = (uintptr_t)NULL; return 0; diff --git a/plat/arm/common/trp/arm_trp_setup.c b/plat/arm/common/trp/arm_trp_setup.c index 59b4c06e9..aeacd1054 100644 --- a/plat/arm/common/trp/arm_trp_setup.c +++ b/plat/arm/common/trp/arm_trp_setup.c @@ -28,6 +28,9 @@ static console_t arm_trp_runtime_console; static int arm_trp_process_manifest(rmm_manifest_t *manifest) { + /* padding field on the manifest must be RES0 */ + assert(manifest->padding == 0U); + /* Verify the Boot Manifest Version. Only the Major is considered */ if (RMMD_MANIFEST_VERSION_MAJOR != RMMD_GET_MANIFEST_VERSION_MAJOR(manifest->version)) { diff --git a/services/std_svc/rmmd/trp/trp_entry.S b/services/std_svc/rmmd/trp/trp_entry.S index 47c1df14d..ef3024daf 100644 --- a/services/std_svc/rmmd/trp/trp_entry.S +++ b/services/std_svc/rmmd/trp/trp_entry.S @@ -83,7 +83,17 @@ trp_head: mov x3, x23 bl trp_setup bl trp_main + b 1f + warm_boot: + mov x0, x20 + mov x1, x21 + mov x2, x22 + mov x3, x23 + bl trp_validate_warmboot_args + cbnz x0, trp_panic /* Failed to validate warmboot args */ + +1: mov_imm x0, RMM_BOOT_COMPLETE mov x1, xzr /* RMM_BOOT_SUCCESS */ smc #0 diff --git a/services/std_svc/rmmd/trp/trp_main.c b/services/std_svc/rmmd/trp/trp_main.c index 5a56af043..b0a1c0929 100644 --- a/services/std_svc/rmmd/trp/trp_main.c +++ b/services/std_svc/rmmd/trp/trp_main.c @@ -66,6 +66,24 @@ void trp_setup(uint64_t x0, trp_early_platform_setup((rmm_manifest_t *)trp_shared_region_start); } +int trp_validate_warmboot_args(uint64_t x0, uint64_t x1, + uint64_t x2, uint64_t x3) +{ + /* + * Validate boot parameters for warm boot + * + * According to the Boot Interface ABI v.0.1, the parameters + * received from EL3 during warm boot are: + * + * x0: CPUID (verified earlier so not used here) + * [x1:x3]: RES0 + */ + + (void)x0; + + return ((x1 | x2 | x3) == 0UL) ? 0 : E_RMM_BOOT_UNKNOWN; +} + /* Main function for TRP */ void trp_main(void) { diff --git a/services/std_svc/rmmd/trp/trp_private.h b/services/std_svc/rmmd/trp/trp_private.h index 945ae1c89..d8c69603b 100644 --- a/services/std_svc/rmmd/trp/trp_private.h +++ b/services/std_svc/rmmd/trp/trp_private.h @@ -53,5 +53,9 @@ void trp_setup(uint64_t x0, uint64_t x2, uint64_t x3); +/* Validate arguments for warm boot only */ +int trp_validate_warmboot_args(uint64_t x0, uint64_t x1, + uint64_t x2, uint64_t x3); + #endif /* __ASSEMBLER__ */ #endif /* TRP_PRIVATE_H */