Merge "fix(spmd): check pwr mgmt status for SPMC framework response" into integration

This commit is contained in:
Olivier Deprez 2025-04-04 15:40:32 +02:00 committed by TrustedFirmware Code Review
commit 8ed1e20b70
4 changed files with 57 additions and 14 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2024, Arm Limited. All rights reserved.
* Copyright (c) 2020-2025, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -57,8 +57,8 @@
<< FFA_MSG_SEND_ATTRS_BLK_SHIFT)
/* Defines for FF-A framework messages exchanged using direct messages. */
#define FFA_FWK_MSG_BIT BIT(31)
#define FFA_FWK_MSG_MASK 0xFF
#define FFA_FWK_MSG_BIT BIT_32(31)
#define FFA_FWK_MSG_MASK U(0xFF)
#define FFA_FWK_MSG_PSCI U(0x0)
/* Defines for FF-A power management messages framework messages. */

View file

@ -888,11 +888,15 @@ uint64_t spmd_smc_handler(uint32_t smc_fid,
}
/*
* If there was an SPMD logical partition direct request on-going,
* Perform a synchronous exit:
* 1. If there was an SPMD logical partition direct request on-going,
* return back to the SPMD logical partition so the error can be
* consumed.
* 2. SPMC sent FFA_ERROR in response to a power management
* operation sent through direct request.
*/
if (is_spmd_logical_sp_dir_req_in_progress(ctx)) {
if (is_spmd_logical_sp_dir_req_in_progress(ctx) ||
ctx->psci_operation_ongoing) {
assert(secure_origin);
spmd_spm_core_sync_exit(0ULL);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2020-2025, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -117,6 +117,8 @@ static int32_t spmd_cpu_off_handler(u_register_t unused)
spmd_spm_core_context_t *ctx = spmd_get_context();
unsigned int linear_id = plat_my_core_pos();
int64_t rc;
uint32_t ffa_resp_func_id, msg_flags;
int status;
assert(ctx != NULL);
assert(ctx->state != SPMC_STATE_OFF);
@ -137,24 +139,60 @@ static int32_t spmd_cpu_off_handler(u_register_t unused)
write_ctx_reg(gpregs, CTX_GPREG_X16, 0);
write_ctx_reg(gpregs, CTX_GPREG_X17, 0);
/* Mark current core as processing a PSCI operation. */
ctx->psci_operation_ongoing = true;
rc = spmd_spm_core_sync_entry(ctx);
if (rc != 0ULL) {
ERROR("%s failed (%" PRIu64 ") on CPU%u\n", __func__, rc, linear_id);
}
ctx->psci_operation_ongoing = false;
/* Expect a direct message response from the SPMC. */
u_register_t ffa_resp_func = read_ctx_reg(get_gpregs_ctx(&ctx->cpu_ctx),
ffa_resp_func_id = (uint32_t)read_ctx_reg(get_gpregs_ctx(&ctx->cpu_ctx),
CTX_GPREG_X0);
if (ffa_resp_func != FFA_MSG_SEND_DIRECT_RESP_SMC32) {
ERROR("%s invalid SPMC response (%lx).\n",
__func__, ffa_resp_func);
return -EINVAL;
/*
* Retrieve flags indicating framework message and power management
* response.
*/
msg_flags = (uint32_t)read_ctx_reg(get_gpregs_ctx(&ctx->cpu_ctx),
CTX_GPREG_X2);
/* Retrieve error code indicating status of power management operation. */
status = (int)read_ctx_reg(get_gpregs_ctx(&ctx->cpu_ctx),
CTX_GPREG_X3);
if (ffa_resp_func_id == FFA_ERROR) {
/*
* It is likely that SPMC does not support receiving PSCI
* operation through framework message. SPMD takes an
* implementation defined choice to not treat it as a fatal
* error. Consequently, SPMD ignores the error and continues
* with power management operation.
*/
VERBOSE("SPMC ignored PSCI CPU_OFF framework message\n");
} else if (ffa_resp_func_id != FFA_MSG_SEND_DIRECT_RESP_SMC32) {
ERROR("%s invalid SPMC response (%x).\n",
__func__, ffa_resp_func_id);
panic();
} else if (((msg_flags & FFA_FWK_MSG_BIT) == 0U) ||
((msg_flags & FFA_FWK_MSG_MASK) != FFA_PM_MSG_PM_RESP)) {
ERROR("SPMC failed to send framework message response for power"
" management operation, message flags = (%x)\n",
msg_flags);
panic();
} else if (status != PSCI_E_SUCCESS) {
ERROR("SPMC denied CPU_OFF power management request\n");
panic();
} else {
VERBOSE("CPU %u off!\n", linear_id);
}
ctx->state = SPMC_STATE_OFF;
VERBOSE("CPU %u off!\n", linear_id);
return 0;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2023, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2019-2025, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -52,6 +52,7 @@ typedef struct spmd_spm_core_context {
cpu_context_t cpu_ctx;
spmc_state_t state;
bool secure_interrupt_ongoing;
bool psci_operation_ongoing;
#if ENABLE_SPMD_LP
uint8_t spmd_lp_sync_req_ongoing;
#endif