From 85252e49df46c165e14a18ff00dacc64748ea1e3 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Fri, 19 Jun 2026 10:05:17 -0700 Subject: [PATCH 1/3] MdePkg/MdeModulePkg: ArmFfaLib: Expand to include first 4 registers The direct message arguments stripped off the header, making the underlying FF-A function interface to lose information when it comes to certain return code, i.e. FFA_YIELD and FFA_INTERRUPT. This change adds back the header field for this purpose so that the callers can decide how to act on the corresponding return codes. It then populates the header field for this purpose in FFA direct message functions so that the callers can decide how to act on the corresponding return codes. Signed-off-by: Kun Qin --- MdeModulePkg/Library/ArmFfaLib/ArmFfaCommon.c | 20 ++++++++++++++++--- MdePkg/Include/Library/ArmFfaLib.h | 12 +++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/MdeModulePkg/Library/ArmFfaLib/ArmFfaCommon.c b/MdeModulePkg/Library/ArmFfaLib/ArmFfaCommon.c index 783faade24..998cb67aa6 100644 --- a/MdeModulePkg/Library/ArmFfaLib/ArmFfaCommon.c +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaCommon.c @@ -741,13 +741,17 @@ ArmFfaLibRun ( ArmCallFfa (&FfaArgs); Status = FfaArgsToEfiStatus (&FfaArgs); - if (EFI_ERROR (Status)) { - return Status; - } + // MU_CHANGE: Copy the FFA header to the direct message arguments + // if (EFI_ERROR (Status)) { + // return Status; + // } if (DirectMsgArg != NULL) { ZeroMem (DirectMsgArg, sizeof (DIRECT_MSG_ARGS)); + // MU_CHANGE: Copy the FFA header to the direct message arguments + CopyMem (&(DirectMsgArg->Header), &FfaArgs, sizeof (DirectMsgArg->Header)); + if (FfaArgs.Arg0 == ARM_FID_FFA_MSG_SEND_DIRECT_RESP) { DirectMsgArg->Arg0 = FfaArgs.Arg3; DirectMsgArg->Arg1 = FfaArgs.Arg4; @@ -782,6 +786,9 @@ ArmFfaLibRun ( @param [in] Flags Message flags @param [in, out] ImpDefArgs Implemented defined arguments and Implemented defined return values + // MU_CHANGE: Copy the FFA header to the direct message arguments + The header registers (x0-x2) will be initialized + with the values from DestPartId and Flags. @retval EFI_SUCCESS Success @retval Others Error @@ -823,6 +830,8 @@ ArmFfaLibMsgSendDirectReq ( Status = FfaArgsToEfiStatus (&FfaArgs); if (EFI_ERROR (Status)) { + // MU_CHANGE: Copy the FFA header to the direct message arguments + CopyMem (ImpDefArgs, &FfaArgs, sizeof (DIRECT_MSG_ARGS)); return Status; } @@ -842,6 +851,9 @@ ArmFfaLibMsgSendDirectReq ( @param [in] ServiceGuid Service guid @param [in, out] ImpDefArgs Implemented defined arguments and Implemented defined return values + // MU_CHANGE: Copy the FFA header to the direct message arguments + The header registers (x0-x3) will be + initialized with the values from DestPartId and ServiceGuid. @retval EFI_SUCCESS Success @retval Others Error @@ -907,6 +919,8 @@ ArmFfaLibMsgSendDirectReq2 ( Status = FfaArgsToEfiStatus (&FfaArgs); if (EFI_ERROR (Status)) { + // MU_CHANGE: Copy the FFA header to the direct message arguments + CopyMem (ImpDefArgs, &FfaArgs, sizeof (DIRECT_MSG_ARGS)); return Status; } diff --git a/MdePkg/Include/Library/ArmFfaLib.h b/MdePkg/Include/Library/ArmFfaLib.h index 8889887a9e..feaf006284 100644 --- a/MdePkg/Include/Library/ArmFfaLib.h +++ b/MdePkg/Include/Library/ArmFfaLib.h @@ -54,6 +54,15 @@ typedef struct ArmFfaArgs { * FFA_SEND_MSG_DIRECT_REQ2/FFA_SEND_MSG_DIRECT_RESP2 (i.e. v2) */ typedef struct DirectMsgArgs { + // MU_CHANGE: Carry the FFA header as part of the direct message content + /// Header containing the arguments for the header registers (x0-x2 (v1) or x0-x3 (v2)) + struct { + UINTN x0; + UINTN x1; + UINTN x2; + UINTN x3; + } Header; + /// Implementation define argument 0, this will be set to/from x3(v1) or x4(v2) UINTN Arg0; @@ -97,6 +106,9 @@ typedef struct DirectMsgArgs { UINTN Arg13; } DIRECT_MSG_ARGS; +// MU_CHANGE: Carry the FFA header as part of the direct message content +STATIC_ASSERT (sizeof (DIRECT_MSG_ARGS) == sizeof (ARM_FFA_ARGS), "DIRECT_MSG_ARGS and ARM_FFA_ARGS must be the same size"); + /** Trigger FF-A ABI call according to PcdFfaLibConduitSmc. From 065ae975b44585d8bbe713dc8c1df980ba9806aa Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Fri, 19 Jun 2026 10:06:24 -0700 Subject: [PATCH 2/3] ArmPkg: MmCommunication: FFA run should use the returned ID As the FFA function now returns the target ID properly, instead of hardcoding the FFA_RUN target ID being the STMM, we use the parsed ID to issue the FFA_RUN. Signed-off-by: Kun Qin --- ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c | 3 ++- ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c b/ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c index 485f38fccf..398386c8f7 100644 --- a/ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c +++ b/ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c @@ -100,7 +100,8 @@ SendFfaMmCommunicate ( while (Status == EFI_INTERRUPT_PENDING) { // We are assuming vCPU0 of the StMM SP since it is UP. - Status = ArmFfaLibRun (mStMmPartId, 0x00, NULL); + // MU_CHANGE: Use the source partition ID of the FFA header for the ffa_run call. + Status = ArmFfaLibRun (GET_SOURCE_PARTITION_ID (CommunicateArgs.Header.x1), 0x00, &CommunicateArgs); } return Status; diff --git a/ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c b/ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c index a3f5388371..dac94ddd57 100644 --- a/ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c +++ b/ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c @@ -235,7 +235,8 @@ SendFfaMmCommunicate ( while (Status == EFI_INTERRUPT_PENDING) { // We are assuming vCPU0 of the StMM SP since it is UP. - Status = ArmFfaLibRun (mStMmPartId, 0x00, NULL); + // MU_CHANGE: Use the source partition ID of the FFA header for the ffa_run call. + Status = ArmFfaLibRun (GET_SOURCE_PARTITION_ID (CommunicateArgs.Header.x1), 0x00, &CommunicateArgs); } return Status; From 0ce4540f6b2eac3af766620bca763565b2d0bfcd Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Fri, 19 Jun 2026 10:07:20 -0700 Subject: [PATCH 3/3] SecurityPkg: Tpm2DeviceLibFfa: FFA run should use the returned ID As the FFA function now returns the target ID properly, instead of hardcoding the FFA_RUN target ID being the TPM SP, we use the parsed ID to issue the FFA_RUN. Signed-off-by: Kun Qin --- .../Tpm2DeviceLibFfa/Tpm2ServiceFfaRaw.c | 18 ++++++++++++------ SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigFfaPeim.c | 3 ++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/SecurityPkg/Library/Tpm2DeviceLibFfa/Tpm2ServiceFfaRaw.c b/SecurityPkg/Library/Tpm2DeviceLibFfa/Tpm2ServiceFfaRaw.c index 398b59c3d0..3a0ce3589f 100644 --- a/SecurityPkg/Library/Tpm2DeviceLibFfa/Tpm2ServiceFfaRaw.c +++ b/SecurityPkg/Library/Tpm2DeviceLibFfa/Tpm2ServiceFfaRaw.c @@ -154,7 +154,8 @@ Tpm2GetInterfaceVersion ( Status = ArmFfaLibMsgSendDirectReq2 (FfaTpm2PartitionId, &gTpm2ServiceFfaGuid, &FfaDirectReq2Args); while (Status == EFI_INTERRUPT_PENDING) { // We are assuming vCPU0 of the TPM SP since it is UP. - Status = ArmFfaLibRun (FfaTpm2PartitionId, 0x00, &FfaDirectReq2Args); + // MU_CHANGE: Use the source partition ID of the FFA header for the ffa_run call. + Status = ArmFfaLibRun (GET_SOURCE_PARTITION_ID (FfaDirectReq2Args.Header.x1), 0x00, &FfaDirectReq2Args); } if (EFI_ERROR (Status)) { @@ -203,7 +204,8 @@ Tpm2GetFeatureInfo ( Status = ArmFfaLibMsgSendDirectReq2 (FfaTpm2PartitionId, &gTpm2ServiceFfaGuid, &FfaDirectReq2Args); while (Status == EFI_INTERRUPT_PENDING) { // We are assuming vCPU0 of the TPM SP since it is UP. - Status = ArmFfaLibRun (FfaTpm2PartitionId, 0x00, &FfaDirectReq2Args); + // MU_CHANGE: Use the source partition ID of the FFA header for the ffa_run call. + Status = ArmFfaLibRun (GET_SOURCE_PARTITION_ID (FfaDirectReq2Args.Header.x1), 0x00, &FfaDirectReq2Args); } if (EFI_ERROR (Status)) { @@ -243,7 +245,8 @@ Tpm2ServiceStart ( Status = ArmFfaLibMsgSendDirectReq2 (FfaTpm2PartitionId, &gTpm2ServiceFfaGuid, &FfaDirectReq2Args); while (Status == EFI_INTERRUPT_PENDING) { // We are assuming vCPU0 of the TPM SP since it is UP. - Status = ArmFfaLibRun (FfaTpm2PartitionId, 0x00, &FfaDirectReq2Args); + // MU_CHANGE: Use the source partition ID of the FFA header for the ffa_run call. + Status = ArmFfaLibRun (GET_SOURCE_PARTITION_ID (FfaDirectReq2Args.Header.x1), 0x00, &FfaDirectReq2Args); } if (EFI_ERROR (Status)) { @@ -284,7 +287,8 @@ Tpm2RegisterNotification ( Status = ArmFfaLibMsgSendDirectReq2 (FfaTpm2PartitionId, &gTpm2ServiceFfaGuid, &FfaDirectReq2Args); while (Status == EFI_INTERRUPT_PENDING) { // We are assuming vCPU0 of the TPM SP since it is UP. - Status = ArmFfaLibRun (FfaTpm2PartitionId, 0x00, &FfaDirectReq2Args); + // MU_CHANGE: Use the source partition ID of the FFA header for the ffa_run call. + Status = ArmFfaLibRun (GET_SOURCE_PARTITION_ID (FfaDirectReq2Args.Header.x1), 0x00, &FfaDirectReq2Args); } if (EFI_ERROR (Status)) { @@ -317,7 +321,8 @@ Tpm2UnregisterNotification ( Status = ArmFfaLibMsgSendDirectReq2 (FfaTpm2PartitionId, &gTpm2ServiceFfaGuid, &FfaDirectReq2Args); while (Status == EFI_INTERRUPT_PENDING) { // We are assuming vCPU0 of the TPM SP since it is UP. - Status = ArmFfaLibRun (FfaTpm2PartitionId, 0x00, &FfaDirectReq2Args); + // MU_CHANGE: Use the source partition ID of the FFA header for the ffa_run call. + Status = ArmFfaLibRun (GET_SOURCE_PARTITION_ID (FfaDirectReq2Args.Header.x1), 0x00, &FfaDirectReq2Args); } if (EFI_ERROR (Status)) { @@ -350,7 +355,8 @@ Tpm2FinishNotified ( Status = ArmFfaLibMsgSendDirectReq2 (FfaTpm2PartitionId, &gTpm2ServiceFfaGuid, &FfaDirectReq2Args); while (Status == EFI_INTERRUPT_PENDING) { // We are assuming vCPU0 of the TPM SP since it is UP. - Status = ArmFfaLibRun (FfaTpm2PartitionId, 0x00, &FfaDirectReq2Args); + // MU_CHANGE: Use the source partition ID of the FFA header for the ffa_run call. + Status = ArmFfaLibRun (GET_SOURCE_PARTITION_ID (FfaDirectReq2Args.Header.x1), 0x00, &FfaDirectReq2Args); } if (EFI_ERROR (Status)) { diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigFfaPeim.c b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigFfaPeim.c index 73a0f9a944..12b0fbeb65 100644 --- a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigFfaPeim.c +++ b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigFfaPeim.c @@ -69,7 +69,8 @@ Tpm2FfaCheckInterfaceVersion ( Status = ArmFfaLibMsgSendDirectReq2 (TpmPartId, &gTpm2ServiceFfaGuid, &TpmArgs); while (Status == EFI_INTERRUPT_PENDING) { // We are assuming vCPU0 of the TPM SP since it is UP. - Status = ArmFfaLibRun (TpmPartId, 0x00, &TpmArgs); + // MU_CHANGE: Use the source partition ID of the FFA header for the ffa_run call. + Status = ArmFfaLibRun (GET_SOURCE_PARTITION_ID (TpmArgs.Header.x1), 0x00, &TpmArgs); } if (EFI_ERROR (Status) || (TpmArgs.Arg0 != TPM2_FFA_SUCCESS_OK_RESULTS_RETURNED)) {