* [edk2-devel] [PATCH v2 01/45] ArmPkg: Add helper function to detect RME
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 02/45] ArmPkg: Introduce SetMemoryProtectionAttribute() for Realms Sami Mujawar
` (38 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, Matteo.Carlini,
Akanksha.Jain2, Sibel.Allinson, nd
Add helper function to check if the Realm Management
Extension (RME) is implemented by the hardware.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmPkg/Include/Chipset/AArch64.h | 3 ++-
ArmPkg/Include/Library/ArmLib.h | 15 ++++++++++++++-
ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c | 16 +++++++++++++++-
3 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/ArmPkg/Include/Chipset/AArch64.h b/ArmPkg/Include/Chipset/AArch64.h
index 5390bf0a2774fb410f33e031cb0367708905c658..33f8df12637b7003b46458ae0680f67ebc3a431a 100644
--- a/ArmPkg/Include/Chipset/AArch64.h
+++ b/ArmPkg/Include/Chipset/AArch64.h
@@ -1,7 +1,7 @@
/** @file
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
- Copyright (c) 2011 - 2021, Arm Limited. All rights reserved.<BR>
+ Copyright (c) 2011 - 2023, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -30,6 +30,7 @@
// ID_AA64PFR0 - AArch64 Processor Feature Register 0 definitions
#define AARCH64_PFR0_FP (0xF << 16)
#define AARCH64_PFR0_GIC (0xF << 24)
+#define AARCH64_PFR0_RME (0xFULL << 52)
// ID_AA64DFR0 - AArch64 Debug Feature Register 0 definitions
#define AARCH64_DFR0_TRACEVER (0xFULL << 4)
diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h
index 6aa8a48f07f39255b70406774d2d803dbfc97b0b..ed876d231bbe82a1655e7455d04c92042aab3a94 100644
--- a/ArmPkg/Include/Library/ArmLib.h
+++ b/ArmPkg/Include/Library/ArmLib.h
@@ -1,7 +1,7 @@
/** @file
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
- Copyright (c) 2011 - 2016, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2011 - 2023, Arm Limited. All rights reserved.<BR>
Copyright (c) 2020 - 2021, NUVIA Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -824,6 +824,19 @@ ArmHasSecurityExtensions (
VOID
);
+#else
+
+/** Checks if RME is implemented.
+
+ @retval TRUE RME is implemented.
+ @retval FALSE RME is not implemented.
+**/
+BOOLEAN
+EFIAPI
+ArmHasRme (
+ VOID
+ );
+
#endif // MDE_CPU_ARM
#endif // ARM_LIB_H_
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
index 87285465871dc100ea0065659959ca845912c549..8952524fb3d56695cce181f852723d8b2a1dc77c 100644
--- a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
+++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
@@ -1,7 +1,7 @@
/** @file
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
- Portions copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+ Portions copyright (c) 2011 - 2023, Arm Limited. All rights reserved.<BR>
Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -150,3 +150,17 @@ ArmHasEte (
// The ID_AA64DFR0_EL1.TraceVer field identifies the presence of FEAT_ETE.
return ((ArmReadIdAA64Dfr0 () & AARCH64_DFR0_TRACEVER) != 0);
}
+
+/** Checks if RME is implemented.
+
+ @retval TRUE RME is implemented.
+ @retval FALSE RME is not implemented.
+**/
+BOOLEAN
+EFIAPI
+ArmHasRme (
+ VOID
+ )
+{
+ return ((ArmReadIdAA64Pfr0 () & AARCH64_PFR0_RME) != 0);
+}
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117672): https://edk2.groups.io/g/devel/message/117672
Mute This Topic: https://groups.io/mt/105483410/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 02/45] ArmPkg: Introduce SetMemoryProtectionAttribute() for Realms
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 01/45] ArmPkg: Add helper function to detect RME Sami Mujawar
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 03/45] ArmPkg: Extend number of parameter registers in SMC call Sami Mujawar
` (37 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, Matteo.Carlini,
Akanksha.Jain2, Sibel.Allinson, nd
Arm CCA requires the software in a Realm to treat the most
significant bit of an IPA as a protection attribute. To
enable/disable sharing of memory regions with the host, the
protection attribute needs to be set/cleared accordingly.
Therefore, introduce SetMemoryProtectionAttribute() so that
the memory regions can be shared/unshared with the host.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmPkg/Include/Library/ArmMmuLib.h | 55 ++++++++++++
ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c | 90 ++++++++++++++++++++
2 files changed, 145 insertions(+)
diff --git a/ArmPkg/Include/Library/ArmMmuLib.h b/ArmPkg/Include/Library/ArmMmuLib.h
index 2ce948e8db1d34e5ba0228de3dc347e186f31c11..1cea71ee6e88d351a3c57c4b97fe229305bfc1af 100644
--- a/ArmPkg/Include/Library/ArmMmuLib.h
+++ b/ArmPkg/Include/Library/ArmMmuLib.h
@@ -71,4 +71,59 @@ ArmSetMemoryAttributes (
IN UINT64 AttributeMask
);
+#ifdef MDE_CPU_AARCH64
+
+/**
+ 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.
+ - The caller must ensure that this function call is invoked by code
+ executing within the Realm.
+
+ @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 EFI_SUCCESS IPA protection attribute updated.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_UNSUPPORTED RME is not supported.
+**/
+EFI_STATUS
+EFIAPI
+SetMemoryProtectionAttribute (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 IpaWidth,
+ IN BOOLEAN Share
+ );
+
+#endif
+
#endif // ARM_MMU_LIB_H_
diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c
index 9d9c623581fe0010e35cb33c0c8ef4061720a6f7..25d32cceb61e1f0fd62d878202cf8ead05cfd9e2 100644
--- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c
+++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c
@@ -7,6 +7,10 @@
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
+* @par Glossary:
+* - Rsi or RSI - Realm Service Interface
+* - IPA - Intermediate Physical Address
+* - RIPAS - Realm IPA state
**/
#include <Uefi.h>
@@ -749,3 +753,89 @@ ArmMmuBaseLibConstructor (
return RETURN_SUCCESS;
}
+
+/**
+ 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.
+ - The caller must ensure that this function call is invoked by code
+ executing within the Realm.
+
+ @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 EFI_SUCCESS IPA protection attribute updated.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_UNSUPPORTED RME is not supported.
+**/
+EFI_STATUS
+EFIAPI
+SetMemoryProtectionAttribute (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 IpaWidth,
+ IN BOOLEAN Share
+ )
+{
+ UINT64 Attributes;
+ UINT64 Mask;
+ UINT64 ProtectionAttributeMask;
+
+ if ((Length == 0) || (IpaWidth == 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!ArmHasRme ()) {
+ return EFI_UNSUPPORTED;
+ }
+
+ /* Software in a Realm should treat the most significant bit of an
+ IPA as a protection attribute.
+ */
+ ProtectionAttributeMask = 1ULL << (IpaWidth - 1);
+
+ if (Share) {
+ Attributes = ProtectionAttributeMask;
+ Mask = ~TT_ADDRESS_MASK_BLOCK_ENTRY;
+ } else {
+ Attributes = 0;
+ Mask = ~(TT_ADDRESS_MASK_BLOCK_ENTRY | ProtectionAttributeMask);
+ }
+
+ return UpdateRegionMapping (
+ BaseAddress,
+ Length,
+ Attributes,
+ Mask,
+ ArmGetTTBR0BaseAddress (),
+ TRUE
+ );
+}
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117669): https://edk2.groups.io/g/devel/message/117669
Mute This Topic: https://groups.io/mt/105483407/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 03/45] ArmPkg: Extend number of parameter registers in SMC call
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 01/45] ArmPkg: Add helper function to detect RME Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 02/45] ArmPkg: Introduce SetMemoryProtectionAttribute() for Realms Sami Mujawar
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 04/45] ArmVirtPkg: Add Arm CCA Realm Service Interface Library Sami Mujawar
` (36 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, Matteo.Carlini,
Akanksha.Jain2, Sibel.Allinson, nd
The Realm Service Interface (RSI) commands use registers between
X1-X10 as parameters and between X0-X8 as return values for SMC
calls.
According to the SMCCC Section 2.6 SMC32/HVC32 argument passing
When an SMC32/HVC32 call is made from AArch32:
- Arguments are passed in registers R1-R7.
- Results are returned in R0-R7.
When an SMC32/HVC32 call is made from AArch64:
- Arguments are passed in registers W1-W7.
- Results are returned in W0-W7.
According to SMCCC Section 2.7 SMC64/HVC64 argument passing
When an SMC64/HVC64 call is made from AArch64:
- Arguments are passed in registers X1-X17.
- Results are returned in X0-X17.
This means SMC calls can take up to 7/17 arguments and return up
to 7/17 return values.
However, for the current use-case(s):
- SMC32/HVC32 calls made from AArch32/AArch64 require up to 7
arguments and 4 return values.
- SMC64/HVC64 calls made from AArch64 require up to 10 arguments
and 9 return values.
Therefore, for SMC32/HVC32 calls made from AArch32/AArch64 there is
no update required. However, for AMC64/HVC64 calls made from AArch64,
extend the ArmCallSmc () to use registers X1-X11 as parameters and
return values for SMC call.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmPkg/Include/Library/ArmSmcLib.h | 50 ++++++++++++++++++--
ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S | 22 ++++++---
2 files changed, 62 insertions(+), 10 deletions(-)
diff --git a/ArmPkg/Include/Library/ArmSmcLib.h b/ArmPkg/Include/Library/ArmSmcLib.h
index beef0175c35ce86aac9e465f9062bf8052b08dfb..e80b74671a6424723323bab95917fb3909771759 100644
--- a/ArmPkg/Include/Library/ArmSmcLib.h
+++ b/ArmPkg/Include/Library/ArmSmcLib.h
@@ -1,10 +1,13 @@
/** @file
*
* Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
-* Copyright (c) 2012-2014, ARM Limited. All rights reserved.
+* Copyright (c) 2012-2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
+* @par Reference(s):
+* - SMC Calling Convention (SMCCC), ARM DEN 0028E, EAC0, 1.4
+* (https://developer.arm.com/documentation/den0028/e/)
**/
#ifndef ARM_SMC_LIB_H_
@@ -13,6 +16,18 @@
/**
* The size of the SMC arguments are different between AArch64 and AArch32.
* The native size is used for the arguments.
+ * According to the SMCCC Section 2.6 SMC32/HVC32 argument passing
+ * When an SMC32/HVC32 call is made from AArch32:
+ * - Arguments are passed in registers R1-R7.
+ * - Results are returned in R0-R7.
+ * When an SMC32/HVC32 call is made from AArch64:
+ * - Arguments are passed in registers W1-W7.
+ * - Results are returned in W0-W7.
+ *
+ * According to SMCCC Section 2.7 SMC64/HVC64 argument passing
+ * When an SMC64/HVC64 call is made from AArch64:
+ * - Arguments are passed in registers X1-X17.
+ * - Results are returned in X0-X17.
*/
typedef struct {
UINTN Arg0;
@@ -23,13 +38,42 @@ typedef struct {
UINTN Arg5;
UINTN Arg6;
UINTN Arg7;
+ #ifdef MDE_CPU_AARCH64
+ UINTN Arg8;
+ UINTN Arg9;
+ UINTN Arg10;
+ UINTN Arg11;
+ #endif
} ARM_SMC_ARGS;
/**
Trigger an SMC call
- SMC calls can take up to 7 arguments and return up to 4 return values.
- Therefore, the 4 first fields in the ARM_SMC_ARGS structure are used
+ According to the SMCCC Section 2.6 SMC32/HVC32 argument passing
+ When an SMC32/HVC32 call is made from AArch32:
+ - Arguments are passed in registers R1-R7.
+ - Results are returned in R0-R7.
+ When an SMC32/HVC32 call is made from AArch64:
+ - Arguments are passed in registers W1-W7.
+ - Results are returned in W0-W7.
+
+ According to SMCCC Section 2.7 SMC64/HVC64 argument passing
+ When an SMC64/HVC64 call is made from AArch64:
+ - Arguments are passed in registers X1-X17.
+ - Results are returned in X0-X17.
+
+ This means SMC calls can take up to 7/17 arguments and return up
+ to 7/17 return values.
+
+ However, the current use-case:
+ - For SMC32/HVC32 calls made from AArch32/AArch64 up to 7 arguments
+ and 4 return values are required. Therefore, limit the maximum
+ arguments to 7 and return values to 4.
+ - For AMC64/HVC64 calls made from AArch64 up to 11 arguments and
+ return values are required. Therefore, limit the maximum arguments
+ and return values to 11.
+
+ The fields in the ARM_SMC_ARGS structure are used
for both input and output values.
**/
diff --git a/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S b/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S
index 4a8c2a8f59eab3e5b66dda2515d5bbced131af13..299d612dc5e1ebfeaf69a356b400c511905d72fe 100644
--- a/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S
+++ b/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S
@@ -1,8 +1,11 @@
//
-// Copyright (c) 2012-2014, ARM Limited. All rights reserved.
+// Copyright (c) 2012-2023, Arm Limited. All rights reserved.
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
+// @par Reference(s):
+// - SMC Calling Convention (SMCCC), ARM DEN 0028E, EAC0, 1.4
+// (https://developer.arm.com/documentation/den0028/e/)
//
#include <AsmMacroIoLibV8.h>
@@ -12,6 +15,8 @@ ASM_FUNC(ArmCallSmc)
str x0, [sp, #-16]!
// Load the SMC arguments values into the appropriate registers
+ ldp x10, x11, [x0, #80]
+ ldp x8, x9, [x0, #64]
ldp x6, x7, [x0, #48]
ldp x4, x5, [x0, #32]
ldp x2, x3, [x0, #16]
@@ -19,14 +24,17 @@ ASM_FUNC(ArmCallSmc)
smc #0
- // Pop the ARM_SMC_ARGS structure address from the stack into x9
- ldr x9, [sp], #16
+ // Pop the ARM_SMC_ARGS structure address from the stack into x13
+ ldr x13, [sp], #16
// Store the SMC returned values into the ARM_SMC_ARGS structure.
- // A SMC call can return up to 4 values - we do not need to store back x4-x7.
- stp x2, x3, [x9, #16]
- stp x0, x1, [x9, #0]
+ stp x10, x11, [x13, #80]
+ stp x8, x9, [x13, #64]
+ stp x6, x7, [x13, #48]
+ stp x4, x5, [x13, #32]
+ stp x2, x3, [x13, #16]
+ stp x0, x1, [x13, #0]
- mov x0, x9
+ mov x0, x13
ret
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117674): https://edk2.groups.io/g/devel/message/117674
Mute This Topic: https://groups.io/mt/105483412/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 04/45] ArmVirtPkg: Add Arm CCA Realm Service Interface Library
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (2 preceding siblings ...)
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 03/45] ArmPkg: Extend number of parameter registers in SMC call Sami Mujawar
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 05/45] ArmVirtPkg: ArmCcaRsiLib: Add interfaces to manage the Realm IPA state Sami Mujawar
` (35 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
The Realm Management Monitor (RMM) is a software component which
forms part of a system which implements the Arm Confidential Compute
Architecture (CCA) and is responsible for management of Realms.
The RMM specification defines a Realm Service Interface (RSI) that
the Guest can use to request services from the RMM.
Therefore, add a library that implements the RSI interfaces to:
- query the RSI version
- get the Realm configuration.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/ArmVirtPkg.dec | 1 +
ArmVirtPkg/Include/Library/ArmCcaRsiLib.h | 72 ++++++++++
ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h | 40 ++++++
ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c | 145 ++++++++++++++++++++
ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.inf | 29 ++++
5 files changed, 287 insertions(+)
diff --git a/ArmVirtPkg/ArmVirtPkg.dec b/ArmVirtPkg/ArmVirtPkg.dec
index 6aa5ea05f4e9bfc7aa17d40777dda916ccc82798..d92cb52fc30a6f0ee3469fbd2a940f88e9cf2c67 100644
--- a/ArmVirtPkg/ArmVirtPkg.dec
+++ b/ArmVirtPkg/ArmVirtPkg.dec
@@ -26,6 +26,7 @@ [Includes.common]
Include # Root include for the package
[LibraryClasses]
+ ArmCcaRsiLib|Include/Library/ArmCcaRsiLib.h
ArmVirtMemInfoLib|Include/Library/ArmVirtMemInfoLib.h
[Guids.common]
diff --git a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
new file mode 100644
index 0000000000000000000000000000000000000000..ab70240b3ab2979996f20190ddf669b53183556b
--- /dev/null
+++ b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
@@ -0,0 +1,72 @@
+/** @file
+ Library that implements the Arm CCA Realm Service Interface calls.
+
+ Copyright (c) 2022 - 2023, Arm Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ - Rsi or RSI - Realm Service Interface
+ - IPA - Intermediate Physical Address
+
+ @par Reference(s):
+ - Realm Management Monitor (RMM) Specification, version A-bet0
+ (https://developer.arm.com/documentation/den0137/)
+**/
+
+#ifndef ARM_CCA_RSI_LIB_
+#define ARM_CCA_RSI_LIB_
+
+#include <Base.h>
+
+/**
+ A macro defining the size of a Realm Granule.
+ See Section A2.2, RMM Specification, version A-bet0
+ DNBXXX A Granule is a unit of physical memory whose size is 4KB.
+*/
+#define REALM_GRANULE_SIZE SIZE_4KB
+
+/** 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.
+*/
+typedef struct RealmConfig {
+ // Width of IPA in bits.
+ UINT64 IpaWidth;
+ // Unused bits of the RsiRealmConfig structure should be zero.
+ UINT8 Reserved[SIZE_4KB - sizeof (UINT64)];
+} REALM_CONFIG;
+
+/**
+ Read the Realm Configuration.
+
+ @param [out] Config Pointer to the address of the buffer to retrieve
+ the Realm configuration.
+
+ Note: The buffer to retrieve the Realm configuration must be aligned to the
+ Realm granule size.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+**/
+RETURN_STATUS
+EFIAPI
+RsiGetRealmConfig (
+ IN REALM_CONFIG *Config
+ );
+
+/**
+ Get the version of the RSI implementation.
+
+ @param [out] Major The major version of the RSI implementation.
+ @param [out] Minor The minor version of the RSI implementation.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ */
+RETURN_STATUS
+EFIAPI
+RsiGetVersion (
+ OUT UINT16 *CONST Major,
+ OUT UINT16 *CONST Minor
+ );
+
+#endif // ARM_CCA_RSI_LIB_
diff --git a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h
new file mode 100644
index 0000000000000000000000000000000000000000..90e9dbb609679c82cd8e8ee8081428fd97021f97
--- /dev/null
+++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h
@@ -0,0 +1,40 @@
+/** @file
+ Definitions for Arm CCA Realm Service Interface.
+
+ Copyright (c) 2022 - 2023, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Glossary:
+ - Rsi or RSI - Realm Service Interface
+ - IPA - Intermediate Physical Address
+
+ @par Reference(s):
+ - Realm Management Monitor (RMM) Specification, version A-bet0
+ (https://developer.arm.com/documentation/den0137/)
+**/
+
+#ifndef ARM_CCA_RSI_H_
+#define ARM_CCA_RSI_H_
+
+// FIDs for Realm Service Interface calls.
+#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.
+ The width of the RsiCommandReturnCode enumeration is 64 bits.
+*/
+#define RSI_SUCCESS 0ULL
+#define RSI_ERROR_INPUT 1ULL
+#define RSI_ERROR_STATE 2ULL
+#define RSI_INCOMPLETE 3ULL
+
+/** RSI interface Version
+ See Section B4.4.3, RMM Specification, version A-bet0.
+ The width of the RsiInterfaceVersion fieldset is 64 bits.
+*/
+#define RSI_VER_MINOR_MASK 0x00FFULL
+#define RSI_VER_MAJOR_MASK 0x7F00ULL
+#define RSI_VER_MAJOR_SHIFT 16
+
+#endif // ARM_CCA_RSI_H_
diff --git a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
new file mode 100644
index 0000000000000000000000000000000000000000..42b99fb7a71c8b38512a2f7472f9bc8a034fe1e9
--- /dev/null
+++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
@@ -0,0 +1,145 @@
+/** @file
+ Library that implements the Arm CCA Realm Service Interface calls.
+
+ 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
+
+ @par Reference(s):
+ - Realm Management Monitor (RMM) Specification, version A-bet0
+ (https://developer.arm.com/documentation/den0137/)
+
+**/
+#include <Base.h>
+
+#include <Library/ArmCcaRsiLib.h>
+#include <Library/ArmLib.h>
+#include <Library/ArmSmcLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include "ArmCcaRsi.h"
+
+/**
+ Convert the RSI status code to EFI Status code.
+
+ @param [in] RsiCommandReturnCode RSI status code.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ @retval RETURN_ABORTED The operation was aborted as the state
+ of the Realm or REC does not match the
+ state expected by the command.
+ @retval RETURN_NOT_READY The operation requested by the command
+ is not complete.
+ **/
+STATIC
+RETURN_STATUS
+RsiCmdStatusToEfiStatus (
+ IN UINT64 RsiCommandReturnCode
+ )
+{
+ switch (RsiCommandReturnCode) {
+ case RSI_SUCCESS:
+ return RETURN_SUCCESS;
+ case RSI_ERROR_INPUT:
+ return RETURN_INVALID_PARAMETER;
+ case RSI_ERROR_STATE:
+ return RETURN_ABORTED;
+ case RSI_INCOMPLETE:
+ return RETURN_NOT_READY;
+ default:
+ // Unknown error code.
+ ASSERT (0);
+ break;
+ } // switch
+
+ return RETURN_ABORTED;
+}
+
+/**
+ Check if the address is aligned to the size of the Realm granule.
+
+ @param [in] Address Address to check granule alignment.
+
+ @retval TRUE Address is aligned to the Realm granule size.
+ @retval FALSE Address is not aligned to the Realm granule size.
+**/
+STATIC
+BOOLEAN
+EFIAPI
+AddrIsGranuleAligned (
+ IN UINT64 *Address
+ )
+{
+ if (((UINT64)Address & (REALM_GRANULE_SIZE - 1)) != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Read the Realm Configuration.
+
+ @param [out] Config Pointer to the address of the buffer to retrieve
+ the Realm configuration.
+
+ Note: The buffer to retrieve the Realm configuration must be aligned to the
+ Realm granule size.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+**/
+RETURN_STATUS
+EFIAPI
+RsiGetRealmConfig (
+ OUT REALM_CONFIG *Config
+ )
+{
+ ARM_SMC_ARGS SmcCmd;
+
+ if ((Config == NULL) || (!AddrIsGranuleAligned ((UINT64 *)Config))) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ ZeroMem (&SmcCmd, sizeof (SmcCmd));
+ SmcCmd.Arg0 = FID_RSI_REALM_CONFIG;
+ SmcCmd.Arg1 = (UINTN)Config;
+
+ ArmCallSmc (&SmcCmd);
+ return RsiCmdStatusToEfiStatus (SmcCmd.Arg0);
+}
+
+/**
+ Get the version of the RSI implementation.
+
+ @param [out] Major The major version of the RSI implementation.
+ @param [out] Minor The minor version of the RSI implementation.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ */
+RETURN_STATUS
+EFIAPI
+RsiGetVersion (
+ OUT UINT16 *CONST Major,
+ OUT UINT16 *CONST Minor
+ )
+{
+ ARM_SMC_ARGS SmcCmd;
+
+ if ((Major == NULL) || (Minor == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ZeroMem (&SmcCmd, sizeof (SmcCmd));
+ SmcCmd.Arg0 = FID_RSI_VERSION;
+
+ ArmCallSmc (&SmcCmd);
+ *Minor = SmcCmd.Arg0 & RSI_VER_MINOR_MASK;
+ *Major = (SmcCmd.Arg0 & RSI_VER_MAJOR_MASK) >> RSI_VER_MAJOR_SHIFT;
+ return RETURN_SUCCESS;
+}
diff --git a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.inf b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.inf
new file mode 100644
index 0000000000000000000000000000000000000000..1e2b72f312587f822dfca1b26b1910f75d4ec7b6
--- /dev/null
+++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.inf
@@ -0,0 +1,29 @@
+## @file
+# Library that implements the Arm CCA Realm Service Interface calls.
+#
+# Copyright (c) 2022 - 2023, Arm Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = ArmCcaRsiLib
+ FILE_GUID = 5EF34A0A-28B5-4E57-A999-CC1528FC629A
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmCcaRsiLib
+
+[Sources]
+ ArmCcaRsiLib.c
+ ArmCcaRsi.h
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ ArmVirtPkg/ArmVirtPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ ArmLib
+ ArmSmcLib
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117681): https://edk2.groups.io/g/devel/message/117681
Mute This Topic: https://groups.io/mt/105483419/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 05/45] ArmVirtPkg: ArmCcaRsiLib: Add interfaces to manage the Realm IPA state
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (3 preceding siblings ...)
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 04/45] ArmVirtPkg: Add Arm CCA Realm Service Interface Library Sami Mujawar
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 06/45] ArmVirtPkg: ArmCcaRsiLib: Add an interface to get an attestation token Sami Mujawar
` (34 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
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+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@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/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 06/45] ArmVirtPkg: ArmCcaRsiLib: Add an interface to get an attestation token
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (4 preceding siblings ...)
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 05/45] ArmVirtPkg: ArmCcaRsiLib: Add interfaces to manage the Realm IPA state Sami Mujawar
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 07/45] ArmVirtPkg: ArmCcaRsiLib: Add interfaces to get/extend REMs Sami Mujawar
` (33 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
A CCA attestation token is a collection of claims about the state of a
Realm and of the CCA platform on which the Realm is running.
A CCA attestation token consists of two parts:
* Realm token - Contains attributes of the Realm, including:
# Realm Initial Measurement
# Realm Extensible Measurements
* CCA platform token - Contains attributes of the CCA platform
on which the Realm is running, including:
# CCA platform identity
# CCA platform life cycle state
# CCA platform software component measurements
The CCA attestation token is used by a verification service to validate
these claims.
The Realm Service Interface defines the following interfaces to retrieve
an attestation token from the Realm Management Monitor (RMM).
- RSI_ATTESTATION_TOKEN_INIT
- RSI_ATTESTATION_TOKEN_CONTINUE
Therefore, update the ArmCcaRsiLib to add an interface to get an
attestation token from the RMM.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/Include/Library/ArmCcaRsiLib.h | 44 ++++-
ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h | 10 +-
ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c | 195 +++++++++++++++++++-
3 files changed, 243 insertions(+), 6 deletions(-)
diff --git a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
index 0c7f1afc78252b286a20dd8a7a81d538cf76ea8f..f88b07ee9806a51dd10add3a82bf5ce1115c0656 100644
--- a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
+++ b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
@@ -31,6 +31,19 @@
*/
#define RIPAS_TYPE_MASK 0xFF
+/* Maximum attestation token size
+ RBXKKY The size of an attestation token is no larger than 4KB.
+*/
+#define MAX_ATTESTATION_TOKEN_SIZE SIZE_4KB
+
+/* Maximum challenge data size in bits.
+*/
+#define MAX_CHALLENGE_DATA_SIZE_BITS 512
+
+/* Minimum recommended challenge data size in bits.
+*/
+#define MIN_CHALLENGE_DATA_SIZE_BITS 256
+
/** An enum describing the RSI RIPAS.
See Section A5.2.2 Realm IPA state, RMM Specification, version A-bet0
*/
@@ -51,6 +64,35 @@ typedef struct RealmConfig {
UINT8 Reserved[SIZE_4KB - sizeof (UINT64)];
} REALM_CONFIG;
+/**
+ Retrieve an attestation token from the RMM.
+
+ @param [in] ChallengeData Pointer to the challenge data to be
+ included in the attestation token.
+ @param [in] ChallengeDataSizeBits Size of the challenge data in bits.
+ @param [out] TokenBuffer Pointer to a buffer to store the
+ retrieved attestation token.
+ @param [in, out] TokenBufferSize Size of the token buffer on input and
+ number of bytes stored in token buffer
+ on return.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ @retval RETURN_ABORTED The operation was aborted as the state
+ of the Realm or REC does not match the
+ state expected by the command.
+ @retval RETURN_NOT_READY The operation requested by the command
+ is not complete.
+**/
+RETURN_STATUS
+EFIAPI
+RsiGetAttestationToken (
+ IN CONST UINT8 *CONST ChallengeData,
+ IN UINT64 ChallengeDataSizeBits,
+ OUT UINT8 *CONST TokenBuffer,
+ IN OUT UINT64 *CONST TokenBufferSize
+ );
+
/**
Returns the IPA state for the page pointed by the address.
@@ -111,7 +153,7 @@ RsiGetRealmConfig (
@retval RETURN_SUCCESS Success.
@retval RETURN_INVALID_PARAMETER A parameter is invalid.
- */
+**/
RETURN_STATUS
EFIAPI
RsiGetVersion (
diff --git a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h
index 9cc12bc5a70b457367077d0b26011c3b91fa63c9..325234d06695befc840dcf37e951130dfe0550c3 100644
--- a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h
+++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h
@@ -18,10 +18,12 @@
#define ARM_CCA_RSI_H_
// FIDs for Realm Service Interface calls.
-#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
+#define FID_RSI_ATTESTATION_TOKEN_CONTINUE 0xC4000195
+#define FID_RSI_ATTESTATION_TOKEN_INIT 0xC4000194
+#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 546df9a94cb86533b37fef7e42fdaf7b8563052d..3cc6be299e0a7bd12e5a91d17eb0b9393f57a907 100644
--- a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
+++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
@@ -82,6 +82,199 @@ AddrIsGranuleAligned (
return TRUE;
}
+/**
+ Continue the operation to retrieve an attestation token.
+
+ @param [out] TokenBuffer Pointer to a buffer to store the
+ retrieved attestation token.
+ @param [in,out] TokenSize On input size of the token buffer,
+ and on output size of the token
+ returned if operation is successful,
+ otherwise 0.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ @retval RETURN_ABORTED The operation was aborted as the state
+ of the Realm or REC does not match the
+ state expected by the command.
+ @retval RETURN_NOT_READY The operation requested by the command
+ is not complete.
+ **/
+STATIC
+RETURN_STATUS
+EFIAPI
+RsiAttestationTokenContinue (
+ OUT UINT8 *CONST TokenBuffer,
+ IN OUT UINT64 *CONST TokenSize
+ )
+{
+ RETURN_STATUS Status;
+ ARM_SMC_ARGS SmcCmd;
+
+ ZeroMem (&SmcCmd, sizeof (SmcCmd));
+ SmcCmd.Arg0 = FID_RSI_ATTESTATION_TOKEN_CONTINUE;
+ // Set the IPA of the Granule to which the token will be written.
+ SmcCmd.Arg1 = (UINTN)TokenBuffer;
+
+ ArmCallSmc (&SmcCmd);
+ Status = RsiCmdStatusToEfiStatus (SmcCmd.Arg0);
+ if (!RETURN_ERROR (Status)) {
+ // Update the token size
+ *TokenSize = SmcCmd.Arg1;
+ } else {
+ // Clear the TokenBuffer on error.
+ ZeroMem (TokenBuffer, *TokenSize);
+ *TokenSize = 0;
+ }
+
+ return Status;
+}
+
+/**
+ Initialize the operation to retrieve an attestation token.
+
+ @param [in] ChallengeData Pointer to the challenge data to be
+ included in the attestation token.
+ @param [in] ChallengeDataSizeBits Size of the challenge data in bits.
+ @param [in] TokenBuffer Pointer to a buffer to store the
+ retrieved attestation token.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ **/
+STATIC
+RETURN_STATUS
+EFIAPI
+RsiAttestationTokenInit (
+ IN CONST UINT8 *CONST ChallengeData,
+ IN UINT64 ChallengeDataSizeBits,
+ IN UINT8 *CONST TokenBuffer
+ )
+{
+ ARM_SMC_ARGS SmcCmd;
+ UINT8 *Buffer8;
+ CONST UINT8 *Data8;
+ UINT64 Count;
+ UINT8 TailBits;
+
+ /* See A7.2.2 Attestation token generation, RMM Specification, version A-bet0
+ IWTKDD - If the size of the challenge provided by the relying party is less
+ than 64 bytes, it should be zero-padded prior to calling
+ RSI_ATTESTATION_TOKEN_INIT.
+
+ Therefore, zero out the SmcCmd memory before coping the ChallengeData
+ bits.
+ */
+ ZeroMem (&SmcCmd, sizeof (SmcCmd));
+ SmcCmd.Arg0 = FID_RSI_ATTESTATION_TOKEN_INIT;
+ // Set the IPA of the Granule to which the token will be written.
+ SmcCmd.Arg1 = (UINTN)TokenBuffer;
+
+ // Copy challenge data.
+ Buffer8 = (UINT8 *)&SmcCmd.Arg2;
+ Data8 = ChallengeData;
+
+ // First copy whole bytes
+ Count = ChallengeDataSizeBits >> 3;
+ CopyMem (Buffer8, Data8, Count);
+
+ // Now copy any remaining tail bits.
+ TailBits = ChallengeDataSizeBits & (8 - 1);
+ if (TailBits > 0) {
+ // Advance buffer pointers.
+ Buffer8 += Count;
+ Data8 += Count;
+
+ // Copy tail byte.
+ *Buffer8 = *Data8;
+
+ // Clear unused tail bits.
+ *Buffer8 &= ~(0xFF << TailBits);
+ }
+
+ ArmCallSmc (&SmcCmd);
+ return RsiCmdStatusToEfiStatus (SmcCmd.Arg0);
+}
+
+/**
+ Retrieve an attestation token from the RMM.
+
+ @param [in] ChallengeData Pointer to the challenge data to be
+ included in the attestation token.
+ @param [in] ChallengeDataSizeBits Size of the challenge data in bits.
+ @param [out] TokenBuffer Pointer to a buffer to store the
+ retrieved attestation token.
+ @param [in, out] TokenBufferSize Size of the token buffer on input and
+ number of bytes stored in token buffer
+ on return.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ @retval RETURN_ABORTED The operation was aborted as the state
+ of the Realm or REC does not match the
+ state expected by the command.
+ @retval RETURN_NOT_READY The operation requested by the command
+ is not complete.
+**/
+RETURN_STATUS
+EFIAPI
+RsiGetAttestationToken (
+ IN CONST UINT8 *CONST ChallengeData,
+ IN UINT64 ChallengeDataSizeBits,
+ OUT UINT8 *CONST TokenBuffer,
+ IN OUT UINT64 *CONST TokenBufferSize
+ )
+{
+ RETURN_STATUS Status;
+
+ if ((TokenBuffer == NULL) ||
+ (TokenBufferSize == NULL) ||
+ (ChallengeData == NULL))
+ {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ if (*TokenBufferSize < MAX_ATTESTATION_TOKEN_SIZE) {
+ *TokenBufferSize = MAX_ATTESTATION_TOKEN_SIZE;
+ return RETURN_BAD_BUFFER_SIZE;
+ }
+
+ if (!AddrIsGranuleAligned ((UINT64 *)TokenBuffer)) {
+ DEBUG ((DEBUG_ERROR, "ERROR : Token buffer not granule aligned\n"));
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ if (ChallengeDataSizeBits > MAX_CHALLENGE_DATA_SIZE_BITS) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ /* See A7.2.2 Attestation token generation, RMM Specification, version A-bet0
+ IWTKDD - Arm recommends that the challenge should contain at least 32 bytes
+ of unique data.
+ */
+ if (ChallengeDataSizeBits < MIN_CHALLENGE_DATA_SIZE_BITS) {
+ DEBUG ((DEBUG_WARN, "Minimum Challenge data size should be 32 bytes\n"));
+ }
+
+ Status = RsiAttestationTokenInit (
+ ChallengeData,
+ ChallengeDataSizeBits,
+ TokenBuffer
+ );
+ if (RETURN_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ /* Loop until the token is ready or there is an error.
+ */
+ do {
+ Status = RsiAttestationTokenContinue (TokenBuffer, TokenBufferSize);
+ } while (Status == RETURN_NOT_READY);
+
+ return Status;
+}
+
/**
Returns the IPA state for the page pointed by the address.
@@ -213,7 +406,7 @@ RsiGetRealmConfig (
@retval RETURN_SUCCESS Success.
@retval RETURN_INVALID_PARAMETER A parameter is invalid.
- */
+**/
RETURN_STATUS
EFIAPI
RsiGetVersion (
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117675): https://edk2.groups.io/g/devel/message/117675
Mute This Topic: https://groups.io/mt/105483413/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 07/45] ArmVirtPkg: ArmCcaRsiLib: Add interfaces to get/extend REMs
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (5 preceding siblings ...)
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 06/45] ArmVirtPkg: ArmCcaRsiLib: Add an interface to get an attestation token Sami Mujawar
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 08/45] ArmVirtPkg: ArmCcaRsiLib: Add an interface to make a RSI Host Call Sami Mujawar
` (32 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Ben.Adderson, Sibel.Allinson, nd
The Section A2.1.3 Realm attributes, RMM Specification, version A-bet0
introduces the concept of REMs as described below:
DGRFCS - A Realm Extensible Measurement (REM) is a measurement value
which can be extended during the lifetime of a Realm.
IFMPYL - Attributes of a Realm include an array of measurement values.
The first entry in this array is a RIM. The remaining entries
in this array are REMs.
The Realm Service Interface commands defined in section
B4.3.7 RSI_MEASUREMENT_READ and B4.3.6 RSI_MEASUREMENT_EXTEND
specify the interfaces to read and extend measurements to REMs.
Therefore, update ArmCcaRsiLib to add interfaces to get and extend REMs.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/Include/Library/ArmCcaRsiLib.h | 53 ++++++++++++
ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h | 2 +
ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c | 91 ++++++++++++++++++++
3 files changed, 146 insertions(+)
diff --git a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
index f88b07ee9806a51dd10add3a82bf5ce1115c0656..99a8175262331f4b0ddc098c3c62a20954b2b516 100644
--- a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
+++ b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
@@ -7,6 +7,8 @@
- Rsi or RSI - Realm Service Interface
- IPA - Intermediate Physical Address
- RIPAS - Realm IPA state
+ - RIM - Realm Initial Measurement
+ - REM - Realm Extensible Measurement
@par Reference(s):
- Realm Management Monitor (RMM) Specification, version A-bet0
@@ -44,6 +46,21 @@
*/
#define MIN_CHALLENGE_DATA_SIZE_BITS 256
+/* Maximum measurement data size in bytes.
+ See Section C1.11 RmmRealmMeasurement type, RMM Specification, version A-bet0
+ The width of the RmmRealmMeasurement type is 512 bits.
+*/
+#define MAX_MEASUREMENT_DATA_SIZE_BYTES 64
+
+/* Minimum and Maximum indices for REMs
+ See Section A2.1.3 Realm attributes, RMM Specification, version A-bet0
+ IFMPYL - Attributes of a Realm include an array of measurement values. The
+ first entry in this array is a RIM. The remaining entries in this array are
+ REMs.
+*/
+#define MIN_REM_INDEX 1
+#define MAX_REM_INDEX 4
+
/** An enum describing the RSI RIPAS.
See Section A5.2.2 Realm IPA state, RMM Specification, version A-bet0
*/
@@ -127,6 +144,42 @@ RsiSetIpaState (
IN RIPAS State
);
+/**
+ Extends a measurement to a REM.
+
+ @param [in] MeasurementIndex Index of the REM.
+ @param [in] Measurement Pointer to the measurement buffer.
+ @param [in] MeasurementSize Size of the measurement data.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+**/
+RETURN_STATUS
+EFIAPI
+RsiExtendMeasurement (
+ IN UINTN MeasurementIndex,
+ IN CONST UINT8 *CONST Measurement,
+ IN UINTN MeasurementSize
+ );
+
+/**
+ Read the measurement value from a REM.
+
+ @param [in] MeasurementIndex Index of the REM.
+ @param [out] MeasurementBuffer Pointer to store the measurement data.
+ @param [in] MeasurementBufferSize Size of the measurement buffer.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+**/
+RETURN_STATUS
+EFIAPI
+RsiReadMeasurement (
+ IN UINTN MeasurementIndex,
+ OUT UINT8 *CONST MeasurementBuffer,
+ IN UINTN MeasurementBufferSize
+ );
+
/**
Read the Realm Configuration.
diff --git a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h
index 325234d06695befc840dcf37e951130dfe0550c3..6f0ee3061ade5a4a99b717a52d5a241e0e446270 100644
--- a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h
+++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h
@@ -22,6 +22,8 @@
#define FID_RSI_ATTESTATION_TOKEN_INIT 0xC4000194
#define FID_RSI_IPA_STATE_GET 0xC4000198
#define FID_RSI_IPA_STATE_SET 0xC4000197
+#define FID_RSI_MEASUREMENT_EXTEND 0xC4000193
+#define FID_RSI_MEASUREMENT_READ 0xC4000192
#define FID_RSI_REALM_CONFIG 0xC4000196
#define FID_RSI_VERSION 0xC4000190
diff --git a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
index 3cc6be299e0a7bd12e5a91d17eb0b9393f57a907..eb9896668a267f2cdf30f36bd14697d56d2612ed 100644
--- a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
+++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
@@ -8,6 +8,7 @@
- Rsi or RSI - Realm Service Interface
- IPA - Intermediate Physical Address
- RIPAS - Realm IPA state
+ - REM - Realm Extensible Measurement
@par Reference(s):
- Realm Management Monitor (RMM) Specification, version A-bet0
@@ -366,6 +367,96 @@ RsiSetIpaState (
return Status;
}
+/**
+ Extends a measurement to a REM.
+
+ @param [in] MeasurementIndex Index of the REM.
+ @param [in] Measurement Pointer to the measurement buffer.
+ @param [in] MeasurementSize Size of the measurement data.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+**/
+RETURN_STATUS
+EFIAPI
+RsiExtendMeasurement (
+ IN UINTN MeasurementIndex,
+ IN CONST UINT8 *CONST Measurement,
+ IN UINTN MeasurementSize
+ )
+{
+ ARM_SMC_ARGS SmcCmd;
+ UINT64 *Data64;
+
+ if ((MeasurementIndex < MIN_REM_INDEX) ||
+ (MeasurementIndex > MAX_REM_INDEX) ||
+ (Measurement == NULL) ||
+ (MeasurementSize == 0) ||
+ (MeasurementSize > MAX_MEASUREMENT_DATA_SIZE_BYTES))
+ {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ ZeroMem (&SmcCmd, sizeof (SmcCmd));
+
+ SmcCmd.Arg0 = FID_RSI_MEASUREMENT_EXTEND;
+ SmcCmd.Arg1 = MeasurementIndex;
+ SmcCmd.Arg2 = MeasurementSize;
+
+ Data64 = &SmcCmd.Arg3;
+ CopyMem (Data64, Measurement, MeasurementSize);
+
+ ArmCallSmc (&SmcCmd);
+ return RsiCmdStatusToEfiStatus (SmcCmd.Arg0);
+}
+
+/**
+ Read the measurement value from a REM.
+
+ @param [in] MeasurementIndex Index of the REM.
+ @param [out] MeasurementBuffer Pointer to store the measurement data.
+ @param [in] MeasurementBufferSize Size of the measurement buffer.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+**/
+RETURN_STATUS
+EFIAPI
+RsiReadMeasurement (
+ IN UINTN MeasurementIndex,
+ OUT UINT8 *CONST MeasurementBuffer,
+ IN UINTN MeasurementBufferSize
+ )
+{
+ RETURN_STATUS Status;
+ ARM_SMC_ARGS SmcCmd;
+ UINT64 *Data64;
+
+ if ((MeasurementIndex < MIN_REM_INDEX) ||
+ (MeasurementIndex > MAX_REM_INDEX) ||
+ (MeasurementBuffer == NULL))
+ {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ if (MeasurementBufferSize < MAX_MEASUREMENT_DATA_SIZE_BYTES) {
+ return RETURN_BUFFER_TOO_SMALL;
+ }
+
+ ZeroMem (&SmcCmd, sizeof (SmcCmd));
+ SmcCmd.Arg0 = FID_RSI_MEASUREMENT_READ;
+ SmcCmd.Arg1 = MeasurementIndex;
+
+ ArmCallSmc (&SmcCmd);
+ Status = RsiCmdStatusToEfiStatus (SmcCmd.Arg0);
+ if (!RETURN_ERROR (Status)) {
+ Data64 = &SmcCmd.Arg1;
+ CopyMem (MeasurementBuffer, Data64, MAX_MEASUREMENT_DATA_SIZE_BYTES);
+ }
+
+ 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 (#117676): https://edk2.groups.io/g/devel/message/117676
Mute This Topic: https://groups.io/mt/105483414/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 08/45] ArmVirtPkg: ArmCcaRsiLib: Add an interface to make a RSI Host Call
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (6 preceding siblings ...)
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 07/45] ArmVirtPkg: ArmCcaRsiLib: Add interfaces to get/extend REMs Sami Mujawar
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 09/45] ArmVirtPkg: Define a GUID HOB for IPA width of a Realm Sami Mujawar
` (31 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
The Section A4.5 Host call, RMM Specification, version A-bet0
describes the programming model for Realm communication with
the Host and specifies the following:
DYDJWT - A Host call is a call made by the Realm to the Host, by
execution of the RSI_HOST_CALL command.
IXNFKZ - A Host call can be used by a Realm to make a hypercall.
DYDJWT - A Host call is a call made by the Realm to the Host, by
execution of the RSI_HOST_CALL command.
Therefore, introduce definition of HOST_CALL_ARGS structure that
represents the arguments to the RSI_HOST_CALL command as defined
in Section B4.3.3 RSI_HOST_CALL command.
Also update the ArmCcaRsiLib library to add a new interface
RsiHostCall () to make a Host call.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/Include/Library/ArmCcaRsiLib.h | 36 ++++++++++++++++++
ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h | 1 +
ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c | 40 ++++++++++++++++++++
3 files changed, 77 insertions(+)
diff --git a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
index 99a8175262331f4b0ddc098c3c62a20954b2b516..db1ae5b4c1a6475a275ce6be3383ea933ec9af20 100644
--- a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
+++ b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
@@ -81,6 +81,21 @@ typedef struct RealmConfig {
UINT8 Reserved[SIZE_4KB - sizeof (UINT64)];
} REALM_CONFIG;
+/** A structure describing the Host Call arguments
+ See Section 4.4.2 RsiHostCall type, RMM Specification, version A-bet0
+*/
+typedef struct HostCallArgs {
+ UINT64 Imm;
+ UINT64 Gprs0;
+ UINT64 Gprs1;
+ UINT64 Gprs2;
+ UINT64 Gprs3;
+ UINT64 Gprs4;
+ UINT64 Gprs5;
+ UINT64 Gprs6;
+ UINT8 Reserved[0x1000 - (sizeof (UINT64) * 8)];
+} HOST_CALL_ARGS;
+
/**
Retrieve an attestation token from the RMM.
@@ -198,6 +213,27 @@ RsiGetRealmConfig (
IN REALM_CONFIG *Config
);
+/**
+ Make a Host Call.
+
+ A Host call can be used by a Realm to make a hypercall.
+ On Realm execution of HVC, an Unknown exception is taken to the Realm.
+
+ @param [in] Args Pointer to the IPA of the Host call data
+ structure.
+
+ Note: The IPA of the Host call arguments data structure must be aligned
+ to the Realm granule size.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+**/
+RETURN_STATUS
+EFIAPI
+RsiHostCall (
+ IN HOST_CALL_ARGS *Args
+ );
+
/**
Get the version of the RSI implementation.
diff --git a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h
index 6f0ee3061ade5a4a99b717a52d5a241e0e446270..70e84a20711f04c32a5850230cc907a6d231f50b 100644
--- a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h
+++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h
@@ -20,6 +20,7 @@
// FIDs for Realm Service Interface calls.
#define FID_RSI_ATTESTATION_TOKEN_CONTINUE 0xC4000195
#define FID_RSI_ATTESTATION_TOKEN_INIT 0xC4000194
+#define FID_RSI_HOST_CALL 0xC4000199
#define FID_RSI_IPA_STATE_GET 0xC4000198
#define FID_RSI_IPA_STATE_SET 0xC4000197
#define FID_RSI_MEASUREMENT_EXTEND 0xC4000193
diff --git a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
index eb9896668a267f2cdf30f36bd14697d56d2612ed..79a65300f05af665b3afebe2a8f8b1f6faf76f23 100644
--- a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
+++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
@@ -489,6 +489,46 @@ RsiGetRealmConfig (
return RsiCmdStatusToEfiStatus (SmcCmd.Arg0);
}
+/**
+ Make a Host Call.
+
+ A Host call can be used by a Realm to make a hypercall.
+ On Realm execution of HVC, an Unknown exception is taken to the Realm.
+
+ @param [in] Args Pointer to the IPA of the Host call data
+ structure.
+
+ Note: The IPA of the Host call arguments data structure must be aligned
+ to the Realm granule size.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+**/
+RETURN_STATUS
+EFIAPI
+RsiHostCall (
+ IN HOST_CALL_ARGS *Args
+ )
+{
+ ARM_SMC_ARGS SmcCmd;
+
+ if ((Args == NULL) || (!AddrIsGranuleAligned ((UINT64 *)Args))) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ STATIC_ASSERT (sizeof (HOST_CALL_ARGS) == SIZE_4KB);
+
+ // Clear the reserved fields
+ ZeroMem (&Args->Reserved, sizeof (Args->Reserved));
+
+ ZeroMem (&SmcCmd, sizeof (SmcCmd));
+ SmcCmd.Arg0 = FID_RSI_HOST_CALL;
+ SmcCmd.Arg1 = (UINTN)Args;
+
+ ArmCallSmc (&SmcCmd);
+ return RsiCmdStatusToEfiStatus (SmcCmd.Arg0);
+}
+
/**
Get the version of the RSI implementation.
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117686): https://edk2.groups.io/g/devel/message/117686
Mute This Topic: https://groups.io/mt/105483425/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 09/45] ArmVirtPkg: Define a GUID HOB for IPA width of a Realm
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (7 preceding siblings ...)
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 08/45] ArmVirtPkg: ArmCcaRsiLib: Add an interface to make a RSI Host Call Sami Mujawar
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 10/45] ArmVirtPkg: Add library for Arm CCA initialisation in PEI Sami Mujawar
` (30 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
The IPA width of a Realm is read from the Realm Config by invoking
the RSI call RSI_REALM_CONFIG to read the Realm Config. The IPA width
is then stored in a GUID HOB gArmCcaIpaWidthGuid for subsequent use.
This GUID HOB is also useful to pass the IPA width of the Realm to the
DXE phase.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/ArmVirtPkg.dec | 1 +
1 file changed, 1 insertion(+)
diff --git a/ArmVirtPkg/ArmVirtPkg.dec b/ArmVirtPkg/ArmVirtPkg.dec
index d92cb52fc30a6f0ee3469fbd2a940f88e9cf2c67..0f95fd43bd189eda713aeccc6c73019e0f815169 100644
--- a/ArmVirtPkg/ArmVirtPkg.dec
+++ b/ArmVirtPkg/ArmVirtPkg.dec
@@ -34,6 +34,7 @@ [Guids.common]
gEarlyPL011BaseAddressGuid = { 0xB199DEA9, 0xFD5C, 0x4A84, { 0x80, 0x82, 0x2F, 0x41, 0x70, 0x78, 0x03, 0x05 } }
gEarly16550UartBaseAddressGuid = { 0xea67ca3e, 0x1f54, 0x436b, { 0x97, 0x88, 0xd4, 0xeb, 0x29, 0xc3, 0x42, 0x67 } }
gArmVirtSystemMemorySizeGuid = { 0x504eccb9, 0x1bf0, 0x4420, { 0x86, 0x5d, 0xdc, 0x66, 0x06, 0xd4, 0x13, 0xbf } }
+ gArmCcaIpaWidthGuid = { 0xbdb66787, 0xfc8a, 0x412e, { 0xa0, 0x9b, 0x84, 0x96, 0x61, 0x81, 0x72, 0xc0 } }
[PcdsFeatureFlag]
#
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117670): https://edk2.groups.io/g/devel/message/117670
Mute This Topic: https://groups.io/mt/105483408/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 10/45] ArmVirtPkg: Add library for Arm CCA initialisation in PEI
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (8 preceding siblings ...)
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 09/45] ArmVirtPkg: Define a GUID HOB for IPA width of a Realm Sami Mujawar
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 11/45] ArmVirtPkg: Add NULL instance of ArmCcaInitPeiLib Sami Mujawar
` (29 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
Add ArmCcaInitPeiLib library that performs the Arm CCA specific
initialisation in the PEI phase like:
- Configuring the system memory as Protected RAM.
- Reading the Realm Config and storing the IPA width in
a GUID HOB i.e., gArmCcaIpaWidthGuid for subsequent use.
- Calling ArmCcaConfigureMmio () to configure the MMIO regions
by setting the Unprotected IPA attribute in the page tables.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/ArmVirtPkg.dec | 1 +
ArmVirtPkg/Include/Library/ArmCcaInitPeiLib.h | 49 +++++++++
ArmVirtPkg/Library/ArmCcaInitPeiLib/ArmCcaInitPeiLib.c | 116 ++++++++++++++++++++
ArmVirtPkg/Library/ArmCcaInitPeiLib/ArmCcaInitPeiLib.inf | 39 +++++++
4 files changed, 205 insertions(+)
diff --git a/ArmVirtPkg/ArmVirtPkg.dec b/ArmVirtPkg/ArmVirtPkg.dec
index 0f95fd43bd189eda713aeccc6c73019e0f815169..23179c89704db789ab649de81873924c3958ab2a 100644
--- a/ArmVirtPkg/ArmVirtPkg.dec
+++ b/ArmVirtPkg/ArmVirtPkg.dec
@@ -26,6 +26,7 @@ [Includes.common]
Include # Root include for the package
[LibraryClasses]
+ ArmCcaInitPeiLib|Include/Library/ArmCcaInitPeiLib.h
ArmCcaRsiLib|Include/Library/ArmCcaRsiLib.h
ArmVirtMemInfoLib|Include/Library/ArmVirtMemInfoLib.h
diff --git a/ArmVirtPkg/Include/Library/ArmCcaInitPeiLib.h b/ArmVirtPkg/Include/Library/ArmCcaInitPeiLib.h
new file mode 100644
index 0000000000000000000000000000000000000000..439a70a54a218badd4cd4d6c419df58f57271cc2
--- /dev/null
+++ b/ArmVirtPkg/Include/Library/ArmCcaInitPeiLib.h
@@ -0,0 +1,49 @@
+/** @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_INIT_PEI_LIB_
+#define ARM_CCA_INIT_PEI_LIB_
+
+#include <Base.h>
+
+/**
+ Configure the System Memory region as Protected RAM.
+
+ When a VMM creates a Realm, a small amount of DRAM (which contains the
+ firmware image) and the initial content is configured as Protected RAM.
+ The remaining System Memory is in the Protected Empty state. The firmware
+ must then initialise the remaining System Memory as Protected RAM before
+ it can be accessed.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ @retval RETURN_UNSUPPORTED The execution context is not in a Realm.
+**/
+RETURN_STATUS
+EFIAPI
+ArmCcaConfigureSystemMemory (
+ VOID
+ );
+
+/**
+ Perform Arm CCA specific initialisations.
+
+ @retval RETURN_SUCCESS Success or execution context is not a Realm.
+ @retval RETURN_OUT_OF_RESOURCES Out of resources.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+**/
+RETURN_STATUS
+EFIAPI
+ArmCcaInitialize (
+ VOID
+ );
+
+#endif // ARM_CCA_LIB_
diff --git a/ArmVirtPkg/Library/ArmCcaInitPeiLib/ArmCcaInitPeiLib.c b/ArmVirtPkg/Library/ArmCcaInitPeiLib/ArmCcaInitPeiLib.c
new file mode 100644
index 0000000000000000000000000000000000000000..2b2801cc5426994efc15c970fd6b0adf43bd7d36
--- /dev/null
+++ b/ArmVirtPkg/Library/ArmCcaInitPeiLib/ArmCcaInitPeiLib.c
@@ -0,0 +1,116 @@
+/** @file
+ Library that implements the Arm CCA initialisation in PEI phase.
+
+ 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 <PiPei.h>
+
+#include <Library/ArmCcaLib.h>
+#include <Library/ArmCcaRsiLib.h>
+#include <Library/ArmMmuLib.h>
+#include <Library/ArmVirtMemInfoLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+
+/**
+ Configure the System Memory region as Protected RAM.
+
+ When a VMM creates a Realm, a small amount of DRAM (which contains the
+ firmware image) and the initial content is configured as Protected RAM.
+ The remaining System Memory is in the Protected Empty state. The firmware
+ must then initialise the remaining System Memory as Protected RAM before
+ it can be accessed.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ @retval RETURN_UNSUPPORTED The execution context is not in a Realm.
+**/
+RETURN_STATUS
+EFIAPI
+ArmCcaConfigureSystemMemory (
+ VOID
+ )
+{
+ RETURN_STATUS Status;
+
+ if (!IsRealm ()) {
+ return RETURN_UNSUPPORTED;
+ }
+
+ Status = RsiSetIpaState (
+ (UINT64 *)PcdGet64 (PcdSystemMemoryBase),
+ PcdGet64 (PcdSystemMemorySize),
+ RipasRam
+ );
+ if (RETURN_ERROR (Status)) {
+ // Panic
+ CpuDeadLoop ();
+ }
+
+ return Status;
+}
+
+/**
+ Perform Arm CCA specific initialisations.
+
+ @retval RETURN_SUCCESS Success or execution context is not a Realm.
+ @retval RETURN_OUT_OF_RESOURCES Out of resources.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+**/
+RETURN_STATUS
+EFIAPI
+ArmCcaInitialize (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ REALM_CONFIG *Config;
+ UINT64 *IpaWidthHobData;
+
+ if (!IsRealm ()) {
+ // Noting to do as the execution context is not a Realm.
+ return RETURN_SUCCESS;
+ }
+
+ // Read the Realm Config and store the IPA width in a GUID HOB.
+ Config = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (REALM_CONFIG)));
+ if (Config == NULL) {
+ ASSERT (0);
+ return RETURN_OUT_OF_RESOURCES;
+ }
+
+ ZeroMem (Config, sizeof (REALM_CONFIG));
+
+ Status = RsiGetRealmConfig (Config);
+ if (RETURN_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ IpaWidthHobData = BuildGuidHob (
+ &gArmCcaIpaWidthGuid,
+ sizeof (*IpaWidthHobData)
+ );
+ if (IpaWidthHobData == NULL) {
+ ASSERT (0);
+ FreePages (Config, EFI_SIZE_TO_PAGES (sizeof (REALM_CONFIG)));
+ return RETURN_OUT_OF_RESOURCES;
+ }
+
+ *IpaWidthHobData = Config->IpaWidth;
+
+ FreePages (Config, EFI_SIZE_TO_PAGES (sizeof (REALM_CONFIG)));
+
+ // Configure the MMIO memory regions.
+ return ArmCcaConfigureMmio (*IpaWidthHobData);
+}
diff --git a/ArmVirtPkg/Library/ArmCcaInitPeiLib/ArmCcaInitPeiLib.inf b/ArmVirtPkg/Library/ArmCcaInitPeiLib/ArmCcaInitPeiLib.inf
new file mode 100644
index 0000000000000000000000000000000000000000..f2a321d9cdfcf1bd87d6584e3c6834686a298bf0
--- /dev/null
+++ b/ArmVirtPkg/Library/ArmCcaInitPeiLib/ArmCcaInitPeiLib.inf
@@ -0,0 +1,39 @@
+## @file
+# Library that implements the Arm CCA initialisation in PEI phase.
+#
+# Copyright (c) 2022 - 2023, Arm Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = ArmCcaInitPeiLib
+ FILE_GUID = 9A8C3768-79ED-487E-8155-BBF4DD638296
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmCcaInitPeiLib
+
+[Sources]
+ ArmCcaInitPeiLib.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ ArmVirtPkg/ArmVirtPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ ArmCcaLib
+ ArmCcaRsiLib
+ ArmLib
+ ArmMmuLib
+ ArmVirtMemInfoLib
+ BaseLib
+
+[Pcd]
+ gArmTokenSpaceGuid.PcdSystemMemoryBase
+ gArmTokenSpaceGuid.PcdSystemMemorySize
+
+[Guids]
+ gArmCcaIpaWidthGuid
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117671): https://edk2.groups.io/g/devel/message/117671
Mute This Topic: https://groups.io/mt/105483409/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 11/45] ArmVirtPkg: Add NULL instance of ArmCcaInitPeiLib
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (9 preceding siblings ...)
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 10/45] ArmVirtPkg: Add library for Arm CCA initialisation in PEI Sami Mujawar
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 12/45] ArmVirtPkg: Add library for Arm CCA helper functions Sami Mujawar
` (28 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
Add a NULL instance of ArmCcaInitPeiLib library that guest firmware
for VMMs that do not implement Arm CCA Realms can use.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/ArmVirt.dsc.inc | 2 +
ArmVirtPkg/Library/ArmCcaInitPeiLibNull/ArmCcaInitPeiLibNull.c | 59 ++++++++++++++++++++
ArmVirtPkg/Library/ArmCcaInitPeiLibNull/ArmCcaInitPeiLibNull.inf | 27 +++++++++
3 files changed, 88 insertions(+)
diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
index 2bc6a29eb131f7c3817c4b411a0a69eb6181a059..8c1063fb73f81e69e866549a2ba9b12945c83d9c 100644
--- a/ArmVirtPkg/ArmVirt.dsc.inc
+++ b/ArmVirtPkg/ArmVirt.dsc.inc
@@ -194,6 +194,8 @@ [LibraryClasses.common.SEC]
DebugLib|ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartFlash.inf
!endif
+ ArmCcaInitPeiLib|ArmVirtPkg/Library/ArmCcaInitPeiLibNull/ArmCcaInitPeiLibNull.inf
+
[LibraryClasses.common.PEI_CORE]
PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
diff --git a/ArmVirtPkg/Library/ArmCcaInitPeiLibNull/ArmCcaInitPeiLibNull.c b/ArmVirtPkg/Library/ArmCcaInitPeiLibNull/ArmCcaInitPeiLibNull.c
new file mode 100644
index 0000000000000000000000000000000000000000..5b606208dbcf4f0494cde79dd8923ef80fa0137b
--- /dev/null
+++ b/ArmVirtPkg/Library/ArmCcaInitPeiLibNull/ArmCcaInitPeiLibNull.c
@@ -0,0 +1,59 @@
+/** @file
+ Library that implements a NULL implementation of the ArmCcaInitPeiLib.
+
+ 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 <Library/ArmCcaLib.h>
+#include <Library/ArmCcaRsiLib.h>
+#include <Library/ArmMmuLib.h>
+#include <Library/ArmVirtMemInfoLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+
+/**
+ Configure the System Memory region as Protected RAM.
+
+ When a VMM creates a Realm, a small amount of DRAM (which contains the
+ firmware image) and the initial content is configured as Protected RAM.
+ The remaining System Memory is in the Protected Empty state. The firmware
+ must then initialise the remaining System Memory as Protected RAM before
+ it can be accessed.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ @retval RETURN_UNSUPPORTED The execution context is not in a Realm.
+**/
+RETURN_STATUS
+EFIAPI
+ArmCcaConfigureSystemMemory (
+ VOID
+ )
+{
+ return RETURN_UNSUPPORTED;
+}
+
+/**
+ Perform Arm CCA specific initialisations.
+
+ @retval EFI_SUCCESS Success or execution context is not a Realm.
+ @retval EFI_OUT_OF_RESOURCES Out of resources.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+**/
+EFI_STATUS
+EFIAPI
+ArmCcaInitialize (
+ VOID
+ )
+{
+ // Noting to do as the execution context is not a Realm.
+ return EFI_SUCCESS;
+}
diff --git a/ArmVirtPkg/Library/ArmCcaInitPeiLibNull/ArmCcaInitPeiLibNull.inf b/ArmVirtPkg/Library/ArmCcaInitPeiLibNull/ArmCcaInitPeiLibNull.inf
new file mode 100644
index 0000000000000000000000000000000000000000..f039c7abdb6d5391f792179546ff9947086fe541
--- /dev/null
+++ b/ArmVirtPkg/Library/ArmCcaInitPeiLibNull/ArmCcaInitPeiLibNull.inf
@@ -0,0 +1,27 @@
+## @file
+# Library that implements a NULL implementation of the ArmCcaInitPeiLib.
+#
+# Copyright (c) 2022 - 2023, Arm Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = ArmCcaInitPeiLib
+ FILE_GUID = 60686C60-8433-49EE-9F2C-DDC424A95652
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmCcaInitPeiLib
+
+[Sources]
+ ArmCcaInitPeiLibNull.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ ArmVirtPkg/ArmVirtPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117677): https://edk2.groups.io/g/devel/message/117677
Mute This Topic: https://groups.io/mt/105483415/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 12/45] ArmVirtPkg: Add library for Arm CCA helper functions
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (10 preceding siblings ...)
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 11/45] ArmVirtPkg: Add NULL instance of ArmCcaInitPeiLib Sami Mujawar
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 13/45] ArmVirtPkg: Add Null instance of ArmCcaLib Sami Mujawar
` (27 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
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.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/ArmVirtPkg.dec | 1 +
ArmVirtPkg/Include/Library/ArmCcaLib.h | 114 +++++++++++++
ArmVirtPkg/Library/ArmCcaLib/ArmCcaLib.c | 174 ++++++++++++++++++++
ArmVirtPkg/Library/ArmCcaLib/ArmCcaLib.inf | 34 ++++
4 files changed, 323 insertions(+)
diff --git a/ArmVirtPkg/ArmVirtPkg.dec b/ArmVirtPkg/ArmVirtPkg.dec
index 23179c89704db789ab649de81873924c3958ab2a..d521e107ddff15e6dc585e3a63567e3ad817189f 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..57b05f308377cf931c5f43fc7793c260dfdc36fb
--- /dev/null
+++ b/ArmVirtPkg/Library/ArmCcaLib/ArmCcaLib.c
@@ -0,0 +1,174 @@
+/** @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 <Uefi/UefiSpec.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
+ )
+{
+ if (!IsRealm ()) {
+ return RETURN_UNSUPPORTED;
+ }
+
+ if ((Length == 0) || (IpaWidth == 0)) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ return SetMemoryProtectionAttribute (
+ BaseAddress,
+ Length,
+ IpaWidth,
+ 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
+ )
+{
+ 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 (#117682): https://edk2.groups.io/g/devel/message/117682
Mute This Topic: https://groups.io/mt/105483420/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 13/45] ArmVirtPkg: Add Null instance of ArmCcaLib
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (11 preceding siblings ...)
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 12/45] ArmVirtPkg: Add library for Arm CCA helper functions Sami Mujawar
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 14/45] ArmVirtPkg: Define an interface to configure MMIO regions for Arm CCA Sami Mujawar
` (26 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
Add a Null instance of ArmCcaLib so that guest firmware that does
not support Arm CCA can link to this Null version of the library.
Also include it in ArmVirt.dsc.inc so that it is linked for the
non-Arm CCA firmware builds.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/ArmVirt.dsc.inc | 4 +-
ArmVirtPkg/Library/ArmCcaLibNull/ArmCcaLibNull.c | 117 ++++++++++++++++++++
ArmVirtPkg/Library/ArmCcaLibNull/ArmCcaLibNull.inf | 28 +++++
3 files changed, 148 insertions(+), 1 deletion(-)
diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
index 8c1063fb73f81e69e866549a2ba9b12945c83d9c..c8a29dd8ebc88107c4caab4f826001d9b0c2e7f7 100644
--- a/ArmVirtPkg/ArmVirt.dsc.inc
+++ b/ArmVirtPkg/ArmVirt.dsc.inc
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011 - 2022, ARM Limited. All rights reserved.
+# Copyright (c) 2011 - 2023, ARM Limited. All rights reserved.
# Copyright (c) 2014, Linaro Limited. All rights reserved.
# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
# Copyright (c) Microsoft Corporation.
@@ -180,6 +180,8 @@ [LibraryClasses.common]
ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
+ ArmCcaLib|ArmVirtPkg/Library/ArmCcaLibNull/ArmCcaLibNull.inf
+
[LibraryClasses.common.SEC]
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
diff --git a/ArmVirtPkg/Library/ArmCcaLibNull/ArmCcaLibNull.c b/ArmVirtPkg/Library/ArmCcaLibNull/ArmCcaLibNull.c
new file mode 100644
index 0000000000000000000000000000000000000000..e5e645e148d485fc324e060ec27fbc3607fe8aae
--- /dev/null
+++ b/ArmVirtPkg/Library/ArmCcaLibNull/ArmCcaLibNull.c
@@ -0,0 +1,117 @@
+/** @file
+ Null implemmentation of the ArmCcaLib library.
+
+ 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 <Library/ArmCcaLib.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 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
+ )
+{
+ return RETURN_UNSUPPORTED;
+}
+
+/**
+ 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
+ )
+{
+ return RETURN_UNSUPPORTED;
+}
diff --git a/ArmVirtPkg/Library/ArmCcaLibNull/ArmCcaLibNull.inf b/ArmVirtPkg/Library/ArmCcaLibNull/ArmCcaLibNull.inf
new file mode 100644
index 0000000000000000000000000000000000000000..8f6c251afb14da48db45ba78d96d1d497e3fe8eb
--- /dev/null
+++ b/ArmVirtPkg/Library/ArmCcaLibNull/ArmCcaLibNull.inf
@@ -0,0 +1,28 @@
+## @file
+# Null implemmentation of the ArmCcaLib library.
+#
+# 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 = 9E3F7AAA-10A6-4513-A960-B87F4D7DCFC5
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmCcaLib
+
+[Sources]
+ ArmCcaLibNull.c
+
+
+[Packages]
+ ArmVirtPkg/ArmVirtPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117673): https://edk2.groups.io/g/devel/message/117673
Mute This Topic: https://groups.io/mt/105483411/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 14/45] ArmVirtPkg: Define an interface to configure MMIO regions for Arm CCA
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (12 preceding siblings ...)
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 13/45] ArmVirtPkg: Add Null instance of ArmCcaLib Sami Mujawar
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 15/45] ArmVirtPkg: CloudHv: Add a NULL implementation of ArmCcaConfigureMmio Sami Mujawar
` (25 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
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.
The Unprotected IPA space is used for sharing memory and for performing
MMIO accesses with the Host.
An Unprotected IPA is an address in the upper half of a Realm's
IPA space. The most significant bit of an Unprotected IPA is 1.
Therefore, the page tables for the MMIO regions must be updated to set
the most significant bit of the IPA space.
To facilitate this define ArmCcaConfigureMmio () that can be called
during the early firmware startup.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/Include/Library/ArmVirtMemInfoLib.h | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/ArmVirtPkg/Include/Library/ArmVirtMemInfoLib.h b/ArmVirtPkg/Include/Library/ArmVirtMemInfoLib.h
index 7812c2e28657ca9525880dcc0d16d7bca90cc334..b70a96ed923e8c2654e51c9714074744a4d5f0c2 100644
--- a/ArmVirtPkg/Include/Library/ArmVirtMemInfoLib.h
+++ b/ArmVirtPkg/Include/Library/ArmVirtMemInfoLib.h
@@ -1,6 +1,6 @@
/** @file
- Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+ Copyright (c) 2011-2023, Arm Limited. All rights reserved.
Copyright (c) 2017, Linaro, Ltd. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -32,4 +32,21 @@ ArmVirtGetMemoryMap (
OUT ARM_MEMORY_REGION_DESCRIPTOR **VirtualMemoryMap
);
+/**
+ Configure the MMIO regions as shared with the VMM.
+
+ Set the protection attribute for the MMIO regions as Unprotected IPA.
+
+ @param[in] IpaWidth IPA width of the Realm.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ @retval RETURN_UNSUPPORTED The execution context is not in a Realm.
+**/
+EFI_STATUS
+EFIAPI
+ArmCcaConfigureMmio (
+ IN UINT64 IpaWidth
+ );
+
#endif
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117687): https://edk2.groups.io/g/devel/message/117687
Mute This Topic: https://groups.io/mt/105483426/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 15/45] ArmVirtPkg: CloudHv: Add a NULL implementation of ArmCcaConfigureMmio
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (13 preceding siblings ...)
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 14/45] ArmVirtPkg: Define an interface to configure MMIO regions for Arm CCA Sami Mujawar
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 16/45] ArmVirtPkg: Qemu: " Sami Mujawar
` (24 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
To support Arm CCA, a hook function ArmCcaConfigureMmio () has
been added to the ArmVirtMemInfoLib library.
Since, Arm CCA has not been enabled for the Cloud Hypervisor guest
firmware, update the CloudHvVirtMemInfoLib library to add a NULL
implementation for ArmCcaConfigureMmio () that returns
RETURN_UNSUPPORTED.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoLib.c | 22 +++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoLib.c b/ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoLib.c
index 98cc13870599c10bfab5029de9f7730a67099b72..c47ddc4a16caf9b3755617627718789098aa2f26 100644
--- a/ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoLib.c
+++ b/ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoLib.c
@@ -1,6 +1,6 @@
/** @file
- Copyright (c) 2022, Arm Limited. All rights reserved.
+ Copyright (c) 2022 - 2023, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -241,3 +241,23 @@ ArmVirtGetMemoryMap (
*VirtualMemoryMap = VirtualMemoryTable;
}
+
+/**
+ Configure the MMIO regions as shared with the VMM.
+
+ Set the protection attribute for the MMIO regions as Unprotected IPA.
+
+ @param[in] IpaWidth IPA width of the Realm.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ @retval RETURN_UNSUPPORTED The execution context is not in a Realm.
+**/
+EFI_STATUS
+EFIAPI
+ArmCcaConfigureMmio (
+ IN UINT64 IpaWidth
+ )
+{
+ return RETURN_UNSUPPORTED;
+}
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117679): https://edk2.groups.io/g/devel/message/117679
Mute This Topic: https://groups.io/mt/105483417/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 16/45] ArmVirtPkg: Qemu: Add a NULL implementation of ArmCcaConfigureMmio
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (14 preceding siblings ...)
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 15/45] ArmVirtPkg: CloudHv: Add a NULL implementation of ArmCcaConfigureMmio Sami Mujawar
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 17/45] ArmVirtPkg: Xen: " Sami Mujawar
` (23 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
To support Arm CCA, a hook function ArmCcaConfigureMmio () has
been added to the ArmVirtMemInfoLib library.
Since, Arm CCA has not been enabled for the Qemu guest firmware,
update the QemuVirtMemInfoLib library to add a NULL implementation
for ArmCcaConfigureMmio () that returns RETURN_UNSUPPORTED.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.c | 21 ++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.c b/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.c
index 62fa62e5f04668227f7412252212e0462114f85a..18fc8a4447bda601d144c240cb2d355d99321aa5 100644
--- a/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.c
+++ b/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.c
@@ -1,6 +1,7 @@
/** @file
Copyright (c) 2014-2017, Linaro Limited. All rights reserved.
+ Copyright (c) 2023, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -122,3 +123,23 @@ ArmVirtGetMemoryMap (
*VirtualMemoryMap = VirtualMemoryTable;
}
+
+/**
+ Configure the MMIO regions as shared with the VMM.
+
+ Set the protection attribute for the MMIO regions as Unprotected IPA.
+
+ @param[in] IpaWidth IPA width of the Realm.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ @retval RETURN_UNSUPPORTED The execution context is not in a Realm.
+**/
+EFI_STATUS
+EFIAPI
+ArmCcaConfigureMmio (
+ IN UINT64 IpaWidth
+ )
+{
+ return RETURN_UNSUPPORTED;
+}
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117691): https://edk2.groups.io/g/devel/message/117691
Mute This Topic: https://groups.io/mt/105483430/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 17/45] ArmVirtPkg: Xen: Add a NULL implementation of ArmCcaConfigureMmio
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (15 preceding siblings ...)
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 16/45] ArmVirtPkg: Qemu: " Sami Mujawar
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 18/45] ArmVirtPkg: Configure the MMIO regions for Arm CCA Sami Mujawar
` (22 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
To support Arm CCA, a hook function ArmCcaConfigureMmio () has
been added to the ArmVirtMemInfoLib library.
Since, Arm CCA has not been enabled for the Xen guest firmware,
update the XenVirtMemInfoLib library to add a NULL implementation
for ArmCcaConfigureMmio () that returns RETURN_UNSUPPORTED.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/Library/XenVirtMemInfoLib/XenVirtMemInfoLib.c | 21 ++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/ArmVirtPkg/Library/XenVirtMemInfoLib/XenVirtMemInfoLib.c b/ArmVirtPkg/Library/XenVirtMemInfoLib/XenVirtMemInfoLib.c
index ac0c75aecfe54090788836f2eea097f4abb112a3..8a9f6e1e1eee91ec2fc1418b342c0966548e8a6c 100644
--- a/ArmVirtPkg/Library/XenVirtMemInfoLib/XenVirtMemInfoLib.c
+++ b/ArmVirtPkg/Library/XenVirtMemInfoLib/XenVirtMemInfoLib.c
@@ -1,6 +1,7 @@
/** @file
Copyright (c) 2014-2017, Linaro Limited. All rights reserved.
+ Copyright (c) 2023, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -55,3 +56,23 @@ ArmVirtGetMemoryMap (
*VirtualMemoryMap = mVirtualMemoryTable;
}
+
+/**
+ Configure the MMIO regions as shared with the VMM.
+
+ Set the protection attribute for the MMIO regions as Unprotected IPA.
+
+ @param[in] IpaWidth IPA width of the Realm.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ @retval RETURN_UNSUPPORTED The execution context is not in a Realm.
+**/
+EFI_STATUS
+EFIAPI
+ArmCcaConfigureMmio (
+ IN UINT64 IpaWidth
+ )
+{
+ return RETURN_UNSUPPORTED;
+}
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117685): https://edk2.groups.io/g/devel/message/117685
Mute This Topic: https://groups.io/mt/105483424/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 18/45] ArmVirtPkg: Configure the MMIO regions for Arm CCA
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (16 preceding siblings ...)
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 17/45] ArmVirtPkg: Xen: " Sami Mujawar
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 19/45] ArmVirtPkg: Kvmtool: Use Null version of DebugLib in PrePi Sami Mujawar
` (21 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
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.
The Unprotected IPA space is used for sharing memory and for performing
MMIO accesses with the Host.
An Unprotected IPA is an address in the upper half of a Realm's
IPA space. The most significant bit of an Unprotected IPA is 1.
The page tables for the MMIO regions must be updated to set the most
significant bit of the IPA space.
Therefore, implement ArmCcaConfigureMmio () which configures the MMIO
regions as Unprotected IPA by setting the protection attribute in the
page tables for the MMIO regions.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/Library/KvmtoolVirtMemInfoLib/KvmtoolVirtMemInfoLib.c | 39 +++++++++++++++++++-
ArmVirtPkg/Library/KvmtoolVirtMemInfoLib/KvmtoolVirtMemInfoLib.inf | 3 +-
2 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/ArmVirtPkg/Library/KvmtoolVirtMemInfoLib/KvmtoolVirtMemInfoLib.c b/ArmVirtPkg/Library/KvmtoolVirtMemInfoLib/KvmtoolVirtMemInfoLib.c
index 79412897f2251712fafa4a9633b44235f2d7bb9b..a4fee904a43ccb8844ceaea992698a99df2a8b3c 100644
--- a/ArmVirtPkg/Library/KvmtoolVirtMemInfoLib/KvmtoolVirtMemInfoLib.c
+++ b/ArmVirtPkg/Library/KvmtoolVirtMemInfoLib/KvmtoolVirtMemInfoLib.c
@@ -1,14 +1,16 @@
/** @file
Kvmtool virtual memory map library.
- Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.
+ Copyright (c) 2018 - 2023, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Base.h>
+#include <Library/ArmCcaLib.h>
#include <Library/ArmLib.h>
+#include <Library/ArmMmuLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
@@ -96,3 +98,38 @@ ArmVirtGetMemoryMap (
*VirtualMemoryMap = VirtualMemoryTable;
}
+
+/**
+ Configure the MMIO regions as shared with the VMM.
+
+ Set the protection attribute for the MMIO regions as Unprotected IPA.
+
+ @param[in] IpaWidth IPA width of the Realm.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ @retval RETURN_UNSUPPORTED The execution context is not in a Realm.
+**/
+EFI_STATUS
+EFIAPI
+ArmCcaConfigureMmio (
+ IN UINT64 IpaWidth
+ )
+{
+ EFI_STATUS Status;
+
+ if (!IsRealm ()) {
+ return RETURN_UNSUPPORTED;
+ }
+
+ // Set the protection attribute for the Peripheral memory.
+ // Peripheral space before DRAM
+ Status = ArmCcaSetMemoryProtectAttribute (
+ 0,
+ PcdGet64 (PcdSystemMemoryBase),
+ IpaWidth,
+ TRUE
+ );
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
diff --git a/ArmVirtPkg/Library/KvmtoolVirtMemInfoLib/KvmtoolVirtMemInfoLib.inf b/ArmVirtPkg/Library/KvmtoolVirtMemInfoLib/KvmtoolVirtMemInfoLib.inf
index a354e734ab1b7308a3e52b4e2b4885ef29592681..8e157a44dc9d11b9258d3f6182d5b169ec97ae9c 100644
--- a/ArmVirtPkg/Library/KvmtoolVirtMemInfoLib/KvmtoolVirtMemInfoLib.inf
+++ b/ArmVirtPkg/Library/KvmtoolVirtMemInfoLib/KvmtoolVirtMemInfoLib.inf
@@ -1,7 +1,7 @@
## @file
# Kvmtool virtual memory map library.
#
-# Copyright (c) 2018, ARM Limited. All rights reserved.
+# Copyright (c) 2018 - 2023, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -26,6 +26,7 @@ [Packages]
MdePkg/MdePkg.dec
[LibraryClasses]
+ ArmCcaLib
ArmLib
BaseLib
BaseMemoryLib
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117683): https://edk2.groups.io/g/devel/message/117683
Mute This Topic: https://groups.io/mt/105483421/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 19/45] ArmVirtPkg: Kvmtool: Use Null version of DebugLib in PrePi
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (17 preceding siblings ...)
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 18/45] ArmVirtPkg: Configure the MMIO regions for Arm CCA Sami Mujawar
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 20/45] ArmVirtPkg: Introduce ArmVirtMonitorLib library Sami Mujawar
` (20 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
The patch at "6c8a08bd8a680 ArmVirtPkg/PrePi: Ensure timely
execution of library constructors" moved the processing of
library constructors before the MMU is initialised.
This resulted in the BaseDebugLibSerialPort library constructor
BaseDebugLibSerialPortConstructor () which initialises the serial
port, being invoked before the MMU is enabled.
However, the Realm Code requires the protection attribute of
the MMIO regions to be configured as unprotected (shared with
the host), which requires the MMU to be enabled. Otherwise,
accesses to the MMIO region result in a synchronous external
abort being reflected to the Realm by the RMM.
Therefore, link the Null version of DebugLib in PrePi stage.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/ArmVirtKvmTool.dsc | 1 +
1 file changed, 1 insertion(+)
diff --git a/ArmVirtPkg/ArmVirtKvmTool.dsc b/ArmVirtPkg/ArmVirtKvmTool.dsc
index 20da3319667900e64755272fa110d57452d1fc67..d09b3e06928ad70dba8581bd605a7c76b231ba61 100644
--- a/ArmVirtPkg/ArmVirtKvmTool.dsc
+++ b/ArmVirtPkg/ArmVirtKvmTool.dsc
@@ -250,6 +250,7 @@ [Components.common]
#
ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf {
<LibraryClasses>
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117690): https://edk2.groups.io/g/devel/message/117690
Mute This Topic: https://groups.io/mt/105483429/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 20/45] ArmVirtPkg: Introduce ArmVirtMonitorLib library
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (18 preceding siblings ...)
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 19/45] ArmVirtPkg: Kvmtool: Use Null version of DebugLib in PrePi Sami Mujawar
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 21/45] ArmVirtPkg: Kvmtool: Use ArmVirt instance of ArmMonitorLib Sami Mujawar
` (19 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
ArmMonitorLib provides an abstraction for invoking monitor calls
using a SMC or HVC conduit based on the value configured in the
PCD PcdMonitorConduitHvc.
The monitor call conduit is fixed for a platform firmware in
most scenarios. For a normal virtual machine guest firmware,
the default conduit is HVC. However, for Arm CCA the Realm
code must use SMC as the conduit.
To have a common code base for Guest/Virtual firmware to be used
by both normal VMs and Realm VMs, the firmware must dynamically
detect the conduit to be used.
Some VMMs like kvmtool setup the PSCI conduit to be used in the
device tree it hands off to the firmware. Therefore, introduce
an ArmVirt instance of ArmMontorLib that parses this device tree
to read the PSCI conduit value and issues monitor calls using
the appropriate conduit.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/Library/ArmVirtMonitorLib/ArmVirtMonitorLib.c | 119 ++++++++++++++++++++
ArmVirtPkg/Library/ArmVirtMonitorLib/ArmVirtMonitorLib.inf | 37 ++++++
2 files changed, 156 insertions(+)
diff --git a/ArmVirtPkg/Library/ArmVirtMonitorLib/ArmVirtMonitorLib.c b/ArmVirtPkg/Library/ArmVirtMonitorLib/ArmVirtMonitorLib.c
new file mode 100644
index 0000000000000000000000000000000000000000..a13bec36b3537a2348e7883c29c5beb6e55dc64b
--- /dev/null
+++ b/ArmVirtPkg/Library/ArmVirtMonitorLib/ArmVirtMonitorLib.c
@@ -0,0 +1,119 @@
+/** @file
+ Arm Monitor Library.
+
+ Copyright (c) 2022 - 2023, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+
+#include <Library/ArmHvcLib.h>
+#include <Library/ArmMonitorLib.h>
+#include <Library/ArmSmcLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/FdtClient.h>
+
+/**
+ An enum representing the PSCI conduits for issuing monitor calls.
+*/
+typedef enum PsciConduit {
+ PsciConduitHvc, // < HVC conduit
+ PsciConduitSmc, // < SMC conduit
+ PsciConduitMax
+} PSCI_CONDUIT;
+
+/**
+ A variable that stores the PSCI conduit to be used.
+*/
+STATIC PSCI_CONDUIT mArmPsciConduit = PsciConduitMax;
+
+/** Monitor call.
+
+ An HyperVisor Call (HVC) or System Monitor Call (SMC) will be issued
+ depending on the conduit. The library constructor for ArmVirtMonitorLib
+ determines the conduit by parsing the Device Tree handed off by the VMM
+ and initialising mArmPsciConduit.
+
+ @param [in,out] Args Arguments for the HVC/SMC.
+**/
+VOID
+EFIAPI
+ArmMonitorCall (
+ IN OUT ARM_MONITOR_ARGS *Args
+ )
+{
+ switch (mArmPsciConduit) {
+ case PsciConduitHvc:
+ ArmCallHvc ((ARM_HVC_ARGS *)Args);
+ break;
+ case PsciConduitSmc:
+ ArmCallSmc ((ARM_SMC_ARGS *)Args);
+ break;
+ default:
+ ASSERT (0);
+ CpuDeadLoop ();
+ }
+}
+
+/** Constructor for ArmVirtMonitorLib.
+
+ The library constructor for ArmVirtMonitorLib determines the conduit
+ by parsing the Device Tree handed off by the VMM and initialising
+ mArmPsciConduit, which can then be used to select the appropriate
+ conduit for invoking the monitor call.
+
+ @retval RETURN_SUCCESS The constructor always returns RETURN_SUCCESS.
+ @retval RETURN_NOT_FOUND An entry for the PSCI conduit was not found in
+ the platform device tree.
+**/
+RETURN_STATUS
+EFIAPI
+ArmVirtMonitorLibConstructor (
+ VOID
+ )
+{
+ RETURN_STATUS Status;
+ FDT_CLIENT_PROTOCOL *FdtClient;
+ CONST VOID *Prop;
+
+ Status = gBS->LocateProtocol (
+ &gFdtClientProtocolGuid,
+ NULL,
+ (VOID **)&FdtClient
+ );
+ if (RETURN_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ Status = FdtClient->FindCompatibleNodeProperty (
+ FdtClient,
+ "arm,psci-0.2",
+ "method",
+ &Prop,
+ NULL
+ );
+ if (RETURN_ERROR (Status)) {
+ return Status;
+ }
+
+ if (AsciiStrnCmp (Prop, "hvc", 3) == 0) {
+ mArmPsciConduit = PsciConduitHvc;
+ } else if (AsciiStrnCmp (Prop, "smc", 3) == 0) {
+ mArmPsciConduit = PsciConduitSmc;
+ } else {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: Unknown PSCI method \"%a\"\n",
+ __func__,
+ Prop
+ ));
+ return RETURN_NOT_FOUND;
+ }
+
+ return RETURN_SUCCESS;
+}
diff --git a/ArmVirtPkg/Library/ArmVirtMonitorLib/ArmVirtMonitorLib.inf b/ArmVirtPkg/Library/ArmVirtMonitorLib/ArmVirtMonitorLib.inf
new file mode 100644
index 0000000000000000000000000000000000000000..d90f92d5faff96de9cd0433c1de18b0168b42592
--- /dev/null
+++ b/ArmVirtPkg/Library/ArmVirtMonitorLib/ArmVirtMonitorLib.inf
@@ -0,0 +1,37 @@
+## @file
+# Arm Virt Monitor Library
+#
+# Copyright (c) 2022 - 2023, Arm Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 1.29
+ BASE_NAME = ArmVirtMonitorLib
+ FILE_GUID = 3E464134-890D-4C3F-A559-D0FE2803E332
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmMonitorLib|DXE_DRIVER DXE_RUNTIME_DRIVER
+ CONSTRUCTOR = ArmVirtMonitorLibConstructor
+
+[Sources]
+ ArmVirtMonitorLib.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ ArmHvcLib
+ ArmSmcLib
+ DebugLib
+ UefiBootServicesTableLib
+
+[Protocols]
+ gFdtClientProtocolGuid ## CONSUMES
+
+[Depex]
+ gFdtClientProtocolGuid
+
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117678): https://edk2.groups.io/g/devel/message/117678
Mute This Topic: https://groups.io/mt/105483416/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 21/45] ArmVirtPkg: Kvmtool: Use ArmVirt instance of ArmMonitorLib
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (19 preceding siblings ...)
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 20/45] ArmVirtPkg: Introduce ArmVirtMonitorLib library Sami Mujawar
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 22/45] ArmVirtPkg: Add Arm CCA libraries for Kvmtool guest firmware Sami Mujawar
` (18 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
ArmVirtMonitorLib parses the device tree handed off by the VMM
to determine the conduit that must be used for monitor calls.
For a normal virtual machine guest firmware, the default conduit
is HVC. However, for Arm CCA the Realm code must use SMC as the
conduit. Kvmtool populates the correct conduit to be used by the
VM instance in the device tree it hands off to the firmware.
Therefore, switch to using ArmVirtMonitorLib as this enables to
have a unified firmware binary for both Normal VMs and Realm VMs.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/ArmVirtKvmTool.dsc | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/ArmVirtPkg/ArmVirtKvmTool.dsc b/ArmVirtPkg/ArmVirtKvmTool.dsc
index d09b3e06928ad70dba8581bd605a7c76b231ba61..a310fbd53ec7a37805865525da142e0610846f86 100644
--- a/ArmVirtPkg/ArmVirtKvmTool.dsc
+++ b/ArmVirtPkg/ArmVirtKvmTool.dsc
@@ -84,7 +84,7 @@ [LibraryClasses.common]
HwInfoParserLib|DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf
DynamicPlatRepoLib|DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoLib.inf
- ArmMonitorLib|ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf
+ ArmMonitorLib|ArmVirtPkg/Library/ArmVirtMonitorLib/ArmVirtMonitorLib.inf
ArmTrngLib|ArmPkg/Library/ArmTrngLib/ArmTrngLib.inf
[LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM]
@@ -126,8 +126,6 @@ [PcdsFeatureFlag.common]
# Use MMIO for accessing RTC controller registers.
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcUseMmio|TRUE
- gArmTokenSpaceGuid.PcdMonitorConduitHvc|TRUE
-
[PcdsFixedAtBuild.common]
gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000000F
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117680): https://edk2.groups.io/g/devel/message/117680
Mute This Topic: https://groups.io/mt/105483418/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 22/45] ArmVirtPkg: Add Arm CCA libraries for Kvmtool guest firmware
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (20 preceding siblings ...)
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 21/45] ArmVirtPkg: Kvmtool: Use ArmVirt instance of ArmMonitorLib Sami Mujawar
@ 2024-04-12 14:32 ` Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 23/45] ArmVirtPkg: Arm CCA configure system memory in early Pei Sami Mujawar
` (17 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:32 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
The following libraries have been introduced for Arm CCA:
* ArmCcaInitPeiLib - provides functions for ARM CCA
initialisations in early PEI phase.
* ArmCcaLib - provides the necessary helper functions
for Arm CCA
* ArmCcaRsiLib - implements functions to call the Realm
Service Interface.
Therefore, add these libraries in the Kvmtool guest firmware
workspace as part of enabling support for Arm CCA.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/ArmVirtKvmTool.dsc | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/ArmVirtPkg/ArmVirtKvmTool.dsc b/ArmVirtPkg/ArmVirtKvmTool.dsc
index a310fbd53ec7a37805865525da142e0610846f86..33eb280f91413141cacb6526375c2733778a853c 100644
--- a/ArmVirtPkg/ArmVirtKvmTool.dsc
+++ b/ArmVirtPkg/ArmVirtKvmTool.dsc
@@ -87,6 +87,10 @@ [LibraryClasses.common]
ArmMonitorLib|ArmVirtPkg/Library/ArmVirtMonitorLib/ArmVirtMonitorLib.inf
ArmTrngLib|ArmPkg/Library/ArmTrngLib/ArmTrngLib.inf
+[LibraryClasses.AARCH64]
+ ArmCcaLib|ArmVirtPkg/Library/ArmCcaLib/ArmCcaLib.inf
+ ArmCcaRsiLib|ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.inf
+
[LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM]
PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
PlatformHookLib|ArmVirtPkg/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.inf
@@ -100,6 +104,9 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER]
DebugLib|MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf
!endif
+[LibraryClasses.AARCH64.SEC, LibraryClasses.AARCH64.PEI_CORE, LibraryClasses.AARCH64.PEIM]
+ ArmCcaInitPeiLib|ArmVirtPkg/Library/ArmCcaInitPeiLib/ArmCcaInitPeiLib.inf
+
[LibraryClasses.common.UEFI_DRIVER]
UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117689): https://edk2.groups.io/g/devel/message/117689
Mute This Topic: https://groups.io/mt/105483428/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 23/45] ArmVirtPkg: Arm CCA configure system memory in early Pei
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (21 preceding siblings ...)
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 22/45] ArmVirtPkg: Add Arm CCA libraries for Kvmtool guest firmware Sami Mujawar
@ 2024-04-12 14:33 ` Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 24/45] ArmVirtPkg: Perform Arm CCA initialisation in the Pei phase Sami Mujawar
` (16 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:33 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
When a VMM creates a Realm, a small amount of DRAM (which contains
the firmware image) and the initial content is configured as Protected
RAM. The remaining System Memory is in the Protected Empty state. The
firmware must then initialise the remaining System Memory as Protected
RAM before it can be accessed.
Therefore, call the ArmCcaConfigureSystemMemory () in the early Pei
phase so that the System Memory is configured as Protected RAM.
Note: ArmCcaConfigureSystemMemory () is implemented in ArmCcaInitPeiLib
for which a Null implementation is provided. Therefore, this change
should not have an impact for non-Arm CCA enabled systems.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S | 6 +++++-
ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf | 3 ++-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S b/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S
index 01623b6b3591242778a5c76df5d401b1ce71834f..03bef60dd408e787cbeb9eeee12d95639821714f 100644
--- a/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S
+++ b/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+// Copyright (c) 2011-2023, Arm Limited. All rights reserved.
// Copyright (c) 2015-2016, Linaro Limited. All rights reserved.
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -11,6 +11,10 @@
ASM_FUNC(_ModuleEntryPoint)
bl ASM_PFX(DiscoverDramFromDt)
+ // Check if we are in a Realm and configure
+ // the System Memory as Protected RAM.
+ bl ASM_PFX(ArmCcaConfigureSystemMemory)
+
// Get ID of this CPU in Multicore system
bl ASM_PFX(ArmReadMpidr)
// Keep a copy of the MpId register value
diff --git a/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf b/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
index 578ee37e7467b2f29bacac0b5d111271061e3ff5..f1c2776c7b74d0fae3529956ea91a9b504ba83c2 100755
--- a/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
+++ b/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
@@ -1,6 +1,6 @@
#/** @file
#
-# Copyright (c) 2011-2015, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2011-2023, Arm Limited. All rights reserved.<BR>
# Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -38,6 +38,7 @@ [Packages]
OvmfPkg/OvmfPkg.dec
[LibraryClasses]
+ ArmCcaInitPeiLib
BaseLib
DebugLib
FdtLib
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117702): https://edk2.groups.io/g/devel/message/117702
Mute This Topic: https://groups.io/mt/105483445/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 24/45] ArmVirtPkg: Perform Arm CCA initialisation in the Pei phase
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (22 preceding siblings ...)
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 23/45] ArmVirtPkg: Arm CCA configure system memory in early Pei Sami Mujawar
@ 2024-04-12 14:33 ` Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 25/45] ArmVirtPkg: Introduce Realm Aperture Management Protocol Sami Mujawar
` (15 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:33 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
Add ArmCcaInitialize () to perform Arm CCA specific initialisation
like:
- Reading the Realm Config by calling the RSI interface.
- Storing the IPA width of the Realm in PcdArmCcaEarlyIpaWidth.
- Configuring the MMIO regions to update the page tables to set
the protection attribute as Unprotected IPA.
Note: ArmCcaInitialize () is implemented in ArmCcaInitPeiLib for
which a Null implementation is provided. Therefore, this change
should not break existing platforms that do not implement the
Arm CCA.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/PrePi/PrePi.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/ArmVirtPkg/PrePi/PrePi.c b/ArmVirtPkg/PrePi/PrePi.c
index f27e0ad3d223820f60d1f8087325a96c60ebe876..405da60177f56238a79687ff8e1839207b14afd3 100755
--- a/ArmVirtPkg/PrePi/PrePi.c
+++ b/ArmVirtPkg/PrePi/PrePi.c
@@ -9,6 +9,7 @@
#include <PiPei.h>
#include <Pi/PiBootMode.h>
+#include <Library/ArmCcaInitPeiLib.h>
#include <Library/PeCoffLib.h>
#include <Library/PrePiLib.h>
#include <Library/PrintLib.h>
@@ -34,6 +35,7 @@ PrePiMain (
CHAR8 Buffer[100];
UINTN CharCount;
UINTN StacksSize;
+ RETURN_STATUS RetStatus;
// Initialize the architecture specific bits
ArchInitialize ();
@@ -61,6 +63,12 @@ PrePiMain (
Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
ASSERT_EFI_ERROR (Status);
+ // Perform the Arm CCA specific initialisations.
+ RetStatus = ArmCcaInitialize ();
+ if (RETURN_ERROR (RetStatus)) {
+ CpuDeadLoop ();
+ }
+
// Initialize the Serial Port
SerialPortInitialize ();
CharCount = AsciiSPrint (
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117688): https://edk2.groups.io/g/devel/message/117688
Mute This Topic: https://groups.io/mt/105483427/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 25/45] ArmVirtPkg: Introduce Realm Aperture Management Protocol
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (23 preceding siblings ...)
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 24/45] ArmVirtPkg: Perform Arm CCA initialisation in the Pei phase Sami Mujawar
@ 2024-04-12 14:33 ` Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 26/45] ArmVirtPkg: IoMMU driver to DMA from Realms Sami Mujawar
` (14 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:33 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
The Realm Aperture Management Protocol (RAMP) is used to manage
the sharing of buffers between the Guest and Host. It configures
the memory regions as Protected EMPTY or Protected RAM by calling
RSI_IPA_STATE_SET command. The RAMP provides interfaces that device
drivers can use to open/close apertures for sharing buffers.
The RAMP also keeps track of the apertures that have been opened
and closes them on ExitBootServices. It also registers for reset
notification and closes all open apertures before the platform
resets the system.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/ArmVirtPkg.dec | 3 +
ArmVirtPkg/Include/Protocol/RealmApertureManagementProtocol.h | 103 +++
ArmVirtPkg/RealmApertureManagementProtocolDxe/RealmApertureManagementProtocolDxe.c | 658 ++++++++++++++++++++
ArmVirtPkg/RealmApertureManagementProtocolDxe/RealmApertureManagementProtocolDxe.inf | 48 ++
4 files changed, 812 insertions(+)
diff --git a/ArmVirtPkg/ArmVirtPkg.dec b/ArmVirtPkg/ArmVirtPkg.dec
index d521e107ddff15e6dc585e3a63567e3ad817189f..a6701ed3f88b9976110992dda22c11eea735cc4c 100644
--- a/ArmVirtPkg/ArmVirtPkg.dec
+++ b/ArmVirtPkg/ArmVirtPkg.dec
@@ -44,6 +44,9 @@ [PcdsFeatureFlag]
#
gArmVirtTokenSpaceGuid.PcdTpm2SupportEnabled|FALSE|BOOLEAN|0x00000004
+[Protocols]
+ gEfiRealmApertureManagementProtocolGuid = { 0x585c00be, 0xcf7c, 0x4db8, { 0x8a, 0xa2, 0x49, 0xd, 0x67, 0xf5, 0xf6, 0xe6 } }
+
[PcdsFixedAtBuild, PcdsPatchableInModule]
##
# This is the physical address of Rsdp which is the core struct of Acpi.
diff --git a/ArmVirtPkg/Include/Protocol/RealmApertureManagementProtocol.h b/ArmVirtPkg/Include/Protocol/RealmApertureManagementProtocol.h
new file mode 100644
index 0000000000000000000000000000000000000000..0f45fd296fd54ec536ed3d4bd7725350ab487295
--- /dev/null
+++ b/ArmVirtPkg/Include/Protocol/RealmApertureManagementProtocol.h
@@ -0,0 +1,103 @@
+/** @file
+ Realm Aperture Management Protocol (RAMP)
+ On Arm CCA Systems the Realm protects access and visibility of Guest memory
+ and code execution from software outside the realm.
+
+ However, software executing in a Realm needs to interact with the external
+ world. This may be done using virtualised disk, network interfaces, etc.
+ The drivers for these virtualised devices need to share buffers with the host
+ OS to exchange information/data.
+
+ Since the Guest memory is protected by the Realm, the host cannot access these
+ buffers unless the IPA state of the buffers is changed to Protected EMPTY by
+ the software executing in the Realm.
+
+ By enabling the sharing of the buffers, we are essentially opening an
+ aperture so that the host OS can access the range of pages that are shared.
+
+ The virtual firmware (Guest firmware) needs a mechanism to manage the sharing
+ of buffers. The Realm Aperture Management Protocol provides an interface that
+ UEFI drivers/modules can use to enable/disable the sharing of buffers with the
+ Host. The protocol also tracks open apertures and ensures they are shut on
+ ExitBootServices.
+
+ Copyright (c) 2022 - 2023, ARM Ltd. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Glossary:
+ - RAMP - Realm Aperture Management Protocol
+**/
+
+#ifndef REALM_APERTURE_MANAGEMENT_PROTOCOL_H_
+#define REALM_APERTURE_MANAGEMENT_PROTOCOL_H_
+
+/** This macro defines the Realm Aperture Management Protocol GUID.
+
+ GUID: {585C00BE-CF7C-4DB8-8AA2-490D67F5F6E6}
+*/
+#define EDKII_REALM_APERTURE_MANAGEMENT_PROTOCOL_GUID \
+ { 0x585c00be, 0xcf7c, 0x4db8, \
+ { 0x8a, 0xa2, 0x49, 0xd, 0x67, 0xf5, 0xf6, 0xe6 } \
+ };
+
+/** This macro defines the Realm Aperture Management Protocol Revision.
+*/
+#define EDKII_REALM_APERTURE_MANAGEMENT_PROTOCOL_REVISION 0x00010000
+
+#pragma pack(1)
+
+/** Enables sharing of the memory buffers with the host.
+
+ @param [in] Memory Pointer to the page start address.
+ @param [in] Pages Number of pages to share.
+ @param [out] ApertureReference Reference to the opened aperture.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
+ @retval EFI_ACCESS_DENIED Aperture already open over memory region.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REALM_APERTURE_MANAGEMENT_PROTOCOL_OPEN_APERTURE)(
+ IN CONST EFI_PHYSICAL_ADDRESS Memory,
+ IN CONST UINTN Pages,
+ OUT EFI_HANDLE *CONST ApertureReference
+ );
+
+/** Disables the sharing of the buffers.
+
+ @param [in] ApertureReference Reference to the aperture for closing.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required buffer information is not found.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REALM_APERTURE_MANAGEMENT_PROTOCOL_CLOSE_APERTURE)(
+ IN CONST EFI_HANDLE ApertureReference
+ );
+
+/** A structure describing the interface provided by the Realm Aperture
+ Management Protocol.
+*/
+typedef struct RealmApertureManagementProtocol {
+ /// The Realm Aperture Management Protocol revision.
+ UINT64 Revision;
+
+ /// Shares Realm Pages(s) with the Host.
+ EDKII_REALM_APERTURE_MANAGEMENT_PROTOCOL_OPEN_APERTURE OpenAperture;
+
+ /// Makes the Realm Pages(s) private to the Realm.
+ EDKII_REALM_APERTURE_MANAGEMENT_PROTOCOL_CLOSE_APERTURE CloseAperture;
+} EDKII_REALM_APERTURE_MANAGEMENT_PROTOCOL;
+
+/** The Realm Aperture Management Protocol GUID.
+*/
+extern EFI_GUID gEfiRealmApertureManagementProtocolGuid;
+
+#pragma pack()
+
+#endif // REALM_APERTURE_MANAGEMENT_PROTOCOL_H_
diff --git a/ArmVirtPkg/RealmApertureManagementProtocolDxe/RealmApertureManagementProtocolDxe.c b/ArmVirtPkg/RealmApertureManagementProtocolDxe/RealmApertureManagementProtocolDxe.c
new file mode 100644
index 0000000000000000000000000000000000000000..991054d47b10b45ed5c211827e795d88f8942c02
--- /dev/null
+++ b/ArmVirtPkg/RealmApertureManagementProtocolDxe/RealmApertureManagementProtocolDxe.c
@@ -0,0 +1,658 @@
+/** @file
+ Realm Aperture Management Protocol Dxe
+
+ Copyright (c) 2022 - 2023, Arm Limited. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Glossary:
+ - IPA - Intermediate Physical Address
+ - RAMP - Realm Aperture Management Protocol
+ - RIPAS - Realm IPA state
+ - RSI - Realm Service Interface
+**/
+
+#include <Base.h>
+#include <Library/ArmCcaLib.h>
+#include <Library/ArmCcaRsiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Protocol/RealmApertureManagementProtocol.h>
+#include <Protocol/ResetNotification.h>
+
+/**
+ A macro defining the signature for the aperture information structure.
+*/
+#define APERTURE_INFO_SIG SIGNATURE_64 ('A', 'P', 'E', 'R', 'T', 'U', 'R', 'E')
+
+/**
+ A structure describing the aperture.
+*/
+typedef struct {
+ /// Signature for identifying this structure.
+ UINT64 Signature;
+
+ /// The linked list entry.
+ LIST_ENTRY Link;
+
+ /// The base address for the start of the aperture.
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+
+ /// The number of pages covered by the aperture.
+ UINTN Pages;
+
+ /// The bit mask of attributes for the memory region. The
+ /// bit mask of available attributes is defined in GetMemoryMap().
+ UINT64 MemoryAttributes;
+
+ /// The RIPAS for the aperture.
+ RIPAS Ripas;
+} APERTURE_INFO;
+
+/**
+ List of the APERTURE_INFO structures that have been set up by OpenAperture()
+ and not yet torn down by CloseAperture(). The list represents the full set
+ of open apertures currently in effect.
+*/
+STATIC
+LIST_ENTRY mApertureInfos = INITIALIZE_LIST_HEAD_VARIABLE (mApertureInfos);
+
+/**
+ A local variable to store the IPA width of the Realm. The IPA width
+ of the Realm is required to configure the protection attribute of
+ memory regions.
+*/
+STATIC UINT64 mIpaWidth;
+
+/** Checks if an open aperture is overlapping the memory region.
+
+ @param [in] MemStart Pointer to the page start address.
+ @param [in] Pages Number of pages to share.
+
+ @retval TRUE If memory region overlaps an open aperture.
+ @retval FALSE Memory region does not overlap any open apertures.
+**/
+STATIC
+BOOLEAN
+EFIAPI
+IsApertureOverlapping (
+ IN CONST EFI_PHYSICAL_ADDRESS MemStart,
+ IN CONST UINTN Pages
+ )
+{
+ LIST_ENTRY *Node;
+ LIST_ENTRY *NextNode;
+ APERTURE_INFO *ApertureInfo;
+ EFI_PHYSICAL_ADDRESS MemEnd;
+ EFI_PHYSICAL_ADDRESS ApertureStart;
+ EFI_PHYSICAL_ADDRESS ApertureEnd;
+
+ MemEnd = MemStart + (EFI_PAGE_SIZE * Pages) - 1;
+
+ // All drivers that had opened the apertures have halted their respective
+ // controllers by now; close all the apertures.
+ for (
+ Node = GetFirstNode (&mApertureInfos);
+ Node != &mApertureInfos;
+ Node = NextNode
+ )
+ {
+ NextNode = GetNextNode (&mApertureInfos, Node);
+ ApertureInfo = CR (Node, APERTURE_INFO, Link, APERTURE_INFO_SIG);
+ ApertureStart = ApertureInfo->BaseAddress;
+ ApertureEnd = ApertureStart + (EFI_PAGE_SIZE * ApertureInfo->Pages) - 1;
+
+ if (((ApertureStart >= MemStart) && (ApertureStart <= MemEnd)) ||
+ ((ApertureEnd >= MemStart) && (ApertureEnd <= MemEnd)) ||
+ ((MemStart >= ApertureStart) && (MemStart <= ApertureEnd)) ||
+ ((MemEnd >= ApertureStart) && (MemEnd <= ApertureEnd)))
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/** Enables sharing of the memory buffers with the host.
+
+ @param [in] Memory Pointer to the page start address.
+ @param [in] Pages Number of pages to share.
+ @param [out] ApertureReference Reference to the opened aperture.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
+ @retval EFI_ACCESS_DENIED Aperture already open over memory region.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+RampOpenAperture (
+ IN CONST EFI_PHYSICAL_ADDRESS Memory,
+ IN CONST UINTN Pages,
+ OUT EFI_HANDLE *CONST ApertureReference
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status1;
+ APERTURE_INFO *ApertInfo;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;
+ EFI_PHYSICAL_ADDRESS MemRangeAddr;
+ UINTN Index;
+
+ if ((Memory == 0) ||
+ (Pages == 0) ||
+ (ApertureReference == NULL) ||
+ ((Memory & (EFI_PAGE_SIZE - 1)) != 0))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // The pages size must be aligned to the Realm Granule size.
+ STATIC_ASSERT ((EFI_PAGE_SIZE & (REALM_GRANULE_SIZE - 1)) == 0);
+
+ // Checks if we already have an open aperture that overlaps the
+ // memory region. If so return the request as invalid.
+ if (IsApertureOverlapping (Memory, Pages)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ MemRangeAddr = Memory;
+ for (Index = 0; Index < Pages; Index++) {
+ Status = gDS->GetMemorySpaceDescriptor (MemRangeAddr, &GcdDescriptor);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "%a: Memory = 0x%lx, MemType = %a\n",
+ __func__,
+ MemRangeAddr,
+ ((GcdDescriptor.Attributes & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) ?
+ "Runtime Services Memory" : "Boot Services Memory"
+ ));
+
+ // We currently do not have a usecase where we would want to open apertures
+ // for runtime services memory
+ if ((GcdDescriptor.Attributes & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MemRangeAddr += EFI_PAGE_SIZE;
+ } // for
+
+ Status = ArmCcaSetMemoryProtectAttribute (
+ Memory,
+ EFI_PAGES_TO_SIZE (Pages),
+ mIpaWidth,
+ TRUE
+ );
+ if (RETURN_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to update page tables for Protected EMPTY page mapping, "
+ "Address = %p, Pages = 0x%lx, Status = %r\n",
+ Memory,
+ Pages,
+ Status
+ ));
+ return Status;
+ }
+
+ // Allocate a APERTURE_INFO structure to remember the apertures opened.
+ ApertInfo = AllocateZeroPool (sizeof (APERTURE_INFO));
+ if (ApertInfo == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto error_handler1;
+ }
+
+ InitializeListHead (&ApertInfo->Link);
+ ApertInfo->Signature = APERTURE_INFO_SIG;
+ ApertInfo->BaseAddress = Memory;
+ ApertInfo->Pages = Pages;
+ ApertInfo->MemoryAttributes = GcdDescriptor.Attributes;
+ ApertInfo->Ripas = RipasEmpty;
+
+ DEBUG ((
+ DEBUG_INFO,
+ "%a: ApertRef = 0x%p, Memory = 0x%lx, Pages = 0x%x, "
+ "MemoryAttributes = 0x%x, Ripas = 0x%x\n",
+ __func__,
+ ApertInfo,
+ ApertInfo->BaseAddress,
+ ApertInfo->Pages,
+ ApertInfo->MemoryAttributes,
+ ApertInfo->Ripas
+ ));
+
+ // Set the Realm IPA state to Empty to open the Aperture
+ Status = RsiSetIpaState (
+ (UINT64 *)Memory,
+ (Pages * EFI_PAGE_SIZE),
+ RipasEmpty
+ );
+ if (RETURN_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: RSI Set IPA State failed, Address = %p, Pages = 0x%lx, "
+ "Status = %r\n",
+ Memory,
+ Pages,
+ Status
+ ));
+ goto error_handler;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "SUCCESS: RSI Set IPA State complete, Address = %p, Pages = 0x%lx, "
+ "Status = %r\n",
+ Memory,
+ Pages,
+ Status
+ ));
+
+ InsertHeadList (&mApertureInfos, &ApertInfo->Link);
+ *ApertureReference = (EFI_HANDLE *)&ApertInfo->Link;
+
+ return Status;
+
+error_handler:
+
+ FreePool (ApertInfo);
+
+error_handler1:
+ Status1 = ArmCcaSetMemoryProtectAttribute (
+ Memory,
+ EFI_PAGES_TO_SIZE (Pages),
+ mIpaWidth,
+ FALSE
+ );
+ if (RETURN_ERROR (Status1)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to update page tables to Protected page mapping, "
+ "Address = %p, Pages = 0x%lx, Status = %r\n",
+ Memory,
+ Pages,
+ Status1
+ ));
+ }
+
+ *ApertureReference = NULL;
+ // return the first error code
+ return Status;
+}
+
+/** Disables the sharing of the buffers.
+
+ @param [in] ApertureReference Reference to the aperture for closing.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required buffer information is not found.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+RampCloseAperture (
+ IN CONST EFI_HANDLE ApertureReference
+ )
+{
+ EFI_STATUS Status;
+ APERTURE_INFO *ApertInfo;
+
+ if (ApertureReference == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ApertInfo = NULL;
+ ApertInfo = CR (ApertureReference, APERTURE_INFO, Link, APERTURE_INFO_SIG);
+ if (ApertInfo == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "%a: ApertRef = 0x%p, Memory = 0x%lx, Pages = 0x%x, "
+ "MemoryAttributes = 0x%x, Ripas = 0x%x\n",
+ __func__,
+ ApertInfo,
+ ApertInfo->BaseAddress,
+ ApertInfo->Pages,
+ ApertInfo->MemoryAttributes,
+ ApertInfo->Ripas
+ ));
+
+ // Set the Realm IPA state to RAM to close the Aperture
+ Status = RsiSetIpaState (
+ (UINT64 *)ApertInfo->BaseAddress,
+ (ApertInfo->Pages * EFI_PAGE_SIZE),
+ RipasRam
+ );
+ if (RETURN_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: RSI Set IPA State failed, Address = %p, Pages = 0x%lx, "
+ "Status = %r\n",
+ ApertInfo->BaseAddress,
+ ApertInfo->Pages,
+ Status
+ ));
+ return Status;
+ }
+
+ Status = ArmCcaSetMemoryProtectAttribute (
+ ApertInfo->BaseAddress,
+ EFI_PAGES_TO_SIZE (ApertInfo->Pages),
+ mIpaWidth,
+ FALSE
+ );
+ if (RETURN_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to update page tables for Protected RAM page mapping,"
+ "Address = %p, Pages = 0x%lx, Status = %r\n",
+ ApertInfo->BaseAddress,
+ ApertInfo->Pages,
+ Status
+ ));
+ }
+
+ RemoveEntryList (&ApertInfo->Link);
+ FreePool (ApertInfo);
+
+ return Status;
+}
+
+/** Closes all open apertures.
+
+**/
+STATIC
+VOID
+EFIAPI
+RampCloseAllApertures (
+ VOID
+ )
+{
+ LIST_ENTRY *Node;
+ LIST_ENTRY *NextNode;
+ APERTURE_INFO *ApertureInfo;
+
+ // All drivers that had opened the apertures have halted their respective
+ // controllers by now; close all the apertures.
+ for (
+ Node = GetFirstNode (&mApertureInfos);
+ Node != &mApertureInfos;
+ Node = NextNode
+ )
+ {
+ NextNode = GetNextNode (&mApertureInfos, Node);
+ ApertureInfo = CR (Node, APERTURE_INFO, Link, APERTURE_INFO_SIG);
+ RampCloseAperture (&ApertureInfo->Link);
+ }
+}
+
+/**
+ Notification function that is queued after the notification functions of all
+ events in the EFI_EVENT_GROUP_EXIT_BOOT_SERVICES event group.
+
+ This function invokes the closing of all open apertures.
+
+ @param[in] Event Event whose notification function is being invoked. Event
+ is permitted to request the queueing of this function
+ only at TPL_CALLBACK task priority level.
+
+ @param[in] Context Ignored.
+**/
+STATIC
+VOID
+EFIAPI
+OnRampExitBootServicesEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ RampCloseAllApertures ();
+}
+
+/**
+ Notification function that is queued when gBS->ExitBootServices() signals the
+ EFI_EVENT_GROUP_EXIT_BOOT_SERVICES event group. This function signals another
+ event, received as Context, and returns.
+
+ Signaling an event in this context is safe. The UEFI spec allows
+ gBS->SignalEvent() to return EFI_SUCCESS only; EFI_OUT_OF_RESOURCES is not
+ listed, hence memory is not allocated.
+
+ @param[in] Event Event whose notification function is being invoked.
+ Event is permitted to request the queueing of this
+ function at TPL_CALLBACK or TPL_NOTIFY task
+ priority level.
+
+ @param[in] EventToSignal Identifies the EFI_EVENT to signal. EventToSignal
+ is permitted to request the queueing of its
+ notification function only at TPL_CALLBACK level.
+**/
+STATIC
+VOID
+EFIAPI
+RampExitBootServices (
+ IN EFI_EVENT Event,
+ IN VOID *EventToSignal
+ )
+{
+ // (1) The NotifyFunctions of all the events in
+ // EFI_EVENT_GROUP_EXIT_BOOT_SERVICES will have been queued before
+ // RampExitBootServices() is entered.
+ //
+ // (2) RampExitBootServices() is executing minimally at TPL_CALLBACK.
+ //
+ // (3) RampExitBootServices() has been queued in unspecified order relative
+ // to the NotifyFunctions of all the other events in
+ // EFI_EVENT_GROUP_EXIT_BOOT_SERVICES whose NotifyTpl is the same as
+ // Event's.
+ //
+ // Consequences:
+ //
+ // - If Event's NotifyTpl is TPL_CALLBACK, then some other NotifyFunctions
+ // queued at TPL_CALLBACK may be invoked after RampExitBootServices()
+ // returns.
+ //
+ // - If Event's NotifyTpl is TPL_NOTIFY, then some other NotifyFunctions
+ // queued at TPL_NOTIFY may be invoked after RampExitBootServices()
+ // returns; plus *all* NotifyFunctions queued at TPL_CALLBACK will be
+ // invoked strictly after all NotifyFunctions queued at TPL_NOTIFY,
+ // including RampExitBootServices(), have been invoked.
+ //
+ // - By signaling EventToSignal here, whose NotifyTpl is TPL_CALLBACK, we
+ // queue EventToSignal's NotifyFunction after the NotifyFunctions of *all*
+ // events in EFI_EVENT_GROUP_EXIT_BOOT_SERVICES.
+ gBS->SignalEvent (EventToSignal);
+}
+
+/** A structure describing the Realm Aperture Management protocol.
+*/
+STATIC
+CONST
+EDKII_REALM_APERTURE_MANAGEMENT_PROTOCOL Ramp = {
+ EDKII_REALM_APERTURE_MANAGEMENT_PROTOCOL_REVISION,
+ RampOpenAperture,
+ RampCloseAperture
+};
+
+/**
+ This routine is called to close all apertures before system reset.
+
+ @param[in] ResetType The type of reset to perform.
+ @param[in] ResetStatus The status code for the reset.
+ @param[in] DataSize The size, in bytes, of ResetData.
+ @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or
+ EfiResetShutdown the data buffer starts with a Null-
+ terminated string, optionally followed by additional
+ binary data. The string is a description that the
+ caller may use to further indicate the reason for
+ the system reset. ResetData is only valid if
+ ResetStatus is something other than EFI_SUCCESS
+ unless the ResetType is EfiResetPlatformSpecific
+ where a minimum amount of ResetData is always
+ required.
+ For a ResetType of EfiResetPlatformSpecific the data
+ buffer also starts with a Null-terminated string
+ that is followed by an EFI_GUID that describes the
+ specific type of reset to perform.
+**/
+VOID
+EFIAPI
+OnResetEvent (
+ IN EFI_RESET_TYPE ResetType,
+ IN EFI_STATUS ResetStatus,
+ IN UINTN DataSize,
+ IN VOID *ResetData OPTIONAL
+ )
+{
+ RampCloseAllApertures ();
+}
+
+/**
+ Hook the system reset to close all apertures.
+
+ @param[in] Event Event whose notification function is being invoked
+ @param[in] Context Pointer to the notification function's context
+**/
+VOID
+EFIAPI
+OnResetNotificationInstall (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EFI_RESET_NOTIFICATION_PROTOCOL *ResetNotify;
+
+ Status = gBS->LocateProtocol (
+ &gEfiResetNotificationProtocolGuid,
+ NULL,
+ (VOID **)&ResetNotify
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = ResetNotify->RegisterResetNotify (ResetNotify, OnResetEvent);
+ ASSERT_EFI_ERROR (Status);
+ DEBUG ((DEBUG_INFO, "RAMP: Hook system reset to close all apertures.\n"));
+ gBS->CloseEvent (Event);
+ }
+}
+
+/** Entry point for Realm Aperture Management Protocol Dxe
+
+ @param [in] ImageHandle Handle for this image.
+ @param [in] SystemTable Pointer to the EFI system table.
+
+ @retval EFI_SUCCESS When executing in a Realm the RAMP was
+ installed successfully.
+ When execution context is not a Realm, this
+ function returns success indicating nothing
+ needs to be done and allow other modules to
+ run.
+ @retval EFI_OUT_OF_RESOURCES There was not enough memory to install the
+ protocols.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+RealmApertureManagementProtocolDxeInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ EFI_EVENT CloseAllAperturesEvent;
+ EFI_EVENT ExitBootEvent;
+ VOID *Registration;
+
+ // When the execution context is a Realm, install the Realm Aperture
+ // Management protocol otherwise return success so that other modules
+ // can run.
+ if (!IsRealm ()) {
+ return EFI_SUCCESS;
+ }
+
+ // Retrieve the IPA Width of the Realm for subsequent use to configure
+ // the protection attribute of memory regions.
+ Status = GetIpaWidth (&mIpaWidth);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to get Ipa Width, Status = %r\n",
+ Status
+ ));
+ ASSERT (0);
+ return Status;
+ }
+
+ /*
+ Create the "late" event whose notification function will close all
+ apertures.
+ */
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL, // Type
+ TPL_CALLBACK, // NotifyTpl
+ OnRampExitBootServicesEvent, // NotifyFunction
+ NULL, // NotifyContext
+ &CloseAllAperturesEvent // Event
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ /*
+ Create the event whose notification function will be queued by
+ gBS->ExitBootServices() and will signal the event created above.
+ */
+ Status = gBS->CreateEvent (
+ EVT_SIGNAL_EXIT_BOOT_SERVICES, // Type
+ TPL_CALLBACK, // NotifyTpl
+ RampExitBootServices, // NotifyFunction
+ CloseAllAperturesEvent, // NotifyContext
+ &ExitBootEvent // Event
+ );
+ if (EFI_ERROR (Status)) {
+ goto error_handler1;
+ }
+
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEfiRealmApertureManagementProtocolGuid,
+ &Ramp,
+ NULL
+ );
+ if (!EFI_ERROR (Status)) {
+ // RAMP Protocol installed successfully
+ // Hook the system reset to close all apertures.
+ EfiCreateProtocolNotifyEvent (
+ &gEfiResetNotificationProtocolGuid,
+ TPL_CALLBACK,
+ OnResetNotificationInstall,
+ NULL,
+ &Registration
+ );
+ return Status;
+ }
+
+ // cleanup on error
+ gBS->CloseEvent (ExitBootEvent);
+
+error_handler1:
+ gBS->CloseEvent (CloseAllAperturesEvent);
+ return Status;
+}
diff --git a/ArmVirtPkg/RealmApertureManagementProtocolDxe/RealmApertureManagementProtocolDxe.inf b/ArmVirtPkg/RealmApertureManagementProtocolDxe/RealmApertureManagementProtocolDxe.inf
new file mode 100644
index 0000000000000000000000000000000000000000..2e3021b82bd75b7f41dc9427117a8394dfde2e68
--- /dev/null
+++ b/ArmVirtPkg/RealmApertureManagementProtocolDxe/RealmApertureManagementProtocolDxe.inf
@@ -0,0 +1,48 @@
+## @file
+# Module to manage the sharing of buffers in a Realm with the Host.
+#
+# Copyright (c) 2022 - 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = RealmApertureManagementProtocolDxe
+ FILE_GUID = CEC2F7D5-2564-46D4-A23F-501623F7F56A
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = RealmApertureManagementProtocolDxeInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = AARCH64
+#
+
+[Sources]
+ RealmApertureManagementProtocolDxe.c
+
+[Packages]
+ ArmVirtPkg/ArmVirtPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ ArmCcaLib
+ ArmCcaRsiLib
+ BaseLib
+ DxeServicesTableLib
+ MemoryAllocationLib
+ PrintLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Protocols]
+ gEfiRealmApertureManagementProtocolGuid ## SOMETIME_PRODUCES
+ gEfiResetNotificationProtocolGuid ## CONSUMES
+
+[Depex]
+ TRUE
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117697): https://edk2.groups.io/g/devel/message/117697
Mute This Topic: https://groups.io/mt/105483438/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 26/45] ArmVirtPkg: IoMMU driver to DMA from Realms
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (24 preceding siblings ...)
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 25/45] ArmVirtPkg: Introduce Realm Aperture Management Protocol Sami Mujawar
@ 2024-04-12 14:33 ` Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 27/45] ArmVirtPkg: Enable Virtio communication for Arm CCA Sami Mujawar
` (13 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:33 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
On Arm CCA systems the access to pages inside the Realm is protected.
However, software executing in a Realm needs to interact with the
external world. This may be done using para virtualisation of the
disk, network interfaces, etc. For this to work the buffers in the
Realm need to be shared with the Host. The sharing and management
of the Realm buffers is done by the Realm Aperture Management
Protocol, which invokes the necessary Realm Service Interfaces
to transition the buffers from Protected IPA to Unprotected IPA.
The ArmCcaIoMmu driver provides the necessary hooks so that DMA
operations can be performed by bouncing buffers using pages shared
with the Host. It uses the Realm Aperture Management protocol to
share the buffers with the Host.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/ArmCcaIoMmuDxe/ArmCcaIoMmu.c | 813 ++++++++++++++++++++
ArmVirtPkg/ArmCcaIoMmuDxe/ArmCcaIoMmu.h | 66 ++
ArmVirtPkg/ArmCcaIoMmuDxe/ArmCcaIoMmuDxe.c | 59 ++
ArmVirtPkg/ArmCcaIoMmuDxe/ArmCcaIoMmuDxe.inf | 45 ++
4 files changed, 983 insertions(+)
diff --git a/ArmVirtPkg/ArmCcaIoMmuDxe/ArmCcaIoMmu.c b/ArmVirtPkg/ArmCcaIoMmuDxe/ArmCcaIoMmu.c
new file mode 100644
index 0000000000000000000000000000000000000000..cf52b82218bb9ece7bfedcb6e3a2ced00eff5e92
--- /dev/null
+++ b/ArmVirtPkg/ArmCcaIoMmuDxe/ArmCcaIoMmu.c
@@ -0,0 +1,813 @@
+/** @file
+ The protocol provides support to allocate, free, map and umap a DMA buffer
+ for bus master (e.g PciHostBridge). When the execution context is a Realm,
+ the DMA operations must be performed on buffers that are shared with the Host.
+ Hence the RAMP protocol is used to manage the sharing of the DMA buffers or
+ in some cases to bounce the buffers.
+
+ Copyright (c) 2017, AMD Inc. All rights reserved.<BR>
+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2022 - 2023, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "ArmCcaIoMmu.h"
+
+/** List of the MAP_INFO structures that have been set up by IoMmuMap() and not
+ yet torn down by IoMmuUnmap(). The list represents the full set of mappings
+ currently in effect.
+*/
+STATIC LIST_ENTRY mMapInfos = INITIALIZE_LIST_HEAD_VARIABLE (mMapInfos);
+
+#if !defined (MDEPKG_NDEBUG)
+
+/** ASCII names for EDKII_IOMMU_OPERATION constants, for debug logging.
+*/
+STATIC CONST CHAR8 *CONST
+mBusMasterOperationName[EdkiiIoMmuOperationMaximum] = {
+ "Read",
+ "Write",
+ "CommonBuffer",
+ "Read64",
+ "Write64",
+ "CommonBuffer64"
+};
+#endif
+
+/** Pointer to the Realm Aperture Management Protocol
+*/
+extern EDKII_REALM_APERTURE_MANAGEMENT_PROTOCOL *mRamp;
+
+/**
+ Given the host address find a mapping node in the linked list.
+
+ @param [in] HostAddress Host address.
+
+ @return Pointer to the MapInfo node if found, otherwise NULL.
+**/
+STATIC
+MAP_INFO *
+EFIAPI
+FindMappingByHostAddress (
+ IN VOID *HostAddress
+ )
+{
+ LIST_ENTRY *Node;
+ LIST_ENTRY *NextNode;
+ MAP_INFO *MapInfo;
+
+ for (Node = GetFirstNode (&mMapInfos); Node != &mMapInfos; Node = NextNode) {
+ NextNode = GetNextNode (&mMapInfos, Node);
+ MapInfo = CR (Node, MAP_INFO, Link, MAP_INFO_SIG);
+ if (MapInfo->HostAddress == HostAddress) {
+ return MapInfo;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ Map a shared buffer
+
+ @param [in] Operation IoMMU operation to perform.
+ @param [in] HostAddress Pointer to the Host buffer.
+ @param [in] NumberOfBytes Number of bytes to map.
+ @param [in] BbAddress Bounce buffer address.
+ @param [in] BbPages Number of pages covering the bounce buffer.
+ @param [out] Mapping Pointer to the MapInfo node.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+STATIC
+EFI_STATUS
+MapSharedBuffer (
+ IN EDKII_IOMMU_OPERATION Operation,
+ IN VOID *HostAddress,
+ IN UINTN NumberOfBytes,
+ IN EFI_PHYSICAL_ADDRESS BbAddress,
+ IN UINTN BbPages,
+ OUT MAP_INFO **Mapping
+ )
+{
+ EFI_STATUS Status;
+ MAP_INFO *MapInfo;
+
+ if (BbPages != EFI_SIZE_TO_PAGES (NumberOfBytes)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Allocate a MAP_INFO structure to remember the mapping when Unmap() is
+ // called later.
+ MapInfo = AllocateZeroPool (sizeof (MAP_INFO));
+ if (MapInfo == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ InitializeListHead (&MapInfo->Link);
+
+ // Initialize the MAP_INFO structure, except the NonParAddress field
+ MapInfo->Signature = MAP_INFO_SIG;
+ MapInfo->Operation = Operation;
+ MapInfo->NumberOfBytes = NumberOfBytes;
+ MapInfo->NumberOfPages = BbPages;
+ MapInfo->HostAddress = HostAddress;
+ MapInfo->BbAddress = BbAddress;
+
+ // Open aperture here
+ Status = mRamp->OpenAperture (
+ BbAddress,
+ BbPages,
+ &MapInfo->ApertureRef
+ );
+ if (EFI_ERROR (Status)) {
+ goto FreeMapInfo;
+ }
+
+ // Track all MAP_INFO structures.
+ InsertHeadList (&mMapInfos, &MapInfo->Link);
+ *Mapping = MapInfo;
+ return Status;
+
+FreeMapInfo:
+ FreePool (MapInfo);
+ return Status;
+}
+
+/**
+ Unmap a shared buffer.
+
+ @param [in] MapInfo Pointer to the MapInfo node.
+ @param [in] MemoryMapLocked The function is executing on the stack of
+ gBS->ExitBootServices(); changes to the UEFI
+ memory map are forbidden.
+
+ @retval RETURN_SUCCESS Success.
+ @retval RETURN_INVALID_PARAMETER A parameter is invalid.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+UnMapSharedBuffer (
+ IN MAP_INFO *MapInfo,
+ IN BOOLEAN MemoryMapLocked
+ )
+{
+ EFI_STATUS Status;
+
+ if (MapInfo == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG ((
+ DEBUG_VERBOSE,
+ "%a: HostAddress = 0x%p, BbAddress = 0x%p\n",
+ __func__,
+ MapInfo->HostAddress,
+ MapInfo->BbAddress
+ ));
+ Status = mRamp->CloseAperture (MapInfo->ApertureRef);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "Failed to close aperture. Status = %r\n",
+ Status
+ ));
+ }
+
+ RemoveEntryList (&MapInfo->Link);
+
+ if (!MemoryMapLocked) {
+ FreePool (MapInfo);
+ }
+
+ return Status;
+}
+
+/**
+ Provides the controller-specific addresses required to access system memory
+ from a DMA bus master. On guest Realms, the DMA operations must be performed
+ on shared buffer hence we allocate a bounce buffer to map the HostAddress to
+ a DeviceAddress. The Realm Aperture Management protocol is then involved to
+ open the aperture for sharing the buffer pages with the Host OS.
+
+ @param This The protocol instance pointer.
+ @param Operation Indicates if the bus master is going to read or
+ write to system memory.
+ @param HostAddress The system memory address to map to the PCI
+ controller.
+ @param NumberOfBytes On input the number of bytes to map. On output
+ the number of bytes that were mapped.
+ @param DeviceAddress The resulting map address for the bus master
+ PCI controller to use to access the hosts
+ HostAddress.
+ @param Mapping A resulting value to pass to Unmap().
+
+ @retval EFI_SUCCESS The range was mapped for the returned
+ NumberOfBytes.
+ @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common
+ buffer.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
+ lack of resources.
+ @retval EFI_DEVICE_ERROR The system hardware could not map the requested
+ address.
+
+**/
+EFI_STATUS
+EFIAPI
+IoMmuMap (
+ IN EDKII_IOMMU_PROTOCOL *This,
+ IN EDKII_IOMMU_OPERATION Operation,
+ IN VOID *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ )
+{
+ EFI_STATUS Status;
+ MAP_INFO *MapInfo;
+ EFI_PHYSICAL_ADDRESS BbAddress;
+ UINTN Pages;
+ EFI_ALLOCATE_TYPE AllocateType;
+
+ DEBUG ((
+ DEBUG_VERBOSE,
+ "%a: Operation=%a Host=0x%p Bytes=0x%lx\n",
+ __func__,
+ ((Operation >= 0 &&
+ Operation < ARRAY_SIZE (mBusMasterOperationName)) ?
+ mBusMasterOperationName[Operation] :
+ "Invalid"),
+ HostAddress,
+ (UINT64)((NumberOfBytes == NULL) ? 0 : *NumberOfBytes)
+ ));
+
+ if ((HostAddress == NULL) ||
+ (NumberOfBytes == NULL) ||
+ (DeviceAddress == NULL) ||
+ (Mapping == NULL) ||
+ (Operation >= EdkiiIoMmuOperationMaximum) ||
+ (Operation < EdkiiIoMmuOperationBusMasterRead))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BbAddress = MAX_ADDRESS;
+ Pages = EFI_SIZE_TO_PAGES (*NumberOfBytes);
+ AllocateType = AllocateAnyPages;
+ switch (Operation) {
+ // For BusMasterRead[64] and BusMasterWrite[64] operations, a bounce buffer
+ // is necessary as the original buffer may not meet the page start/end and
+ // page size alignment requirements. Also we need to consider the case where
+ // the original buffer crosses the 4GB limit.
+ case EdkiiIoMmuOperationBusMasterRead:
+ case EdkiiIoMmuOperationBusMasterWrite:
+ BbAddress = BASE_4GB - 1;
+ AllocateType = AllocateMaxAddress;
+ // fall through
+ case EdkiiIoMmuOperationBusMasterRead64:
+ case EdkiiIoMmuOperationBusMasterWrite64:
+ // Allocate a bounce buffer.
+ Status = gBS->AllocatePages (
+ AllocateType,
+ EfiBootServicesData,
+ Pages,
+ &BbAddress
+ );
+ if (EFI_ERROR (Status)) {
+ goto Failed;
+ }
+
+ // Open aperture here
+ Status = MapSharedBuffer (
+ Operation,
+ HostAddress,
+ *NumberOfBytes,
+ BbAddress,
+ Pages,
+ &MapInfo
+ );
+ if (EFI_ERROR (Status)) {
+ goto FreeBounceBuffer;
+ }
+
+ break;
+
+ // For BusMasterCommonBuffer[64] operations, the buffer is already allocated
+ // and mapped in a call to AllocateBuffer(). So, we only need to return the
+ // device address and the mapping info
+ case EdkiiIoMmuOperationBusMasterCommonBuffer:
+ // fall through
+ case EdkiiIoMmuOperationBusMasterCommonBuffer64:
+ MapInfo = FindMappingByHostAddress (HostAddress);
+ if (MapInfo == NULL) {
+ ASSERT (MapInfo == NULL);
+ goto Failed;
+ }
+
+ BbAddress = MapInfo->BbAddress;
+ break;
+
+ default:
+ // Operation is invalid
+ Status = EFI_INVALID_PARAMETER;
+ goto Failed;
+ } // switch
+
+ // If this is a read operation from the Bus Master's point of view,
+ // then copy the contents of the real buffer into the mapped buffer
+ // so the Bus Master can read the contents of the real buffer.
+ // No special action is needed for BusMasterCommonBuffer[64] operations.
+ if ((Operation == EdkiiIoMmuOperationBusMasterRead) ||
+ (Operation == EdkiiIoMmuOperationBusMasterRead64))
+ {
+ CopyMem (
+ (VOID *)(UINTN)BbAddress,
+ (VOID *)(UINTN)HostAddress,
+ MapInfo->NumberOfBytes
+ );
+ }
+
+ // Populate output parameters.
+ *DeviceAddress = BbAddress;
+ *Mapping = MapInfo;
+
+ DEBUG ((
+ DEBUG_VERBOSE,
+ "%a: Mapping=0x%p HostAddress = 0x%p BBAddress = 0x%Lx Pages=0x%Lx\n",
+ __func__,
+ MapInfo,
+ HostAddress,
+ MapInfo->BbAddress,
+ MapInfo->NumberOfPages
+ ));
+
+ return EFI_SUCCESS;
+
+FreeBounceBuffer:
+ gBS->FreePages (BbAddress, Pages);
+
+Failed:
+ *NumberOfBytes = 0;
+ return Status;
+}
+
+/**
+ Completes the Map() operation and releases any corresponding resources.
+
+ This is an internal worker function that only extends the Map() API with
+ the MemoryMapLocked parameter.
+
+ @param This The protocol instance pointer.
+ @param MapInfo The mapping value returned from Map().
+ @param MemoryMapLocked The function is executing on the stack of
+ gBS->ExitBootServices(); changes to the UEFI
+ memory map are forbidden.
+
+ @retval EFI_SUCCESS The range was unmapped.
+ @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by
+ Map().
+ @retval EFI_DEVICE_ERROR The data was not committed to the target system
+ memory.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+IoMmuUnmapWorker (
+ IN EDKII_IOMMU_PROTOCOL *This,
+ IN MAP_INFO *MapInfo,
+ IN BOOLEAN MemoryMapLocked
+ )
+{
+ EFI_STATUS Status;
+ PHYSICAL_ADDRESS BbAddress;
+ UINTN Pages;
+
+ DEBUG ((
+ DEBUG_VERBOSE,
+ "%a: MapInfo=0x%p MemoryMapLocked=%d\n",
+ __func__,
+ MapInfo,
+ MemoryMapLocked
+ ));
+
+ if (MapInfo == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BbAddress = MapInfo->BbAddress;
+ Pages = MapInfo->NumberOfPages;
+
+ // For BusMasterWrite[64] operations and BusMasterCommonBuffer[64] operations
+ // we have to copy the results, ultimately to the original place (i.e.,
+ // "MapInfo->HostAddress").
+ // No special operaton is needed for BusMasterCommonBuffer[64] operations.
+ switch (MapInfo->Operation) {
+ case EdkiiIoMmuOperationBusMasterCommonBuffer:
+ case EdkiiIoMmuOperationBusMasterCommonBuffer64:
+ ASSERT (BbAddress == (PHYSICAL_ADDRESS)MapInfo->HostAddress);
+ break;
+ case EdkiiIoMmuOperationBusMasterWrite:
+ case EdkiiIoMmuOperationBusMasterWrite64:
+ CopyMem (
+ (VOID *)(UINTN)MapInfo->HostAddress,
+ (VOID *)(UINTN)BbAddress,
+ MapInfo->NumberOfBytes
+ );
+ break;
+
+ default:
+ // nothing to do for BusMasterRead[64] operations
+ break;
+ }
+
+ // For all other operations, fill the late bounce buffer with zeros, and
+ // then release it (unless the UEFI memory map is locked).
+ if ((MapInfo->Operation != EdkiiIoMmuOperationBusMasterCommonBuffer) &&
+ (MapInfo->Operation != EdkiiIoMmuOperationBusMasterCommonBuffer64))
+ {
+ ZeroMem (
+ (VOID *)(UINTN)BbAddress,
+ EFI_PAGES_TO_SIZE (Pages)
+ );
+
+ // UnMapSharedPages
+ Status = UnMapSharedBuffer (MapInfo, MemoryMapLocked);
+ ASSERT_EFI_ERROR (Status);
+
+ if (!MemoryMapLocked) {
+ gBS->FreePages (BbAddress, Pages);
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Completes the Map() operation and releases any corresponding resources.
+
+ @param This The protocol instance pointer.
+ @param Mapping The mapping value returned from Map().
+
+ @retval EFI_SUCCESS The range was unmapped.
+ @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by
+ Map().
+ @retval EFI_DEVICE_ERROR The data was not committed to the target system
+ memory.
+**/
+EFI_STATUS
+EFIAPI
+IoMmuUnmap (
+ IN EDKII_IOMMU_PROTOCOL *This,
+ IN VOID *Mapping
+ )
+{
+ return IoMmuUnmapWorker (
+ This,
+ (MAP_INFO *)Mapping,
+ FALSE // MemoryMapLocked
+ );
+}
+
+/**
+ Allocates pages that are suitable for an OperationBusMasterCommonBuffer or
+ OperationBusMasterCommonBuffer64 mapping.
+
+ @param This The protocol instance pointer.
+ @param Type This parameter is not used and must be ignored.
+ @param MemoryType The type of memory to allocate,
+ EfiBootServicesData or EfiRuntimeServicesData.
+ @param Pages The number of pages to allocate.
+ @param HostAddress A pointer to store the base system memory
+ address of the allocated range.
+ @param Attributes The requested bit mask of attributes for the
+ allocated range.
+
+ @retval EFI_SUCCESS The requested memory pages were allocated.
+ @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal
+ attribute bits are MEMORY_WRITE_COMBINE and
+ MEMORY_CACHED.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+ @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
+
+**/
+EFI_STATUS
+EFIAPI
+IoMmuAllocateBuffer (
+ IN EDKII_IOMMU_PROTOCOL *This,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ IN OUT VOID **HostAddress,
+ IN UINT64 Attributes
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS BbAddress;
+ MAP_INFO *MapInfo;
+
+ // Validate Attributes
+ if ((Attributes & EDKII_IOMMU_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ // Check for invalid inputs
+ if (HostAddress == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // The only valid memory types are EfiBootServicesData
+ if (MemoryType != EfiBootServicesData) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Pages >= MAX_UINTN) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BbAddress = (UINTN)-1;
+ if ((Attributes & EDKII_IOMMU_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0) {
+ // Limit allocations to memory below 4GB
+ BbAddress = SIZE_4GB - 1;
+ }
+
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ MemoryType,
+ Pages,
+ &BbAddress
+ );
+ if (EFI_ERROR (Status)) {
+ // Set the host address to NULL in case of error
+ *HostAddress = NULL;
+ } else {
+ *HostAddress = (VOID *)(UINTN)BbAddress;
+ Status = MapSharedBuffer (
+ EdkiiIoMmuOperationBusMasterCommonBuffer,
+ *HostAddress,
+ EFI_PAGES_TO_SIZE (Pages),
+ BbAddress,
+ Pages,
+ &MapInfo
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return Status;
+}
+
+/**
+ Frees memory that was allocated with AllocateBuffer().
+
+ @param This The protocol instance pointer.
+ @param Pages The number of pages to free.
+ @param HostAddress The base system memory address of the allocated
+ range.
+
+ @retval EFI_SUCCESS The requested memory pages were freed.
+ @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and
+ Pages was not allocated with AllocateBuffer().
+
+**/
+EFI_STATUS
+EFIAPI
+IoMmuFreeBuffer (
+ IN EDKII_IOMMU_PROTOCOL *This,
+ IN UINTN Pages,
+ IN VOID *HostAddress
+ )
+{
+ EFI_STATUS Status;
+ MAP_INFO *MapInfo;
+
+ // Release the common buffer itself. Unmap() has re-encrypted it in-place, so
+ // no need to zero it.
+ MapInfo = FindMappingByHostAddress (HostAddress);
+ if (MapInfo == NULL) {
+ ASSERT (0);
+ return EFI_NOT_FOUND;
+ } else {
+ // UnMapSharedPages
+ Status = UnMapSharedBuffer (MapInfo, FALSE);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return gBS->FreePages ((UINTN)HostAddress, Pages);
+}
+
+/**
+ Set IOMMU attribute for a system memory.
+
+ If the IOMMU protocol exists, the system memory cannot be used
+ for DMA by default.
+
+ When a device requests a DMA access to system memory,
+ the device driver need use SetAttribute() to update the IOMMU
+ attribute to request DMA access (read and/or write).
+
+ The DeviceHandle is used to identify which device submits the request.
+ The IOMMU implementation need to translate the device path to an IOMMU device
+ ID, and set the IOMMU hardware register accordingly.
+ 1) DeviceHandle can be a standard PCI device.
+ The memory for BusMasterRead needs EDKII_IOMMU_ACCESS_READ set.
+ The memory for BusMasterWrite needs EDKII_IOMMU_ACCESS_WRITE set.
+ The memory for BusMasterCommonBuffer needs
+ EDKII_IOMMU_ACCESS_READ|EDKII_IOMMU_ACCESS_WRITE set.
+ After the memory is used, the memory need set 0 to keep it being
+ protected.
+ 2) DeviceHandle can be an ACPI device (ISA, I2C, SPI, etc).
+ The memory for DMA access need set EDKII_IOMMU_ACCESS_READ and/or
+ EDKII_IOMMU_ACCESS_WRITE.
+
+ @param[in] This The protocol instance pointer.
+ @param[in] DeviceHandle The device initiating the DMA access
+ request.
+ @param[in] Mapping The mapping value returned from Map().
+ @param[in] IoMmuAccess The IOMMU access.
+
+ @retval EFI_UNSUPPORTED Operation not supported by IOMMU.
+
+**/
+EFI_STATUS
+EFIAPI
+IoMmuSetAttribute (
+ IN EDKII_IOMMU_PROTOCOL *This,
+ IN EFI_HANDLE DeviceHandle,
+ IN VOID *Mapping,
+ IN UINT64 IoMmuAccess
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/** Arm CCA IoMMU protocol
+*/
+EDKII_IOMMU_PROTOCOL mArmCcaIoMmu = {
+ EDKII_IOMMU_PROTOCOL_REVISION,
+ IoMmuSetAttribute,
+ IoMmuMap,
+ IoMmuUnmap,
+ IoMmuAllocateBuffer,
+ IoMmuFreeBuffer,
+};
+
+/**
+ Notification function that is queued when gBS->ExitBootServices() signals the
+ EFI_EVENT_GROUP_EXIT_BOOT_SERVICES event group. This function signals another
+ event, received as Context, and returns.
+
+ Signaling an event in this context is safe. The UEFI spec allows
+ gBS->SignalEvent() to return EFI_SUCCESS only; EFI_OUT_OF_RESOURCES is not
+ listed, hence memory is not allocated. The edk2 implementation also does not
+ release memory (and we only have to care about the edk2 implementation
+ because EDKII_IOMMU_PROTOCOL is edk2-specific anyway).
+
+ @param[in] Event Event whose notification function is being invoked.
+ Event is permitted to request the queueing of this
+ function at TPL_CALLBACK or TPL_NOTIFY task
+ priority level.
+
+ @param[in] EventToSignal Identifies the EFI_EVENT to signal. EventToSignal
+ is permitted to request the queueing of its
+ notification function only at TPL_CALLBACK level.
+**/
+STATIC
+VOID
+EFIAPI
+ArmCcaIoMmuExitBoot (
+ IN EFI_EVENT Event,
+ IN VOID *EventToSignal
+ )
+{
+ // (1) The NotifyFunctions of all the events in
+ // EFI_EVENT_GROUP_EXIT_BOOT_SERVICES will have been queued before
+ // ArmCcaIoMmuExitBoot() is entered.
+ //
+ // (2) ArmCcaIoMmuExitBoot() is executing minimally at TPL_CALLBACK.
+ //
+ // (3) ArmCcaIoMmuExitBoot() has been queued in unspecified order relative
+ // to the NotifyFunctions of all the other events in
+ // EFI_EVENT_GROUP_EXIT_BOOT_SERVICES whose NotifyTpl is the same as
+ // Event's.
+ //
+ // Consequences:
+ //
+ // - If Event's NotifyTpl is TPL_CALLBACK, then some other NotifyFunctions
+ // queued at TPL_CALLBACK may be invoked after ArmCcaIoMmuExitBoot()
+ // returns.
+ //
+ // - If Event's NotifyTpl is TPL_NOTIFY, then some other NotifyFunctions
+ // queued at TPL_NOTIFY may be invoked after ArmCcaIoMmuExitBoot() returns;
+ // plus *all* NotifyFunctions queued at TPL_CALLBACK will be invoked
+ // strictly after all NotifyFunctions queued at TPL_NOTIFY, including
+ // ArmCcaIoMmuExitBoot(), have been invoked.
+ //
+ // - By signaling EventToSignal here, whose NotifyTpl is TPL_CALLBACK, we
+ // queue EventToSignal's NotifyFunction after the NotifyFunctions of *all*
+ // events in EFI_EVENT_GROUP_EXIT_BOOT_SERVICES.
+ gBS->SignalEvent (EventToSignal);
+}
+
+/**
+ Notification function that is queued after the notification functions of all
+ events in the EFI_EVENT_GROUP_EXIT_BOOT_SERVICES event group. The same memory
+ map restrictions apply.
+
+ This function unmaps all currently existing IOMMU mappings.
+
+ @param[in] Event Event whose notification function is being invoked. Event
+ is permitted to request the queueing of this function
+ only at TPL_CALLBACK task priority level.
+
+ @param[in] Context Ignored.
+**/
+STATIC
+VOID
+EFIAPI
+ArmCcaIoMmuUnmapAllMappings (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ LIST_ENTRY *Node;
+ LIST_ENTRY *NextNode;
+ MAP_INFO *MapInfo;
+
+ // All drivers that had set up IOMMU mappings have halted their respective
+ // controllers by now; tear down the mappings.
+ for (Node = GetFirstNode (&mMapInfos); Node != &mMapInfos; Node = NextNode) {
+ NextNode = GetNextNode (&mMapInfos, Node);
+ MapInfo = CR (Node, MAP_INFO, Link, MAP_INFO_SIG);
+ IoMmuUnmapWorker (
+ &mArmCcaIoMmu, // This
+ MapInfo, // Mapping
+ TRUE // MemoryMapLocked
+ );
+ }
+}
+
+/**
+ Initialize and install the ArmCca IoMmu Protocol.
+
+ @return RETURN_SUCCESS if successful, otherwise any other error.
+**/
+EFI_STATUS
+EFIAPI
+ArmCcaInstallIoMmuProtocol (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT UnmapAllMappingsEvent;
+ EFI_EVENT ExitBootEvent;
+ EFI_HANDLE Handle;
+
+ // Create the "late" event whose notification function will tear down all
+ // left-over IOMMU mappings.
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL, // Type
+ TPL_CALLBACK, // NotifyTpl
+ ArmCcaIoMmuUnmapAllMappings, // NotifyFunction
+ NULL, // NotifyContext
+ &UnmapAllMappingsEvent // Event
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Create the event whose notification function will be queued by
+ // gBS->ExitBootServices() and will signal the event created above.
+ Status = gBS->CreateEvent (
+ EVT_SIGNAL_EXIT_BOOT_SERVICES, // Type
+ TPL_CALLBACK, // NotifyTpl
+ ArmCcaIoMmuExitBoot, // NotifyFunction
+ UnmapAllMappingsEvent, // NotifyContext
+ &ExitBootEvent // Event
+ );
+ if (EFI_ERROR (Status)) {
+ goto CloseUnmapAllMappingsEvent;
+ }
+
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEdkiiIoMmuProtocolGuid,
+ &mArmCcaIoMmu,
+ NULL
+ );
+ if (!EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // cleanup on error
+ gBS->CloseEvent (ExitBootEvent);
+
+CloseUnmapAllMappingsEvent:
+ gBS->CloseEvent (UnmapAllMappingsEvent);
+
+ return Status;
+}
diff --git a/ArmVirtPkg/ArmCcaIoMmuDxe/ArmCcaIoMmu.h b/ArmVirtPkg/ArmCcaIoMmuDxe/ArmCcaIoMmu.h
new file mode 100644
index 0000000000000000000000000000000000000000..070f7bebf5bff84fc3e530e434d62c1205bfb70a
--- /dev/null
+++ b/ArmVirtPkg/ArmCcaIoMmuDxe/ArmCcaIoMmu.h
@@ -0,0 +1,66 @@
+/** @file
+ The protocol provides support to allocate, free, map and umap a DMA buffer
+ for bus master (e.g PciHostBridge). When the execution context is a Realm,
+ the DMA operations must be performed on buffers that are shared with the HOST,
+ hence the RAMP protocol is used to manage the sharing of the DMA buffers or in
+ some cases bounce the buffers.
+
+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2017, AMD Inc. All rights reserved.<BR>
+ (C) Copyright 2017 Hewlett Packard Enterprise Development LP<BR>
+ Copyright (c) 2022 - 2023, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef ARM_CCA_IOMMU_H_
+#define ARM_CCA_IOMMU_H_
+
+#include <Protocol/IoMmu.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/RealmApertureManagementProtocol.h>
+
+/**
+ A macro defning the signature for the MAP_INFO structure.
+*/
+#define MAP_INFO_SIG SIGNATURE_64 ('M', 'A', 'P', '_', 'I', 'N', 'F', 'O')
+
+/** A structure describing the mapping for the buffers shared with the host.
+*/
+typedef struct {
+ /// Signature.
+ UINT64 Signature;
+ /// Linked List node entry.
+ LIST_ENTRY Link;
+ /// IoMMU operation.
+ EDKII_IOMMU_OPERATION Operation;
+ /// Number of bytes.
+ UINTN NumberOfBytes;
+ /// Number of pages.
+ UINTN NumberOfPages;
+ /// Address of the Host buffer.
+ VOID *HostAddress;
+
+ /// Address for the Bounce Buffer.
+ EFI_PHYSICAL_ADDRESS BbAddress;
+ /// Handle to the Aperture.
+ EFI_HANDLE ApertureRef;
+} MAP_INFO;
+
+/**
+ Install IOMMU protocol to provide the DMA support for PciHostBridge and
+ RAMP.
+
+**/
+EFI_STATUS
+EFIAPI
+ArmCcaInstallIoMmuProtocol (
+ VOID
+ );
+
+#endif
diff --git a/ArmVirtPkg/ArmCcaIoMmuDxe/ArmCcaIoMmuDxe.c b/ArmVirtPkg/ArmCcaIoMmuDxe/ArmCcaIoMmuDxe.c
new file mode 100644
index 0000000000000000000000000000000000000000..deba9dd5e72041f318336141ca8095b4a43d8b9b
--- /dev/null
+++ b/ArmVirtPkg/ArmCcaIoMmuDxe/ArmCcaIoMmuDxe.c
@@ -0,0 +1,59 @@
+/** @file
+
+ IoMmuArmBowDxe driver installs EDKII_IOMMU_PROTOCOL to support
+ DMA operations when the execution context is a Realm.
+
+ Copyright (c) 2017, AMD Inc. All rights reserved.<BR>
+ Copyright (c) 2022 - 2023, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "ArmCcaIoMmu.h"
+
+/** Pointer to the Realm Aperture Management Protocol
+*/
+EDKII_REALM_APERTURE_MANAGEMENT_PROTOCOL *mRamp = NULL;
+
+/** Entrypoint of Arm CCA IoMMU Dxe.
+
+ @param [in] ImageHandle Image handle of this driver.
+ @param [in] SystemTable Pointer to the EFI System Table.
+
+ @return RETURN_SUCCESS if successful, otherwise any other error.
+**/
+EFI_STATUS
+EFIAPI
+ArmCcaIoMmuDxeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+
+ // When the execution context is a Realm, install ArmCcaIoMmu protocol
+ // otherwise install the placeholder protocol so that other dependent
+ // module can run.
+ Status = gBS->LocateProtocol (
+ &gEfiRealmApertureManagementProtocolGuid,
+ NULL,
+ (VOID **)&mRamp
+ );
+ if (!EFI_ERROR (Status)) {
+ // If the Realm Aperture Management Protocol is present
+ // then the execution context is a Realm.
+ Status = ArmCcaInstallIoMmuProtocol ();
+ } else {
+ DEBUG ((DEBUG_INFO, "Execution context is not a Realm.\n"));
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gIoMmuAbsentProtocolGuid,
+ NULL,
+ NULL
+ );
+ }
+
+ return Status;
+}
diff --git a/ArmVirtPkg/ArmCcaIoMmuDxe/ArmCcaIoMmuDxe.inf b/ArmVirtPkg/ArmCcaIoMmuDxe/ArmCcaIoMmuDxe.inf
new file mode 100644
index 0000000000000000000000000000000000000000..b8e125296f4da417a7a07ccbaebce33c29d411e5
--- /dev/null
+++ b/ArmVirtPkg/ArmCcaIoMmuDxe/ArmCcaIoMmuDxe.inf
@@ -0,0 +1,45 @@
+## @file
+# Driver provides the IOMMU protcol support for PciHostBridgeIo and others
+# drivers.
+#
+# Copyright (c) 2017, AMD Inc. All rights reserved.<BR>
+# Copyright (c) 2022 - 2023, Arm Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = IoMmuDxe
+ FILE_GUID = AA6C1A48-A341-439C-950E-CC394FDFE144
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ArmCcaIoMmuDxeEntryPoint
+
+[Sources]
+ ArmCcaIoMmu.c
+ ArmCcaIoMmu.h
+ ArmCcaIoMmuDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ OvmfPkg/OvmfPkg.dec
+ ArmVirtPkg/ArmVirtPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gEdkiiIoMmuProtocolGuid ## SOMETIME_PRODUCES
+ gIoMmuAbsentProtocolGuid ## SOMETIME_PRODUCES
+ gEfiRealmApertureManagementProtocolGuid
+
+[Depex]
+ gEfiRealmApertureManagementProtocolGuid
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117700): https://edk2.groups.io/g/devel/message/117700
Mute This Topic: https://groups.io/mt/105483443/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 27/45] ArmVirtPkg: Enable Virtio communication for Arm CCA
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (25 preceding siblings ...)
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 26/45] ArmVirtPkg: IoMMU driver to DMA from Realms Sami Mujawar
@ 2024-04-12 14:33 ` Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 28/45] MdePkg: Warn if AArch64 RNDR instruction is not supported Sami Mujawar
` (12 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:33 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
Arm CCA Realms protect the access to memory from outside the
Realm. For Virtio to work the Realm Guest and the Host should
be able to share buffers.
Realm Aperture Management protocol (RAMP) manages the sharing
of buffers between the Realm Guest and the Host, while the
ArmCcaIoMmuDxe implements the EDKII_IOMMU_PROTOCOL which
provides the necessary hooks so that DMA accesses can be
performed by bouncing buffers using pages shared with the
host.
Therefore, enable the support for Realm Aperture Management
Protocol and ArmCcaIoMmuDxe for Kvmtool Guest firmware.
Note: The ArmCcaIoMmuDxe and RAMP check if the code is executing
in a Realm before installing the respective protocols. If the
code is not executing in a Realm the gIoMmuAbsentProtocolGuid is
installed, thereby allowing the same firmware to be used both for
normal and Realm Guest firmware.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/ArmVirtKvmTool.dsc | 13 +++++++++++--
ArmVirtPkg/ArmVirtKvmTool.fdf | 10 ++++++++++
2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/ArmVirtPkg/ArmVirtKvmTool.dsc b/ArmVirtPkg/ArmVirtKvmTool.dsc
index 33eb280f91413141cacb6526375c2733778a853c..c358b0a55daea8f8231b037cc63005cc86fe9a18 100644
--- a/ArmVirtPkg/ArmVirtKvmTool.dsc
+++ b/ArmVirtPkg/ArmVirtKvmTool.dsc
@@ -401,9 +401,18 @@ [Components.common]
#
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
-!if $(ARCH) == AARCH64
+[Components.AARCH64]
#
# ACPI Support
#
ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManagerDxe.inf
-!endif
+
+ #
+ # Realm Aperture Management
+ #
+ ArmVirtPkg/RealmApertureManagementProtocolDxe/RealmApertureManagementProtocolDxe.inf
+
+ #
+ # IoMMU support for Arm CCA
+ #
+ ArmVirtPkg/ArmCcaIoMmuDxe/ArmCcaIoMmuDxe.inf
diff --git a/ArmVirtPkg/ArmVirtKvmTool.fdf b/ArmVirtPkg/ArmVirtKvmTool.fdf
index cdf756c11289b90cb3815295a6cb38cb2f74916f..07d86f649e01a9e61f2acb76f748a95eb57c0a6e 100644
--- a/ArmVirtPkg/ArmVirtKvmTool.fdf
+++ b/ArmVirtPkg/ArmVirtKvmTool.fdf
@@ -212,6 +212,16 @@ [FV.FvMain]
!include DynamicTablesPkg/DynamicTables.fdf.inc
INF ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManagerDxe.inf
+
+ #
+ # Realm Aperture Management
+ #
+ INF ArmVirtPkg/RealmApertureManagementProtocolDxe/RealmApertureManagementProtocolDxe.inf
+
+ #
+ # IoMMU support for Arm CCA
+ #
+ INF ArmVirtPkg/ArmCcaIoMmuDxe/ArmCcaIoMmuDxe.inf
!endif
#
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117695): https://edk2.groups.io/g/devel/message/117695
Mute This Topic: https://groups.io/mt/105483435/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 28/45] MdePkg: Warn if AArch64 RNDR instruction is not supported
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (26 preceding siblings ...)
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 27/45] ArmVirtPkg: Enable Virtio communication for Arm CCA Sami Mujawar
@ 2024-04-12 14:33 ` Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 29/45] ArmVirtPkg: Kvmtool: Switch to use BaseRng for AArch64 Sami Mujawar
` (11 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:33 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, michael.d.kinney,
gaoliming, zhiguang.liu, Matteo.Carlini, Akanksha.Jain2,
Sibel.Allinson, nd, Gerd Hoffmann
The BaseRngLib library constructor for AArch64 asserts if the
RNDR instruction is not supported by the CPU. This approach to
warn about the unsupported instruction may be suitable for the
host platform firmware. However, for a guest firmware the only
mechanism to discover the supported RNG interface is by probing
the processor feature registers.
The guest firmware may therefore assume that RNDR instruction
is supported and if the probe fails, fall back to an alternate
RNG source, e.g. Virtio RNG.
Therefore, replace the assert with a warning message to allow
the guest firmware to progress.
Note:
- If RNDR instruction is not supported, the GetRandomNumberXXX
functions will return FALSE to indicate that the random number
generation has failed. It is expected that the calling function
checks the status and handles this error appropriately.
- This change should not have any side effect as the behaviour
will be similar to that of release builds where the asserts
would be removed.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
MdePkg/Library/BaseRngLib/AArch64/Rndr.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/MdePkg/Library/BaseRngLib/AArch64/Rndr.c b/MdePkg/Library/BaseRngLib/AArch64/Rndr.c
index d39db62153eed415151e7a27a5931231febd20d3..dc41eea8fbfd7d18bca24e2ebe1cdc56b4eb8d81 100644
--- a/MdePkg/Library/BaseRngLib/AArch64/Rndr.c
+++ b/MdePkg/Library/BaseRngLib/AArch64/Rndr.c
@@ -49,10 +49,14 @@ BaseRngLibConstructor (
// Determine RNDR support by examining bits 63:60 of the ISAR0 register returned by
// MSR. A non-zero value indicates that the processor supports the RNDR instruction.
//
- Isar0 = ArmReadIdIsar0 ();
- ASSERT ((Isar0 & RNDR_MASK) != 0);
-
+ Isar0 = ArmReadIdIsar0 ();
mRndrSupported = ((Isar0 & RNDR_MASK) != 0);
+ if (!mRndrSupported) {
+ DEBUG ((
+ DEBUG_WARN,
+ "WARNING: BaseRngLib: RNDR instruction not supported by the processor.\n"
+ ));
+ }
return EFI_SUCCESS;
}
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117701): https://edk2.groups.io/g/devel/message/117701
Mute This Topic: https://groups.io/mt/105483444/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 29/45] ArmVirtPkg: Kvmtool: Switch to use BaseRng for AArch64
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (27 preceding siblings ...)
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 28/45] MdePkg: Warn if AArch64 RNDR instruction is not supported Sami Mujawar
@ 2024-04-12 14:33 ` Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 31/45] ArmVirtPkg: ArmCcaRsiLib: Fix size of Imm field in HostCallArgs Sami Mujawar
` (10 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:33 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
The kvmtool guest firmware is using the default RNG library
defined in ArmVirtPkg.dsc.inc which is BaseRngLibTimerLib.
BaseRngLibTimerLib is only present to use for test purposes on
platforms that do not have a suitable RNG source and must not be
used for production purposes.
Armv8.5 introduces random number instructions (e.g., RNDR) which
return a 64-bit random number. Although, this feature is optional,
it can be assumed that most modern platforms will implement this
support. This feature i.e. FEAT_RNG can be discovered by examining
the processor feature registers.
It is therefore desirable to use the RNDR instructions instead of
using the default BaseRngLibTimerLib which is unsafe.
The BaseRngLib in MdePkg already implements the RNG support using
RNDR. However, it is worth noting that FEAT_RNG is supported in
AArch64 state only. Therefore, switch to using the BaseRngLib
instance for AArch64 firmware builds. The AArch32 firmware builds
will continue to use BaseRngLibTimerLib.
Note: The guest firmware already supports Virtio RNG. So, should
the processor not implement FEAT_RNG, the guest firmware can fall
back to use Virtio RNG.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/ArmVirtKvmTool.dsc | 1 +
1 file changed, 1 insertion(+)
diff --git a/ArmVirtPkg/ArmVirtKvmTool.dsc b/ArmVirtPkg/ArmVirtKvmTool.dsc
index c358b0a55daea8f8231b037cc63005cc86fe9a18..835e4f1a5a618537d885682322a288f12b8ce8dd 100644
--- a/ArmVirtPkg/ArmVirtKvmTool.dsc
+++ b/ArmVirtPkg/ArmVirtKvmTool.dsc
@@ -90,6 +90,7 @@ [LibraryClasses.common]
[LibraryClasses.AARCH64]
ArmCcaLib|ArmVirtPkg/Library/ArmCcaLib/ArmCcaLib.inf
ArmCcaRsiLib|ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.inf
+ RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
[LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM]
PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117692): https://edk2.groups.io/g/devel/message/117692
Mute This Topic: https://groups.io/mt/105483431/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 31/45] ArmVirtPkg: ArmCcaRsiLib: Fix size of Imm field in HostCallArgs
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (28 preceding siblings ...)
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 29/45] ArmVirtPkg: Kvmtool: Switch to use BaseRng for AArch64 Sami Mujawar
@ 2024-04-12 14:33 ` Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 32/45] ArmVirtPkg: RMM 1.0-bet1 - Update width of RSI host call struct Sami Mujawar
` (9 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:33 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
The section B4.4.2 'RsiHostCall type' of the RMM specification
version A-bet0 specifies the Imm field in HostCallArgs structure
as a 16 bit wide value and the offset for the gprs[0] field is
0x8, which means the 6 bytes after the Imm field are padded.
Therefore, define the Imm field as UINT16 and add an additional
field UINT8 Reserved1[6] for padding.
Also update the RsiHostCall() to initialise the Reserved1 field
to zero.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/Include/Library/ArmCcaRsiLib.h | 4 +++-
ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c | 1 +
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
index db1ae5b4c1a6475a275ce6be3383ea933ec9af20..af4be275d37f0376335de5344f9626c9a92c70d2 100644
--- a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
+++ b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
@@ -85,7 +85,9 @@ typedef struct RealmConfig {
See Section 4.4.2 RsiHostCall type, RMM Specification, version A-bet0
*/
typedef struct HostCallArgs {
- UINT64 Imm;
+ UINT16 Imm;
+ UINT8 Reserved1[6];
+
UINT64 Gprs0;
UINT64 Gprs1;
UINT64 Gprs2;
diff --git a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
index 79a65300f05af665b3afebe2a8f8b1f6faf76f23..dc41e77b55f4369e89592b5437e525baf80aa0b3 100644
--- a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
+++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
@@ -519,6 +519,7 @@ RsiHostCall (
STATIC_ASSERT (sizeof (HOST_CALL_ARGS) == SIZE_4KB);
// Clear the reserved fields
+ ZeroMem (&Args->Reserved1, sizeof (Args->Reserved1));
ZeroMem (&Args->Reserved, sizeof (Args->Reserved));
ZeroMem (&SmcCmd, sizeof (SmcCmd));
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117693): https://edk2.groups.io/g/devel/message/117693
Mute This Topic: https://groups.io/mt/105483432/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 32/45] ArmVirtPkg: RMM 1.0-bet1 - Update width of RSI host call struct
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (29 preceding siblings ...)
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 31/45] ArmVirtPkg: ArmCcaRsiLib: Fix size of Imm field in HostCallArgs Sami Mujawar
@ 2024-04-12 14:33 ` Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 33/45] ArmVirtPkg: RMM 1.0-bet2 - Increase number of RSI host call args Sami Mujawar
` (8 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:33 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
The RMM 1.0-bet1 updates the width of the RsiHostCall
structure to 256 (0x100) bytes.
Therefore, update the RSI HOST_CALL_ARGS structure to reflect
these changes.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/Include/Library/ArmCcaRsiLib.h | 6 +++---
ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c | 6 ++++--
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
index af4be275d37f0376335de5344f9626c9a92c70d2..81d125a81941cc1680cfdfb08e001193851d50e5 100644
--- a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
+++ b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
@@ -11,7 +11,7 @@
- REM - Realm Extensible Measurement
@par Reference(s):
- - Realm Management Monitor (RMM) Specification, version A-bet0
+ - Realm Management Monitor (RMM) Specification, version 1.0-bet1
(https://developer.arm.com/documentation/den0137/)
**/
@@ -82,7 +82,7 @@ typedef struct RealmConfig {
} REALM_CONFIG;
/** A structure describing the Host Call arguments
- See Section 4.4.2 RsiHostCall type, RMM Specification, version A-bet0
+ See Section 4.4.2 RsiHostCall type, RMM Specification, version 1.0-bet1
*/
typedef struct HostCallArgs {
UINT16 Imm;
@@ -95,7 +95,7 @@ typedef struct HostCallArgs {
UINT64 Gprs4;
UINT64 Gprs5;
UINT64 Gprs6;
- UINT8 Reserved[0x1000 - (sizeof (UINT64) * 8)];
+ UINT8 Reserved[0x100 - (sizeof (UINT64) * 8)];
} HOST_CALL_ARGS;
/**
diff --git a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
index dc41e77b55f4369e89592b5437e525baf80aa0b3..5984651f6d9d627d9fee30a4fbf11c45b3951877 100644
--- a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
+++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
@@ -11,7 +11,7 @@
- REM - Realm Extensible Measurement
@par Reference(s):
- - Realm Management Monitor (RMM) Specification, version A-bet0
+ - Realm Management Monitor (RMM) Specification, version 1.0-bet1
(https://developer.arm.com/documentation/den0137/)
**/
@@ -516,7 +516,9 @@ RsiHostCall (
return RETURN_INVALID_PARAMETER;
}
- STATIC_ASSERT (sizeof (HOST_CALL_ARGS) == SIZE_4KB);
+ // See RMM specification, version 1.0-bet1, Section B4.4.2 RsiHostCall type
+ // The width of the RsiHostCall structure is 256 (0x100) bytes.
+ STATIC_ASSERT (sizeof (HOST_CALL_ARGS) == 0x100);
// Clear the reserved fields
ZeroMem (&Args->Reserved1, sizeof (Args->Reserved1));
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117694): https://edk2.groups.io/g/devel/message/117694
Mute This Topic: https://groups.io/mt/105483434/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 33/45] ArmVirtPkg: RMM 1.0-bet2 - Increase number of RSI host call args
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (30 preceding siblings ...)
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 32/45] ArmVirtPkg: RMM 1.0-bet1 - Update width of RSI host call struct Sami Mujawar
@ 2024-04-12 14:33 ` Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 34/45] ArmVirtPkg: RMM 1.0-eac0 - Update RsiSetIpaState parameter usage Sami Mujawar
` (7 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:33 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
The RMM 1.0-bet2 spec expands the set of GPRs for RSI host call
to X0-X30.
Therefore, update the RSI HOST_CALL_ARGS structure to reflect
these changes.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/Include/Library/ArmCcaRsiLib.h | 29 ++++++++++++++++++--
ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c | 3 +-
2 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
index 81d125a81941cc1680cfdfb08e001193851d50e5..3d6ace866def5f10dd74afd4e9340530150f6f43 100644
--- a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
+++ b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
@@ -11,7 +11,7 @@
- REM - Realm Extensible Measurement
@par Reference(s):
- - Realm Management Monitor (RMM) Specification, version 1.0-bet1
+ - Realm Management Monitor (RMM) Specification, version 1.0-bet2
(https://developer.arm.com/documentation/den0137/)
**/
@@ -82,7 +82,7 @@ typedef struct RealmConfig {
} REALM_CONFIG;
/** A structure describing the Host Call arguments
- See Section 4.4.2 RsiHostCall type, RMM Specification, version 1.0-bet1
+ See Section 4.4.2 RsiHostCall type, RMM Specification, version 1.0-bet2
*/
typedef struct HostCallArgs {
UINT16 Imm;
@@ -95,7 +95,30 @@ typedef struct HostCallArgs {
UINT64 Gprs4;
UINT64 Gprs5;
UINT64 Gprs6;
- UINT8 Reserved[0x100 - (sizeof (UINT64) * 8)];
+ UINT64 Gprs7;
+ UINT64 Gprs8;
+ UINT64 Gprs9;
+ UINT64 Gprs10;
+ UINT64 Gprs11;
+ UINT64 Gprs12;
+ UINT64 Gprs13;
+ UINT64 Gprs14;
+ UINT64 Gprs15;
+ UINT64 Gprs16;
+ UINT64 Gprs17;
+ UINT64 Gprs18;
+ UINT64 Gprs19;
+ UINT64 Gprs20;
+ UINT64 Gprs21;
+ UINT64 Gprs22;
+ UINT64 Gprs23;
+ UINT64 Gprs24;
+ UINT64 Gprs25;
+ UINT64 Gprs26;
+ UINT64 Gprs27;
+ UINT64 Gprs28;
+ UINT64 Gprs29;
+ UINT64 Gprs30;
} HOST_CALL_ARGS;
/**
diff --git a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
index 5984651f6d9d627d9fee30a4fbf11c45b3951877..ceec0477d7ec9ba0ae831aa5a4f31d8a3791b9d1 100644
--- a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
+++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
@@ -11,7 +11,7 @@
- REM - Realm Extensible Measurement
@par Reference(s):
- - Realm Management Monitor (RMM) Specification, version 1.0-bet1
+ - Realm Management Monitor (RMM) Specification, version 1.0-bet2
(https://developer.arm.com/documentation/den0137/)
**/
@@ -522,7 +522,6 @@ RsiHostCall (
// Clear the reserved fields
ZeroMem (&Args->Reserved1, sizeof (Args->Reserved1));
- ZeroMem (&Args->Reserved, sizeof (Args->Reserved));
ZeroMem (&SmcCmd, sizeof (SmcCmd));
SmcCmd.Arg0 = FID_RSI_HOST_CALL;
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117703): https://edk2.groups.io/g/devel/message/117703
Mute This Topic: https://groups.io/mt/105483446/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 34/45] ArmVirtPkg: RMM 1.0-eac0 - Update RsiSetIpaState parameter usage
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (31 preceding siblings ...)
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 33/45] ArmVirtPkg: RMM 1.0-bet2 - Increase number of RSI host call args Sami Mujawar
@ 2024-04-12 14:33 ` Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 35/45] ArmVirtPkg: RMM 1.0-eac1 - Relax alignment of RSI host call arg Sami Mujawar
` (6 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:33 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
The RMM 1.0-eac0 specification updates the parameter usage for the
RSI_IPA_STATE_SET command to change the parameter 3 from IPA region
size to Top of target IPA region.
Therefore, update the RseSetIpaState () implementation to reflect
this change.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
index ceec0477d7ec9ba0ae831aa5a4f31d8a3791b9d1..59b9d7a12c82a534280595328347995f1ff51ee2 100644
--- a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
+++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
@@ -11,7 +11,7 @@
- REM - Realm Extensible Measurement
@par Reference(s):
- - Realm Management Monitor (RMM) Specification, version 1.0-bet2
+ - Realm Management Monitor (RMM) Specification, version 1.0-eac0
(https://developer.arm.com/documentation/den0137/)
**/
@@ -351,7 +351,7 @@ RsiSetIpaState (
ZeroMem (&SmcCmd, sizeof (SmcCmd));
SmcCmd.Arg0 = FID_RSI_IPA_STATE_SET;
SmcCmd.Arg1 = (UINTN)BaseAddress;
- SmcCmd.Arg2 = (UINTN)Size;
+ SmcCmd.Arg2 = (UINTN)EndAddress;
SmcCmd.Arg3 = (UINTN)State;
ArmCallSmc (&SmcCmd);
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117699): https://edk2.groups.io/g/devel/message/117699
Mute This Topic: https://groups.io/mt/105483442/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 35/45] ArmVirtPkg: RMM 1.0-eac1 - Relax alignment of RSI host call arg
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (32 preceding siblings ...)
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 34/45] ArmVirtPkg: RMM 1.0-eac0 - Update RsiSetIpaState parameter usage Sami Mujawar
@ 2024-04-12 14:33 ` Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 36/45] ArmVirtPkg: RMM 1.0-eac2 - Update RsiRealmConfig structure Sami Mujawar
` (5 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:33 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
The RMM 1.0-eac1 relaxed the RSI_HOST_CALL alignment requirement
from 4KB to 256B.
Therefore, update the alignment check for the address parameter
of the RSI_HOST_CALL command to relax the alignment requirement
to 256 bytes.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
index 59b9d7a12c82a534280595328347995f1ff51ee2..0280d8e42882ddfb02d0a40c47a6fba7855ba84f 100644
--- a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
+++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
@@ -11,7 +11,7 @@
- REM - Realm Extensible Measurement
@par Reference(s):
- - Realm Management Monitor (RMM) Specification, version 1.0-eac0
+ - Realm Management Monitor (RMM) Specification, version 1.0-eac1
(https://developer.arm.com/documentation/den0137/)
**/
@@ -512,7 +512,11 @@ RsiHostCall (
{
ARM_SMC_ARGS SmcCmd;
- if ((Args == NULL) || (!AddrIsGranuleAligned ((UINT64 *)Args))) {
+ // The RMM specification, version 1.0-eac1, relaxes the alignment
+ // requirement for RSI_HOST_CALL from 4KB to 256B. Also see RMM
+ // specification, sections B4.3.3 RSI_HOST_CALL command and
+ // section B4.3.3.2 Failure conditions.
+ if ((Args == NULL) || (((UINT64)Args & (0x100 - 1)) != 0)) {
return RETURN_INVALID_PARAMETER;
}
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117705): https://edk2.groups.io/g/devel/message/117705
Mute This Topic: https://groups.io/mt/105483448/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 36/45] ArmVirtPkg: RMM 1.0-eac2 - Update RsiRealmConfig structure
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (33 preceding siblings ...)
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 35/45] ArmVirtPkg: RMM 1.0-eac1 - Relax alignment of RSI host call arg Sami Mujawar
@ 2024-04-12 14:33 ` Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 37/45] ArmVirtPkg: RMM 1.0-eac2 - Add RIPAS DESTROYED state Sami Mujawar
` (4 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:33 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
The RMM 1.0-eac2 specification updates the RsiRealmConfig
structure to add a new member to identify the Realm hash
algorithm.
Therefore, update the REALM_CONFIG structure to add a
new member HashAlgorithm that represents the Realm hash
value. Also add macros to define the RsiHashAlgorithm
enumeration values SHA-256 and SHA-512.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/Include/Library/ArmCcaRsiLib.h | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
index 3d6ace866def5f10dd74afd4e9340530150f6f43..2b72ad09da85a9fd2f067db1c511d12f636d3dda 100644
--- a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
+++ b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
@@ -11,7 +11,7 @@
- REM - Realm Extensible Measurement
@par Reference(s):
- - Realm Management Monitor (RMM) Specification, version 1.0-bet2
+ - Realm Management Monitor (RMM) Specification, version 1.0-eac2
(https://developer.arm.com/documentation/den0137/)
**/
@@ -61,6 +61,16 @@
#define MIN_REM_INDEX 1
#define MAX_REM_INDEX 4
+/* The values of the RsiHashAlgorithm enumeration.
+ SHA-256 (Secure Hash Standard (SHS))
+*/
+#define RSI_HASH_SHA_256 0
+
+/* The values of the RsiHashAlgorithm enumeration.
+ SHA-512 (Secure Hash Standard (SHS))
+*/
+#define RSI_HASH_SHA_512 1
+
/** An enum describing the RSI RIPAS.
See Section A5.2.2 Realm IPA state, RMM Specification, version A-bet0
*/
@@ -71,14 +81,16 @@ typedef enum Ripas {
} RIPAS;
/** A structure describing the Realm Configuration.
- See Section B4.4.4 RsiRealmConfig type, RMM Specification, version A-bet0
+ See Section B4.4.5 RsiRealmConfig type, RMM Specification, version 1.0-eac2
The width of the RsiRealmConfig structure is 4096 (0x1000) bytes.
*/
typedef struct RealmConfig {
// Width of IPA in bits.
UINT64 IpaWidth;
+ // Width of the RsiHashAlgorithm enumeration is 8 bits.
+ UINT8 HashAlgorithm;
// Unused bits of the RsiRealmConfig structure should be zero.
- UINT8 Reserved[SIZE_4KB - sizeof (UINT64)];
+ UINT8 Reserved[SIZE_4KB - (sizeof (UINT64) + sizeof (UINT8))];
} REALM_CONFIG;
/** A structure describing the Host Call arguments
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117698): https://edk2.groups.io/g/devel/message/117698
Mute This Topic: https://groups.io/mt/105483441/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 37/45] ArmVirtPkg: RMM 1.0-eac2 - Add RIPAS DESTROYED state
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (34 preceding siblings ...)
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 36/45] ArmVirtPkg: RMM 1.0-eac2 - Update RsiRealmConfig structure Sami Mujawar
@ 2024-04-12 14:33 ` Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 38/45] ArmVirtPkg: RMM 1.0-eac2 - Add RsiRipasChangeFlags definitions Sami Mujawar
` (3 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:33 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
The RMM specification 1.0-eac2 updates the RIPAS state
to add a new DESTROYED state for an address which is
inaccessible to the Realm due to an action taken by
the Host.
Therefore, update the RSI RIPAS state enum to add the
new RIPAS_DESTROYED state.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/Include/Library/ArmCcaRsiLib.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
index 2b72ad09da85a9fd2f067db1c511d12f636d3dda..e237187dbc481d32aa6018c135aabe6f5a0781c6 100644
--- a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
+++ b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
@@ -72,11 +72,12 @@
#define RSI_HASH_SHA_512 1
/** An enum describing the RSI RIPAS.
- See Section A5.2.2 Realm IPA state, RMM Specification, version A-bet0
+ See Section A5.2.2 Realm IPA state, RMM Specification, version 1.0-eac2
*/
typedef enum Ripas {
RipasEmpty, ///< Unused IPA location.
RipasRam, ///< Private code or data owned by the Realm.
+ RipasDestroyed, ///< An address which is inaccessible to the Realm.
RipasMax ///< A valid RIPAS type value is less than RipasMax.
} RIPAS;
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117704): https://edk2.groups.io/g/devel/message/117704
Mute This Topic: https://groups.io/mt/105483447/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 38/45] ArmVirtPkg: RMM 1.0-eac2 - Add RsiRipasChangeFlags definitions
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (35 preceding siblings ...)
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 37/45] ArmVirtPkg: RMM 1.0-eac2 - Add RIPAS DESTROYED state Sami Mujawar
@ 2024-04-12 14:33 ` Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 39/45] ArmVirtPkg: RMM 1.0-eac2 - Add Flags to RsiSetIpaState() Sami Mujawar
` (2 subsequent siblings)
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:33 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
The RMM specification 1.0-eac2 updates the RSI_IPA_STATE_SET
interface to add a new parameter RsiRipasChangeFlags.
The RsiRipasChangeFlags fieldset is 64 bits and the bit 0
describes the RsiRipasChangeDestroyed type which is used
to indicate if a RIPAS change from DESTROYED should be
permitted or not.
Therefore, define the macros for specifying the
RsiRipasChangeFlags that represent the
RsiRipasChangeDestroyed type.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/Include/Library/ArmCcaRsiLib.h | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
index e237187dbc481d32aa6018c135aabe6f5a0781c6..154a5717f259502952a36312f6c3b3d6b75f15cb 100644
--- a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
+++ b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
@@ -71,6 +71,26 @@
*/
#define RSI_HASH_SHA_512 1
+/* The RsiRipasChangeFlags fieldset contains flags provided by
+ the Realm when requesting a RIPAS change.
+ See section B4.4.8 RsiRipasChangeFlags type in the
+ RMM Specification, version 1.0-eac2.
+ The following macros prefixed RIPAS_CHANGE_FLAGS_xxx
+ define the values of the RsiRipasChangeFlags fieldset.
+*/
+
+/* A RIPAS change from DESTROYED should not be permitted.
+ See section B4.4.7 RsiRipasChangeDestroyed type in the
+ RMM Specification, version 1.0-eac2
+*/
+#define RIPAS_CHANGE_FLAGS_RSI_NO_CHANGE_DESTROYED 0
+
+/* A RIPAS change from DESTROYED should be permitted.
+ See section B4.4.7 RsiRipasChangeDestroyed type in the
+ RMM Specification, version 1.0-eac2
+*/
+#define RIPAS_CHANGE_FLAGS_RSI_CHANGE_DESTROYED 1
+
/** An enum describing the RSI RIPAS.
See Section A5.2.2 Realm IPA state, RMM Specification, version 1.0-eac2
*/
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117708): https://edk2.groups.io/g/devel/message/117708
Mute This Topic: https://groups.io/mt/105483452/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 39/45] ArmVirtPkg: RMM 1.0-eac2 - Add Flags to RsiSetIpaState()
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (36 preceding siblings ...)
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 38/45] ArmVirtPkg: RMM 1.0-eac2 - Add RsiRipasChangeFlags definitions Sami Mujawar
@ 2024-04-12 14:33 ` Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 40/45] ArmVirtPkg: RMM 1.0-eac3 - Handle RsiSetIpaState() response Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 42/45] ArmVirtPkg: RMM 1.0-eac5 - Attestation token API updates Sami Mujawar
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:33 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
The RMM specification 1.0-eac2 updates the RSI_IPA_STATE_SET
interface to add a new parameter RsiRipasChangeFlags.
The RsiRipasChangeFlags fieldset is 64 bits and the bit 0
describes the RsiRipasChangeDestroyed type which is used
to indicate if a RIPAS change from DESTROYED should be
permitted or not.
Therefore, update the RsiSetIpaState() to add a new
parameter for specifying the RsiRipasChangeFlags.
Also update the usage of RsiSetIpaState() in ArmCcaInitPeiLib
and in RealmApertureManagementProtocolDxe.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/Include/Library/ArmCcaRsiLib.h | 4 +++-
ArmVirtPkg/Library/ArmCcaInitPeiLib/ArmCcaInitPeiLib.c | 3 ++-
ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c | 7 +++++--
ArmVirtPkg/RealmApertureManagementProtocolDxe/RealmApertureManagementProtocolDxe.c | 6 ++++--
4 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
index 154a5717f259502952a36312f6c3b3d6b75f15cb..5c2f996d3b4376e831a901f2919780acffec3313 100644
--- a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
+++ b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
@@ -205,6 +205,7 @@ RsiGetIpaState (
@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.
+ @param [in] Flags The RIPAS change flags.
@retval RETURN_SUCCESS Success.
@retval RETURN_INVALID_PARAMETER A parameter is invalid.
@@ -214,7 +215,8 @@ EFIAPI
RsiSetIpaState (
IN UINT64 *Address,
IN UINT64 Size,
- IN RIPAS State
+ IN RIPAS State,
+ IN UINT64 Flags
);
/**
diff --git a/ArmVirtPkg/Library/ArmCcaInitPeiLib/ArmCcaInitPeiLib.c b/ArmVirtPkg/Library/ArmCcaInitPeiLib/ArmCcaInitPeiLib.c
index 2b2801cc5426994efc15c970fd6b0adf43bd7d36..e59a990da42526e280c1951b404e318df6a7bfca 100644
--- a/ArmVirtPkg/Library/ArmCcaInitPeiLib/ArmCcaInitPeiLib.c
+++ b/ArmVirtPkg/Library/ArmCcaInitPeiLib/ArmCcaInitPeiLib.c
@@ -50,7 +50,8 @@ ArmCcaConfigureSystemMemory (
Status = RsiSetIpaState (
(UINT64 *)PcdGet64 (PcdSystemMemoryBase),
PcdGet64 (PcdSystemMemorySize),
- RipasRam
+ RipasRam,
+ RIPAS_CHANGE_FLAGS_RSI_NO_CHANGE_DESTROYED
);
if (RETURN_ERROR (Status)) {
// Panic
diff --git a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
index 0280d8e42882ddfb02d0a40c47a6fba7855ba84f..0535254a3991bfe7a19b904e83b9482f801da20c 100644
--- a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
+++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
@@ -11,7 +11,7 @@
- REM - Realm Extensible Measurement
@par Reference(s):
- - Realm Management Monitor (RMM) Specification, version 1.0-eac1
+ - Realm Management Monitor (RMM) Specification, version 1.0-eac2
(https://developer.arm.com/documentation/den0137/)
**/
@@ -318,6 +318,7 @@ RsiGetIpaState (
@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.
+ @param [in] Flags The RIPAS change flags.
@retval RETURN_SUCCESS Success.
@retval RETURN_INVALID_PARAMETER A parameter is invalid.
@@ -327,7 +328,8 @@ EFIAPI
RsiSetIpaState (
IN UINT64 *Address,
IN UINT64 Size,
- IN RIPAS State
+ IN RIPAS State,
+ IN UINT64 Flags
)
{
RETURN_STATUS Status;
@@ -353,6 +355,7 @@ RsiSetIpaState (
SmcCmd.Arg1 = (UINTN)BaseAddress;
SmcCmd.Arg2 = (UINTN)EndAddress;
SmcCmd.Arg3 = (UINTN)State;
+ SmcCmd.Arg4 = Flags;
ArmCallSmc (&SmcCmd);
Status = RsiCmdStatusToEfiStatus (SmcCmd.Arg0);
diff --git a/ArmVirtPkg/RealmApertureManagementProtocolDxe/RealmApertureManagementProtocolDxe.c b/ArmVirtPkg/RealmApertureManagementProtocolDxe/RealmApertureManagementProtocolDxe.c
index 991054d47b10b45ed5c211827e795d88f8942c02..9212f0f6d2522a59bf289d2699d0972a074b8f9d 100644
--- a/ArmVirtPkg/RealmApertureManagementProtocolDxe/RealmApertureManagementProtocolDxe.c
+++ b/ArmVirtPkg/RealmApertureManagementProtocolDxe/RealmApertureManagementProtocolDxe.c
@@ -236,7 +236,8 @@ RampOpenAperture (
Status = RsiSetIpaState (
(UINT64 *)Memory,
(Pages * EFI_PAGE_SIZE),
- RipasEmpty
+ RipasEmpty,
+ RIPAS_CHANGE_FLAGS_RSI_NO_CHANGE_DESTROYED
);
if (RETURN_ERROR (Status)) {
DEBUG ((
@@ -335,7 +336,8 @@ RampCloseAperture (
Status = RsiSetIpaState (
(UINT64 *)ApertInfo->BaseAddress,
(ApertInfo->Pages * EFI_PAGE_SIZE),
- RipasRam
+ RipasRam,
+ RIPAS_CHANGE_FLAGS_RSI_NO_CHANGE_DESTROYED
);
if (RETURN_ERROR (Status)) {
DEBUG ((
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117696): https://edk2.groups.io/g/devel/message/117696
Mute This Topic: https://groups.io/mt/105483436/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 40/45] ArmVirtPkg: RMM 1.0-eac3 - Handle RsiSetIpaState() response
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (37 preceding siblings ...)
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 39/45] ArmVirtPkg: RMM 1.0-eac2 - Add Flags to RsiSetIpaState() Sami Mujawar
@ 2024-04-12 14:33 ` Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 42/45] ArmVirtPkg: RMM 1.0-eac5 - Attestation token API updates Sami Mujawar
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:33 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
The RMM 1.0-eac3 specification extends the RSI_IPA_STATE_SET
command to return a new RsiResponse value to indicate if the
Host accepts or rejects the IPA state change request to RAM.
Therefore, define the RsiResponse enum and return an error
RETURN_ACCESS_DENIED if the Host rejects the RIPAS change
request to RAM.
Such a failure is fatal and not recoverable and the caller
is then expected to tear down the Realm.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/Include/Library/ArmCcaRsiLib.h | 26 +++++++++++++++++++-
ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c | 8 +++++-
2 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
index 5c2f996d3b4376e831a901f2919780acffec3313..88351f53336c42c032fcff6ea97ea7728b917b76 100644
--- a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
+++ b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
@@ -11,7 +11,7 @@
- REM - Realm Extensible Measurement
@par Reference(s):
- - Realm Management Monitor (RMM) Specification, version 1.0-eac2
+ - Realm Management Monitor (RMM) Specification, version 1.0-eac3
(https://developer.arm.com/documentation/den0137/)
**/
@@ -91,6 +91,29 @@
*/
#define RIPAS_CHANGE_FLAGS_RSI_CHANGE_DESTROYED 1
+/* The RsiResponse type is a value returned by the
+ RSI_IPA_STATE_SET command and represents whether
+ the Host accepted or rejected a Realm request.
+ See section B4.4.6 RsiResponse type in the
+ RMM Specification, version 1.0-eac3.
+ The width of the RsiResponse enumeration is 1 bit
+ and the following macros prefixed RIPAS_CHANGE_RESPONSE_xxx
+ define the values of the RsiResponse type.
+*/
+
+/* The RIPAS change request to RAM was accepted
+ by the host.
+*/
+#define RIPAS_CHANGE_RESPONSE_ACCEPT 0
+
+/* The RIPAS change request to RAM was rejected
+ by the host.
+*/
+#define RIPAS_CHANGE_RESPONSE_REJECT 1
+
+/* A mask for the RSI Response bit */
+#define RSI_RESPONSE_MASK BIT0
+
/** An enum describing the RSI RIPAS.
See Section A5.2.2 Realm IPA state, RMM Specification, version 1.0-eac2
*/
@@ -209,6 +232,7 @@ RsiGetIpaState (
@retval RETURN_SUCCESS Success.
@retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ @retval RETURN_ACCESS_DENIED RIPAS change request was rejected.
**/
RETURN_STATUS
EFIAPI
diff --git a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
index 0535254a3991bfe7a19b904e83b9482f801da20c..12636c484824426b2ea81ca007d962f5f7c58f8c 100644
--- a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
+++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
@@ -11,7 +11,7 @@
- REM - Realm Extensible Measurement
@par Reference(s):
- - Realm Management Monitor (RMM) Specification, version 1.0-eac2
+ - Realm Management Monitor (RMM) Specification, version 1.0-eac3
(https://developer.arm.com/documentation/den0137/)
**/
@@ -322,6 +322,7 @@ RsiGetIpaState (
@retval RETURN_SUCCESS Success.
@retval RETURN_INVALID_PARAMETER A parameter is invalid.
+ @retval RETURN_ACCESS_DENIED RIPAS change request was rejected.
**/
RETURN_STATUS
EFIAPI
@@ -365,6 +366,11 @@ RsiSetIpaState (
BaseAddress = (UINT64 *)SmcCmd.Arg1;
Size = EndAddress - BaseAddress;
+
+ if ((SmcCmd.Arg2 & RSI_RESPONSE_MASK) == RIPAS_CHANGE_RESPONSE_REJECT) {
+ Status = RETURN_ACCESS_DENIED;
+ break;
+ }
} // while
return Status;
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117707): https://edk2.groups.io/g/devel/message/117707
Mute This Topic: https://groups.io/mt/105483451/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [edk2-devel] [PATCH v2 42/45] ArmVirtPkg: RMM 1.0-eac5 - Attestation token API updates
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
` (38 preceding siblings ...)
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 40/45] ArmVirtPkg: RMM 1.0-eac3 - Handle RsiSetIpaState() response Sami Mujawar
@ 2024-04-12 14:33 ` Sami Mujawar
39 siblings, 0 replies; 40+ messages in thread
From: Sami Mujawar @ 2024-04-12 14:33 UTC (permalink / raw)
To: devel
Cc: Sami Mujawar, ardb+tianocore, quic_llindhol, kraxel,
Matteo.Carlini, Akanksha.Jain2, Sibel.Allinson, nd
The RMM 1.0-eac3 specification removed the restriction that
attestation token size must not exceed 4KB. Further it also
extended the RSI_ATTESTATION_TOKEN_CONTINUE command so as to
return up to a granule worth of the attestation token data.
The RMM 1.0-eac5 specification simplified the attestation
token interfaces such that, the RSI_ATTESTATION_TOKEN_INIT
command returns the upper bound of the attestation token
size. This eliminates the need for relocation of token data
buffers during attestation token retrieval.
Therefore, implement the attestation token API updates
from RMM 1.0-eac3 through to RMM 1.0-eac5 specification.
Note: The RsiGetAttestationToken() API has been modified
such that ArmCcaRsiLib allocates memory for the returned
attestation token buffer. The caller is therefore required
to call RsiFreeAttestationToken() to free the memory that
was allocated for the attestation token buffer.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/Include/Library/ArmCcaRsiLib.h | 31 ++--
ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c | 160 +++++++++++++++-----
2 files changed, 146 insertions(+), 45 deletions(-)
diff --git a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
index 8c1c0d5bc19d14fa640464c8d0d44e3ef522ba79..b768f3498314a2ea61762af65bf2668d463909a6 100644
--- a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
+++ b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
@@ -11,7 +11,7 @@
- REM - Realm Extensible Measurement
@par Reference(s):
- - Realm Management Monitor (RMM) Specification, version 1.0-eac4
+ - Realm Management Monitor (RMM) Specification, version 1.0-eac5
(https://developer.arm.com/documentation/den0137/)
**/
@@ -33,11 +33,6 @@
*/
#define RIPAS_TYPE_MASK 0xFF
-/* Maximum attestation token size
- RBXKKY The size of an attestation token is no larger than 4KB.
-*/
-#define MAX_ATTESTATION_TOKEN_SIZE SIZE_4KB
-
/* Maximum challenge data size in bits.
*/
#define MAX_CHALLENGE_DATA_SIZE_BITS 512
@@ -185,9 +180,10 @@ typedef struct HostCallArgs {
@param [in] ChallengeDataSizeBits Size of the challenge data in bits.
@param [out] TokenBuffer Pointer to a buffer to store the
retrieved attestation token.
- @param [in, out] TokenBufferSize Size of the token buffer on input and
- number of bytes stored in token buffer
- on return.
+ @param [out] TokenBufferSize Length of token data returned.
+
+ Note: The TokenBuffer allocated must be freed by the caller
+ using RsiFreeAttestationToken().
@retval RETURN_SUCCESS Success.
@retval RETURN_INVALID_PARAMETER A parameter is invalid.
@@ -202,8 +198,21 @@ EFIAPI
RsiGetAttestationToken (
IN CONST UINT8 *CONST ChallengeData,
IN UINT64 ChallengeDataSizeBits,
- OUT UINT8 *CONST TokenBuffer,
- IN OUT UINT64 *CONST TokenBufferSize
+ OUT UINT8 **CONST TokenBuffer,
+ OUT UINT64 *CONST TokenBufferSize
+ );
+
+/**
+ Free the attestation token buffer.
+
+ @param [in] TokenBuffer Pointer to the retrieved
+ attestation token.
+ @param [in] TokenBufferSize Size of the token buffer.
+**/
+VOID
+RsiFreeAttestationToken (
+ IN UINT8 *CONST TokenBuffer,
+ IN UINT64 CONST TokenBufferSize
);
/**
diff --git a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
index edd2e11f786d11191f13dd9b087cdeec4127b375..b861b2e79d5d659a0eb16206d329a0cb039eda0d 100644
--- a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
+++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
@@ -11,7 +11,7 @@
- REM - Realm Extensible Measurement
@par Reference(s):
- - Realm Management Monitor (RMM) Specification, version 1.0-eac4
+ - Realm Management Monitor (RMM) Specification, version 1.0-eac5
(https://developer.arm.com/documentation/den0137/)
**/
@@ -22,6 +22,7 @@
#include <Library/ArmSmcLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
#include "ArmCcaRsi.h"
/**
@@ -88,6 +89,8 @@ AddrIsGranuleAligned (
@param [out] TokenBuffer Pointer to a buffer to store the
retrieved attestation token.
+ @param [in] Offset Offset within Token buffer granule
+ to start of buffer in bytes.
@param [in,out] TokenSize On input size of the token buffer,
and on output size of the token
returned if operation is successful,
@@ -106,6 +109,7 @@ RETURN_STATUS
EFIAPI
RsiAttestationTokenContinue (
OUT UINT8 *CONST TokenBuffer,
+ IN UINT64 CONST Offset,
IN OUT UINT64 *CONST TokenSize
)
{
@@ -116,6 +120,10 @@ RsiAttestationTokenContinue (
SmcCmd.Arg0 = FID_RSI_ATTESTATION_TOKEN_CONTINUE;
// Set the IPA of the Granule to which the token will be written.
SmcCmd.Arg1 = (UINTN)TokenBuffer;
+ // Set the Offset within Granule to start of buffer in bytes
+ SmcCmd.Arg2 = (UINTN)Offset;
+ // Set the size of the buffer in bytes
+ SmcCmd.Arg3 = (UINTN)*TokenSize;
ArmCallSmc (&SmcCmd);
Status = RsiCmdStatusToEfiStatus (SmcCmd.Arg0);
@@ -137,8 +145,8 @@ RsiAttestationTokenContinue (
@param [in] ChallengeData Pointer to the challenge data to be
included in the attestation token.
@param [in] ChallengeDataSizeBits Size of the challenge data in bits.
- @param [in] TokenBuffer Pointer to a buffer to store the
- retrieved attestation token.
+ @param [out] MaxTokenSize Pointer to an integer to retrieve
+ the maximum attestation token size.
@retval RETURN_SUCCESS Success.
@retval RETURN_INVALID_PARAMETER A parameter is invalid.
@@ -149,14 +157,15 @@ EFIAPI
RsiAttestationTokenInit (
IN CONST UINT8 *CONST ChallengeData,
IN UINT64 ChallengeDataSizeBits,
- IN UINT8 *CONST TokenBuffer
+ OUT UINT64 *CONST MaxTokenSize
)
{
- ARM_SMC_ARGS SmcCmd;
- UINT8 *Buffer8;
- CONST UINT8 *Data8;
- UINT64 Count;
- UINT8 TailBits;
+ RETURN_STATUS Status;
+ ARM_SMC_ARGS SmcCmd;
+ UINT8 *Buffer8;
+ CONST UINT8 *Data8;
+ UINT64 Count;
+ UINT8 TailBits;
/* See A7.2.2 Attestation token generation, RMM Specification, version A-bet0
IWTKDD - If the size of the challenge provided by the relying party is less
@@ -168,11 +177,8 @@ RsiAttestationTokenInit (
*/
ZeroMem (&SmcCmd, sizeof (SmcCmd));
SmcCmd.Arg0 = FID_RSI_ATTESTATION_TOKEN_INIT;
- // Set the IPA of the Granule to which the token will be written.
- SmcCmd.Arg1 = (UINTN)TokenBuffer;
-
// Copy challenge data.
- Buffer8 = (UINT8 *)&SmcCmd.Arg2;
+ Buffer8 = (UINT8 *)&SmcCmd.Arg1;
Data8 = ChallengeData;
// First copy whole bytes
@@ -194,7 +200,38 @@ RsiAttestationTokenInit (
}
ArmCallSmc (&SmcCmd);
- return RsiCmdStatusToEfiStatus (SmcCmd.Arg0);
+ Status = RsiCmdStatusToEfiStatus (SmcCmd.Arg0);
+ if (RETURN_ERROR (Status)) {
+ // Set the max token size to zero
+ *MaxTokenSize = 0;
+ } else {
+ *MaxTokenSize = SmcCmd.Arg1;
+ }
+
+ return Status;
+}
+
+/**
+ Free the attestation token buffer.
+
+ @param [in] TokenBuffer Pointer to the retrieved
+ attestation token.
+ @param [in] TokenBufferSize Size of the token buffer.
+**/
+VOID
+RsiFreeAttestationToken (
+ IN UINT8 *CONST TokenBuffer,
+ IN UINT64 CONST TokenBufferSize
+ )
+{
+ if (TokenBuffer != NULL) {
+ if (TokenBufferSize > 0) {
+ // Scrub the token buffer
+ ZeroMem (TokenBuffer, TokenBufferSize);
+ }
+
+ FreePool (TokenBuffer);
+ }
}
/**
@@ -205,9 +242,10 @@ RsiAttestationTokenInit (
@param [in] ChallengeDataSizeBits Size of the challenge data in bits.
@param [out] TokenBuffer Pointer to a buffer to store the
retrieved attestation token.
- @param [in, out] TokenBufferSize Size of the token buffer on input and
- number of bytes stored in token buffer
- on return.
+ @param [out] TokenBufferSize Length of token data returned.
+
+ Note: The TokenBuffer allocated must be freed by the caller
+ using RsiFreeAttestationToken().
@retval RETURN_SUCCESS Success.
@retval RETURN_INVALID_PARAMETER A parameter is invalid.
@@ -222,11 +260,17 @@ EFIAPI
RsiGetAttestationToken (
IN CONST UINT8 *CONST ChallengeData,
IN UINT64 ChallengeDataSizeBits,
- OUT UINT8 *CONST TokenBuffer,
- IN OUT UINT64 *CONST TokenBufferSize
+ OUT UINT8 **CONST TokenBuffer,
+ OUT UINT64 *CONST TokenBufferSize
)
{
RETURN_STATUS Status;
+ UINT8 *Granule;
+ UINT64 GranuleSize;
+ UINT64 Offset;
+ UINT8 *Token;
+ UINT64 TokenSize;
+ UINT64 MaxTokenSize;
if ((TokenBuffer == NULL) ||
(TokenBufferSize == NULL) ||
@@ -235,16 +279,6 @@ RsiGetAttestationToken (
return RETURN_INVALID_PARAMETER;
}
- if (*TokenBufferSize < MAX_ATTESTATION_TOKEN_SIZE) {
- *TokenBufferSize = MAX_ATTESTATION_TOKEN_SIZE;
- return RETURN_BAD_BUFFER_SIZE;
- }
-
- if (!AddrIsGranuleAligned ((UINT64 *)TokenBuffer)) {
- DEBUG ((DEBUG_ERROR, "ERROR : Token buffer not granule aligned\n"));
- return RETURN_INVALID_PARAMETER;
- }
-
if (ChallengeDataSizeBits > MAX_CHALLENGE_DATA_SIZE_BITS) {
return RETURN_INVALID_PARAMETER;
}
@@ -260,18 +294,76 @@ RsiGetAttestationToken (
Status = RsiAttestationTokenInit (
ChallengeData,
ChallengeDataSizeBits,
- TokenBuffer
+ &MaxTokenSize
);
if (RETURN_ERROR (Status)) {
ASSERT (0);
return Status;
}
- /* Loop until the token is ready or there is an error.
- */
+ // Allocate a granule to retrieve the attestation token chunk.
+ Granule = (UINT8 *)AllocateAlignedPages (
+ EFI_SIZE_TO_PAGES (REALM_GRANULE_SIZE),
+ REALM_GRANULE_SIZE
+ );
+ if (Granule == NULL) {
+ ASSERT (0);
+ return RETURN_OUT_OF_RESOURCES;
+ }
+
+ // Alloate a buffer to store the retrieved attestation token.
+ Token = AllocateZeroPool (MaxTokenSize);
+ if (Token == NULL) {
+ ASSERT (0);
+ Status = RETURN_OUT_OF_RESOURCES;
+ goto exit_handler;
+ }
+
+ TokenSize = 0;
do {
- Status = RsiAttestationTokenContinue (TokenBuffer, TokenBufferSize);
- } while (Status == RETURN_NOT_READY);
+ // Retrieve one Granule of data per loop iteration
+ ZeroMem (Granule, REALM_GRANULE_SIZE);
+ Offset = 0;
+ do {
+ // Retrieve sub-Granule chunk of data per loop iteration
+ GranuleSize = REALM_GRANULE_SIZE - Offset;
+ Status = RsiAttestationTokenContinue (
+ Granule,
+ Offset,
+ &GranuleSize
+ );
+ Offset += GranuleSize;
+ } while ((Status == RETURN_NOT_READY) && (Offset < REALM_GRANULE_SIZE));
+
+ if (RETURN_ERROR (Status) && (Status != RETURN_NOT_READY)) {
+ ASSERT (0);
+ goto exit_handler1;
+ }
+
+ // "Offset" bytes of data are now ready for consumption from "Granule"
+ // Copy the new token data from the Granule.
+ CopyMem (&Token[TokenSize], Granule, Offset);
+ TokenSize += Offset;
+ } while ((Status == RETURN_NOT_READY) && (TokenSize < MaxTokenSize));
+
+ *TokenBuffer = Token;
+ *TokenBufferSize = TokenSize;
+ goto exit_handler;
+
+exit_handler1:
+ if (Token != NULL) {
+ // Scrub the old Token
+ ZeroMem (Token, TokenSize);
+ FreePool (Token);
+ }
+
+ *TokenBuffer = NULL;
+ *TokenBufferSize = 0;
+
+exit_handler:
+ // Scrub the Granule buffer
+ ZeroMem (Granule, REALM_GRANULE_SIZE);
+ FreePages (Granule, EFI_SIZE_TO_PAGES (REALM_GRANULE_SIZE));
return Status;
}
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117706): https://edk2.groups.io/g/devel/message/117706
Mute This Topic: https://groups.io/mt/105483450/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 40+ messages in thread