The IPA space of a Realm is divided into two halves: Protected IPA space and Unprotected IPA space. Software in a Realm should treat the most significant bit of an IPA as a protection attribute. A Protected IPA is an address in the lower half of a Realm's IPA space. An Unprotected IPA is an address in the upper half of a Realm's IPA space.
A Protected IPA has an associated Realm IPA state (RIPAS). The RIPAS values are: * EMPTY - Unused address * RAM - Private code or data owned by the Realm. Software in the Realm needs to share memory with the host to communicate with the outside world, e.g. network, disk image, etc. To share memory, the software in the Realm first transitions the RIPAS of memory region it wants to share with the host from RAM to EMPTY. The Realm software can then access the shared memory region using the Unprotected IPA address. The RMM specification defines the following Realm Service Interfaces for managing the IPA state: * RSI_IPA_STATE_GET * RSI_IPA_STATE_SET Therefore, update the ArmCcaRsiLib to add interfaces to get and set the IPA state of Realm memory pages. Signed-off-by: Sami Mujawar <sami.muja...@arm.com> --- ArmVirtPkg/Include/Library/ArmCcaRsiLib.h | 50 +++++++++++ ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h | 7 +- ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c | 92 ++++++++++++++++++++ 3 files changed, 147 insertions(+), 2 deletions(-) diff --git a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h index ab70240b3ab2979996f20190ddf669b53183556b..ae798a2feb9c3c417f06b7c2dfdb49479731df52 100644 --- a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h +++ b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h @@ -6,6 +6,7 @@ - Rsi or RSI - Realm Service Interface - IPA - Intermediate Physical Address + - RIPAS - Realm IPA state @par Reference(s): - Realm Management Monitor (RMM) Specification, version A-bet0 @@ -24,6 +25,21 @@ */ #define REALM_GRANULE_SIZE SIZE_4KB +/** + A macro defining the mask for the RSI RIPAS type. + See Section B4.4.5 RsiRipas type, RMM Specification, version A-bet0. +*/ +#define RIPAS_TYPE_MASK 0xFF + +/** An enum describing the RSI RIPAS. + See Section A5.2.2 Realm IPA state, RMM Specification, version A-bet0 +*/ +typedef enum Ripas { + RIPAS_EMPTY, ///< Unused IPA location. + RIPAS_RAM, ///< Private code or data owned by the Realm. + RIPAS_MAX ///< A valid RIPAS type value is less than RIPAS_MAX. +} RIPAS; + /** A structure describing the Realm Configuration. See Section B4.4.4 RsiRealmConfig type, RMM Specification, version A-bet0 The width of the RsiRealmConfig structure is 4096 (0x1000) bytes. @@ -35,6 +51,40 @@ typedef struct RealmConfig { UINT8 Reserved[SIZE_4KB - sizeof (UINT64)]; } REALM_CONFIG; +/** + Returns the IPA state for the page pointed by the address. + + @param [in] Address Address to retrive IPA state. + @param [out] State The RIPAS state for the address specified. + + @retval RETURN_SUCCESS Success. + @retval RETURN_INVALID_PARAMETER A parameter is invalid. +**/ +RETURN_STATUS +EFIAPI +RsiGetIpaState ( + IN UINT64 *Address, + OUT RIPAS *State + ); + +/** + Sets the IPA state for the pages pointed by the memory range. + + @param [in] Address Address to the start of the memory range. + @param [in] Size Length of the memory range. + @param [in] State The RIPAS state to be configured. + + @retval RETURN_SUCCESS Success. + @retval RETURN_INVALID_PARAMETER A parameter is invalid. +**/ +RETURN_STATUS +EFIAPI +RsiSetIpaState ( + IN UINT64 *Address, + IN UINT64 Size, + IN RIPAS State + ); + /** Read the Realm Configuration. diff --git a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h index 90e9dbb609679c82cd8e8ee8081428fd97021f97..9cc12bc5a70b457367077d0b26011c3b91fa63c9 100644 --- a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h +++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h @@ -7,6 +7,7 @@ @par Glossary: - Rsi or RSI - Realm Service Interface - IPA - Intermediate Physical Address + - RIPAS - Realm IPA state @par Reference(s): - Realm Management Monitor (RMM) Specification, version A-bet0 @@ -17,8 +18,10 @@ #define ARM_CCA_RSI_H_ // FIDs for Realm Service Interface calls. -#define FID_RSI_REALM_CONFIG 0xC4000196 -#define FID_RSI_VERSION 0xC4000190 +#define FID_RSI_IPA_STATE_GET 0xC4000198 +#define FID_RSI_IPA_STATE_SET 0xC4000197 +#define FID_RSI_REALM_CONFIG 0xC4000196 +#define FID_RSI_VERSION 0xC4000190 /** RSI Command Return codes See Section B4.4.1, RMM Specification, version A-bet0. diff --git a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c index 42b99fb7a71c8b38512a2f7472f9bc8a034fe1e9..546df9a94cb86533b37fef7e42fdaf7b8563052d 100644 --- a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c +++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c @@ -7,6 +7,7 @@ @par Glossary: - Rsi or RSI - Realm Service Interface - IPA - Intermediate Physical Address + - RIPAS - Realm IPA state @par Reference(s): - Realm Management Monitor (RMM) Specification, version A-bet0 @@ -81,6 +82,97 @@ AddrIsGranuleAligned ( return TRUE; } +/** + Returns the IPA state for the page pointed by the address. + + @param [in] Address Address to retrive IPA state. + @param [out] State The RIPAS state for the address specified. + + @retval RETURN_SUCCESS Success. + @retval RETURN_INVALID_PARAMETER A parameter is invalid. +**/ +RETURN_STATUS +EFIAPI +RsiGetIpaState ( + IN UINT64 *Address, + OUT RIPAS *State + ) +{ + RETURN_STATUS Status; + ARM_SMC_ARGS SmcCmd; + + if ((State == NULL) || (!AddrIsGranuleAligned (Address))) { + return RETURN_INVALID_PARAMETER; + } + + ZeroMem (&SmcCmd, sizeof (SmcCmd)); + SmcCmd.Arg0 = FID_RSI_IPA_STATE_GET; + SmcCmd.Arg1 = (UINTN)Address; + + ArmCallSmc (&SmcCmd); + Status = RsiCmdStatusToEfiStatus (SmcCmd.Arg0); + if (!RETURN_ERROR (Status)) { + *State = (RIPAS)(SmcCmd.Arg1 & RIPAS_TYPE_MASK); + } + + return Status; +} + +/** + Sets the IPA state for the pages pointed by the memory range. + + @param [in] Address Address to the start of the memory range. + @param [in] Size Length of the memory range. + @param [in] State The RIPAS state to be configured. + + @retval RETURN_SUCCESS Success. + @retval RETURN_INVALID_PARAMETER A parameter is invalid. +**/ +RETURN_STATUS +EFIAPI +RsiSetIpaState ( + IN UINT64 *Address, + IN UINT64 Size, + IN RIPAS State + ) +{ + RETURN_STATUS Status; + UINT64 *BaseAddress; + UINT64 *EndAddress; + ARM_SMC_ARGS SmcCmd; + + if ((Size == 0) || + ((Size & (REALM_GRANULE_SIZE - 1)) != 0) || + (!AddrIsGranuleAligned (Address))) + { + return RETURN_INVALID_PARAMETER; + } + + BaseAddress = Address; + // Divide Size by 8 for the pointer arithmetic + // to work, as we are adding to UINT64*. + EndAddress = Address + (Size >> 3); + + while (Size > 0) { + ZeroMem (&SmcCmd, sizeof (SmcCmd)); + SmcCmd.Arg0 = FID_RSI_IPA_STATE_SET; + SmcCmd.Arg1 = (UINTN)BaseAddress; + SmcCmd.Arg2 = (UINTN)Size; + SmcCmd.Arg3 = (UINTN)State; + + ArmCallSmc (&SmcCmd); + Status = RsiCmdStatusToEfiStatus (SmcCmd.Arg0); + if (RETURN_ERROR (Status)) { + break; + } + + BaseAddress = (UINT64 *)SmcCmd.Arg1; + Size = EndAddress - BaseAddress; + } // while + + return Status; +} + /** Read the Realm Configuration. -- 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)' -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#103555): https://edk2.groups.io/g/devel/message/103555 Mute This Topic: https://groups.io/mt/98495959/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-