From 5e92be5121e8ecd81a0f89eaae0d1a7ac8f4bfd7 Mon Sep 17 00:00:00 2001 From: Naman Trivedi Manojbhai Date: Tue, 7 Mar 2023 12:41:11 +0530 Subject: [PATCH] fix(xilinx): handle CRC failure in IPI Currently, if CRC validation fails during IPI communication, pm_ipi_buff_read() logs error message but don't return error code to upper layers. Added CRC failure specific error code which will be returned by pm_ipi_buff_read() if CRC validation fails. Signed-off-by: Naman Trivedi Manojbhai Change-Id: I33be330f276973471f4ce4115d1e1609ed8fb754 --- plat/xilinx/common/pm_service/pm_ipi.c | 11 ++++++++++- plat/xilinx/versal/pm_service/pm_defs.h | 4 ++++ plat/xilinx/zynqmp/pm_service/pm_defs.h | 3 +++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c index a3c3a6f23..81f1939f4 100644 --- a/plat/xilinx/common/pm_service/pm_ipi.c +++ b/plat/xilinx/common/pm_service/pm_ipi.c @@ -136,7 +136,9 @@ static enum pm_ret_status pm_ipi_buff_read(const struct pm_proc *proc, uint32_t *value, size_t count) { size_t i; + enum pm_ret_status ret; #if IPI_CRC_CHECK + uint32_t *payload_ptr = value; size_t j; uint32_t response_payload[PAYLOAD_ARG_CNT]; #endif @@ -155,6 +157,8 @@ static enum pm_ret_status pm_ipi_buff_read(const struct pm_proc *proc, *value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE)); value++; } + + ret = mmio_read_32(buffer_base); #if IPI_CRC_CHECK for (j = 0; j < PAYLOAD_ARG_CNT; j++) { response_payload[j] = mmio_read_32(buffer_base + @@ -165,10 +169,15 @@ static enum pm_ret_status pm_ipi_buff_read(const struct pm_proc *proc, calculate_crc(response_payload, IPI_W0_TO_W6_SIZE)) { NOTICE("ERROR in CRC response payload value:0x%x\n", response_payload[PAYLOAD_CRC_POS]); + ret = PM_RET_ERROR_INVALID_CRC; + /* Payload data is invalid as CRC validation failed + * Clear the payload to avoid leakage of data to upper layers + */ + memset(payload_ptr, 0, count); } #endif - return mmio_read_32(buffer_base); + return ret; } /** diff --git a/plat/xilinx/versal/pm_service/pm_defs.h b/plat/xilinx/versal/pm_service/pm_defs.h index 2922b5dd0..dbc801c66 100644 --- a/plat/xilinx/versal/pm_service/pm_defs.h +++ b/plat/xilinx/versal/pm_service/pm_defs.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved. + * Copyright (c) 2022-2023, Advanced Micro Devices Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -115,11 +116,13 @@ typedef enum { XPM_SUBSYSID_MAX, } XPm_SubsystemId; +/* TODO: move pm_ret_status from device specific location to common location */ /** * @PM_RET_SUCCESS: success * @PM_RET_ERROR_ARGS: illegal arguments provided (deprecated) * @PM_RET_ERROR_NOTSUPPORTED: feature not supported (deprecated) * @PM_RET_ERROR_NOFEATURE: feature is not available + * @PM_RET_ERROR_INVALID_CRC: invalid crc in IPI communication * @PM_RET_ERROR_INTERNAL: internal error * @PM_RET_ERROR_CONFLICT: conflict * @PM_RET_ERROR_ACCESS: access rights violation @@ -134,6 +137,7 @@ enum pm_ret_status { PM_RET_ERROR_ARGS = 1, PM_RET_ERROR_NOTSUPPORTED = 4, PM_RET_ERROR_NOFEATURE = 19, + PM_RET_ERROR_INVALID_CRC = 301, PM_RET_ERROR_INTERNAL = 2000, PM_RET_ERROR_CONFLICT = 2001, PM_RET_ERROR_ACCESS = 2002, diff --git a/plat/xilinx/zynqmp/pm_service/pm_defs.h b/plat/xilinx/zynqmp/pm_service/pm_defs.h index 008cfdc90..f00ab4b1c 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_defs.h +++ b/plat/xilinx/zynqmp/pm_service/pm_defs.h @@ -243,11 +243,13 @@ enum pm_opchar_type { PM_OPCHAR_TYPE_LATENCY, }; +/* TODO: move pm_ret_status from device specific location to common location */ /** * @PM_RET_SUCCESS: success * @PM_RET_ERROR_ARGS: illegal arguments provided (deprecated) * @PM_RET_ERROR_NOTSUPPORTED: feature not supported (deprecated) * @PM_RET_ERROR_NOT_ENABLED: feature is not enabled + * @PM_RET_ERROR_INVALID_CRC: invalid crc in IPI communication * @PM_RET_ERROR_INTERNAL: internal error * @PM_RET_ERROR_CONFLICT: conflict * @PM_RET_ERROR_ACCESS: access rights violation @@ -262,6 +264,7 @@ enum pm_ret_status { PM_RET_ERROR_ARGS = (1U), PM_RET_ERROR_NOTSUPPORTED = (4U), PM_RET_ERROR_NOT_ENABLED = (29U), + PM_RET_ERROR_INVALID_CRC = (301U), PM_RET_ERROR_INTERNAL = (2000U), PM_RET_ERROR_CONFLICT = (2001U), PM_RET_ERROR_ACCESS = (2002U),