[edk2-devel] [RFC PATCH v1 14/30] ArmVirtPkg: Add library for Arm CCA helper functions
Sami Mujawar
sami.mujawar at arm.com
Tue Apr 25 16:04:12 UTC 2023
Introduce ArmCcaLib library that implements helper
functions to:
- probe if the code is executing in a Realm context
- configure the protection attribute in page tables
for the memory regions shared with the host
- get the IPA width of the Realm which was stored in
the GUID HOB gArmCcaIpaWidthGuid.
Signed-off-by: Sami Mujawar <sami.mujawar at arm.com>
---
ArmVirtPkg/ArmVirtPkg.dec | 1 +
ArmVirtPkg/Include/Library/ArmCcaLib.h | 114 ++++++++++++
ArmVirtPkg/Library/ArmCcaLib/ArmCcaLib.c | 190 ++++++++++++++++++++
ArmVirtPkg/Library/ArmCcaLib/ArmCcaLib.inf | 34 ++++
4 files changed, 339 insertions(+)
diff --git a/ArmVirtPkg/ArmVirtPkg.dec b/ArmVirtPkg/ArmVirtPkg.dec
index c270d4a1ee268fb57a5338fd71487ed54699f496..c61ed9c492e97aa00ba9dbab1a5544354b6e7de7 100644
--- a/ArmVirtPkg/ArmVirtPkg.dec
+++ b/ArmVirtPkg/ArmVirtPkg.dec
@@ -27,6 +27,7 @@ [Includes.common]
[LibraryClasses]
ArmCcaInitPeiLib|Include/Library/ArmCcaInitPeiLib.h
+ ArmCcaLib|Include/Library/ArmCcaLib.h
ArmCcaRsiLib|Include/Library/ArmCcaRsiLib.h
ArmVirtMemInfoLib|Include/Library/ArmVirtMemInfoLib.h
diff --git a/ArmVirtPkg/Include/Library/ArmCcaLib.h b/ArmVirtPkg/Include/Library/ArmCcaLib.h
new file mode 100644
index 0000000000000000000000000000000000000000..a47e14b507f1bfd1feece636063eb2ba83357a5b
--- /dev/null
+++ b/ArmVirtPkg/Include/Library/ArmCcaLib.h
@@ -0,0 +1,114 @@
+/** @file
+ Library that implements the Arm CCA helper functions.
+
+ Copyright (c) 2022 - 2023, Arm Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ - Rsi or RSI - Realm Service Interface
+ - IPA - Intermediate Physical Address
+ - RIPAS - Realm IPA state
+**/
+
+#ifndef ARM_CCA_LIB_
+#define ARM_CCA_LIB_
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+
+/**
+ Check if running in a Realm.
+
+ @retval TRUE The execution is within the context of a Realm.
+ @retval FALSE The execution is not within the context of a Realm.
+**/
+BOOLEAN
+EFIAPI
+IsRealm (
+ VOID
+ );
+
+/**
+ Configure the protection attribute for the page tables
+ describing the memory region.
+
+ 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 Realms IPA
+ space. The most significant bit of a Protected IPA is 0.
+
+ An Unprotected IPA is an address in the upper half of a Realms
+ IPA space. The most significant bit of an Unprotected IPA is 1.
+
+ Note:
+ - Configuring the memory region as Unprotected IPA enables the
+ Realm to share the memory region with the Host.
+ - This function updates the page table entries to reflect the
+ protection attribute.
+ - A separate call to transition the memory range using the Realm
+ Service Interface (RSI) RSI_IPA_STATE_SET command is additionally
+ required and is expected to be done outside this function.
+
+ @param [in] BaseAddress Base address of the memory region.
+ @param [in] Length Length of the memory region.
+ @param [in] IpaWidth IPA width of the Realm.
+ @param [in] Share If TRUE, set the most significant
+ bit of the IPA to configure the memory
+ region as Unprotected IPA.
+ If FALSE, clear the most significant
+ bit of the IPA to configure the memory
+ region as Protected IPA.
+
+ @retval RETURN_SUCCESS IPA protection attribute updated.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ @retval RETURN_UNSUPPORTED The request is not initiated in a
+ Realm.
+**/
+RETURN_STATUS
+EFIAPI
+ArmCcaSetMemoryProtectAttribute (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 IpaWidth,
+ IN BOOLEAN Share
+ );
+
+/**
+ Return the IPA width of the Realm.
+
+ The IPA width of the Realm is used to configure the protection attribute
+ for memory regions, see ArmCcaSetMemoryProtectAttribute().
+
+ The IPA width of the Realm is present in the Realm config which is read
+ when the ArmCcaInitPeiLib library hook function ArmCcaInitialize () is
+ called in the PrePi phase. ArmCcaInitialize () stores the IPA width of
+ the Realm in a GUID HOB gArmCcaIpaWidthGuid.
+
+ This function searches the GUID HOB gArmCcaIpaWidthGuid and returns the
+ IPA width value stored therein.
+
+ Note:
+ - This function must only be called after ArmCcaInitialize () has setup
+ the GUID HOB gArmCcaIpaWidthGuid.
+
+ @param [out] IpaWidth IPA width of the Realm.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ @retval RETURN_NOT_FOUND The GUID HOB gArmCcaIpaWidthGuid is not
+ found and could mean that this function
+ was called before ArmCcaInitialize ()
+ has created and initialised the GUID
+ HOB gArmCcaIpaWidthGuid.
+**/
+RETURN_STATUS
+EFIAPI
+GetIpaWidth (
+ OUT UINT64 *IpaWidth
+ );
+
+#endif // ARM_CCA_LIB_
diff --git a/ArmVirtPkg/Library/ArmCcaLib/ArmCcaLib.c b/ArmVirtPkg/Library/ArmCcaLib/ArmCcaLib.c
new file mode 100644
index 0000000000000000000000000000000000000000..32cfcbcadea261d0fa616b0e0b75ede47bd0f747
--- /dev/null
+++ b/ArmVirtPkg/Library/ArmCcaLib/ArmCcaLib.c
@@ -0,0 +1,190 @@
+/** @file
+ Library that implements the Arm CCA helper functions.
+
+ Copyright (c) 2022 - 2023, Arm Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Glossary:
+ - Rsi or RSI - Realm Service Interface
+ - IPA - Intermediate Physical Address
+ - RIPAS - Realm IPA state
+**/
+#include <Base.h>
+
+#include <Chipset/AArch64.h>
+#include <Library/ArmCcaLib.h>
+#include <Library/ArmCcaRsiLib.h>
+#include <Library/ArmMmuLib.h>
+#include <Library/BaseLib.h>
+
+#include <Uefi/UefiMultiPhase.h>
+#include <Pi/PiBootMode.h>
+#include <Pi/PiHob.h>
+#include <Library/HobLib.h>
+
+/**
+ Check if running in a Realm.
+
+ @retval TRUE The execution is within the context of a Realm.
+ @retval FALSE The execution is not within the context of a Realm.
+**/
+BOOLEAN
+EFIAPI
+IsRealm (
+ VOID
+ )
+{
+ RETURN_STATUS Status;
+ UINT16 Major;
+ UINT16 Minor;
+
+ if (ArmHasRme ()) {
+ Status = RsiGetVersion (&Major, &Minor);
+ if (!RETURN_ERROR (Status)) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ Configure the protection attribute for the page tables
+ describing the memory region.
+
+ 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 Realms IPA
+ space. The most significant bit of a Protected IPA is 0.
+
+ An Unprotected IPA is an address in the upper half of a Realms
+ IPA space. The most significant bit of an Unprotected IPA is 1.
+
+ Note:
+ - Configuring the memory region as Unprotected IPA enables the
+ Realm to share the memory region with the Host.
+ - This function updates the page table entries to reflect the
+ protection attribute.
+ - A separate call to transition the memory range using the Realm
+ Service Interface (RSI) RSI_IPA_STATE_SET command is additionally
+ required and is expected to be done outside this function.
+
+ @param [in] BaseAddress Base address of the memory region.
+ @param [in] Length Length of the memory region.
+ @param [in] IpaWidth IPA width of the Realm.
+ @param [in] Share If TRUE, set the most significant
+ bit of the IPA to configure the memory
+ region as Unprotected IPA.
+ If FALSE, clear the most significant
+ bit of the IPA to configure the memory
+ region as Protected IPA.
+
+ @retval RETURN_SUCCESS IPA protection attribute updated.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ @retval RETURN_UNSUPPORTED The request is not initiated in a
+ Realm.
+**/
+RETURN_STATUS
+EFIAPI
+ArmCcaSetMemoryProtectAttribute (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 IpaWidth,
+ IN BOOLEAN Share
+ )
+{
+ UINT64 Val;
+ UINT64 Mask;
+ UINT64 ProtectionAttributeMask;
+
+ if (!IsRealm ()) {
+ return RETURN_UNSUPPORTED;
+ }
+
+ if (IpaWidth == 0) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ /* Software in a Realm should treat the most significant bit of an
+ IPA as a protection attribute.
+ */
+ ProtectionAttributeMask = 1ULL << (IpaWidth - 1);
+
+ if (Share) {
+ Val = ProtectionAttributeMask;
+ Mask = ~TT_ADDRESS_MASK_BLOCK_ENTRY;
+ } else {
+ Val = 0;
+ Mask = ~(TT_ADDRESS_MASK_BLOCK_ENTRY | ProtectionAttributeMask);
+ }
+
+ return SetMemoryRegionAttribute (
+ BaseAddress,
+ Length,
+ Val,
+ Mask
+ );
+}
+
+/**
+ Return the IPA width of the Realm.
+
+ The IPA width of the Realm is used to configure the protection attribute
+ for memory regions, see ArmCcaSetMemoryProtectAttribute().
+
+ The IPA width of the Realm is present in the Realm config which is read
+ when the ArmCcaInitPeiLib library hook function ArmCcaInitialize () is
+ called in the PrePi phase. ArmCcaInitialize () stores the IPA width of
+ the Realm in a GUID HOB gArmCcaIpaWidthGuid.
+
+ This function searches the GUID HOB gArmCcaIpaWidthGuid and returns the
+ IPA width value stored therein.
+
+ Note:
+ - This function must only be called after ArmCcaInitialize () has setup
+ the GUID HOB gArmCcaIpaWidthGuid.
+
+ @param [out] IpaWidth IPA width of the Realm.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ @retval RETURN_NOT_FOUND The GUID HOB gArmCcaIpaWidthGuid is not
+ found and could mean that this function
+ was called before ArmCcaInitialize ()
+ has created and initialised the GUID
+ HOB gArmCcaIpaWidthGuid.
+**/
+RETURN_STATUS
+EFIAPI
+GetIpaWidth (
+ OUT UINT64 *IpaWidth
+ )
+{
+ VOID *Hob;
+ UINT64 *CcaIpaWidth;
+
+ if (IpaWidth == NULL) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ Hob = GetFirstGuidHob (&gArmCcaIpaWidthGuid);
+ if ((Hob == NULL) ||
+ (GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (UINT64)))
+ {
+ return RETURN_NOT_FOUND;
+ }
+
+ CcaIpaWidth = GET_GUID_HOB_DATA (Hob);
+ if ((UINT64)*CcaIpaWidth == 0) {
+ return RETURN_NOT_FOUND;
+ }
+
+ *IpaWidth = *CcaIpaWidth;
+
+ return RETURN_SUCCESS;
+}
diff --git a/ArmVirtPkg/Library/ArmCcaLib/ArmCcaLib.inf b/ArmVirtPkg/Library/ArmCcaLib/ArmCcaLib.inf
new file mode 100644
index 0000000000000000000000000000000000000000..7d90b4535d69c12672af5de3d7cab63a3cd528a6
--- /dev/null
+++ b/ArmVirtPkg/Library/ArmCcaLib/ArmCcaLib.inf
@@ -0,0 +1,34 @@
+## @file
+# Library that implements the Arm CCA helper functions.
+#
+# Copyright (c) 2022 - 2023, Arm Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = ArmCcaLib
+ FILE_GUID = 11C18743-52F9-405E-B35B-D7BE91A26F9F
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmCcaLib
+
+[Sources]
+ ArmCcaLib.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ ArmVirtPkg/ArmVirtPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ ArmCcaRsiLib
+ ArmLib
+ ArmMmuLib
+ BaseLib
+ HobLib
+
+[Guids]
+ gArmCcaIpaWidthGuid
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#103566): https://edk2.groups.io/g/devel/message/103566
Mute This Topic: https://groups.io/mt/98495975/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-
More information about the edk2-devel-archive
mailing list