diff options
author | Olivier Deprez <olivier.deprez@arm.com> | 2023-05-03 18:15:40 +0200 |
---|---|---|
committer | TrustedFirmware Code Review <review@review.trustedfirmware.org> | 2023-05-03 18:15:40 +0200 |
commit | 17f9732da56df0b991351723b187ce3d57017091 (patch) | |
tree | e1cfffdaab70b03742a8cc5b3b261f7b7efb8766 | |
parent | 73ede2bf1914929f0842560f01b6d996d4196ef1 (diff) | |
parent | e60172911943b3c20817c3db8d12cd75e17804d5 (diff) | |
download | arm-trusted-firmware-17f9732da56df0b991351723b187ce3d57017091.tar.gz |
Merge changes from topic "mp/group0_support" into integration
* changes:
docs(spm): support for handling Group0 interrupts
feat(spmd): introduce platform handler for Group0 interrupt
feat(spmd): add support for FFA_EL3_INTR_HANDLE_32 ABI
feat(spmd): register handler for group0 interrupt from NWd
-rw-r--r-- | docs/components/secure-partition-manager.rst | 21 | ||||
-rw-r--r-- | include/services/ffa_svc.h | 6 | ||||
-rw-r--r-- | plat/arm/board/corstone1000/common/corstone1000_bl31_setup.c | 18 | ||||
-rw-r--r-- | plat/arm/board/corstone1000/platform.mk | 1 | ||||
-rw-r--r-- | plat/arm/board/fvp/fvp_spmd.c | 17 | ||||
-rw-r--r-- | plat/arm/board/fvp/platform.mk | 4 | ||||
-rw-r--r-- | plat/arm/board/n1sdp/n1sdp_bl31_setup.c | 11 | ||||
-rw-r--r-- | plat/hisilicon/hikey960/hikey960_bl31_setup.c | 11 | ||||
-rw-r--r-- | plat/qemu/common/qemu_common.c | 13 | ||||
-rw-r--r-- | services/std_svc/spmd/spmd_main.c | 84 | ||||
-rw-r--r-- | services/std_svc/spmd/spmd_private.h | 9 |
11 files changed, 189 insertions, 6 deletions
diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst index f0caf89f7..8dc1c6136 100644 --- a/docs/components/secure-partition-manager.rst +++ b/docs/components/secure-partition-manager.rst @@ -1318,6 +1318,25 @@ A brief description of the events: direct request to SP2 by invoking FFA_RUN. - 9) SPMC resumes the pre-empted vCPU of SP2. +EL3 interrupt handling +~~~~~~~~~~~~~~~~~~~~~~ + +In GICv3 based systems, EL3 interrupts are configured as Group0 secure +interrupts. Execution traps to SPMC when a Group0 interrupt triggers while an +SP is running. Further, SPMC running at S-EL2 uses FFA_EL3_INTR_HANDLE ABI to +request EL3 platform firmware to handle a pending Group0 interrupt. +Similarly, SPMD registers a handler with interrupt management framework to +delegate handling of Group0 interrupt to the platform if the interrupt triggers +in normal world. + + - Platform hook + + - plat_spmd_handle_group0_interrupt + + SPMD provides platform hook to handle Group0 secure interrupts. In the + current design, SPMD expects the platform not to delegate handling to the + NWd (such as through SDEI) while processing Group0 interrupts. + Power management ---------------- @@ -1557,4 +1576,4 @@ Client <https://developer.arm.com/documentation/den0006/d/>`__ -------------- -*Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.* diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h index 8bc911a68..64af437bb 100644 --- a/include/services/ffa_svc.h +++ b/include/services/ffa_svc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022, Arm Limited. All rights reserved. + * Copyright (c) 2020-2023, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -24,7 +24,7 @@ /* The macros below are used to identify FFA calls from the SMC function ID */ #define FFA_FNUM_MIN_VALUE U(0x60) -#define FFA_FNUM_MAX_VALUE U(0x8B) +#define FFA_FNUM_MAX_VALUE U(0x8C) #define is_ffa_fid(fid) __extension__ ({ \ __typeof__(fid) _fid = (fid); \ ((GET_SMC_NUM(_fid) >= FFA_FNUM_MIN_VALUE) && \ @@ -118,6 +118,7 @@ #define FFA_FNUM_MSG_SEND2 U(0x86) #define FFA_FNUM_SECONDARY_EP_REGISTER U(0x87) #define FFA_FNUM_PARTITION_INFO_GET_REGS U(0x8B) +#define FFA_FNUM_EL3_INTR_HANDLE U(0x8C) /* FFA SMC32 FIDs */ #define FFA_ERROR FFA_FID(SMC_32, FFA_FNUM_ERROR) @@ -163,6 +164,7 @@ #define FFA_MEM_FRAG_TX FFA_FID(SMC_32, FFA_FNUM_MEM_FRAG_TX) #define FFA_SPM_ID_GET FFA_FID(SMC_32, FFA_FNUM_SPM_ID_GET) #define FFA_NORMAL_WORLD_RESUME FFA_FID(SMC_32, FFA_FNUM_NORMAL_WORLD_RESUME) +#define FFA_EL3_INTR_HANDLE FFA_FID(SMC_32, FFA_FNUM_EL3_INTR_HANDLE) /* FFA SMC64 FIDs */ #define FFA_ERROR_SMC64 FFA_FID(SMC_64, FFA_FNUM_ERROR) diff --git a/plat/arm/board/corstone1000/common/corstone1000_bl31_setup.c b/plat/arm/board/corstone1000/common/corstone1000_bl31_setup.c new file mode 100644 index 000000000..b6765a60e --- /dev/null +++ b/plat/arm/board/corstone1000/common/corstone1000_bl31_setup.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdint.h> + +#if defined(SPD_spmd) +/* + * A dummy implementation of the platform handler for Group0 secure interrupt. + */ +int plat_spmd_handle_group0_interrupt(uint32_t intid) +{ + (void)intid; + return -1; +} +#endif /*defined(SPD_spmd)*/ diff --git a/plat/arm/board/corstone1000/platform.mk b/plat/arm/board/corstone1000/platform.mk index d89169142..3edffe087 100644 --- a/plat/arm/board/corstone1000/platform.mk +++ b/plat/arm/board/corstone1000/platform.mk @@ -56,6 +56,7 @@ BL31_SOURCES += drivers/cfi/v2m/v2m_flash.c \ plat/arm/board/corstone1000/common/corstone1000_security.c \ plat/arm/board/corstone1000/common/corstone1000_plat.c \ plat/arm/board/corstone1000/common/corstone1000_pm.c \ + plat/arm/board/corstone1000/common/corstone1000_bl31_setup.c \ ${CORSTONE1000_CPU_LIBS} \ ${CORSTONE1000_GIC_SOURCES} diff --git a/plat/arm/board/fvp/fvp_spmd.c b/plat/arm/board/fvp/fvp_spmd.c new file mode 100644 index 000000000..8213e5ea4 --- /dev/null +++ b/plat/arm/board/fvp/fvp_spmd.c @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdint.h> + +int plat_spmd_handle_group0_interrupt(uint32_t intid) +{ + /* + * As of now, there are no sources of Group0 secure interrupt enabled + * for FVP. + */ + (void)intid; + return -1; +} diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index cc6a96a67..ea3f95486 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -512,3 +512,7 @@ ifeq (${PLATFORM_TEST_EA_FFH}, 1) endif BL31_SOURCES += plat/arm/board/fvp/aarch64/fvp_ea.c endif + +ifeq (${SPD},spmd) +BL31_SOURCES += plat/arm/board/fvp/fvp_spmd.c +endif diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c index 4941a4bd4..6809541a6 100644 --- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c +++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c @@ -159,3 +159,14 @@ void bl31_platform_setup(void) if ((plat_info.multichip_mode) && (plat_info.remote_ddr_size != 0)) remote_dmc_ecc_setup(plat_info.remote_ddr_size); } + +#if defined(SPD_spmd) +/* + * A dummy implementation of the platform handler for Group0 secure interrupt. + */ +int plat_spmd_handle_group0_interrupt(uint32_t intid) +{ + (void)intid; + return -1; +} +#endif /*defined(SPD_spmd)*/ diff --git a/plat/hisilicon/hikey960/hikey960_bl31_setup.c b/plat/hisilicon/hikey960/hikey960_bl31_setup.c index 50751ee38..1d7bc94a6 100644 --- a/plat/hisilicon/hikey960/hikey960_bl31_setup.c +++ b/plat/hisilicon/hikey960/hikey960_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -245,6 +245,15 @@ static uint64_t hikey_debug_fiq_handler(uint32_t id, return 0; } +#elif defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1) +/* + * A dummy implementation of the platform handler for Group0 secure interrupt. + */ +int plat_spmd_handle_group0_interrupt(uint32_t intid) +{ + (void)intid; + return -1; +} #endif void bl31_plat_runtime_setup(void) diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c index 935ba7a77..9aec213d2 100644 --- a/plat/qemu/common/qemu_common.c +++ b/plat/qemu/common/qemu_common.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -162,3 +162,14 @@ int plat_spmc_shmem_reclaim(struct ffa_mtd *desc) return 0; } #endif + +#if defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1) +/* + * A dummy implementation of the platform handler for Group0 secure interrupt. + */ +int plat_spmd_handle_group0_interrupt(uint32_t intid) +{ + (void)intid; + return -1; +} +#endif /*defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1)*/ diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 0e1899ede..80b506bc6 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -249,6 +249,74 @@ static uint64_t spmd_secure_interrupt_handler(uint32_t id, SMC_RET0(&ctx->cpu_ctx); } +/******************************************************************************* + * spmd_group0_interrupt_handler_nwd + * Group0 secure interrupt in the normal world are trapped to EL3. Delegate the + * handling of the interrupt to the platform handler, and return only upon + * successfully handling the Group0 interrupt. + ******************************************************************************/ +static uint64_t spmd_group0_interrupt_handler_nwd(uint32_t id, + uint32_t flags, + void *handle, + void *cookie) +{ + uint32_t intid; + + /* Sanity check the security state when the exception was generated. */ + assert(get_interrupt_src_ss(flags) == NON_SECURE); + + /* Sanity check the pointer to this cpu's context. */ + assert(handle == cm_get_context(NON_SECURE)); + + assert(id == INTR_ID_UNAVAILABLE); + + assert(plat_ic_get_pending_interrupt_type() == INTR_TYPE_EL3); + + intid = plat_ic_get_pending_interrupt_id(); + + if (plat_spmd_handle_group0_interrupt(intid) < 0) { + ERROR("Group0 interrupt %u not handled\n", intid); + panic(); + } + + return 0U; +} + +/******************************************************************************* + * spmd_handle_group0_intr_swd + * SPMC delegates handling of Group0 secure interrupt to EL3 firmware using + * FFA_EL3_INTR_HANDLE SMC call. Further, SPMD delegates the handling of the + * interrupt to the platform handler, and returns only upon successfully + * handling the Group0 interrupt. + ******************************************************************************/ +static uint64_t spmd_handle_group0_intr_swd(void *handle) +{ + uint32_t intid; + + /* Sanity check the pointer to this cpu's context */ + assert(handle == cm_get_context(SECURE)); + + assert(plat_ic_get_pending_interrupt_type() == INTR_TYPE_EL3); + + intid = plat_ic_get_pending_interrupt_id(); + + /* + * TODO: Currently due to a limitation in SPMD implementation, the + * platform handler is expected to not delegate handling to NWd while + * processing Group0 secure interrupt. + */ + if (plat_spmd_handle_group0_interrupt(intid) < 0) { + /* Group0 interrupt was not handled by the platform. */ + ERROR("Group0 interrupt %u not handled\n", intid); + panic(); + } + + /* Return success. */ + SMC_RET8(handle, FFA_SUCCESS_SMC32, FFA_PARAM_MBZ, FFA_PARAM_MBZ, + FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, + FFA_PARAM_MBZ); +} + #if ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31 static int spmd_dynamic_map_mem(uintptr_t base_addr, size_t size, unsigned int attr, uintptr_t *align_addr, @@ -492,6 +560,16 @@ static int spmd_spmc_init(void *pm_addr) panic(); } + /* + * Register an interrupt handler routing Group0 interrupts to SPMD + * while the NWd is running. + */ + rc = register_interrupt_type_handler(INTR_TYPE_EL3, + spmd_group0_interrupt_handler_nwd, + flags); + if (rc != 0) { + panic(); + } return 0; } @@ -1089,6 +1167,12 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, handle, flags); break; /* Not reached */ #endif + case FFA_EL3_INTR_HANDLE: + if (secure_origin) { + return spmd_handle_group0_intr_swd(handle); + } else { + return spmd_ffa_error_return(handle, FFA_ERROR_DENIED); + } default: WARN("SPM: Unsupported call 0x%08x\n", smc_fid); return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED); diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h index d21a622fd..ff6942e41 100644 --- a/services/std_svc/spmd/spmd_private.h +++ b/services/std_svc/spmd/spmd_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2023, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -93,6 +93,13 @@ spmd_spm_core_context_t *spmd_get_context(void); int spmd_pm_secondary_ep_register(uintptr_t entry_point); bool spmd_check_address_in_binary_image(uint64_t address); +/* + * Platform hook in EL3 firmware to handle for Group0 secure interrupt. + * Return values: + * 0 = success + * otherwise it returns a negative value + */ +int plat_spmd_handle_group0_interrupt(uint32_t id); #endif /* __ASSEMBLER__ */ #endif /* SPMD_PRIVATE_H */ |