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.

Cc: Ard Biesheuvel <ardb+tianoc...@kernel.org>
Cc: Leif Lindholm <quic_llind...@quicinc.com>
Cc: Gerd Hoffmann <kra...@redhat.com>
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..0c7f1afc78252b286a20dd8a7a81d538cf76ea8f
 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 {
+  RipasEmpty,      ///< Unused IPA location.
+  RipasRam,        ///< Private code or data owned by the Realm.
+  RipasMax         ///< A valid RIPAS type value is less than RipasMax.
+} 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 (#117684): https://edk2.groups.io/g/devel/message/117684
Mute This Topic: https://groups.io/mt/105483423/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to