public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH 00/13] Extend secure variable service to be usable from Standalone MM
@ 2018-12-14 12:13 Jagadeesh Ujja
  2018-12-14 12:13 ` [PATCH 01/13] StandaloneMmPkg: Pull in additonal libraries from staging branch Jagadeesh Ujja
                   ` (14 more replies)
  0 siblings, 15 replies; 52+ messages in thread
From: Jagadeesh Ujja @ 2018-12-14 12:13 UTC (permalink / raw)
  To: edk2-devel, liming.gao, chao.b.zhang, leif.lindholm,
	ard.biesheuvel

Changes since RFC v4:
- Addressed all the comments from Liming Gao
  - Added an additional PCD 'PcdStandaloneMmCodeEnabled' to indicate
    presence of StandaloneMM support.
  - MdePkg.dec file updated to include StandaloneMmServiceTableLib and
    StandaloneMmRuntimeDxe library.
  - Platform specific changes will be posted in a seperate patchset.
  - AsmLfence wrapper function is supported for AArch64 platforms.
  - All the patches in this series can be pulled from
    https://github.com/jagadeeshujja/edk2 (branch: topics/aarch64_secure_vars)

Changes since RFC v3: 
- Addressed all the comments from Liming Gao
  - Added a AArch64 implementation of AsmLfence which is a wrapper for
    MemoryFence. The changes in variable service driver in v3 of this
    patchset that used MemoryFence instead of AsmLfence have been removed.
  - Added StandaloneMmServicesTableLib.h and StandaloneMmRuntimeDxe
    library into MdePkg.
  - Renamed PcdStandaloneMmEnable as PcdStandaloneMmVariableEnabled and
    added to in to MdePkg.
  - Now with above changes, edk2 packages don't need to depend on
    StandaloneMmPkg/StandaloneMmPkg.dec
- Addressed comments from Ting Ye
  - Removed the hacks in the v3 version.
  - Will relook into the “TimerWrapp.c” file and add a appropriate
    implementation of this for MM Standalone mode code.

Changes since RFC v2: 
- Added 'Contributed-under' tag, removed Change-ID tag and
  maintained a single signed-off-by for the all the patches.  

Changes since RFC v1:
- Addressed all the comments from Liming Gao
  - Removed the use of #ifdef/#else/#endif and used a Pcd instead to
    select between MM and non-MM paths.
  - Removed all dependencies on edk2-platforms.
  - Dropped the use of mMmst and used gSmst instead.
  - Added a dummy implementation UefiRuntimeServiceTableLib for
    MM_STANDALONE usage
- Replaced all uses of AsmLfence with MemoryFence from variable
  service code.
- Add a new StandaloneMmRuntimeDxe library to for use by non-MM code.

This patch series extends the existing secure variable service support for
use with Standalone MM. This is applicable to paltforms that use Standalone 
Management Mode to protect access to non-volatile memory (NOR flash in case 
of these patches) used to store the secure EFI variables.

The first patch pulls in additional libraries from the staging branch of 
StandaloneMmPkg into the edk2's StandaloneMmPkg. The existing secure variable 
service implementation supports only the traditional MM mode and so the rest 
of the patches extends the existing secure variable service support to be 
useable with Standalone MM mode as well.

Jagadeesh Ujja (13):
  StandaloneMmPkg: Pull in additonal libraries from staging branch
  MdePkg: Add a PCD that indicates presence of Standalone MM mode
  MdeModulePkg: Add a PCD to indicate Standalone MM supports secure
    variable
  MdePkg/Include: add StandaloneMmServicesTableLib header file
  MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
  MdePkg/Library: Add StandaloneMmRuntimeDxe library
  MdeModulePkg/FaultTolerantWriteDxe: allow reusability as a MM driver
  MdeModulePkg/Variable/RuntimeDxe: adapt for usability with MM
    Standalone
  MdeModulePkg/Variable/RuntimeDxe: adapt as a MM Standalone driver
  MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this
    library
  ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver
  SecurityPkg/AuthVariableLib: allow MM_STANDALONE drivers to use this
    library
  CryptoPkg/BaseCryptLib: allow MM_STANDALONE drivers to use this
    library

 ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c                                     |   2 +-
 ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c                                            | 210 ++++-
 ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h                                            |   5 +-
 ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf                                          |   2 +
 ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c                                         |  96 +--
 ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf                                 |  76 ++
 CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf                                             |   7 +-
 CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf                                          |   4 +
 CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c                                       |  15 +-
 MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf                                            |   5 +-
 MdeModulePkg/MdeModulePkg.dec                                                               |   5 +
 MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf                      |   1 +
 MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c                        | 203 +++--
 MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf             | 101 +++
 MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c                           |  27 +-
 MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c                                       |  37 +-
 MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf                           |   1 +
 MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c                                    | 201 ++++-
 MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c                          |  31 +-
 MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf                        |   3 +
 MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf                         | 132 ++++
 MdePkg/Include/Library/BaseLib.h                                                            |  33 +-
 MdePkg/Include/Library/StandaloneMmRuntimeDxe.h                                             |  39 +
 MdePkg/Include/Library/StandaloneMmServicesTableLib.h                                       |  25 +
 MdePkg/Library/BaseLib/AArch64/AsmLfence.S                                                  |  42 +
 MdePkg/Library/BaseLib/AArch64/AsmLfence.asm                                                |  41 +
 MdePkg/Library/BaseLib/BaseLib.inf                                                          |   2 +
 MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c                              |  36 +
 MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf                            |  36 +
 MdePkg/MdePkg.dec                                                                           |  12 +
 SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf                                     |   5 +-
 StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf                   |   2 +-
 StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmCoreHobLibInternal.c         |  64 ++
 StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c                             | 655 ++++++++++++++++
 StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf                           |  48 ++
 StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c   | 824 ++++++++++++++++++++
 StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf |  45 ++
 StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.c         |  64 ++
 StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf       |  36 +
 39 files changed, 2929 insertions(+), 244 deletions(-)
 create mode 100644 ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
 create mode 100644 MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf
 create mode 100644 MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
 create mode 100644 MdePkg/Include/Library/StandaloneMmRuntimeDxe.h
 create mode 100644 MdePkg/Include/Library/StandaloneMmServicesTableLib.h
 create mode 100644 MdePkg/Library/BaseLib/AArch64/AsmLfence.S
 create mode 100644 MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
 create mode 100644 MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c
 create mode 100644 MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf
 create mode 100644 StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmCoreHobLibInternal.c
 create mode 100644 StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
 create mode 100644 StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
 create mode 100644 StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c
 create mode 100644 StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf
 create mode 100644 StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.c
 create mode 100644 StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf

-- 
2.7.4



^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 01/13] StandaloneMmPkg: Pull in additonal libraries from staging branch
  2018-12-14 12:13 [PATCH 00/13] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
@ 2018-12-14 12:13 ` Jagadeesh Ujja
  2018-12-21  8:58   ` Ard Biesheuvel
  2018-12-14 12:13 ` [PATCH 02/13] MdePkg: Add a PCD that indicates presence of Standalone MM mode Jagadeesh Ujja
                   ` (13 subsequent siblings)
  14 siblings, 1 reply; 52+ messages in thread
From: Jagadeesh Ujja @ 2018-12-14 12:13 UTC (permalink / raw)
  To: edk2-devel, liming.gao, chao.b.zhang, leif.lindholm,
	ard.biesheuvel

Three additional library packages are being pulled into StandaloneMmPkg
from the staging area in order to support the secure variable service.
The three packages being pulled in are
  - StandaloneMmHobLib
  - StandaloneMmMemoryAllocationLib
  - StandaloneMmServicesTableLib

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
---
 StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf                   |   2 +-
 StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmCoreHobLibInternal.c         |  64 ++
 StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c                             | 655 ++++++++++++++++
 StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf                           |  48 ++
 StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c   | 824 ++++++++++++++++++++
 StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf |  45 ++
 StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.c         |  64 ++
 StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf       |  36 +
 8 files changed, 1737 insertions(+), 1 deletion(-)

diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf b/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf
index db19d3c..ac036e3 100644
--- a/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf
@@ -24,7 +24,7 @@
   MODULE_TYPE                    = MM_CORE_STANDALONE
   VERSION_STRING                 = 1.0
   PI_SPECIFICATION_VERSION       = 0x00010032
-  LIBRARY_CLASS                  = HobLib|MM_CORE_STANDALONE MM_STANDALONE
+  LIBRARY_CLASS                  = HobLib|MM_CORE_STANDALONE
 
 #
 #  VALID_ARCHITECTURES           = AARCH64
diff --git a/StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmCoreHobLibInternal.c b/StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmCoreHobLibInternal.c
new file mode 100644
index 0000000..ac5a1c0
--- /dev/null
+++ b/StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmCoreHobLibInternal.c
@@ -0,0 +1,64 @@
+/** @file
+  HOB Library implementation for Standalone MM Core.
+
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiMm.h>
+
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <Guid/MemoryAllocationHob.h>
+
+//
+// Cache copy of HobList pointer.
+//
+extern VOID *gHobList;
+
+EFI_HOB_HANDOFF_INFO_TABLE*
+HobConstructor (
+  IN VOID   *EfiMemoryBegin,
+  IN UINTN  EfiMemoryLength,
+  IN VOID   *EfiFreeMemoryBottom,
+  IN VOID   *EfiFreeMemoryTop
+  )
+{
+  EFI_HOB_HANDOFF_INFO_TABLE  *Hob;
+  EFI_HOB_GENERIC_HEADER      *HobEnd;
+
+  Hob    = EfiFreeMemoryBottom;
+  HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1);
+
+  Hob->Header.HobType     = EFI_HOB_TYPE_HANDOFF;
+  Hob->Header.HobLength   = sizeof(EFI_HOB_HANDOFF_INFO_TABLE);
+  Hob->Header.Reserved    = 0;
+
+  HobEnd->HobType     = EFI_HOB_TYPE_END_OF_HOB_LIST;
+  HobEnd->HobLength   = sizeof(EFI_HOB_GENERIC_HEADER);
+  HobEnd->Reserved    = 0;
+
+  Hob->Version             = EFI_HOB_HANDOFF_TABLE_VERSION;
+  Hob->BootMode            = BOOT_WITH_FULL_CONFIGURATION;
+
+  Hob->EfiMemoryTop        = (UINTN)EfiMemoryBegin + EfiMemoryLength;
+  Hob->EfiMemoryBottom     = (UINTN)EfiMemoryBegin;
+  Hob->EfiFreeMemoryTop    = (UINTN)EfiFreeMemoryTop;
+  Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd+1);
+  Hob->EfiEndOfHobList     = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
+
+  gHobList = Hob;
+
+  return Hob;
+}
diff --git a/StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c b/StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
new file mode 100644
index 0000000..591a78c
--- /dev/null
+++ b/StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
@@ -0,0 +1,655 @@
+/** @file
+  HOB Library implementation for Standalone MM Core.
+
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiMm.h>
+
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <Guid/MemoryAllocationHob.h>
+
+//
+// Cache copy of HobList pointer.
+//
+VOID *gHobList = NULL;
+
+EFI_MM_SYSTEM_TABLE   *gMmst = NULL;
+
+/**
+  The constructor function caches the pointer to HOB list.
+
+  The constructor function gets the start address of HOB list from system configuration table.
+  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
+
+  @param  ImageHandle   The firmware allocated handle for the EFI image.
+  @param  SystemTable   A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS   The constructor successfully gets HobList.
+  @retval Other value   The constructor can't get HobList.
+
+**/
+EFI_STATUS
+EFIAPI
+HobLibConstructor (
+  IN EFI_HANDLE             ImageHandle,
+  IN EFI_MM_SYSTEM_TABLE  *SmmSystemTable
+  )
+{
+  UINTN       Index;
+
+  for (Index = 0; Index < gMmst->NumberOfTableEntries; Index++) {
+    if (CompareGuid (&gEfiHobListGuid, &gMmst->MmConfigurationTable[Index].VendorGuid)) {
+      gHobList = gMmst->MmConfigurationTable[Index].VendorTable;
+      break;
+    }
+  }
+
+  /* HACK: Use the ImageHandle to smuggle the hoblist into the library constructor */
+  if (ImageHandle)
+	  gHobList = (VOID *) ImageHandle;
+
+  return EFI_SUCCESS;
+}
+/**
+  Returns the pointer to the HOB list.
+
+  This function returns the pointer to first HOB in the list.
+  If the pointer to the HOB list is NULL, then ASSERT().
+
+  @return The pointer to the HOB list.
+
+**/
+VOID *
+EFIAPI
+GetHobList (
+  VOID
+  )
+{
+  UINTN       Index;
+
+  if (gHobList == NULL) {
+    for (Index = 0; Index < gMmst->NumberOfTableEntries; Index++) {
+      if (CompareGuid (&gEfiHobListGuid, &gMmst->MmConfigurationTable[Index].VendorGuid)) {
+        gHobList = gMmst->MmConfigurationTable[Index].VendorTable;
+        break;
+      }
+    }
+  }
+  ASSERT (gHobList != NULL);
+  return gHobList;
+}
+
+/**
+  Returns the next instance of a HOB type from the starting HOB.
+
+  This function searches the first instance of a HOB type from the starting HOB pointer.
+  If there does not exist such HOB type from the starting HOB pointer, it will return NULL.
+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;
+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
+
+  If HobStart is NULL, then ASSERT().
+
+  @param  Type          The HOB type to return.
+  @param  HobStart      The starting HOB pointer to search from.
+
+  @return The next instance of a HOB type from the starting HOB.
+
+**/
+VOID *
+EFIAPI
+GetNextHob (
+  IN UINT16                 Type,
+  IN CONST VOID             *HobStart
+  )
+{
+  EFI_PEI_HOB_POINTERS  Hob;
+
+  ASSERT (HobStart != NULL);
+
+  Hob.Raw = (UINT8 *) HobStart;
+  //
+  // Parse the HOB list until end of list or matching type is found.
+  //
+  while (!END_OF_HOB_LIST (Hob)) {
+    if (Hob.Header->HobType == Type) {
+      return Hob.Raw;
+    }
+    Hob.Raw = GET_NEXT_HOB (Hob);
+  }
+  return NULL;
+}
+
+/**
+  Returns the first instance of a HOB type among the whole HOB list.
+
+  This function searches the first instance of a HOB type among the whole HOB list.
+  If there does not exist such HOB type in the HOB list, it will return NULL.
+
+  If the pointer to the HOB list is NULL, then ASSERT().
+
+  @param  Type          The HOB type to return.
+
+  @return The next instance of a HOB type from the starting HOB.
+
+**/
+VOID *
+EFIAPI
+GetFirstHob (
+  IN UINT16                 Type
+  )
+{
+  VOID      *HobList;
+
+  HobList = GetHobList ();
+  return GetNextHob (Type, HobList);
+}
+
+/**
+  Returns the next instance of the matched GUID HOB from the starting HOB.
+
+  This function searches the first instance of a HOB from the starting HOB pointer.
+  Such HOB should satisfy two conditions:
+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION, and its GUID Name equals to the input Guid.
+  If such a HOB from the starting HOB pointer does not exist, it will return NULL.
+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
+  to extract the data section and its size information, respectively.
+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;
+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
+
+  If Guid is NULL, then ASSERT().
+  If HobStart is NULL, then ASSERT().
+
+  @param  Guid          The GUID to match with in the HOB list.
+  @param  HobStart      A pointer to a Guid.
+
+  @return The next instance of the matched GUID HOB from the starting HOB.
+
+**/
+VOID *
+EFIAPI
+GetNextGuidHob (
+  IN CONST EFI_GUID         *Guid,
+  IN CONST VOID             *HobStart
+  )
+{
+  EFI_PEI_HOB_POINTERS  GuidHob;
+
+  GuidHob.Raw = (UINT8 *) HobStart;
+  while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {
+    if (CompareGuid (Guid, &GuidHob.Guid->Name)) {
+      break;
+    }
+    GuidHob.Raw = GET_NEXT_HOB (GuidHob);
+  }
+  return GuidHob.Raw;
+}
+
+/**
+  Returns the first instance of the matched GUID HOB among the whole HOB list.
+
+  This function searches the first instance of a HOB among the whole HOB list.
+  Such HOB should satisfy two conditions:
+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
+  If such a HOB from the starting HOB pointer does not exist, it will return NULL.
+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
+  to extract the data section and its size information, respectively.
+
+  If the pointer to the HOB list is NULL, then ASSERT().
+  If Guid is NULL, then ASSERT().
+
+  @param  Guid          The GUID to match with in the HOB list.
+
+  @return The first instance of the matched GUID HOB among the whole HOB list.
+
+**/
+VOID *
+EFIAPI
+GetFirstGuidHob (
+  IN CONST EFI_GUID         *Guid
+  )
+{
+  VOID      *HobList;
+
+  HobList = GetHobList ();
+  return GetNextGuidHob (Guid, HobList);
+}
+
+/**
+  Get the system boot mode from the HOB list.
+
+  This function returns the system boot mode information from the
+  PHIT HOB in HOB list.
+
+  If the pointer to the HOB list is NULL, then ASSERT().
+
+  @param  VOID
+
+  @return The Boot Mode.
+
+**/
+EFI_BOOT_MODE
+EFIAPI
+GetBootModeHob (
+  VOID
+  )
+{
+  EFI_HOB_HANDOFF_INFO_TABLE    *HandOffHob;
+
+  HandOffHob = (EFI_HOB_HANDOFF_INFO_TABLE *) GetHobList ();
+
+  return  HandOffHob->BootMode;
+}
+
+VOID *
+CreateHob (
+  IN  UINT16    HobType,
+  IN  UINT16    HobLength
+  )
+{
+  EFI_HOB_HANDOFF_INFO_TABLE  *HandOffHob;
+  EFI_HOB_GENERIC_HEADER      *HobEnd;
+  EFI_PHYSICAL_ADDRESS        FreeMemory;
+  VOID                        *Hob;
+
+  HandOffHob = GetHobList ();
+
+  HobLength = (UINT16)((HobLength + 0x7) & (~0x7));
+
+  FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom;
+
+  if (FreeMemory < HobLength) {
+      return NULL;
+  }
+
+  Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;
+  ((EFI_HOB_GENERIC_HEADER*) Hob)->HobType = HobType;
+  ((EFI_HOB_GENERIC_HEADER*) Hob)->HobLength = HobLength;
+  ((EFI_HOB_GENERIC_HEADER*) Hob)->Reserved = 0;
+
+  HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN)Hob + HobLength);
+  HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+  HobEnd->HobType   = EFI_HOB_TYPE_END_OF_HOB_LIST;
+  HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
+  HobEnd->Reserved  = 0;
+  HobEnd++;
+  HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+  return Hob;
+}
+
+/**
+  Builds a HOB for a loaded PE32 module.
+
+  This function builds a HOB for a loaded PE32 module.
+  If ModuleName is NULL, then ASSERT().
+  If there is no additional space for HOB creation, then ASSERT().
+
+  @param  ModuleName              The GUID File Name of the module.
+  @param  MemoryAllocationModule  The 64 bit physical address of the module.
+  @param  ModuleLength            The length of the module in bytes.
+  @param  EntryPoint              The 64 bit physical address of the module entry point.
+
+**/
+VOID
+EFIAPI
+BuildModuleHob (
+  IN CONST EFI_GUID         *ModuleName,
+  IN EFI_PHYSICAL_ADDRESS   MemoryAllocationModule,
+  IN UINT64                 ModuleLength,
+  IN EFI_PHYSICAL_ADDRESS   EntryPoint
+  )
+{
+  EFI_HOB_MEMORY_ALLOCATION_MODULE  *Hob;
+
+  ASSERT (((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&
+          ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0));
+
+  Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));
+
+  CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);
+  Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;
+  Hob->MemoryAllocationHeader.MemoryLength      = ModuleLength;
+  Hob->MemoryAllocationHeader.MemoryType        = EfiBootServicesCode;
+
+  //
+  // Zero the reserved space to match HOB spec
+  //
+  ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved));
+
+  CopyGuid (&Hob->ModuleName, ModuleName);
+  Hob->EntryPoint = EntryPoint;
+}
+
+/**
+  Builds a HOB that describes a chunk of system memory.
+
+  This function builds a HOB that describes a chunk of system memory.
+  If there is no additional space for HOB creation, then ASSERT().
+
+  @param  ResourceType        The type of resource described by this HOB.
+  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.
+  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.
+  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.
+
+**/
+VOID
+EFIAPI
+BuildResourceDescriptorHob (
+  IN EFI_RESOURCE_TYPE            ResourceType,
+  IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,
+  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,
+  IN UINT64                       NumberOfBytes
+  )
+{
+  EFI_HOB_RESOURCE_DESCRIPTOR  *Hob;
+
+  Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
+  ASSERT(Hob != NULL);
+
+  Hob->ResourceType      = ResourceType;
+  Hob->ResourceAttribute = ResourceAttribute;
+  Hob->PhysicalStart     = PhysicalStart;
+  Hob->ResourceLength    = NumberOfBytes;
+}
+
+/**
+  Builds a GUID HOB with a certain data length.
+
+  This function builds a customized HOB tagged with a GUID for identification
+  and returns the start address of GUID HOB data so that caller can fill the customized data.
+  The HOB Header and Name field is already stripped.
+  If Guid is NULL, then ASSERT().
+  If there is no additional space for HOB creation, then ASSERT().
+  If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
+
+  @param  Guid          The GUID to tag the customized HOB.
+  @param  DataLength    The size of the data payload for the GUID HOB.
+
+  @return The start address of GUID HOB data.
+
+**/
+VOID *
+EFIAPI
+BuildGuidHob (
+  IN CONST EFI_GUID              *Guid,
+  IN UINTN                       DataLength
+  )
+{
+  EFI_HOB_GUID_TYPE *Hob;
+
+  //
+  // Make sure that data length is not too long.
+  //
+  ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));
+
+  Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength));
+  CopyGuid (&Hob->Name, Guid);
+  return Hob + 1;
+}
+
+
+/**
+  Copies a data buffer to a newly-built HOB.
+
+  This function builds a customized HOB tagged with a GUID for identification,
+  copies the input data to the HOB data field and returns the start address of the GUID HOB data.
+  The HOB Header and Name field is already stripped.
+  If Guid is NULL, then ASSERT().
+  If Data is NULL and DataLength > 0, then ASSERT().
+  If there is no additional space for HOB creation, then ASSERT().
+  If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
+
+  @param  Guid          The GUID to tag the customized HOB.
+  @param  Data          The data to be copied into the data field of the GUID HOB.
+  @param  DataLength    The size of the data payload for the GUID HOB.
+
+  @return The start address of GUID HOB data.
+
+**/
+VOID *
+EFIAPI
+BuildGuidDataHob (
+  IN CONST EFI_GUID              *Guid,
+  IN VOID                        *Data,
+  IN UINTN                       DataLength
+  )
+{
+  VOID  *HobData;
+
+  ASSERT (Data != NULL || DataLength == 0);
+
+  HobData = BuildGuidHob (Guid, DataLength);
+
+  return CopyMem (HobData, Data, DataLength);
+}
+
+/**
+  Builds a Firmware Volume HOB.
+
+  This function builds a Firmware Volume HOB.
+  If there is no additional space for HOB creation, then ASSERT().
+
+  @param  BaseAddress   The base address of the Firmware Volume.
+  @param  Length        The size of the Firmware Volume in bytes.
+
+**/
+VOID
+EFIAPI
+BuildFvHob (
+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
+  IN UINT64                      Length
+  )
+{
+  EFI_HOB_FIRMWARE_VOLUME  *Hob;
+
+  Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));
+
+  Hob->BaseAddress = BaseAddress;
+  Hob->Length      = Length;
+}
+
+
+/**
+  Builds a EFI_HOB_TYPE_FV2 HOB.
+
+  This function builds a EFI_HOB_TYPE_FV2 HOB.
+  If there is no additional space for HOB creation, then ASSERT().
+
+  @param  BaseAddress   The base address of the Firmware Volume.
+  @param  Length        The size of the Firmware Volume in bytes.
+  @param  FvName       The name of the Firmware Volume.
+  @param  FileName      The name of the file.
+
+**/
+VOID
+EFIAPI
+BuildFv2Hob (
+  IN          EFI_PHYSICAL_ADDRESS        BaseAddress,
+  IN          UINT64                      Length,
+  IN CONST    EFI_GUID                    *FvName,
+  IN CONST    EFI_GUID                    *FileName
+  )
+{
+  EFI_HOB_FIRMWARE_VOLUME2  *Hob;
+
+  Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));
+
+  Hob->BaseAddress = BaseAddress;
+  Hob->Length      = Length;
+  CopyGuid (&Hob->FvName, FvName);
+  CopyGuid (&Hob->FileName, FileName);
+}
+
+
+/**
+  Builds a HOB for the CPU.
+
+  This function builds a HOB for the CPU.
+  If there is no additional space for HOB creation, then ASSERT().
+
+  @param  SizeOfMemorySpace   The maximum physical memory addressability of the processor.
+  @param  SizeOfIoSpace       The maximum physical I/O addressability of the processor.
+
+**/
+VOID
+EFIAPI
+BuildCpuHob (
+  IN UINT8                       SizeOfMemorySpace,
+  IN UINT8                       SizeOfIoSpace
+  )
+{
+  EFI_HOB_CPU  *Hob;
+
+  Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));
+
+  Hob->SizeOfMemorySpace = SizeOfMemorySpace;
+  Hob->SizeOfIoSpace     = SizeOfIoSpace;
+
+  //
+  // Zero the reserved space to match HOB spec
+  //
+  ZeroMem (Hob->Reserved, sizeof (Hob->Reserved));
+}
+
+/**
+  Builds a HOB for the memory allocation.
+
+  This function builds a HOB for the memory allocation.
+  If there is no additional space for HOB creation, then ASSERT().
+
+  @param  BaseAddress   The 64 bit physical address of the memory.
+  @param  Length        The length of the memory allocation in bytes.
+  @param  MemoryType    Type of memory allocated by this HOB.
+
+**/
+VOID
+EFIAPI
+BuildMemoryAllocationHob (
+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
+  IN UINT64                      Length,
+  IN EFI_MEMORY_TYPE             MemoryType
+  )
+{
+  EFI_HOB_MEMORY_ALLOCATION  *Hob;
+
+  ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
+          ((Length & (EFI_PAGE_SIZE - 1)) == 0));
+
+  Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));
+
+  ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));
+  Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
+  Hob->AllocDescriptor.MemoryLength      = Length;
+  Hob->AllocDescriptor.MemoryType        = MemoryType;
+  //
+  // Zero the reserved space to match HOB spec
+  //
+  ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
+}
+
+/**
+  Builds a HOB that describes a chunk of system memory with Owner GUID.
+
+  This function builds a HOB that describes a chunk of system memory.
+  If there is no additional space for HOB creation, then ASSERT().
+
+  @param  ResourceType        The type of resource described by this HOB.
+  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.
+  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.
+  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.
+  @param  OwnerGUID           GUID for the owner of this resource.
+
+**/
+VOID
+EFIAPI
+BuildResourceDescriptorWithOwnerHob (
+  IN EFI_RESOURCE_TYPE            ResourceType,
+  IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,
+  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,
+  IN UINT64                       NumberOfBytes,
+  IN EFI_GUID                     *OwnerGUID
+  )
+{
+  ASSERT (FALSE);
+}
+
+/**
+  Builds a Capsule Volume HOB.
+
+  This function builds a Capsule Volume HOB.
+  If the platform does not support Capsule Volume HOBs, then ASSERT().
+  If there is no additional space for HOB creation, then ASSERT().
+
+  @param  BaseAddress   The base address of the Capsule Volume.
+  @param  Length        The size of the Capsule Volume in bytes.
+
+**/
+VOID
+EFIAPI
+BuildCvHob (
+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
+  IN UINT64                      Length
+  )
+{
+  ASSERT (FALSE);
+}
+
+
+/**
+  Builds a HOB for the BSP store.
+
+  This function builds a HOB for BSP store.
+  If there is no additional space for HOB creation, then ASSERT().
+
+  @param  BaseAddress   The 64 bit physical address of the BSP.
+  @param  Length        The length of the BSP store in bytes.
+  @param  MemoryType    Type of memory allocated by this HOB.
+
+**/
+VOID
+EFIAPI
+BuildBspStoreHob (
+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
+  IN UINT64                      Length,
+  IN EFI_MEMORY_TYPE             MemoryType
+  )
+{
+  ASSERT (FALSE);
+}
+
+/**
+  Builds a HOB for the Stack.
+
+  This function builds a HOB for the stack.
+  If there is no additional space for HOB creation, then ASSERT().
+
+  @param  BaseAddress   The 64 bit physical address of the Stack.
+  @param  Length        The length of the stack in bytes.
+
+**/
+VOID
+EFIAPI
+BuildStackHob (
+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
+  IN UINT64                      Length
+  )
+{
+  ASSERT (FALSE);
+}
diff --git a/StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf b/StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
new file mode 100644
index 0000000..d73188e
--- /dev/null
+++ b/StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
@@ -0,0 +1,48 @@
+## @file
+# Instance of HOB Library for Standalone MM Core.
+#
+# HOB Library implementation for the Standalone MM Core. Does not have a constructor.
+#  Uses gHobList defined in the Standalone MM Core Entry Point Library.
+#
+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php.
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = HobLib
+  FILE_GUID                      = 8262551B-AB2D-4E76-99FC-5EBB83F4988E
+  MODULE_TYPE                    = MM_STANDALONE
+  VERSION_STRING                 = 1.0
+  PI_SPECIFICATION_VERSION       = 0x00010032
+  LIBRARY_CLASS                  = HobLib|MM_STANDALONE
+  CONSTRUCTOR                    = HobLibConstructor
+#
+#  VALID_ARCHITECTURES           = AARCH64
+#
+[Sources.Common]
+  StandaloneMmHobLib.c
+
+[Sources.AARCH64]
+  AArch64/StandaloneMmCoreHobLibInternal.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  MmServicesTableLib
+
+[Guids]
+  gEfiHobListGuid                               ## CONSUMES  ## SystemTable
diff --git a/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c
new file mode 100644
index 0000000..e989f27
--- /dev/null
+++ b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c
@@ -0,0 +1,824 @@
+/** @file
+  Support routines for memory allocation routines based on Standalone MM Core internal functions.
+
+  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiMm.h>
+
+#include <Guid/MmramMemoryReserve.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+
+extern EFI_MM_SYSTEM_TABLE   *gMmst;
+
+/**
+  Allocates one or more 4KB pages of a certain memory type.
+
+  Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated
+  buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL is returned.
+  If there is not enough memory remaining to satisfy the request, then NULL is returned.
+
+  @param  MemoryType            The type of memory to allocate.
+  @param  Pages                 The number of 4 KB pages to allocate.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+InternalAllocatePages (
+  IN EFI_MEMORY_TYPE  MemoryType,
+  IN UINTN            Pages
+  )
+{
+  EFI_STATUS            Status;
+  EFI_PHYSICAL_ADDRESS  Memory;
+
+  if (Pages == 0) {
+    return NULL;
+  }
+
+  Status = gMmst->MmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+  return (VOID *) (UINTN) Memory;
+}
+
+/**
+  Allocates one or more 4KB pages of type EfiBootServicesData.
+
+  Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
+  allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
+  is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
+  returned.
+
+  @param  Pages                 The number of 4 KB pages to allocate.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocatePages (
+  IN UINTN  Pages
+  )
+{
+  return InternalAllocatePages (EfiRuntimeServicesData, Pages);
+}
+
+/**
+  Allocates one or more 4KB pages of type EfiRuntimeServicesData.
+
+  Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
+  allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
+  is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
+  returned.
+
+  @param  Pages                 The number of 4 KB pages to allocate.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateRuntimePages (
+  IN UINTN  Pages
+  )
+{
+  return InternalAllocatePages (EfiRuntimeServicesData, Pages);
+}
+
+/**
+  Allocates one or more 4KB pages of type EfiReservedMemoryType.
+
+  Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
+  allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
+  is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
+  returned.
+
+  @param  Pages                 The number of 4 KB pages to allocate.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateReservedPages (
+  IN UINTN  Pages
+  )
+{
+  return NULL;
+}
+
+/**
+  Frees one or more 4KB pages that were previously allocated with one of the page allocation
+  functions in the Memory Allocation Library.
+
+  Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.  Buffer
+  must have been allocated on a previous call to the page allocation services of the Memory
+  Allocation Library.  If it is not possible to free allocated pages, then this function will
+  perform no actions.
+
+  If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
+  then ASSERT().
+  If Pages is zero, then ASSERT().
+
+  @param  Buffer                Pointer to the buffer of pages to free.
+  @param  Pages                 The number of 4 KB pages to free.
+
+**/
+VOID
+EFIAPI
+FreePages (
+  IN VOID   *Buffer,
+  IN UINTN  Pages
+  )
+{
+  EFI_STATUS  Status;
+
+  ASSERT (Pages != 0);
+  Status = gMmst->MmFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  Allocates one or more 4KB pages of a certain memory type at a specified alignment.
+
+  Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
+  specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is returned.
+  If there is not enough memory at the specified alignment remaining to satisfy the request, then
+  NULL is returned.
+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+  If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
+
+  @param  MemoryType            The type of memory to allocate.
+  @param  Pages                 The number of 4 KB pages to allocate.
+  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
+                                If Alignment is zero, then byte alignment is used.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+InternalAllocateAlignedPages (
+  IN EFI_MEMORY_TYPE  MemoryType,
+  IN UINTN            Pages,
+  IN UINTN            Alignment
+  )
+{
+  EFI_STATUS            Status;
+  EFI_PHYSICAL_ADDRESS  Memory;
+  UINTN                 AlignedMemory;
+  UINTN                 AlignmentMask;
+  UINTN                 UnalignedPages;
+  UINTN                 RealPages;
+
+  //
+  // Alignment must be a power of two or zero.
+  //
+  ASSERT ((Alignment & (Alignment - 1)) == 0);
+
+  if (Pages == 0) {
+    return NULL;
+  }
+  if (Alignment > EFI_PAGE_SIZE) {
+    //
+    // Calculate the total number of pages since alignment is larger than page size.
+    //
+    AlignmentMask  = Alignment - 1;
+    RealPages      = Pages + EFI_SIZE_TO_PAGES (Alignment);
+    //
+    // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
+    //
+    ASSERT (RealPages > Pages);
+
+    Status         = gMmst->MmAllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);
+    if (EFI_ERROR (Status)) {
+      return NULL;
+    }
+    AlignedMemory  = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;
+    UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory);
+    if (UnalignedPages > 0) {
+      //
+      // Free first unaligned page(s).
+      //
+      Status = gMmst->MmFreePages (Memory, UnalignedPages);
+      ASSERT_EFI_ERROR (Status);
+    }
+    Memory         = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));
+    UnalignedPages = RealPages - Pages - UnalignedPages;
+    if (UnalignedPages > 0) {
+      //
+      // Free last unaligned page(s).
+      //
+      Status = gMmst->MmFreePages (Memory, UnalignedPages);
+      ASSERT_EFI_ERROR (Status);
+    }
+  } else {
+    //
+    // Do not over-allocate pages in this case.
+    //
+    Status = gMmst->MmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
+    if (EFI_ERROR (Status)) {
+      return NULL;
+    }
+    AlignedMemory  = (UINTN) Memory;
+  }
+  return (VOID *) AlignedMemory;
+}
+
+/**
+  Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
+
+  Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
+  alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
+  returned.  If there is not enough memory at the specified alignment remaining to satisfy the
+  request, then NULL is returned.
+
+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+  If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
+
+  @param  Pages                 The number of 4 KB pages to allocate.
+  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
+                                If Alignment is zero, then byte alignment is used.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateAlignedPages (
+  IN UINTN  Pages,
+  IN UINTN  Alignment
+  )
+{
+  return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
+}
+
+/**
+  Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
+
+  Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
+  alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
+  returned.  If there is not enough memory at the specified alignment remaining to satisfy the
+  request, then NULL is returned.
+
+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+  If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
+
+  @param  Pages                 The number of 4 KB pages to allocate.
+  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
+                                If Alignment is zero, then byte alignment is used.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateAlignedRuntimePages (
+  IN UINTN  Pages,
+  IN UINTN  Alignment
+  )
+{
+  return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
+}
+
+/**
+  Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
+
+  Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
+  alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
+  returned.  If there is not enough memory at the specified alignment remaining to satisfy the
+  request, then NULL is returned.
+
+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+  If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
+
+  @param  Pages                 The number of 4 KB pages to allocate.
+  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
+                                If Alignment is zero, then byte alignment is used.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateAlignedReservedPages (
+  IN UINTN  Pages,
+  IN UINTN  Alignment
+  )
+{
+  return NULL;
+}
+
+/**
+  Frees one or more 4KB pages that were previously allocated with one of the aligned page
+  allocation functions in the Memory Allocation Library.
+
+  Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.  Buffer
+  must have been allocated on a previous call to the aligned page allocation services of the Memory
+  Allocation Library.  If it is not possible to free allocated pages, then this function will
+  perform no actions.
+
+  If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
+  Library, then ASSERT().
+  If Pages is zero, then ASSERT().
+
+  @param  Buffer                Pointer to the buffer of pages to free.
+  @param  Pages                 The number of 4 KB pages to free.
+
+**/
+VOID
+EFIAPI
+FreeAlignedPages (
+  IN VOID   *Buffer,
+  IN UINTN  Pages
+  )
+{
+  EFI_STATUS  Status;
+
+  ASSERT (Pages != 0);
+  Status = gMmst->MmFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  Allocates a buffer of a certain pool type.
+
+  Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
+  pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
+  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
+
+  @param  MemoryType            The type of memory to allocate.
+  @param  AllocationSize        The number of bytes to allocate.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+InternalAllocatePool (
+  IN EFI_MEMORY_TYPE  MemoryType,
+  IN UINTN            AllocationSize
+  )
+{
+  EFI_STATUS  Status;
+  VOID        *Memory;
+
+  Memory = NULL;
+
+  Status = gMmst->MmAllocatePool (MemoryType, AllocationSize, &Memory);
+  if (EFI_ERROR (Status)) {
+    Memory = NULL;
+  }
+  return Memory;
+}
+
+/**
+  Allocates a buffer of type EfiBootServicesData.
+
+  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
+  pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
+  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
+
+  @param  AllocationSize        The number of bytes to allocate.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocatePool (
+  IN UINTN  AllocationSize
+  )
+{
+  return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
+}
+
+/**
+  Allocates a buffer of type EfiRuntimeServicesData.
+
+  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
+  a pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
+  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
+
+  @param  AllocationSize        The number of bytes to allocate.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateRuntimePool (
+  IN UINTN  AllocationSize
+  )
+{
+  return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
+}
+
+/**
+  Allocates a buffer of type EfiReservedMemoryType.
+
+  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
+  a pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
+  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
+
+  @param  AllocationSize        The number of bytes to allocate.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateReservedPool (
+  IN UINTN  AllocationSize
+  )
+{
+  return NULL;
+}
+
+/**
+  Allocates and zeros a buffer of a certain pool type.
+
+  Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
+  with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a valid
+  buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the request,
+  then NULL is returned.
+
+  @param  PoolType              The type of memory to allocate.
+  @param  AllocationSize        The number of bytes to allocate and zero.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+InternalAllocateZeroPool (
+  IN EFI_MEMORY_TYPE  PoolType,
+  IN UINTN            AllocationSize
+  )
+{
+  VOID  *Memory;
+
+  Memory = InternalAllocatePool (PoolType, AllocationSize);
+  if (Memory != NULL) {
+    Memory = ZeroMem (Memory, AllocationSize);
+  }
+  return Memory;
+}
+
+/**
+  Allocates and zeros a buffer of type EfiBootServicesData.
+
+  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
+  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
+  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
+  request, then NULL is returned.
+
+  @param  AllocationSize        The number of bytes to allocate and zero.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateZeroPool (
+  IN UINTN  AllocationSize
+  )
+{
+  return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
+}
+
+/**
+  Allocates and zeros a buffer of type EfiRuntimeServicesData.
+
+  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
+  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
+  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
+  request, then NULL is returned.
+
+  @param  AllocationSize        The number of bytes to allocate and zero.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateRuntimeZeroPool (
+  IN UINTN  AllocationSize
+  )
+{
+  return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
+}
+
+/**
+  Allocates and zeros a buffer of type EfiReservedMemoryType.
+
+  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
+  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
+  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
+  request, then NULL is returned.
+
+  @param  AllocationSize        The number of bytes to allocate and zero.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateReservedZeroPool (
+  IN UINTN  AllocationSize
+  )
+{
+  return NULL;
+}
+
+/**
+  Copies a buffer to an allocated buffer of a certain pool type.
+
+  Allocates the number bytes specified by AllocationSize of a certain pool type, copies
+  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
+  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
+  is not enough memory remaining to satisfy the request, then NULL is returned.
+  If Buffer is NULL, then ASSERT().
+  If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+  @param  PoolType              The type of pool to allocate.
+  @param  AllocationSize        The number of bytes to allocate and zero.
+  @param  Buffer                The buffer to copy to the allocated buffer.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+InternalAllocateCopyPool (
+  IN EFI_MEMORY_TYPE  PoolType,
+  IN UINTN            AllocationSize,
+  IN CONST VOID       *Buffer
+  )
+{
+  VOID  *Memory;
+
+  ASSERT (Buffer != NULL);
+  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
+
+  Memory = InternalAllocatePool (PoolType, AllocationSize);
+  if (Memory != NULL) {
+     Memory = CopyMem (Memory, Buffer, AllocationSize);
+  }
+  return Memory;
+}
+
+/**
+  Copies a buffer to an allocated buffer of type EfiBootServicesData.
+
+  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
+  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
+  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
+  is not enough memory remaining to satisfy the request, then NULL is returned.
+
+  If Buffer is NULL, then ASSERT().
+  If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+  @param  AllocationSize        The number of bytes to allocate and zero.
+  @param  Buffer                The buffer to copy to the allocated buffer.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateCopyPool (
+  IN UINTN       AllocationSize,
+  IN CONST VOID  *Buffer
+  )
+{
+  return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
+}
+
+/**
+  Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
+
+  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
+  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
+  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
+  is not enough memory remaining to satisfy the request, then NULL is returned.
+
+  If Buffer is NULL, then ASSERT().
+  If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+  @param  AllocationSize        The number of bytes to allocate and zero.
+  @param  Buffer                The buffer to copy to the allocated buffer.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateRuntimeCopyPool (
+  IN UINTN       AllocationSize,
+  IN CONST VOID  *Buffer
+  )
+{
+  return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
+}
+
+/**
+  Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
+
+  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
+  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
+  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
+  is not enough memory remaining to satisfy the request, then NULL is returned.
+
+  If Buffer is NULL, then ASSERT().
+  If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+  @param  AllocationSize        The number of bytes to allocate and zero.
+  @param  Buffer                The buffer to copy to the allocated buffer.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateReservedCopyPool (
+  IN UINTN       AllocationSize,
+  IN CONST VOID  *Buffer
+  )
+{
+  return NULL;
+}
+
+/**
+  Reallocates a buffer of a specified memory type.
+
+  Allocates and zeros the number bytes specified by NewSize from memory of the type
+  specified by PoolType.  If OldBuffer is not NULL, then the smaller of OldSize and
+  NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
+  OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
+  If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
+  enough memory remaining to satisfy the request, then NULL is returned.
+
+  If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
+  is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
+
+  @param  PoolType       The type of pool to allocate.
+  @param  OldSize        The size, in bytes, of OldBuffer.
+  @param  NewSize        The size, in bytes, of the buffer to reallocate.
+  @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
+                         parameter that may be NULL.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+InternalReallocatePool (
+  IN EFI_MEMORY_TYPE  PoolType,
+  IN UINTN            OldSize,
+  IN UINTN            NewSize,
+  IN VOID             *OldBuffer  OPTIONAL
+  )
+{
+  VOID  *NewBuffer;
+
+  NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);
+  if (NewBuffer != NULL && OldBuffer != NULL) {
+    CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
+    FreePool (OldBuffer);
+  }
+  return NewBuffer;
+}
+
+/**
+  Reallocates a buffer of type EfiBootServicesData.
+
+  Allocates and zeros the number bytes specified by NewSize from memory of type
+  EfiBootServicesData.  If OldBuffer is not NULL, then the smaller of OldSize and
+  NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
+  OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
+  If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
+  enough memory remaining to satisfy the request, then NULL is returned.
+
+  If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
+  is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
+
+  @param  OldSize        The size, in bytes, of OldBuffer.
+  @param  NewSize        The size, in bytes, of the buffer to reallocate.
+  @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
+                         parameter that may be NULL.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+ReallocatePool (
+  IN UINTN  OldSize,
+  IN UINTN  NewSize,
+  IN VOID   *OldBuffer  OPTIONAL
+  )
+{
+  return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);
+}
+
+/**
+  Reallocates a buffer of type EfiRuntimeServicesData.
+
+  Allocates and zeros the number bytes specified by NewSize from memory of type
+  EfiRuntimeServicesData.  If OldBuffer is not NULL, then the smaller of OldSize and
+  NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
+  OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
+  If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
+  enough memory remaining to satisfy the request, then NULL is returned.
+
+  If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
+  is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
+
+  @param  OldSize        The size, in bytes, of OldBuffer.
+  @param  NewSize        The size, in bytes, of the buffer to reallocate.
+  @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
+                         parameter that may be NULL.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+ReallocateRuntimePool (
+  IN UINTN  OldSize,
+  IN UINTN  NewSize,
+  IN VOID   *OldBuffer  OPTIONAL
+  )
+{
+  return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);
+}
+
+/**
+  Reallocates a buffer of type EfiReservedMemoryType.
+
+  Allocates and zeros the number bytes specified by NewSize from memory of type
+  EfiReservedMemoryType.  If OldBuffer is not NULL, then the smaller of OldSize and
+  NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
+  OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
+  If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
+  enough memory remaining to satisfy the request, then NULL is returned.
+
+  If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
+  is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
+
+  @param  OldSize        The size, in bytes, of OldBuffer.
+  @param  NewSize        The size, in bytes, of the buffer to reallocate.
+  @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
+                         parameter that may be NULL.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+ReallocateReservedPool (
+  IN UINTN  OldSize,
+  IN UINTN  NewSize,
+  IN VOID   *OldBuffer  OPTIONAL
+  )
+{
+  return NULL;
+}
+
+/**
+  Frees a buffer that was previously allocated with one of the pool allocation functions in the
+  Memory Allocation Library.
+
+  Frees the buffer specified by Buffer.  Buffer must have been allocated on a previous call to the
+  pool allocation services of the Memory Allocation Library.  If it is not possible to free pool
+  resources, then this function will perform no actions.
+
+  If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
+  then ASSERT().
+
+  @param  Buffer                Pointer to the buffer to free.
+
+**/
+VOID
+EFIAPI
+FreePool (
+  IN VOID   *Buffer
+  )
+{
+  EFI_STATUS    Status;
+
+  Status = gMmst->MmFreePool (Buffer);
+  ASSERT_EFI_ERROR (Status);
+}
+
diff --git a/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf
new file mode 100644
index 0000000..9ac03df
--- /dev/null
+++ b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf
@@ -0,0 +1,45 @@
+## @file
+# Memory Allocation Library instance dedicated to MM Core.
+# The implementation borrows the MM Core Memory Allocation services as the primitive
+# for memory allocation instead of using MM System Table servces in an indirect way.
+# It is assumed that this library instance must be linked with MM Core in this package.
+#
+# Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = MemoryAllocationLib
+  FILE_GUID                      = 54646378-A9DC-473F-9BE1-BD027C4C76DE
+  MODULE_TYPE                    = MM_CORE_STANDALONE
+  VERSION_STRING                 = 1.0
+  PI_SPECIFICATION_VERSION       = 0x00010032
+  LIBRARY_CLASS                  = MemoryAllocationLib|MM_STANDALONE
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  StandaloneMmMemoryAllocationLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  StandaloneMmPkg/StandaloneMmPkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  MmServicesTableLib
+  HobLib
diff --git a/StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.c b/StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.c
new file mode 100644
index 0000000..e0e0044
--- /dev/null
+++ b/StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.c
@@ -0,0 +1,64 @@
+/** @file
+  MM Core MM Services Table Library.
+
+  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiMm.h>
+#include <Library/DebugLib.h>
+
+extern EFI_MM_SYSTEM_TABLE         *gMmst;
+
+/**
+  The constructor function caches the pointer of MM Services Table.
+
+  @param  ImageHandle   The firmware allocated handle for the EFI image.
+  @param  SystemTable   A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+StandaloneMmServicesTableLibConstructor (
+  IN EFI_HANDLE             ImageHandle,
+  IN EFI_MM_SYSTEM_TABLE  *MmSystemTable
+  )
+{
+  gMmst = MmSystemTable;
+  return EFI_SUCCESS;
+}
+
+/**
+  This function allows the caller to determine if the driver is executing in
+  Standalone Management Mode(SMM).
+
+  This function returns TRUE if the driver is executing in SMM and FALSE if the
+  driver is not executing in SMM.
+
+  @retval  TRUE  The driver is executing in Standalone Management Mode (SMM).
+  @retval  FALSE The driver is not executing in Standalone Management Mode (SMM).
+
+**/
+BOOLEAN
+EFIAPI
+InMm (
+  VOID
+  )
+{
+  //
+  // We are already in Standalone MM
+  //
+  return TRUE;
+}
+
diff --git a/StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf b/StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf
new file mode 100644
index 0000000..c362429
--- /dev/null
+++ b/StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf
@@ -0,0 +1,36 @@
+## @file
+# MM Core MM Services Table Library.
+#
+# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = StandaloneMmServicesTableLib
+  FILE_GUID                      = BEE33A2F-F49D-4B71-AF3E-FFCCB9885DEA
+  MODULE_TYPE                    = MM_STANDALONE
+  VERSION_STRING                 = 1.0
+  PI_SPECIFICATION_VERSION       = 0x00010032
+  LIBRARY_CLASS                  = MmServicesTableLib|MM_STANDALONE
+  CONSTRUCTOR                    = StandaloneMmServicesTableLibConstructor
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  StandaloneMmServicesTableLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 02/13] MdePkg: Add a PCD that indicates presence of Standalone MM mode
  2018-12-14 12:13 [PATCH 00/13] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
  2018-12-14 12:13 ` [PATCH 01/13] StandaloneMmPkg: Pull in additonal libraries from staging branch Jagadeesh Ujja
@ 2018-12-14 12:13 ` Jagadeesh Ujja
  2018-12-21  9:13   ` Ard Biesheuvel
  2018-12-14 12:13 ` [PATCH 03/13] MdeModulePkg: Add a PCD to indicate Standalone MM supports secure variable Jagadeesh Ujja
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 52+ messages in thread
From: Jagadeesh Ujja @ 2018-12-14 12:13 UTC (permalink / raw)
  To: edk2-devel, liming.gao, chao.b.zhang, leif.lindholm,
	ard.biesheuvel

Add a flag to indicate the presence of Standalone MM mode. For existing
library and/or drivers that can be refactored to be used as a Standalone
MM component, this flag can be used to choose the portions of the code
that gets executed in Standalone MM.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
---
 MdePkg/MdePkg.dec | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index 712bd46..af694fc 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -2073,6 +2073,11 @@
   # @Prompt Fixed Debug Message Print Level.
   gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel|0xFFFFFFFF|UINT32|0x30001016
 
+  ## This flag indicates Standalone MM execution mode is enabled
+  #  TRUE  - Standalone MM execution mode is enabled
+  #  FALSE - Standalone MM execution mode is not enabled
+  gEfiMdePkgTokenSpaceGuid.PcdStandaloneMmCodeEnabled|FALSE|BOOLEAN|0x30001017
+
 [PcdsFixedAtBuild,PcdsPatchableInModule]
   ## Indicates the maximum length of unicode string used in the following
   #  BaseLib functions: StrLen(), StrSize(), StrCmp(), StrnCmp(), StrCpy(), StrnCpy()<BR><BR>
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 03/13] MdeModulePkg: Add a PCD to indicate Standalone MM supports secure variable
  2018-12-14 12:13 [PATCH 00/13] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
  2018-12-14 12:13 ` [PATCH 01/13] StandaloneMmPkg: Pull in additonal libraries from staging branch Jagadeesh Ujja
  2018-12-14 12:13 ` [PATCH 02/13] MdePkg: Add a PCD that indicates presence of Standalone MM mode Jagadeesh Ujja
@ 2018-12-14 12:13 ` Jagadeesh Ujja
  2018-12-21  9:13   ` Ard Biesheuvel
  2018-12-14 12:13 ` [PATCH 04/13] MdePkg/Include: add StandaloneMmServicesTableLib header file Jagadeesh Ujja
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 52+ messages in thread
From: Jagadeesh Ujja @ 2018-12-14 12:13 UTC (permalink / raw)
  To: edk2-devel, liming.gao, chao.b.zhang, leif.lindholm,
	ard.biesheuvel

Add a flag that indicates whether Standalone MM mode supports
secure storage of variables.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
---
 MdeModulePkg/MdeModulePkg.dec | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 41d2b04..badea4a 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -1041,6 +1041,11 @@
   # @Prompt Enable UEFI Stack Guard.
   gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|FALSE|BOOLEAN|0x30001055
 
+  ## This flag indicates secure variable functionality is implemented by Standalone MM
+  #  TRUE  - Secure variable storage supported by Standalone MM code.
+  #  FALSE - Standalone MM code does not support secure storage of variables
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStandaloneMmVariableEnabled|FALSE|BOOLEAN|0x30001056
+
 [PcdsFixedAtBuild, PcdsPatchableInModule]
   ## Dynamic type PCD can be registered callback function for Pcd setting action.
   #  PcdMaxPeiPcdCallBackNumberPerPcdEntry indicates the maximum number of callback function
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 04/13] MdePkg/Include: add StandaloneMmServicesTableLib header file
  2018-12-14 12:13 [PATCH 00/13] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
                   ` (2 preceding siblings ...)
  2018-12-14 12:13 ` [PATCH 03/13] MdeModulePkg: Add a PCD to indicate Standalone MM supports secure variable Jagadeesh Ujja
@ 2018-12-14 12:13 ` Jagadeesh Ujja
  2018-12-14 12:13 ` [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add AsmLfence function Jagadeesh Ujja
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 52+ messages in thread
From: Jagadeesh Ujja @ 2018-12-14 12:13 UTC (permalink / raw)
  To: edk2-devel, liming.gao, chao.b.zhang, leif.lindholm,
	ard.biesheuvel

Some of the existing DXE drivers can be refactored to execute within
the Standalone MM execution environment as well. Allow such drivers to
get access to the Standalone MM services tables.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
---
 MdePkg/Include/Library/StandaloneMmServicesTableLib.h | 25 ++++++++++++++++++++
 MdePkg/MdePkg.dec                                     |  4 ++++
 2 files changed, 29 insertions(+)

diff --git a/MdePkg/Include/Library/StandaloneMmServicesTableLib.h b/MdePkg/Include/Library/StandaloneMmServicesTableLib.h
new file mode 100644
index 0000000..db310ac
--- /dev/null
+++ b/MdePkg/Include/Library/StandaloneMmServicesTableLib.h
@@ -0,0 +1,25 @@
+/** @file
+  Provides a service to retrieve a pointer to the Standalone MM Services Table.
+  Only available to Standalone MM module types.
+
+Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __MM_SERVICES_TABLE_LIB_H__
+#define __MM_SERVICES_TABLE_LIB_H__
+
+#include <PiMm.h>
+
+extern EFI_MM_SYSTEM_TABLE         *gMmst;
+
+#endif
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index af694fc..17c90c2 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -243,6 +243,10 @@
   ##
   SafeIntLib|Include/Library/SafeIntLib.h
 
+  ## @libraryclass Provides a service to retrieve a pointer to the Standalone MM Services Table.
+  #                 Only available to MM_STANDALONE module types.
+  MmServicesTableLib|Include/Library/StandaloneMmServicesTableLib.h
+
 [LibraryClasses.IA32, LibraryClasses.X64]
   ##  @libraryclass  Abstracts both S/W SMI generation and detection.
   ##
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
  2018-12-14 12:13 [PATCH 00/13] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
                   ` (3 preceding siblings ...)
  2018-12-14 12:13 ` [PATCH 04/13] MdePkg/Include: add StandaloneMmServicesTableLib header file Jagadeesh Ujja
@ 2018-12-14 12:13 ` Jagadeesh Ujja
  2018-12-14 13:53   ` Ard Biesheuvel
  2018-12-14 12:13 ` [PATCH 06/13] MdePkg/Library: Add StandaloneMmRuntimeDxe library Jagadeesh Ujja
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 52+ messages in thread
From: Jagadeesh Ujja @ 2018-12-14 12:13 UTC (permalink / raw)
  To: edk2-devel, liming.gao, chao.b.zhang, leif.lindholm,
	ard.biesheuvel

Variable service driver includes a call to AsmLfence. To reuse this
driver on AArch64 based platforms, add an implementation of AsmLfence
that acts as a wrapper on the AArch64 specific MemoryFence function.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
---
 MdePkg/Include/Library/BaseLib.h             | 33 +++++++++------
 MdePkg/Library/BaseLib/AArch64/AsmLfence.S   | 42 ++++++++++++++++++++
 MdePkg/Library/BaseLib/AArch64/AsmLfence.asm | 41 +++++++++++++++++++
 MdePkg/Library/BaseLib/BaseLib.inf           |  2 +
 4 files changed, 105 insertions(+), 13 deletions(-)

diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index 8cc0869..ca961ee 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -7697,19 +7697,6 @@ AsmWriteTr (
   );
 
 /**
-  Performs a serializing operation on all load-from-memory instructions that
-  were issued prior the AsmLfence function.
-
-  Executes a LFENCE instruction. This function is only available on IA-32 and x64.
-
-**/
-VOID
-EFIAPI
-AsmLfence (
-  VOID
-  );
-
-/**
   Patch the immediate operand of an IA32 or X64 instruction such that the byte,
   word, dword or qword operand is encoded at the end of the instruction's
   binary representation.
@@ -7752,4 +7739,24 @@ PatchInstructionX86 (
   );
 
 #endif // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
+
+#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64)
+
+/**
+  Performs a serializing operation on all load-from-memory instructions that
+  were issued prior the AsmLfence function.
+
+  In case of IA-32 and x64, Executes a LFENCE instruction.
+
+  In case of AArch64 this acts as a wrapper on the AArch64
+  specific MemoryFence function
+
+**/
+VOID
+EFIAPI
+AsmLfence (
+  VOID
+  );
+
+#endif  // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64)
 #endif // !defined (__BASE_LIB__)
diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.S b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
new file mode 100644
index 0000000..2fd804b
--- /dev/null
+++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
@@ -0,0 +1,42 @@
+##------------------------------------------------------------------------------
+#
+# AsmLfence() for AArch64
+#
+# Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##------------------------------------------------------------------------------
+
+.text
+.p2align 2
+
+GCC_ASM_EXPORT(AsmLfence)
+
+# IMPORT
+GCC_ASM_IMPORT(MemoryFence)
+
+#/**
+#  Used to serialize load and store operations.
+#
+#  All loads and stores that proceed calls to this function are guaranteed to be
+#  globally visible when this function returns.
+#
+#**/
+#VOID
+#EFIAPI
+#AsmLfence (
+#  VOID
+#  );
+#
+ASM_PFX(AsmLfence):
+    stp   x29, x30, [sp, #-16]!
+    bl MemoryFence
+    ldp   x29, x30, [sp], #0x10
+    ret
diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
new file mode 100644
index 0000000..7dd5659
--- /dev/null
+++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------
+;
+; AsmLfence() for AArch64
+;
+; Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
+;
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution.  The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;------------------------------------------------------------------------------
+
+  EXPORT AsmLfence
+  AREA BaseLib_LowLevel, CODE, READONLY
+  # IMPORT
+  GCC_ASM_IMPORT(MemoryFence)
+
+;/**
+;  Used to serialize load and store operations.
+;
+;  All loads and stores that proceed calls to this function are guaranteed to be
+;  globally visible when this function returns.
+;
+;**/
+;VOID
+;EFIAPI
+;AsmLfence (
+;  VOID
+;  );
+;
+AsmLfence
+    stp   x29, x30, [sp, #-16]!
+    bl MemoryFence
+    ldp   x29, x30, [sp], #0x10
+    ret
+
+  END
diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
index b84e583..b7d7bcb 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -585,6 +585,7 @@
   Math64.c
 
   AArch64/MemoryFence.S             | GCC
+  AArch64/AsmLfence.S               | GCC
   AArch64/SwitchStack.S             | GCC
   AArch64/EnableInterrupts.S        | GCC
   AArch64/DisableInterrupts.S       | GCC
@@ -593,6 +594,7 @@
   AArch64/CpuBreakpoint.S           | GCC
 
   AArch64/MemoryFence.asm           | MSFT
+  AArch64/AsmLfence.asm             | MSFT
   AArch64/SwitchStack.asm           | MSFT
   AArch64/EnableInterrupts.asm      | MSFT
   AArch64/DisableInterrupts.asm     | MSFT
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 06/13] MdePkg/Library: Add StandaloneMmRuntimeDxe library
  2018-12-14 12:13 [PATCH 00/13] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
                   ` (4 preceding siblings ...)
  2018-12-14 12:13 ` [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add AsmLfence function Jagadeesh Ujja
@ 2018-12-14 12:13 ` Jagadeesh Ujja
  2018-12-14 12:13 ` [PATCH 07/13] MdeModulePkg/FaultTolerantWriteDxe: allow reusability as a MM driver Jagadeesh Ujja
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 52+ messages in thread
From: Jagadeesh Ujja @ 2018-12-14 12:13 UTC (permalink / raw)
  To: edk2-devel, liming.gao, chao.b.zhang, leif.lindholm,
	ard.biesheuvel

To resuse some the libraries in both MM and non-MM mode, a mechanism to
determine the execution mode is required, i.e, in MM or non-MM. Add a
new library for use by non-MM code to determine the current execution
mode.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
---
 MdePkg/Include/Library/StandaloneMmRuntimeDxe.h                  | 39 ++++++++++++++++++++
 MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c   | 36 ++++++++++++++++++
 MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf | 36 ++++++++++++++++++
 MdePkg/MdePkg.dec                                                |  3 ++
 4 files changed, 114 insertions(+)

diff --git a/MdePkg/Include/Library/StandaloneMmRuntimeDxe.h b/MdePkg/Include/Library/StandaloneMmRuntimeDxe.h
new file mode 100644
index 0000000..9c45c4d
--- /dev/null
+++ b/MdePkg/Include/Library/StandaloneMmRuntimeDxe.h
@@ -0,0 +1,39 @@
+/** @file
+  Provides a InMm implementation for RUNTIME DXE drivers
+
+Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __STANDALONE_MM_RUNTIME_DXE_H__
+#define __STANDALONE_MM_RUNTIME_DXE_H__
+
+#include <PiDxe.h>
+
+/**
+  This function allows the caller to determine if the driver is executing in
+  Standalone Management Mode(SMM).
+
+  This function returns TRUE if the driver is executing in SMM and FALSE if the
+  driver is not executing in SMM.
+
+  @retval  TRUE  The driver is executing in Standalone Management Mode (SMM).
+  @retval  FALSE The driver is not executing in Standalone Management Mode (SMM).
+
+**/
+BOOLEAN
+EFIAPI
+InMm (
+  VOID
+  );
+
+#endif
diff --git a/MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c b/MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c
new file mode 100644
index 0000000..61ef59a
--- /dev/null
+++ b/MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c
@@ -0,0 +1,36 @@
+/** @file
+  StandaloneMmRuntimeDxe Library.
+
+  Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiDxe.h>
+
+/**
+  This function allows the caller to determine if the driver is executing in
+  Standalone Management Mode(SMM).
+
+  This function returns TRUE if the driver is executing in SMM and FALSE if the
+  driver is not executing in SMM.
+
+  @retval  TRUE  The driver is executing in Standalone Management Mode (SMM).
+  @retval  FALSE The driver is not executing in Standalone Management Mode (SMM).
+
+**/
+BOOLEAN
+EFIAPI
+InMm (
+  VOID
+  )
+{
+  return FALSE;
+}
diff --git a/MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf b/MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf
new file mode 100644
index 0000000..43f5f26
--- /dev/null
+++ b/MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf
@@ -0,0 +1,36 @@
+## @file
+#  Provides StandaloneMmRuntimeDxe.
+#
+#  Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions
+#  of the BSD License which accompanies this distribution.  The
+#  full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = StandaloneMmRuntimeDxe
+  FILE_GUID                      = 8099cfbf-9564-4c9b-9052-e66b1da88930
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = StandaloneMmRuntimeDxe |DXE_RUNTIME_DRIVER DXE_SMM_DRIVER MM_STANDALONE
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  StandaloneMmRuntimeDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index 17c90c2..0c2ebf5 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -247,6 +247,9 @@
   #                 Only available to MM_STANDALONE module types.
   MmServicesTableLib|Include/Library/StandaloneMmServicesTableLib.h
 
+  ## @libraryclass  Provides services to RUNTIME DXE drivers to determine execution mode
+  StandaloneMmRuntimeDxe|Include/Library/StandaloneMmRuntimeDxe.h
+
 [LibraryClasses.IA32, LibraryClasses.X64]
   ##  @libraryclass  Abstracts both S/W SMI generation and detection.
   ##
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 07/13] MdeModulePkg/FaultTolerantWriteDxe: allow reusability as a MM driver
  2018-12-14 12:13 [PATCH 00/13] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
                   ` (5 preceding siblings ...)
  2018-12-14 12:13 ` [PATCH 06/13] MdePkg/Library: Add StandaloneMmRuntimeDxe library Jagadeesh Ujja
@ 2018-12-14 12:13 ` Jagadeesh Ujja
  2018-12-14 12:13 ` [PATCH 08/13] MdeModulePkg/Variable/RuntimeDxe: adapt for usability with MM Standalone Jagadeesh Ujja
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 52+ messages in thread
From: Jagadeesh Ujja @ 2018-12-14 12:13 UTC (permalink / raw)
  To: edk2-devel, liming.gao, chao.b.zhang, leif.lindholm,
	ard.biesheuvel

Adapt the FaultTolerantWriteDxe driver to be used as a MM_STANDALONE
driver to provide UEFI fault tolerant write protocol functionality
for variable reclaim operation on EFI variables stored on a NOR flash
that is only accessible to code executing in MM Standalone mode.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
---
 MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf          |   1 +
 MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c            | 203 +++++++++++++++-----
 MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf | 101 ++++++++++
 MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c               |  27 +--
 4 files changed, 271 insertions(+), 61 deletions(-)

diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
index dcde58d..026bc60 100644
--- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
@@ -77,6 +77,7 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase      ## SOMETIMES_CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64    ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize      ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStandaloneMmVariableEnabled
 
 #
 # gBS->CalculateCrc32() is consumed in EntryPoint.
diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
index 27fcab1..c5c9452 100644
--- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
+++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
@@ -44,6 +44,7 @@
   This driver need to make sure the CommBuffer is not in the SMRAM range.
 
 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -55,13 +56,16 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/
 
 #include <PiSmm.h>
+#include <PiMm.h>
 #include <Library/SmmServicesTableLib.h>
 #include <Library/SmmMemLib.h>
+#include <Library/StandaloneMmMemLib.h>
 #include <Library/BaseLib.h>
 #include <Protocol/SmmSwapAddressRange.h>
 #include "FaultTolerantWrite.h"
 #include "FaultTolerantWriteSmmCommon.h"
 #include <Protocol/SmmEndOfDxe.h>
+#include <Library/StandaloneMmServicesTableLib.h>
 
 EFI_EVENT                                 mFvbRegistration = NULL;
 EFI_FTW_DEVICE                            *mFtwDevice      = NULL;
@@ -92,11 +96,19 @@ FtwGetFvbByHandle (
   //
   // To get the SMM FVB protocol interface on the handle
   //
-  return gSmst->SmmHandleProtocol (
-                  FvBlockHandle,
-                  &gEfiSmmFirmwareVolumeBlockProtocolGuid,
-                  (VOID **) FvBlock
-                  );
+  if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) {
+    return gSmst->SmmHandleProtocol (
+                    FvBlockHandle,
+                    &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+                    (VOID **) FvBlock
+                    );
+  } else {
+    return gMmst->MmHandleProtocol (
+                    FvBlockHandle,
+                    &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+                    (VOID **) FvBlock
+                    );
+  }
 }
 
 /**
@@ -119,11 +131,19 @@ FtwGetSarProtocol (
   //
   // Locate Smm Swap Address Range protocol
   //
-  Status = gSmst->SmmLocateProtocol (
-                    &gEfiSmmSwapAddressRangeProtocolGuid,
-                    NULL,
-                    SarProtocol
-                    );
+  if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) {
+    Status = gSmst->SmmLocateProtocol (
+                      &gEfiSmmSwapAddressRangeProtocolGuid,
+                      NULL,
+                      SarProtocol
+                      );
+  } else {
+    Status = gMmst->MmLocateProtocol (
+                      &gEfiSmmSwapAddressRangeProtocolGuid,
+                      NULL,
+                      SarProtocol
+                      );
+  }
   return Status;
 }
 
@@ -158,13 +178,23 @@ GetFvbCountAndBuffer (
   BufferSize     = 0;
   *NumberHandles = 0;
   *Buffer        = NULL;
-  Status = gSmst->SmmLocateHandle (
-                    ByProtocol,
-                    &gEfiSmmFirmwareVolumeBlockProtocolGuid,
-                    NULL,
-                    &BufferSize,
-                    *Buffer
-                    );
+  if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) {
+    Status = gSmst->SmmLocateHandle (
+                      ByProtocol,
+                      &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+                      NULL,
+                      &BufferSize,
+                      *Buffer
+                      );
+  } else {
+    Status = gMmst->MmLocateHandle (
+                      ByProtocol,
+                      &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+                      NULL,
+                      &BufferSize,
+                      *Buffer
+                      );
+  }
   if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL) {
     return EFI_NOT_FOUND;
   }
@@ -173,15 +203,23 @@ GetFvbCountAndBuffer (
   if (*Buffer == NULL) {
     return EFI_OUT_OF_RESOURCES;
   }
-
-  Status = gSmst->SmmLocateHandle (
-                    ByProtocol,
-                    &gEfiSmmFirmwareVolumeBlockProtocolGuid,
-                    NULL,
-                    &BufferSize,
-                    *Buffer
-                    );
-
+  if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) {
+    Status = gSmst->SmmLocateHandle (
+                      ByProtocol,
+                      &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+                      NULL,
+                      &BufferSize,
+                      *Buffer
+                      );
+  } else {
+    Status = gMmst->MmLocateHandle (
+                      ByProtocol,
+                      &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+                      NULL,
+                      &BufferSize,
+                      *Buffer
+                      );
+  }
   *NumberHandles = BufferSize / sizeof(EFI_HANDLE);
   if (EFI_ERROR(Status)) {
     *NumberHandles = 0;
@@ -335,10 +373,16 @@ SmmFaultTolerantWriteHandler (
     return EFI_SUCCESS;
   }
   CommBufferPayloadSize = TempCommBufferSize - SMM_FTW_COMMUNICATE_HEADER_SIZE;
-
-  if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {
-    DEBUG ((EFI_D_ERROR, "SmmFtwHandler: SMM communication buffer in SMRAM or overflow!\n"));
-    return EFI_SUCCESS;
+  if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) {
+    if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {
+      DEBUG ((EFI_D_ERROR, "SmmFtwHandler: SMM communication buffer in SMRAM or overflow!\n"));
+      return EFI_SUCCESS;
+    }
+  } else {
+    if (!MmIsBufferOutsideMmValid ((UINTN)CommBuffer, TempCommBufferSize)) {
+      DEBUG ((EFI_D_ERROR, "SmmFtwHandler: SMM communication buffer in SMRAM or overflow!\n"));
+      return EFI_SUCCESS;
+    }
   }
 
   SmmFtwFunctionHeader = (SMM_FTW_COMMUNICATE_FUNCTION_HEADER *)CommBuffer;
@@ -531,11 +575,19 @@ FvbNotificationEvent (
   // Just return to avoid install SMM FaultTolerantWriteProtocol again
   // if SMM Fault Tolerant Write protocol had been installed.
   //
-  Status = gSmst->SmmLocateProtocol (
-                    &gEfiSmmFaultTolerantWriteProtocolGuid,
-                    NULL,
-                    (VOID **) &FtwProtocol
-                    );
+  if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) {
+    Status = gSmst->SmmLocateProtocol (
+                      &gEfiSmmFaultTolerantWriteProtocolGuid,
+                      NULL,
+                      (VOID **) &FtwProtocol
+                      );
+  } else {
+    Status = gMmst->MmLocateProtocol (
+                      &gEfiSmmFaultTolerantWriteProtocolGuid,
+                      NULL,
+                      (VOID **) &FtwProtocol
+                      );
+  }
   if (!EFI_ERROR (Status)) {
     return EFI_SUCCESS;
   }
@@ -551,31 +603,45 @@ FvbNotificationEvent (
   //
   // Install protocol interface
   //
-  Status = gSmst->SmmInstallProtocolInterface (
-                    &mFtwDevice->Handle,
-                    &gEfiSmmFaultTolerantWriteProtocolGuid,
-                    EFI_NATIVE_INTERFACE,
-                    &mFtwDevice->FtwInstance
-                    );
+  if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) {
+    Status = gSmst->SmmInstallProtocolInterface (
+                      &mFtwDevice->Handle,
+                      &gEfiSmmFaultTolerantWriteProtocolGuid,
+                      EFI_NATIVE_INTERFACE,
+                      &mFtwDevice->FtwInstance
+                      );
+  } else {
+    Status = gMmst->MmInstallProtocolInterface (
+                      &mFtwDevice->Handle,
+                      &gEfiSmmFaultTolerantWriteProtocolGuid,
+                      EFI_NATIVE_INTERFACE,
+                      &mFtwDevice->FtwInstance
+                      );
+  }
   ASSERT_EFI_ERROR (Status);
 
   ///
   /// Register SMM FTW SMI handler
   ///
-  Status = gSmst->SmiHandlerRegister (SmmFaultTolerantWriteHandler, &gEfiSmmFaultTolerantWriteProtocolGuid, &SmmFtwHandle);
-  ASSERT_EFI_ERROR (Status);
+  if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) {
+    Status = gSmst->SmiHandlerRegister (SmmFaultTolerantWriteHandler, &gEfiSmmFaultTolerantWriteProtocolGuid, &SmmFtwHandle);
+    ASSERT_EFI_ERROR (Status);
 
-  //
-  // Notify the Ftw wrapper driver SMM Ftw is ready
-  //
-  FtwHandle = NULL;
-  Status = gBS->InstallProtocolInterface (
+    //
+    // Notify the Ftw wrapper driver SMM Ftw is ready
+    //
+    FtwHandle = NULL;
+    Status = gBS->InstallProtocolInterface (
                   &FtwHandle,
                   &gEfiSmmFaultTolerantWriteProtocolGuid,
                   EFI_NATIVE_INTERFACE,
                   NULL
                   );
-  ASSERT_EFI_ERROR (Status);
+    ASSERT_EFI_ERROR (Status);
+  } else {
+    Status = gMmst->MmiHandlerRegister (SmmFaultTolerantWriteHandler, &gEfiSmmFaultTolerantWriteProtocolGuid, &SmmFtwHandle);
+    ASSERT_EFI_ERROR (Status);
+  }
 
   return EFI_SUCCESS;
 }
@@ -655,3 +721,42 @@ SmmFaultTolerantWriteInitialize (
 
   return EFI_SUCCESS;
 }
+
+/**
+  This function is the entry point of the Fault Tolerant Write driver.
+
+  @param[in] ImageHandle        A handle for the image that is initializing this driver
+  @param[in] SystemTable        A pointer to the EFI system table
+
+  @retval EFI_SUCCESS           The initialization finished successfully.
+  @retval EFI_OUT_OF_RESOURCES  Allocate memory error
+  @retval EFI_INVALID_PARAMETER Workspace or Spare block does not exist
+
+**/
+EFI_STATUS
+EFIAPI
+StandaloneMmFaultTolerantWriteInitialize (
+  IN EFI_HANDLE                           ImageHandle,
+  IN EFI_MM_SYSTEM_TABLE                  *SystemTable
+  )
+{
+  EFI_STATUS                              Status;
+
+  //
+  // Allocate private data structure for SMM FTW protocol and do some initialization
+  //
+  Status = InitFtwDevice (&mFtwDevice);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+  Status = gMmst->MmRegisterProtocolNotify (
+                    &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+                    FvbNotificationEvent,
+                    &mFvbRegistration
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  FvbNotificationEvent (NULL, NULL, NULL);
+
+  return EFI_SUCCESS;
+}
diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf
new file mode 100644
index 0000000..615f688
--- /dev/null
+++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf
@@ -0,0 +1,101 @@
+## @file
+#   Fault Tolerant Write Smm Driver.
+#
+#   This driver installs SMM Fault Tolerant Write (FTW) protocol, which provides fault
+#   tolerant write capability in SMM environment for block devices. Its implementation
+#   depends on the full functionality SMM FVB protocol that support read, write/erase
+#   flash access.
+#
+# Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = FaultTolerantWriteMmStandalone
+  MODULE_UNI_FILE                = SmmFaultTolerantWriteDxe.uni
+  FILE_GUID                      = 470CB248-E8AC-473c-BB4F-81069A1FE6FD
+  MODULE_TYPE                    = MM_STANDALONE
+  VERSION_STRING                 = 1.0
+  PI_SPECIFICATION_VERSION       = 0x00010032
+  ENTRY_POINT                    = StandaloneMmFaultTolerantWriteInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  FtwMisc.c
+  UpdateWorkingBlock.c
+  FaultTolerantWrite.c
+  FaultTolerantWriteSmm.c
+  FaultTolerantWrite.h
+  FaultTolerantWriteSmmCommon.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  StandaloneMmPkg/StandaloneMmPkg.dec
+
+[LibraryClasses]
+  MemoryAllocationLib
+  BaseMemoryLib
+  DebugLib
+  PcdLib
+  ReportStatusCodeLib
+  MemLib
+  StandaloneMmDriverEntryPoint
+  BaseLib
+  MmServicesTableLib
+
+[Guids]
+  #
+  # Signature in EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER
+  #
+  ## CONSUMES           ## GUID
+  ## PRODUCES           ## GUID
+  gEdkiiWorkingBlockSignatureGuid
+
+[Protocols]
+  gEfiSmmSwapAddressRangeProtocolGuid | gEfiMdeModulePkgTokenSpaceGuid.PcdFullFtwServiceEnable  ## SOMETIMES_CONSUMES
+  ## NOTIFY
+  ## CONSUMES
+  gEfiSmmFirmwareVolumeBlockProtocolGuid
+  ## PRODUCES
+  ## UNDEFINED # SmiHandlerRegister
+  gEfiSmmFaultTolerantWriteProtocolGuid
+  gEfiSmmEndOfDxeProtocolGuid                      ## CONSUMES
+
+[FeaturePcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFullFtwServiceEnable    ## CONSUMES
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase    ## SOMETIMES_CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64  ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize    ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase      ## SOMETIMES_CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64    ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize      ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStandaloneMmVariableEnabled
+#
+# gBS->CalculateCrc32() is consumed in EntryPoint.
+# PI spec said: When the DXE Foundation is notified that the EFI_RUNTIME_ARCH_PROTOCOL
+# has been installed, then the Boot Service CalculateCrc32() is available.
+# So add gEfiRuntimeArchProtocolGuid Depex here.
+#
+[Depex]
+  TRUE
+  #gEfiSmmFirmwareVolumeBlockProtocolGuid AND gEfiRuntimeArchProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+  SmmFaultTolerantWriteDxeExtra.uni
diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c b/MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c
index 50d3421..9c98e57 100644
--- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c
+++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c
@@ -3,6 +3,7 @@
    Internal functions to operate Working Block Space.
 
 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -57,19 +58,21 @@ InitializeLocalWorkSpaceHeader (
     );
   mWorkingBlockHeader.WriteQueueSize = PcdGet32 (PcdFlashNvStorageFtwWorkingSize) - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER);
 
-  //
-  // Crc is calculated with all the fields except Crc and STATE, so leave them as FTW_ERASED_BYTE.
-  //
+  if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) {
+    //
+    // Crc is calculated with all the fields except Crc and STATE, so leave them as FTW_ERASED_BYTE.
+    //
 
-  //
-  // Calculate the Crc of woking block header
-  //
-  Status = gBS->CalculateCrc32 (
-                  &mWorkingBlockHeader,
-                  sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),
-                  &mWorkingBlockHeader.Crc
-                  );
-  ASSERT_EFI_ERROR (Status);
+    //
+    // Calculate the Crc of woking block header
+    //
+    Status = gBS->CalculateCrc32 (
+                    &mWorkingBlockHeader,
+                    sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),
+                    &mWorkingBlockHeader.Crc
+                    );
+    ASSERT_EFI_ERROR (Status);
+  }
 
   mWorkingBlockHeader.WorkingBlockValid    = FTW_VALID_STATE;
   mWorkingBlockHeader.WorkingBlockInvalid  = FTW_INVALID_STATE;
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 08/13] MdeModulePkg/Variable/RuntimeDxe: adapt for usability with MM Standalone
  2018-12-14 12:13 [PATCH 00/13] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
                   ` (6 preceding siblings ...)
  2018-12-14 12:13 ` [PATCH 07/13] MdeModulePkg/FaultTolerantWriteDxe: allow reusability as a MM driver Jagadeesh Ujja
@ 2018-12-14 12:13 ` Jagadeesh Ujja
  2018-12-14 12:13 ` [PATCH 09/13] MdeModulePkg/Variable/RuntimeDxe: adapt as a MM Standalone driver Jagadeesh Ujja
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 52+ messages in thread
From: Jagadeesh Ujja @ 2018-12-14 12:13 UTC (permalink / raw)
  To: edk2-devel, liming.gao, chao.b.zhang, leif.lindholm,
	ard.biesheuvel

Adapt the VariableSmmRuntimeDxe driver to communicate with a VariableSmm
driver that is implemented as a MM Standalone driver.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
---
 MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf    |  1 +
 MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c   | 31 +++++++++++++-------
 MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf |  3 ++
 3 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
index 868981c..4d768db 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
@@ -131,6 +131,7 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxUserNvVariableSpaceSize           ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdBoottimeReservedNvVariableSpaceSize  ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdReclaimVariableSpaceAtEndOfDxe  ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStandaloneMmVariableEnabled
 
 [FeaturePcd]
   gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics  ## CONSUMES # statistic the information of variable.
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
index 85d655d..1902348 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
@@ -14,6 +14,8 @@
   InitCommunicateBuffer() is really function to check the variable data size.
 
 Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
+
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -179,7 +181,11 @@ SendCommunicateBuffer (
   SMM_VARIABLE_COMMUNICATE_HEADER           *SmmVariableFunctionHeader;
 
   CommSize = DataSize + SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
-  Status = mSmmCommunication->Communicate (mSmmCommunication, mVariableBufferPhysical, &CommSize);
+  if (PcdGetBool (PcdStandaloneMmVariableEnabled)) {
+    Status = mSmmCommunication->Communicate (mSmmCommunication, mVariableBuffer, &CommSize);
+  } else {
+    Status = mSmmCommunication->Communicate (mSmmCommunication, mVariableBufferPhysical, &CommSize);
+  }
   ASSERT_EFI_ERROR (Status);
 
   SmmCommunicateHeader      = (EFI_SMM_COMMUNICATE_HEADER *) mVariableBuffer;
@@ -991,9 +997,11 @@ SmmVariableReady (
 {
   EFI_STATUS                                Status;
 
-  Status = gBS->LocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **)&mSmmVariable);
-  if (EFI_ERROR (Status)) {
-    return;
+  if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) {
+    Status = gBS->LocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **)&mSmmVariable);
+    if (EFI_ERROR (Status)) {
+      return;
+    }
   }
 
   Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &mSmmCommunication);
@@ -1069,13 +1077,14 @@ SmmVariableWriteReady (
 {
   EFI_STATUS                                Status;
   VOID                                      *ProtocolOps;
-
-  //
-  // Check whether the protocol is installed or not.
-  //
-  Status = gBS->LocateProtocol (&gSmmVariableWriteGuid, NULL, (VOID **) &ProtocolOps);
-  if (EFI_ERROR (Status)) {
-    return;
+  if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) {
+    //
+    // Check whether the protocol is installed or not.
+    //
+    Status = gBS->LocateProtocol (&gSmmVariableWriteGuid, NULL, (VOID **) &ProtocolOps);
+    if (EFI_ERROR (Status)) {
+      return;
+    }
   }
 
   //
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
index bd73f7a..c84dd2d 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
@@ -87,6 +87,9 @@
   ## SOMETIMES_CONSUMES   ## Variable:L"dbt"
   gEfiImageSecurityDatabaseGuid
 
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStandaloneMmVariableEnabled
+
 [Depex]
   gEfiSmmCommunicationProtocolGuid
 
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 09/13] MdeModulePkg/Variable/RuntimeDxe: adapt as a MM Standalone driver
  2018-12-14 12:13 [PATCH 00/13] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
                   ` (7 preceding siblings ...)
  2018-12-14 12:13 ` [PATCH 08/13] MdeModulePkg/Variable/RuntimeDxe: adapt for usability with MM Standalone Jagadeesh Ujja
@ 2018-12-14 12:13 ` Jagadeesh Ujja
  2018-12-14 12:13 ` [PATCH 10/13] MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this library Jagadeesh Ujja
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 52+ messages in thread
From: Jagadeesh Ujja @ 2018-12-14 12:13 UTC (permalink / raw)
  To: edk2-devel, liming.gao, chao.b.zhang, leif.lindholm,
	ard.biesheuvel

Adapt the variable runtime dxe driver to be used as a MM_STANDALONE
driver to provide variable storage service in MM Standalone mode.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
---
 MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c               |  37 ++--
 MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c            | 201 ++++++++++++++++----
 MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf | 132 +++++++++++++
 3 files changed, 312 insertions(+), 58 deletions(-)

diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
index d100b1d..e8976c1 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
@@ -18,6 +18,7 @@
 
 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
 (C) Copyright 2015-2018 Hewlett Packard Enterprise Development LP<BR>
+Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -3277,19 +3278,21 @@ VariableServiceSetVariable (
     }
   }
 
-  //
-  // Special Handling for MOR Lock variable.
-  //
-  Status = SetVariableCheckHandlerMor (VariableName, VendorGuid, Attributes, PayloadSize, (VOID *) ((UINTN) Data + DataSize - PayloadSize));
-  if (Status == EFI_ALREADY_STARTED) {
+  if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) {
     //
-    // EFI_ALREADY_STARTED means the SetVariable() action is handled inside of SetVariableCheckHandlerMor().
-    // Variable driver can just return SUCCESS.
+    // Special Handling for MOR Lock variable.
     //
-    return EFI_SUCCESS;
-  }
-  if (EFI_ERROR (Status)) {
-    return Status;
+    Status = SetVariableCheckHandlerMor (VariableName, VendorGuid, Attributes, PayloadSize, (VOID *) ((UINTN) Data + DataSize - PayloadSize));
+    if (Status == EFI_ALREADY_STARTED) {
+      //
+      // EFI_ALREADY_STARTED means the SetVariable() action is handled inside of SetVariableCheckHandlerMor().
+      // Variable driver can just return SUCCESS.
+      //
+      return EFI_SUCCESS;
+    }
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
   }
 
   Status = VarCheckLibSetVariableCheck (VariableName, VendorGuid, Attributes, PayloadSize, (VOID *) ((UINTN) Data + DataSize - PayloadSize), mRequestSource);
@@ -4098,12 +4101,14 @@ VariableWriteServiceInitialize (
     }
   }
 
-  ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+  if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) {
+    ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
 
-  //
-  // Initialize MOR Lock variable.
-  //
-  MorLockInit ();
+    //
+    // Initialize MOR Lock variable.
+    //
+    MorLockInit ();
+  }
 
   return Status;
 }
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
index 6dc19c2..59f3109 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
@@ -15,6 +15,7 @@
   SmmVariableGetStatistics() should also do validation based on its own knowledge.
 
 Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -34,6 +35,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/SmmServicesTableLib.h>
 #include <Library/SmmMemLib.h>
 
+#include <Library/StandaloneMmMemLib.h>
+#include <Library/StandaloneMmServicesTableLib.h>
 #include <Guid/SmmVariableCommon.h>
 #include "Variable.h"
 
@@ -218,11 +221,19 @@ GetFtwProtocol (
   //
   // Locate Smm Fault Tolerent Write protocol
   //
-  Status = gSmst->SmmLocateProtocol (
-                    &gEfiSmmFaultTolerantWriteProtocolGuid,
-                    NULL,
-                    FtwProtocol
-                    );
+  if (PcdGetBool (PcdStandaloneMmVariableEnabled)) {
+    Status = gMmst->MmLocateProtocol (
+                      &gEfiSmmFaultTolerantWriteProtocolGuid,
+                      NULL,
+                      FtwProtocol
+                      );
+  } else {
+    Status = gSmst->SmmLocateProtocol (
+                      &gEfiSmmFaultTolerantWriteProtocolGuid,
+                      NULL,
+                      FtwProtocol
+                      );
+  }
   return Status;
 }
 
@@ -248,11 +259,19 @@ GetFvbByHandle (
   //
   // To get the SMM FVB protocol interface on the handle
   //
-  return gSmst->SmmHandleProtocol (
-                  FvBlockHandle,
-                  &gEfiSmmFirmwareVolumeBlockProtocolGuid,
-                  (VOID **) FvBlock
-                  );
+  if (PcdGetBool (PcdStandaloneMmVariableEnabled)) {
+    return gMmst->MmHandleProtocol (
+                    FvBlockHandle,
+                    &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+                    (VOID **) FvBlock
+                    );
+  } else {
+    return gSmst->SmmHandleProtocol (
+                    FvBlockHandle,
+                    &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+                    (VOID **) FvBlock
+                    );
+  }
 }
 
 
@@ -287,13 +306,23 @@ GetFvbCountAndBuffer (
   BufferSize     = 0;
   *NumberHandles = 0;
   *Buffer        = NULL;
-  Status = gSmst->SmmLocateHandle (
-                    ByProtocol,
-                    &gEfiSmmFirmwareVolumeBlockProtocolGuid,
-                    NULL,
-                    &BufferSize,
-                    *Buffer
-                    );
+  if (PcdGetBool (PcdStandaloneMmVariableEnabled)) {
+    Status = gMmst->MmLocateHandle (
+                      ByProtocol,
+                      &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+                      NULL,
+                      &BufferSize,
+                      *Buffer
+                      );
+  } else {
+    Status = gSmst->SmmLocateHandle (
+                      ByProtocol,
+                      &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+                      NULL,
+                      &BufferSize,
+                      *Buffer
+                      );
+  }
   if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL) {
     return EFI_NOT_FOUND;
   }
@@ -303,14 +332,23 @@ GetFvbCountAndBuffer (
     return EFI_OUT_OF_RESOURCES;
   }
 
-  Status = gSmst->SmmLocateHandle (
-                    ByProtocol,
-                    &gEfiSmmFirmwareVolumeBlockProtocolGuid,
-                    NULL,
-                    &BufferSize,
-                    *Buffer
-                    );
-
+  if (PcdGetBool (PcdStandaloneMmVariableEnabled)) {
+     Status = gMmst->MmLocateHandle (
+                       ByProtocol,
+                       &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+                       NULL,
+                       &BufferSize,
+                       *Buffer
+                       );
+  } else {
+    Status = gSmst->SmmLocateHandle (
+                      ByProtocol,
+                      &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+                      NULL,
+                      &BufferSize,
+                      *Buffer
+                      );
+  }
   *NumberHandles = BufferSize / sizeof(EFI_HANDLE);
   if (EFI_ERROR(Status)) {
     *NumberHandles = 0;
@@ -499,10 +537,16 @@ SmmVariableHandler (
     DEBUG ((EFI_D_ERROR, "SmmVariableHandler: SMM communication buffer payload size invalid!\n"));
     return EFI_SUCCESS;
   }
-
-  if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {
-    DEBUG ((EFI_D_ERROR, "SmmVariableHandler: SMM communication buffer in SMRAM or overflow!\n"));
-    return EFI_SUCCESS;
+  if (PcdGetBool (PcdStandaloneMmVariableEnabled)) {
+    if (!MmIsBufferOutsideMmValid ((UINTN)CommBuffer, TempCommBufferSize)) {
+      DEBUG ((EFI_D_ERROR, "SmmVariableHandler: SMM communication buffer in SMRAM or overflow!\n"));
+      return EFI_SUCCESS;
+    }
+  } else {
+    if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {
+      DEBUG ((EFI_D_ERROR, "SmmVariableHandler: SMM communication buffer in SMRAM or overflow!\n"));
+      return EFI_SUCCESS;
+    }
   }
 
   SmmVariableFunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *)CommBuffer;
@@ -691,13 +735,17 @@ SmmVariableHandler (
         break;
       }
       if (!mEndOfDxe) {
-        MorLockInitAtEndOfDxe ();
-        mEndOfDxe = TRUE;
-        VarCheckLibInitializeAtEndOfDxe (NULL);
-        //
-        // The initialization for variable quota.
-        //
-        InitializeVariableQuota ();
+        if (!PcdGetBool (PcdStandaloneMmVariableEnabled)){
+          MorLockInitAtEndOfDxe ();
+          mEndOfDxe = TRUE;
+          VarCheckLibInitializeAtEndOfDxe (NULL);
+          //
+          // The initialization for variable quota.
+          //
+          InitializeVariableQuota ();
+        } else {
+          mEndOfDxe = TRUE;
+        }
       }
       ReclaimForOS ();
       Status = EFI_SUCCESS;
@@ -911,12 +959,22 @@ SmmFtwNotificationEvent (
   //
   // Notify the variable wrapper driver the variable write service is ready
   //
-  Status = gBS->InstallProtocolInterface (
-                  &mSmmVariableHandle,
-                  &gSmmVariableWriteGuid,
-                  EFI_NATIVE_INTERFACE,
-                  NULL
-                  );
+  if (PcdGetBool (PcdStandaloneMmVariableEnabled)) {
+    Status = gMmst->MmInstallProtocolInterface (
+                      &mSmmVariableHandle,
+                      &gSmmVariableWriteGuid,
+                      EFI_NATIVE_INTERFACE,
+                      NULL
+                      );
+  } else {
+    Status = gBS->InstallProtocolInterface (
+                    &mSmmVariableHandle,
+                    &gSmmVariableWriteGuid,
+                    EFI_NATIVE_INTERFACE,
+                    NULL
+                    );
+  }
+
   ASSERT_EFI_ERROR (Status);
 
   return EFI_SUCCESS;
@@ -1026,4 +1084,63 @@ VariableServiceInitialize (
   return EFI_SUCCESS;
 }
 
+/**
+  Variable Driver main entry point. The Variable driver places the 4 EFI
+  runtime services in the EFI System Table and installs arch protocols
+  for variable read and write services being available. It also registers
+  a notification function for an EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
+
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
+  @param[in] SystemTable    A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS       Variable service successfully initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+StandaloneMmVariableServiceInitialize (
+  IN EFI_HANDLE                           ImageHandle,
+  IN EFI_MM_SYSTEM_TABLE                     *SystemTable
+  )
+{
+  EFI_STATUS                              Status;
+  EFI_HANDLE                              VariableHandle;
+  VOID                                    *SmmFtwRegistration;
+
+  //
+  // Variable initialize.
+  //
+  Status = VariableCommonInitialize ();
+  ASSERT_EFI_ERROR (Status);
+
+  mVariableBufferPayloadSize = GetMaxVariableSize () +
+                               OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name) - GetVariableHeaderSize ();
+
+  Status = gMmst->MmAllocatePool (
+                    EfiRuntimeServicesData,
+                    mVariableBufferPayloadSize,
+                    (VOID **)&mVariableBufferPayload
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Register SMM variable SMI handler
+  ///
+  VariableHandle = NULL;
+  Status = gMmst->MmiHandlerRegister (SmmVariableHandler, &gEfiSmmVariableProtocolGuid, &VariableHandle);
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Register FtwNotificationEvent () notify function.
+  //
+  Status = gMmst->MmRegisterProtocolNotify (
+                    &gEfiSmmFaultTolerantWriteProtocolGuid,
+                    SmmFtwNotificationEvent,
+                    &SmmFtwRegistration
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  SmmFtwNotificationEvent (NULL, NULL, NULL);
+
+  return EFI_SUCCESS;
+}
 
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
new file mode 100644
index 0000000..dde9ea4
--- /dev/null
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
@@ -0,0 +1,132 @@
+## @file
+#  Provides MM variable service.
+#
+#  The whole MM authentication variable design relies on the integrity of flash part and MM.
+#  which is assumed to be protected by platform.  All variable code and metadata in flash/MM Memory
+#  may not be modified without authorization. If platform fails to protect these resources,
+#  the authentication service provided in this driver will be broken, and the behavior is undefined.
+#
+# Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001000A
+  BASE_NAME                      = VariableSmm
+  MODULE_UNI_FILE                = VariableSmm.uni
+  FILE_GUID                      = 23A089B3-EED5-4ac5-B2AB-43E3298C2343
+  MODULE_TYPE                    = MM_STANDALONE
+  VERSION_STRING                 = 1.0
+  PI_SPECIFICATION_VERSION       = 0x00010032
+  ENTRY_POINT                    = StandaloneMmVariableServiceInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  Reclaim.c
+  Variable.c
+  VariableSmm.c
+  VarCheck.c
+  Variable.h
+  PrivilegePolymorphic.h
+  VariableExLib.c
+  TcgMorLockSmm.c
+  LoadFenceSmm.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  StandaloneMmPkg/StandaloneMmPkg.dec
+
+[LibraryClasses]
+  StandaloneMmDriverEntryPoint
+  MemoryAllocationLib
+  BaseLib
+  SynchronizationLib
+  BaseMemoryLib
+  DebugLib
+  HobLib
+  PcdLib
+  AuthVariableLib
+  VarCheckLib
+  MemLib
+  MmServicesTableLib
+
+[Protocols]
+  gEfiSmmFirmwareVolumeBlockProtocolGuid        ## CONSUMES
+  ## CONSUMES
+  ## NOTIFY
+  gEfiSmmFaultTolerantWriteProtocolGuid
+  ## PRODUCES
+  ## UNDEFINED # SmiHandlerRegister
+  gEfiSmmVariableProtocolGuid
+  ##gEfiSmmEndOfDxeProtocolGuid                   ## NOTIFY
+  gEdkiiSmmVarCheckProtocolGuid                 ## PRODUCES
+  gEfiTcgProtocolGuid                           ## SOMETIMES_CONSUMES
+  gEfiTcg2ProtocolGuid                          ## SOMETIMES_CONSUMES
+
+[Guids]
+  ## SOMETIMES_CONSUMES   ## GUID # Signature of Variable store header
+  ## SOMETIMES_PRODUCES   ## GUID # Signature of Variable store header
+  ## SOMETIMES_CONSUMES   ## HOB
+  ## SOMETIMES_PRODUCES   ## SystemTable
+  gEfiAuthenticatedVariableGuid
+
+  ## SOMETIMES_CONSUMES   ## GUID # Signature of Variable store header
+  ## SOMETIMES_PRODUCES   ## GUID # Signature of Variable store header
+  ## SOMETIMES_CONSUMES   ## HOB
+  ## SOMETIMES_PRODUCES   ## SystemTable
+  gEfiVariableGuid
+
+  ## SOMETIMES_CONSUMES   ## Variable:L"PlatformLang"
+  ## SOMETIMES_PRODUCES   ## Variable:L"PlatformLang"
+  ## SOMETIMES_CONSUMES   ## Variable:L"Lang"
+  ## SOMETIMES_PRODUCES   ## Variable:L"Lang"
+  gEfiGlobalVariableGuid
+
+  gEfiMemoryOverwriteControlDataGuid            ## SOMETIMES_CONSUMES   ## Variable:L"MemoryOverwriteRequestControl"
+  gEfiMemoryOverwriteRequestControlLockGuid     ## SOMETIMES_PRODUCES   ## Variable:L"MemoryOverwriteRequestControlLock"
+
+  gSmmVariableWriteGuid                         ## PRODUCES             ## GUID # Install protocol
+  gEfiSystemNvDataFvGuid                        ## CONSUMES             ## GUID
+  gEdkiiFaultTolerantWriteGuid                  ## SOMETIMES_CONSUMES   ## HOB
+
+  ## SOMETIMES_CONSUMES   ## Variable:L"VarErrorFlag"
+  ## SOMETIMES_PRODUCES   ## Variable:L"VarErrorFlag"
+  gEdkiiVarErrorFlagGuid
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize       ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase       ## SOMETIMES_CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64     ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize                  ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize              ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVolatileVariableSize          ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize     ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize                ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize                 ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxUserNvVariableSpaceSize           ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBoottimeReservedNvVariableSpaceSize  ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdReclaimVariableSpaceAtEndOfDxe   ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStandaloneMmVariableEnabled
+
+[FeaturePcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics        ## CONSUMES  # statistic the information of variable.
+  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate       ## CONSUMES  # Auto update PlatformLang/Lang
+
+[Depex]
+  TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+  VariableSmmExtra.uni
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 10/13] MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this library
  2018-12-14 12:13 [PATCH 00/13] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
                   ` (8 preceding siblings ...)
  2018-12-14 12:13 ` [PATCH 09/13] MdeModulePkg/Variable/RuntimeDxe: adapt as a MM Standalone driver Jagadeesh Ujja
@ 2018-12-14 12:13 ` Jagadeesh Ujja
  2019-01-02 13:05   ` Ard Biesheuvel
  2018-12-14 12:13 ` [PATCH 11/13] ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver Jagadeesh Ujja
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 52+ messages in thread
From: Jagadeesh Ujja @ 2018-12-14 12:13 UTC (permalink / raw)
  To: edk2-devel, liming.gao, chao.b.zhang, leif.lindholm,
	ard.biesheuvel

“VarCheckLib” library can be used by MM_STANDALONE drivers as well.
So add MM_STANDALONE as the module type this library supports.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
---
 MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf b/MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
index 099f83d..c8cf810 100644
--- a/MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
+++ b/MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
@@ -2,6 +2,7 @@
 #  Provides variable check services and database management.
 #
 #  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions
@@ -21,12 +22,12 @@
   FILE_GUID                      = 63E12D08-0C5D-47F8-95E4-09F89D7506C5
   MODULE_TYPE                    = DXE_RUNTIME_DRIVER
   VERSION_STRING                 = 1.0
-  LIBRARY_CLASS                  = VarCheckLib|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER
+  LIBRARY_CLASS                  = VarCheckLib|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER MM_STANDALONE
 
 #
 # The following information is for reference only and not required by the build tools.
 #
-#  VALID_ARCHITECTURES           = IA32 X64
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
 #
 
 [Sources]
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 11/13] ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver
  2018-12-14 12:13 [PATCH 00/13] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
                   ` (9 preceding siblings ...)
  2018-12-14 12:13 ` [PATCH 10/13] MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this library Jagadeesh Ujja
@ 2018-12-14 12:13 ` Jagadeesh Ujja
  2018-12-21 11:07   ` Ard Biesheuvel
  2018-12-14 12:13 ` [PATCH 12/13] SecurityPkg/AuthVariableLib: allow MM_STANDALONE drivers to use this library Jagadeesh Ujja
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 52+ messages in thread
From: Jagadeesh Ujja @ 2018-12-14 12:13 UTC (permalink / raw)
  To: edk2-devel, liming.gao, chao.b.zhang, leif.lindholm,
	ard.biesheuvel

Adapt the NorFlashDxe driver to be used as a MM_STANDALONE driver to
allow access to NOR flash for code executing in MM_STANDALONE mode.
This allows storing of EFI variables on NOR flash which is accessible
only via the MM STANDALONE mode software.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
---
 ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c     |   2 +-
 ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c            | 210 ++++++++++++++++----
 ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h            |   5 +-
 ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf          |   2 +
 ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c         |  96 ++++-----
 ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf |  76 +++++++
 6 files changed, 302 insertions(+), 89 deletions(-)

diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c
index 279b77c..4c002c7 100644
--- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c
+++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c
@@ -1,6 +1,6 @@
 /** @file  NorFlashBlockIoDxe.c
 
-  Copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>
+  Copyright (c) 2011-2018, ARM Ltd. All rights reserved.<BR>
 
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c
index af40a4c..9c56010 100644
--- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c
+++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c
@@ -1,6 +1,6 @@
 /** @file  NorFlashDxe.c
 
-  Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+  Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.<BR>
 
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
@@ -138,29 +138,102 @@ NorFlashCreateInstance (
 
   if (SupportFvb) {
     NorFlashFvbInitialize (Instance);
+    if (!InMm ()) {
+        Status = gBS->InstallMultipleProtocolInterfaces (
+                        &Instance->Handle,
+                        &gEfiDevicePathProtocolGuid, &Instance->DevicePath,
+                        &gEfiBlockIoProtocolGuid,  &Instance->BlockIoProtocol,
+                        &gEfiFirmwareVolumeBlockProtocolGuid, &Instance->FvbProtocol,
+                        NULL
+                        );
+        if (EFI_ERROR(Status)) {
+          FreePool (Instance);
+          return Status;
+        }
+    } else {
+      //Install DevicePath Protocol
+      Status = gMmst->MmInstallProtocolInterface (
+                        &Instance->Handle,
+                        &gEfiDevicePathProtocolGuid,
+                        EFI_NATIVE_INTERFACE,
+                        &Instance->DevicePath
+                        );
+      if (EFI_ERROR(Status)) {
+        FreePool (Instance);
+        return Status;
+      }
+      //Install BlockIo Protocol
+      Status = gMmst->MmInstallProtocolInterface (
+                        &Instance->Handle,
+                        &gEfiBlockIoProtocolGuid,
+                        EFI_NATIVE_INTERFACE,
+                        &Instance->BlockIoProtocol
+                        );
+      if (EFI_ERROR(Status)) {
+        FreePool (Instance);
+        return Status;
+      }
 
-    Status = gBS->InstallMultipleProtocolInterfaces (
-                  &Instance->Handle,
-                  &gEfiDevicePathProtocolGuid, &Instance->DevicePath,
-                  &gEfiBlockIoProtocolGuid,  &Instance->BlockIoProtocol,
-                  &gEfiFirmwareVolumeBlockProtocolGuid, &Instance->FvbProtocol,
-                  NULL
-                  );
-    if (EFI_ERROR(Status)) {
-      FreePool (Instance);
-      return Status;
+      //Install FirmwareVolumeBlock Protocol
+      Status = gMmst->MmInstallProtocolInterface (
+                        &Instance->Handle,
+                        &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+                        EFI_NATIVE_INTERFACE,
+                        &Instance->FvbProtocol
+                        );
+      if (EFI_ERROR(Status)) {
+        FreePool (Instance);
+        return Status;
+      }
     }
   } else {
-    Status = gBS->InstallMultipleProtocolInterfaces (
-                    &Instance->Handle,
-                    &gEfiDevicePathProtocolGuid, &Instance->DevicePath,
-                    &gEfiBlockIoProtocolGuid,  &Instance->BlockIoProtocol,
-                    &gEfiDiskIoProtocolGuid, &Instance->DiskIoProtocol,
-                    NULL
-                    );
-    if (EFI_ERROR(Status)) {
-      FreePool (Instance);
-      return Status;
+    if (!InMm ()) {
+      Status = gBS->InstallMultipleProtocolInterfaces (
+                      &Instance->Handle,
+                      &gEfiDevicePathProtocolGuid, &Instance->DevicePath,
+                      &gEfiBlockIoProtocolGuid,  &Instance->BlockIoProtocol,
+                      &gEfiDiskIoProtocolGuid, &Instance->DiskIoProtocol,
+                      NULL
+                      );
+      if (EFI_ERROR(Status)) {
+        FreePool (Instance);
+        return Status;
+      }
+    } else {
+      //Install DevicePath Protocol
+      Status = gMmst->MmInstallProtocolInterface (
+                        &Instance->Handle,
+                        &gEfiDevicePathProtocolGuid,
+                        EFI_NATIVE_INTERFACE,
+                        &Instance->DevicePath
+                        );
+      if (EFI_ERROR(Status)) {
+        FreePool (Instance);
+        return Status;
+      }
+      //Install BlockIo Protocol
+      Status = gMmst->MmInstallProtocolInterface (
+                        &Instance->Handle,
+                        &gEfiBlockIoProtocolGuid,
+                        EFI_NATIVE_INTERFACE,
+                        &Instance->BlockIoProtocol
+                        );
+      if (EFI_ERROR(Status)) {
+        FreePool (Instance);
+        return Status;
+      }
+
+      //Install DiskIO Protocol
+      Status = gMmst->MmInstallProtocolInterface (
+                        &Instance->Handle,
+                        &gEfiDiskIoProtocolGuid,
+                        EFI_NATIVE_INTERFACE,
+                        &Instance->DiskIoProtocol
+                        );
+      if (EFI_ERROR(Status)) {
+        FreePool (Instance);
+        return Status;
+      }
     }
   }
 
@@ -342,13 +415,15 @@ NorFlashUnlockAndEraseSingleBlock (
   UINTN           Index;
   EFI_TPL         OriginalTPL;
 
-  if (!EfiAtRuntime ()) {
-    // Raise TPL to TPL_HIGH to stop anyone from interrupting us.
-    OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
-  } else {
-    // This initialization is only to prevent the compiler to complain about the
-    // use of uninitialized variables
-    OriginalTPL = TPL_HIGH_LEVEL;
+  if (!InMm ()) {
+    if (!EfiAtRuntime ()) {
+      // Raise TPL to TPL_HIGH to stop anyone from interrupting us.
+      OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+    } else {
+      // This initialization is only to prevent the compiler to complain about the
+      // use of uninitialized variables
+      OriginalTPL = TPL_HIGH_LEVEL;
+    }
   }
 
   Index = 0;
@@ -367,9 +442,11 @@ NorFlashUnlockAndEraseSingleBlock (
     DEBUG((EFI_D_ERROR,"EraseSingleBlock(BlockAddress=0x%08x: Block Locked Error (try to erase %d times)\n", BlockAddress,Index));
   }
 
-  if (!EfiAtRuntime ()) {
-    // Interruptions can resume.
-    gBS->RestoreTPL (OriginalTPL);
+  if (!InMm ()) {
+    if (!EfiAtRuntime ()) {
+      // Interruptions can resume.
+      gBS->RestoreTPL (OriginalTPL);
+    }
   }
 
   return Status;
@@ -595,13 +672,15 @@ NorFlashWriteFullBlock (
   // Start writing from the first address at the start of the block
   WordAddress = BlockAddress;
 
-  if (!EfiAtRuntime ()) {
-    // Raise TPL to TPL_HIGH to stop anyone from interrupting us.
-    OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
-  } else {
-    // This initialization is only to prevent the compiler to complain about the
-    // use of uninitialized variables
-    OriginalTPL = TPL_HIGH_LEVEL;
+  if (!InMm ()) {
+    if (!EfiAtRuntime ()) {
+      // Raise TPL to TPL_HIGH to stop anyone from interrupting us.
+      OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+    } else {
+      // This initialization is only to prevent the compiler to complain about the
+      // use of uninitialized variables
+      OriginalTPL = TPL_HIGH_LEVEL;
+    }
   }
 
   Status = NorFlashUnlockAndEraseSingleBlock (Instance, BlockAddress);
@@ -661,9 +740,11 @@ NorFlashWriteFullBlock (
   }
 
 EXIT:
-  if (!EfiAtRuntime ()) {
-    // Interruptions can resume.
-    gBS->RestoreTPL (OriginalTPL);
+  if (!InMm ()) {
+    if (!EfiAtRuntime ()) {
+      // Interruptions can resume.
+      gBS->RestoreTPL (OriginalTPL);
+    }
   }
 
   if (EFI_ERROR(Status)) {
@@ -1334,6 +1415,53 @@ NorFlashInitialise (
                   &mNorFlashVirtualAddrChangeEvent
                   );
   ASSERT_EFI_ERROR (Status);
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+StandaloneMmNorFlashInitialise (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_MM_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS              Status;
+  UINT32                  Index;
+  NOR_FLASH_DESCRIPTION*  NorFlashDevices;
+  BOOLEAN                 ContainVariableStorage;
+
+  Status = NorFlashPlatformInitialization ();
+  if (EFI_ERROR(Status)) {
+    DEBUG((EFI_D_ERROR,"NorFlashInitialise: Fail to initialize Nor Flash devices\n"));
+    return Status;
+  }
+
+  Status = NorFlashPlatformGetDevices (&NorFlashDevices, &mNorFlashDeviceCount);
+  if (EFI_ERROR(Status)) {
+    DEBUG((EFI_D_ERROR,"NorFlashInitialise: Fail to get Nor Flash devices\n"));
+    return Status;
+  }
+
+  mNorFlashInstances = AllocateRuntimePool (sizeof(NOR_FLASH_INSTANCE*) * mNorFlashDeviceCount);
 
+  for (Index = 0; Index < mNorFlashDeviceCount; Index++) {
+    // Check if this NOR Flash device contain the variable storage region
+    ContainVariableStorage =
+        (NorFlashDevices[Index].RegionBaseAddress <= PcdGet32 (PcdFlashNvStorageVariableBase)) &&
+        (PcdGet32 (PcdFlashNvStorageVariableBase) + PcdGet32 (PcdFlashNvStorageVariableSize) <= NorFlashDevices[Index].RegionBaseAddress + NorFlashDevices[Index].Size);
+
+    Status = NorFlashCreateInstance (
+      NorFlashDevices[Index].DeviceBaseAddress,
+      NorFlashDevices[Index].RegionBaseAddress,
+      NorFlashDevices[Index].Size,
+      Index,
+      NorFlashDevices[Index].BlockSize,
+      ContainVariableStorage,
+      &mNorFlashInstances[Index]
+    );
+    if (EFI_ERROR(Status)) {
+      DEBUG((EFI_D_ERROR,"NorFlashInitialise: Fail to create instance for NorFlash[%d]\n",Index));
+    }
+  }
   return Status;
 }
diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h
index c0563f6..90929d3 100644
--- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h
+++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h
@@ -1,6 +1,6 @@
 /** @file  NorFlashDxe.h
 
-  Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+  Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.<BR>
 
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
@@ -19,6 +19,7 @@
 #include <Base.h>
 #include <PiDxe.h>
 
+#include <PiMm.h>
 #include <Guid/EventGroup.h>
 
 #include <Protocol/BlockIo.h>
@@ -30,6 +31,8 @@
 #include <Library/NorFlashPlatformLib.h>
 #include <Library/UefiLib.h>
 #include <Library/UefiRuntimeLib.h>
+#include <Library/StandaloneMmServicesTableLib.h>
+#include <Library/StandaloneMmRuntimeDxe.h>
 
 #define NOR_FLASH_ERASE_RETRY                     10
 
diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
index a59a21a..cbe740e 100644
--- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
+++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
@@ -44,6 +44,7 @@
   UefiBootServicesTableLib
   UefiRuntimeLib
   DxeServicesTableLib
+  StandaloneMmRuntimeDxe
 
 [Guids]
   gEfiSystemNvDataFvGuid
@@ -57,6 +58,7 @@
   gEfiDevicePathProtocolGuid
   gEfiFirmwareVolumeBlockProtocolGuid
   gEfiDiskIoProtocolGuid
+  gEfiSmmFirmwareVolumeBlockProtocolGuid
 
 [Pcd.common]
   gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c
index e62ffbb..e4d7100 100644
--- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c
+++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c
@@ -1,6 +1,6 @@
 /*++ @file  NorFlashFvbDxe.c
 
- Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.<BR>
 
  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
@@ -720,27 +720,29 @@ NorFlashFvbInitialize (
   DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n"));
   ASSERT((Instance != NULL));
 
-  //
-  // Declare the Non-Volatile storage as EFI_MEMORY_RUNTIME
-  //
-
-  // Note: all the NOR Flash region needs to be reserved into the UEFI Runtime memory;
-  //       even if we only use the small block region at the top of the NOR Flash.
-  //       The reason is when the NOR Flash memory is set into program mode, the command
-  //       is written as the base of the flash region (ie: Instance->DeviceBaseAddress)
-  RuntimeMmioRegionSize = (Instance->RegionBaseAddress - Instance->DeviceBaseAddress) + Instance->Size;
-
-  Status = gDS->AddMemorySpace (
-      EfiGcdMemoryTypeMemoryMappedIo,
-      Instance->DeviceBaseAddress, RuntimeMmioRegionSize,
-      EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
-      );
-  ASSERT_EFI_ERROR (Status);
-
-  Status = gDS->SetMemorySpaceAttributes (
-      Instance->DeviceBaseAddress, RuntimeMmioRegionSize,
-      EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);
-  ASSERT_EFI_ERROR (Status);
+  if (!InMm ()) {
+    //
+    // Declare the Non-Volatile storage as EFI_MEMORY_RUNTIME
+    //
+
+    // Note: all the NOR Flash region needs to be reserved into the UEFI Runtime memory;
+    //       even if we only use the small block region at the top of the NOR Flash.
+    //       The reason is when the NOR Flash memory is set into program mode, the command
+    //       is written as the base of the flash region (ie: Instance->DeviceBaseAddress)
+    RuntimeMmioRegionSize = (Instance->RegionBaseAddress - Instance->DeviceBaseAddress) + Instance->Size;
+
+    Status = gDS->AddMemorySpace (
+        EfiGcdMemoryTypeMemoryMappedIo,
+        Instance->DeviceBaseAddress, RuntimeMmioRegionSize,
+        EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
+        );
+    ASSERT_EFI_ERROR (Status);
+
+    Status = gDS->SetMemorySpaceAttributes (
+        Instance->DeviceBaseAddress, RuntimeMmioRegionSize,
+        EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);
+    ASSERT_EFI_ERROR (Status);
+  }
 
   mFlashNvStorageVariableBase = FixedPcdGet32 (PcdFlashNvStorageVariableBase);
 
@@ -777,30 +779,32 @@ NorFlashFvbInitialize (
     }
   }
 
-  //
-  // The driver implementing the variable read service can now be dispatched;
-  // the varstore headers are in place.
-  //
-  Status = gBS->InstallProtocolInterface (
-                  &gImageHandle,
-                  &gEdkiiNvVarStoreFormattedGuid,
-                  EFI_NATIVE_INTERFACE,
-                  NULL
-                  );
-  ASSERT_EFI_ERROR (Status);
-
-  //
-  // Register for the virtual address change event
-  //
-  Status = gBS->CreateEventEx (
-                  EVT_NOTIFY_SIGNAL,
-                  TPL_NOTIFY,
-                  FvbVirtualNotifyEvent,
-                  NULL,
-                  &gEfiEventVirtualAddressChangeGuid,
-                  &mFvbVirtualAddrChangeEvent
-                  );
-  ASSERT_EFI_ERROR (Status);
+  if (!InMm ()) {
+    //
+    // The driver implementing the variable read service can now be dispatched;
+    // the varstore headers are in place.
+    //
+    Status = gBS->InstallProtocolInterface (
+                    &gImageHandle,
+                    &gEdkiiNvVarStoreFormattedGuid,
+                    EFI_NATIVE_INTERFACE,
+                    NULL
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    //
+    // Register for the virtual address change event
+    //
+    Status = gBS->CreateEventEx (
+                    EVT_NOTIFY_SIGNAL,
+                    TPL_NOTIFY,
+                    FvbVirtualNotifyEvent,
+                    NULL,
+                    &gEfiEventVirtualAddressChangeGuid,
+                    &mFvbVirtualAddrChangeEvent
+                    );
+    ASSERT_EFI_ERROR (Status);
+  }
 
   return Status;
 }
diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
new file mode 100644
index 0000000..a6d0581
--- /dev/null
+++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
@@ -0,0 +1,76 @@
+#/** @file
+#
+#  Component description file for NorFlashDxe module
+#
+#  Copyright (c) 2018, ARM Limited. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = StandaloneMmNorFlash
+  FILE_GUID                      = 166F677B-DAC9-4AE4-AD34-2FF2504B0637
+  MODULE_TYPE                    = MM_STANDALONE
+  VERSION_STRING                 = 1.0
+  PI_SPECIFICATION_VERSION       = 0x00010032
+  ENTRY_POINT                    = StandaloneMmNorFlashInitialise
+
+[Sources.common]
+  NorFlashDxe.c
+  NorFlashFvbDxe.c
+  NorFlashBlockIoDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+  StandaloneMmPkg/StandaloneMmPkg.dec
+
+[LibraryClasses]
+  StandaloneMmDriverEntryPoint
+  BaseMemoryLib
+  ArmSvcLib
+  ArmLib
+  IoLib
+  BaseLib
+  DebugLib
+  HobLib
+  MemoryAllocationLib
+  NorFlashPlatformLib
+  MmServicesTableLib
+
+[Guids]
+  gEfiSystemNvDataFvGuid
+  gEfiVariableGuid
+  gEfiAuthenticatedVariableGuid
+  gEfiEventVirtualAddressChangeGuid
+  gEdkiiNvVarStoreFormattedGuid     ## PRODUCES ## PROTOCOL
+
+[Protocols]
+  gEfiBlockIoProtocolGuid
+  gEfiDevicePathProtocolGuid
+  gEfiSmmFirmwareVolumeBlockProtocolGuid
+  gEfiDiskIoProtocolGuid
+
+[Pcd.common]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+
+  gArmPlatformTokenSpaceGuid.PcdNorFlashCheckBlockLocked
+
+[Depex]
+  TRUE
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 12/13] SecurityPkg/AuthVariableLib: allow MM_STANDALONE drivers to use this library
  2018-12-14 12:13 [PATCH 00/13] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
                   ` (10 preceding siblings ...)
  2018-12-14 12:13 ` [PATCH 11/13] ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver Jagadeesh Ujja
@ 2018-12-14 12:13 ` Jagadeesh Ujja
  2019-01-02 13:05   ` Ard Biesheuvel
  2018-12-14 12:13 ` [PATCH 13/13] CryptoPkg/BaseCryptLib: " Jagadeesh Ujja
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 52+ messages in thread
From: Jagadeesh Ujja @ 2018-12-14 12:13 UTC (permalink / raw)
  To: edk2-devel, liming.gao, chao.b.zhang, leif.lindholm,
	ard.biesheuvel

“AuthVariableLib” library can be used by MM_STANDALONE drivers as well.
So add MM_STANDALONE as the module type this library supports.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
Reviewed-by: Chao Zhang <chao.b.zhang@intel.com>
---
 SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
index 572ba4e..4294d3b 100644
--- a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
+++ b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
@@ -2,6 +2,7 @@
 #  Provides authenticated variable services.
 #
 #  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions
@@ -21,12 +22,12 @@
   FILE_GUID                      = B23CF5FB-6FCC-4422-B145-D855DBC05457
   MODULE_TYPE                    = DXE_RUNTIME_DRIVER
   VERSION_STRING                 = 1.0
-  LIBRARY_CLASS                  = AuthVariableLib|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER
+  LIBRARY_CLASS                  = AuthVariableLib|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER MM_STANDALONE
 
 #
 # The following information is for reference only and not required by the build tools.
 #
-#  VALID_ARCHITECTURES           = IA32 X64
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
 #
 
 [Sources]
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 13/13] CryptoPkg/BaseCryptLib: allow MM_STANDALONE drivers to use this library
  2018-12-14 12:13 [PATCH 00/13] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
                   ` (11 preceding siblings ...)
  2018-12-14 12:13 ` [PATCH 12/13] SecurityPkg/AuthVariableLib: allow MM_STANDALONE drivers to use this library Jagadeesh Ujja
@ 2018-12-14 12:13 ` Jagadeesh Ujja
  2018-12-21 10:13   ` Ard Biesheuvel
  2018-12-17  1:45 ` [PATCH 00/13] Extend secure variable service to be usable from Standalone MM Gao, Liming
  2018-12-21  2:57 ` Wang, Jian J
  14 siblings, 1 reply; 52+ messages in thread
From: Jagadeesh Ujja @ 2018-12-14 12:13 UTC (permalink / raw)
  To: edk2-devel, liming.gao, chao.b.zhang, leif.lindholm,
	ard.biesheuvel

“BaseCryptLib” library can be used by MM_STANDALONE drivers as well.
So add MM_STANDALONE as the module type this library supports.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
---
 CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf       |  7 ++++++-
 CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf    |  4 ++++
 CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c | 15 +++++++++------
 3 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
index f29445c..b6ebac5 100644
--- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
@@ -7,6 +7,7 @@
 #  buffer overflow or integer overflow.
 #
 #  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
@@ -24,7 +25,7 @@
   FILE_GUID                      = be3bb803-91b6-4da0-bd91-a8b21c18ca5d
   MODULE_TYPE                    = DXE_DRIVER
   VERSION_STRING                 = 1.0
-  LIBRARY_CLASS                  = BaseCryptLib|DXE_DRIVER DXE_CORE UEFI_APPLICATION UEFI_DRIVER
+  LIBRARY_CLASS                  = BaseCryptLib|DXE_DRIVER DXE_CORE UEFI_APPLICATION UEFI_DRIVER MM_STANDALONE
 
 #
 # The following information is for reference only and not required by the build tools.
@@ -85,6 +86,10 @@
   OpensslLib
   IntrinsicLib
   PrintLib
+  PcdLib
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdStandaloneMmCodeEnabled
 
 #
 # Remove these [BuildOptions] after this library is cleaned up
diff --git a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
index 32628c8..fb16451 100644
--- a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
@@ -91,6 +91,10 @@
   OpensslLib
   IntrinsicLib
   PrintLib
+  PcdLib
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdStandaloneMmCodeEnabled
 
 #
 # Remove these [BuildOptions] after this library is cleaned up
diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c b/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
index 5f9b0c2..de8e756 100644
--- a/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
+++ b/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
@@ -3,6 +3,7 @@
   for OpenSSL-based Cryptographic Library (used in DXE & RUNTIME).
 
 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -77,12 +78,14 @@ time_t time (time_t *timer)
   time_t      CalTime;
   UINTN       Year;
 
-  //
-  // Get the current time and date information
-  //
-  Status = gRT->GetTime (&Time, NULL);
-  if (EFI_ERROR (Status) || (Time.Year < 1970)) {
-    return 0;
+  if (!PcdGetBool (PcdStandaloneMmCodeEnabled)) {
+    //
+    // Get the current time and date information
+    //
+    Status = gRT->GetTime (&Time, NULL);
+    if (EFI_ERROR (Status) || (Time.Year < 1970)) {
+      return 0;
+    }
   }
 
   //
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 52+ messages in thread

* Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
  2018-12-14 12:13 ` [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add AsmLfence function Jagadeesh Ujja
@ 2018-12-14 13:53   ` Ard Biesheuvel
  2018-12-17  2:04     ` Gao, Liming
  0 siblings, 1 reply; 52+ messages in thread
From: Ard Biesheuvel @ 2018-12-14 13:53 UTC (permalink / raw)
  To: Jagadeesh Ujja, Leif Lindholm
  Cc: edk2-devel@lists.01.org, Gao, Liming, Zhang, Chao B

On Fri, 14 Dec 2018 at 13:13, Jagadeesh Ujja <jagadeesh.ujja@arm.com> wrote:
>
> Variable service driver includes a call to AsmLfence. To reuse this
> driver on AArch64 based platforms, add an implementation of AsmLfence
> that acts as a wrapper on the AArch64 specific MemoryFence function.
>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> ---
>  MdePkg/Include/Library/BaseLib.h             | 33 +++++++++------
>  MdePkg/Library/BaseLib/AArch64/AsmLfence.S   | 42 ++++++++++++++++++++
>  MdePkg/Library/BaseLib/AArch64/AsmLfence.asm | 41 +++++++++++++++++++
>  MdePkg/Library/BaseLib/BaseLib.inf           |  2 +
>  4 files changed, 105 insertions(+), 13 deletions(-)
>
> diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
> index 8cc0869..ca961ee 100644
> --- a/MdePkg/Include/Library/BaseLib.h
> +++ b/MdePkg/Include/Library/BaseLib.h
> @@ -7697,19 +7697,6 @@ AsmWriteTr (
>    );
>
>  /**
> -  Performs a serializing operation on all load-from-memory instructions that
> -  were issued prior the AsmLfence function.
> -
> -  Executes a LFENCE instruction. This function is only available on IA-32 and x64.
> -
> -**/
> -VOID
> -EFIAPI
> -AsmLfence (
> -  VOID
> -  );
> -
> -/**
>    Patch the immediate operand of an IA32 or X64 instruction such that the byte,
>    word, dword or qword operand is encoded at the end of the instruction's
>    binary representation.
> @@ -7752,4 +7739,24 @@ PatchInstructionX86 (
>    );
>
>  #endif // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> +
> +#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64)
> +
> +/**
> +  Performs a serializing operation on all load-from-memory instructions that
> +  were issued prior the AsmLfence function.
> +
> +  In case of IA-32 and x64, Executes a LFENCE instruction.
> +
> +  In case of AArch64 this acts as a wrapper on the AArch64
> +  specific MemoryFence function
> +
> +**/
> +VOID
> +EFIAPI
> +AsmLfence (
> +  VOID
> +  );
> +
> +#endif  // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64)
>  #endif // !defined (__BASE_LIB__)
> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.S b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> new file mode 100644
> index 0000000..2fd804b
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> @@ -0,0 +1,42 @@
> +##------------------------------------------------------------------------------
> +#
> +# AsmLfence() for AArch64
> +#
> +# Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> +#
> +# This program and the accompanying materials
> +# are licensed and made available under the terms and conditions of the BSD License
> +# which accompanies this distribution.  The full text of the license may be found at
> +# http://opensource.org/licenses/bsd-license.php.
> +#
> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +#
> +##------------------------------------------------------------------------------
> +
> +.text
> +.p2align 2
> +
> +GCC_ASM_EXPORT(AsmLfence)
> +
> +# IMPORT
> +GCC_ASM_IMPORT(MemoryFence)
> +
> +#/**
> +#  Used to serialize load and store operations.
> +#
> +#  All loads and stores that proceed calls to this function are guaranteed to be
> +#  globally visible when this function returns.
> +#
> +#**/
> +#VOID
> +#EFIAPI
> +#AsmLfence (
> +#  VOID
> +#  );
> +#
> +ASM_PFX(AsmLfence):
> +    stp   x29, x30, [sp, #-16]!
> +    bl MemoryFence
> +    ldp   x29, x30, [sp], #0x10
> +    ret

Any reason we can't simply do

b MemoryFence

here?

Also, why I understand the rationale, I still think it would be better
to change callers of the [x86 specific] AsmLfence() than to introduce
an alias of MemoryFence() for architectures where Lfence is not
defined.

This is not only about tidiness, but also about potentially having
different semantics, which we can't provide in general on ARM, but
only in particular cases [such as the code that is modified in this
series]

In other words, newly introduced occurrences of AsmLfence() now have
to be audited for being appropriate on AArc64 if they are added to
generic code.


> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> new file mode 100644
> index 0000000..7dd5659
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> @@ -0,0 +1,41 @@
> +;------------------------------------------------------------------------------
> +;
> +; AsmLfence() for AArch64
> +;
> +; Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> +;
> +; This program and the accompanying materials
> +; are licensed and made available under the terms and conditions of the BSD License
> +; which accompanies this distribution.  The full text of the license may be found at
> +; http://opensource.org/licenses/bsd-license.php.
> +;
> +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +;
> +;------------------------------------------------------------------------------
> +
> +  EXPORT AsmLfence
> +  AREA BaseLib_LowLevel, CODE, READONLY
> +  # IMPORT
> +  GCC_ASM_IMPORT(MemoryFence)
> +
> +;/**
> +;  Used to serialize load and store operations.
> +;
> +;  All loads and stores that proceed calls to this function are guaranteed to be
> +;  globally visible when this function returns.
> +;
> +;**/
> +;VOID
> +;EFIAPI
> +;AsmLfence (
> +;  VOID
> +;  );
> +;
> +AsmLfence
> +    stp   x29, x30, [sp, #-16]!
> +    bl MemoryFence
> +    ldp   x29, x30, [sp], #0x10
> +    ret
> +
> +  END
> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
> index b84e583..b7d7bcb 100644
> --- a/MdePkg/Library/BaseLib/BaseLib.inf
> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> @@ -585,6 +585,7 @@
>    Math64.c
>
>    AArch64/MemoryFence.S             | GCC
> +  AArch64/AsmLfence.S               | GCC
>    AArch64/SwitchStack.S             | GCC
>    AArch64/EnableInterrupts.S        | GCC
>    AArch64/DisableInterrupts.S       | GCC
> @@ -593,6 +594,7 @@
>    AArch64/CpuBreakpoint.S           | GCC
>
>    AArch64/MemoryFence.asm           | MSFT
> +  AArch64/AsmLfence.asm             | MSFT
>    AArch64/SwitchStack.asm           | MSFT
>    AArch64/EnableInterrupts.asm      | MSFT
>    AArch64/DisableInterrupts.asm     | MSFT
> --
> 2.7.4
>


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 00/13] Extend secure variable service to be usable from Standalone MM
  2018-12-14 12:13 [PATCH 00/13] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
                   ` (12 preceding siblings ...)
  2018-12-14 12:13 ` [PATCH 13/13] CryptoPkg/BaseCryptLib: " Jagadeesh Ujja
@ 2018-12-17  1:45 ` Gao, Liming
  2018-12-17 11:46   ` Jagadeesh Ujja
  2018-12-21  2:57 ` Wang, Jian J
  14 siblings, 1 reply; 52+ messages in thread
From: Gao, Liming @ 2018-12-17  1:45 UTC (permalink / raw)
  To: Jagadeesh Ujja, edk2-devel@lists.01.org, Zhang, Chao B,
	leif.lindholm@linaro.org, ard.biesheuvel@linaro.org

One question here. Why separate StandaloneMmServicesTableLib to two library classes? Current MdePkg\Include\Library\SmmServicesTableLib.h is one library class. MdePkg\Library\SmmServicesTableLib\SmmServicesTableLib.inf is its implementation. StandaloneMmServicesTableLib should be same to it. 
StandaloneMmServicesTableLib is the library class. MdePkg\Library\StandaloneMmRuntimeDxe is its library instance. 

Thanks
Liming
>-----Original Message-----
>From: Jagadeesh Ujja [mailto:jagadeesh.ujja@arm.com]
>Sent: Friday, December 14, 2018 8:13 PM
>To: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>; Zhang,
>Chao B <chao.b.zhang@intel.com>; leif.lindholm@linaro.org;
>ard.biesheuvel@linaro.org
>Subject: [PATCH 00/13] Extend secure variable service to be usable from
>Standalone MM
>
>Changes since RFC v4:
>- Addressed all the comments from Liming Gao
>  - Added an additional PCD 'PcdStandaloneMmCodeEnabled' to indicate
>    presence of StandaloneMM support.
>  - MdePkg.dec file updated to include StandaloneMmServiceTableLib and
>    StandaloneMmRuntimeDxe library.
>  - Platform specific changes will be posted in a seperate patchset.
>  - AsmLfence wrapper function is supported for AArch64 platforms.
>  - All the patches in this series can be pulled from
>    https://github.com/jagadeeshujja/edk2 (branch:
>topics/aarch64_secure_vars)
>
>Changes since RFC v3:
>- Addressed all the comments from Liming Gao
>  - Added a AArch64 implementation of AsmLfence which is a wrapper for
>    MemoryFence. The changes in variable service driver in v3 of this
>    patchset that used MemoryFence instead of AsmLfence have been
>removed.
>  - Added StandaloneMmServicesTableLib.h and StandaloneMmRuntimeDxe
>    library into MdePkg.
>  - Renamed PcdStandaloneMmEnable as PcdStandaloneMmVariableEnabled
>and
>    added to in to MdePkg.
>  - Now with above changes, edk2 packages don't need to depend on
>    StandaloneMmPkg/StandaloneMmPkg.dec
>- Addressed comments from Ting Ye
>  - Removed the hacks in the v3 version.
>  - Will relook into the “TimerWrapp.c” file and add a appropriate
>    implementation of this for MM Standalone mode code.
>
>Changes since RFC v2:
>- Added 'Contributed-under' tag, removed Change-ID tag and
>  maintained a single signed-off-by for the all the patches.
>
>Changes since RFC v1:
>- Addressed all the comments from Liming Gao
>  - Removed the use of #ifdef/#else/#endif and used a Pcd instead to
>    select between MM and non-MM paths.
>  - Removed all dependencies on edk2-platforms.
>  - Dropped the use of mMmst and used gSmst instead.
>  - Added a dummy implementation UefiRuntimeServiceTableLib for
>    MM_STANDALONE usage
>- Replaced all uses of AsmLfence with MemoryFence from variable
>  service code.
>- Add a new StandaloneMmRuntimeDxe library to for use by non-MM code.
>
>This patch series extends the existing secure variable service support for
>use with Standalone MM. This is applicable to paltforms that use Standalone
>Management Mode to protect access to non-volatile memory (NOR flash in
>case
>of these patches) used to store the secure EFI variables.
>
>The first patch pulls in additional libraries from the staging branch of
>StandaloneMmPkg into the edk2's StandaloneMmPkg. The existing secure
>variable
>service implementation supports only the traditional MM mode and so the
>rest
>of the patches extends the existing secure variable service support to be
>useable with Standalone MM mode as well.
>
>Jagadeesh Ujja (13):
>  StandaloneMmPkg: Pull in additonal libraries from staging branch
>  MdePkg: Add a PCD that indicates presence of Standalone MM mode
>  MdeModulePkg: Add a PCD to indicate Standalone MM supports secure
>    variable
>  MdePkg/Include: add StandaloneMmServicesTableLib header file
>  MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
>  MdePkg/Library: Add StandaloneMmRuntimeDxe library
>  MdeModulePkg/FaultTolerantWriteDxe: allow reusability as a MM driver
>  MdeModulePkg/Variable/RuntimeDxe: adapt for usability with MM
>    Standalone
>  MdeModulePkg/Variable/RuntimeDxe: adapt as a MM Standalone driver
>  MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this
>    library
>  ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver
>  SecurityPkg/AuthVariableLib: allow MM_STANDALONE drivers to use this
>    library
>  CryptoPkg/BaseCryptLib: allow MM_STANDALONE drivers to use this
>    library
>
> ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c
>|   2 +-
> ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c                                            |
>210 ++++-
> ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h                                            |
>5 +-
> ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf                                          |
>2 +
> ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c
>|  96 +--
> ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
>|  76 ++
> CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf                                             |   7
>+-
> CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf                                          |   4
>+
> CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c                                       |
>15 +-
> MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf                                            |
>5 +-
> MdeModulePkg/MdeModulePkg.dec                                                               |   5 +
> MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
>|   1 +
> MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
>| 203 +++--
>
>MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandal
>oneMm.inf             | 101 +++
> MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c
>|  27 +-
> MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
>|  37 +-
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
>|   1 +
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
>| 201 ++++-
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
>|  31 +-
>
>MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.i
>nf                        |   3 +
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
>| 132 ++++
> MdePkg/Include/Library/BaseLib.h                                                            |  33 +-
> MdePkg/Include/Library/StandaloneMmRuntimeDxe.h
>|  39 +
> MdePkg/Include/Library/StandaloneMmServicesTableLib.h
>|  25 +
> MdePkg/Library/BaseLib/AArch64/AsmLfence.S                                                  |  42
>+
> MdePkg/Library/BaseLib/AArch64/AsmLfence.asm                                                |
>41 +
> MdePkg/Library/BaseLib/BaseLib.inf                                                          |   2 +
> MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c
>|  36 +
> MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf
>|  36 +
> MdePkg/MdePkg.dec                                                                           |  12 +
> SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf                                     |
>5 +-
>
>StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreH
>obLib.inf                   |   2 +-
>
>StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmC
>oreHobLibInternal.c         |  64 ++
> StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
>| 655 ++++++++++++++++
> StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
>|  48 ++
>
>StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalone
>MmMemoryAllocationLib.c   | 824 ++++++++++++++++++++
>
>StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalone
>MmMemoryAllocationLib.inf |  45 ++
>
>StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmS
>ervicesTableLib.c         |  64 ++
>
>StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmS
>ervicesTableLib.inf       |  36 +
> 39 files changed, 2929 insertions(+), 244 deletions(-)
> create mode 100644
>ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
> create mode 100644
>MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandal
>oneMm.inf
> create mode 100644
>MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
> create mode 100644 MdePkg/Include/Library/StandaloneMmRuntimeDxe.h
> create mode 100644
>MdePkg/Include/Library/StandaloneMmServicesTableLib.h
> create mode 100644 MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> create mode 100644 MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> create mode 100644
>MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c
> create mode 100644
>MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf
> create mode 100644
>StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmC
>oreHobLibInternal.c
> create mode 100644
>StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
> create mode 100644
>StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
> create mode 100644
>StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalone
>MmMemoryAllocationLib.c
> create mode 100644
>StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalone
>MmMemoryAllocationLib.inf
> create mode 100644
>StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmS
>ervicesTableLib.c
> create mode 100644
>StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmS
>ervicesTableLib.inf
>
>--
>2.7.4


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
  2018-12-14 13:53   ` Ard Biesheuvel
@ 2018-12-17  2:04     ` Gao, Liming
  2018-12-17  3:29       ` Yao, Jiewen
  0 siblings, 1 reply; 52+ messages in thread
From: Gao, Liming @ 2018-12-17  2:04 UTC (permalink / raw)
  To: Ard Biesheuvel, Jagadeesh Ujja, Leif Lindholm
  Cc: edk2-devel@lists.01.org, Zhang, Chao B

Ard:
  My first comment is to suggest updating the caller code for the arch specific code.  But, there are two drivers that have the same usage. This way will introduce the duplicated code logic. So, I suggest another way to extend  AsmLfence() API scope for the different ARCHs. If you think it brings the confuse, I just think another way to resolve this case in the caller code. 

#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
AsmLfence();
#else
MemoryFence()
#endif

Thanks
Liming
>-----Original Message-----
>From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
>Sent: Friday, December 14, 2018 9:54 PM
>To: Jagadeesh Ujja <jagadeesh.ujja@arm.com>; Leif Lindholm
><leif.lindholm@linaro.org>
>Cc: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>; Zhang,
>Chao B <chao.b.zhang@intel.com>
>Subject: Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
>AsmLfence function
>
>On Fri, 14 Dec 2018 at 13:13, Jagadeesh Ujja <jagadeesh.ujja@arm.com>
>wrote:
>>
>> Variable service driver includes a call to AsmLfence. To reuse this
>> driver on AArch64 based platforms, add an implementation of AsmLfence
>> that acts as a wrapper on the AArch64 specific MemoryFence function.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.1
>> Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
>> ---
>>  MdePkg/Include/Library/BaseLib.h             | 33 +++++++++------
>>  MdePkg/Library/BaseLib/AArch64/AsmLfence.S   | 42
>++++++++++++++++++++
>>  MdePkg/Library/BaseLib/AArch64/AsmLfence.asm | 41
>+++++++++++++++++++
>>  MdePkg/Library/BaseLib/BaseLib.inf           |  2 +
>>  4 files changed, 105 insertions(+), 13 deletions(-)
>>
>> diff --git a/MdePkg/Include/Library/BaseLib.h
>b/MdePkg/Include/Library/BaseLib.h
>> index 8cc0869..ca961ee 100644
>> --- a/MdePkg/Include/Library/BaseLib.h
>> +++ b/MdePkg/Include/Library/BaseLib.h
>> @@ -7697,19 +7697,6 @@ AsmWriteTr (
>>    );
>>
>>  /**
>> -  Performs a serializing operation on all load-from-memory instructions that
>> -  were issued prior the AsmLfence function.
>> -
>> -  Executes a LFENCE instruction. This function is only available on IA-32 and
>x64.
>> -
>> -**/
>> -VOID
>> -EFIAPI
>> -AsmLfence (
>> -  VOID
>> -  );
>> -
>> -/**
>>    Patch the immediate operand of an IA32 or X64 instruction such that the
>byte,
>>    word, dword or qword operand is encoded at the end of the instruction's
>>    binary representation.
>> @@ -7752,4 +7739,24 @@ PatchInstructionX86 (
>>    );
>>
>>  #endif // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
>> +
>> +#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) || defined
>(MDE_CPU_AARCH64)
>> +
>> +/**
>> +  Performs a serializing operation on all load-from-memory instructions that
>> +  were issued prior the AsmLfence function.
>> +
>> +  In case of IA-32 and x64, Executes a LFENCE instruction.
>> +
>> +  In case of AArch64 this acts as a wrapper on the AArch64
>> +  specific MemoryFence function
>> +
>> +**/
>> +VOID
>> +EFIAPI
>> +AsmLfence (
>> +  VOID
>> +  );
>> +
>> +#endif  // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) ||
>defined (MDE_CPU_AARCH64)
>>  #endif // !defined (__BASE_LIB__)
>> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
>b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
>> new file mode 100644
>> index 0000000..2fd804b
>> --- /dev/null
>> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
>> @@ -0,0 +1,42 @@
>> +##------------------------------------------------------------------------------
>> +#
>> +# AsmLfence() for AArch64
>> +#
>> +# Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
>> +#
>> +# This program and the accompanying materials
>> +# are licensed and made available under the terms and conditions of the
>BSD License
>> +# which accompanies this distribution.  The full text of the license may be
>found at
>> +# http://opensource.org/licenses/bsd-license.php.
>> +#
>> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
>BASIS,
>> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
>EXPRESS OR IMPLIED.
>> +#
>> +##------------------------------------------------------------------------------
>> +
>> +.text
>> +.p2align 2
>> +
>> +GCC_ASM_EXPORT(AsmLfence)
>> +
>> +# IMPORT
>> +GCC_ASM_IMPORT(MemoryFence)
>> +
>> +#/**
>> +#  Used to serialize load and store operations.
>> +#
>> +#  All loads and stores that proceed calls to this function are guaranteed to
>be
>> +#  globally visible when this function returns.
>> +#
>> +#**/
>> +#VOID
>> +#EFIAPI
>> +#AsmLfence (
>> +#  VOID
>> +#  );
>> +#
>> +ASM_PFX(AsmLfence):
>> +    stp   x29, x30, [sp, #-16]!
>> +    bl MemoryFence
>> +    ldp   x29, x30, [sp], #0x10
>> +    ret
>
>Any reason we can't simply do
>
>b MemoryFence
>
>here?
>
>Also, why I understand the rationale, I still think it would be better
>to change callers of the [x86 specific] AsmLfence() than to introduce
>an alias of MemoryFence() for architectures where Lfence is not
>defined.
>
>This is not only about tidiness, but also about potentially having
>different semantics, which we can't provide in general on ARM, but
>only in particular cases [such as the code that is modified in this
>series]
>
>In other words, newly introduced occurrences of AsmLfence() now have
>to be audited for being appropriate on AArc64 if they are added to
>generic code.
>
>
>> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
>b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
>> new file mode 100644
>> index 0000000..7dd5659
>> --- /dev/null
>> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
>> @@ -0,0 +1,41 @@
>> +;------------------------------------------------------------------------------
>> +;
>> +; AsmLfence() for AArch64
>> +;
>> +; Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
>> +;
>> +; This program and the accompanying materials
>> +; are licensed and made available under the terms and conditions of the
>BSD License
>> +; which accompanies this distribution.  The full text of the license may be
>found at
>> +; http://opensource.org/licenses/bsd-license.php.
>> +;
>> +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
>BASIS,
>> +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
>EXPRESS OR IMPLIED.
>> +;
>> +;------------------------------------------------------------------------------
>> +
>> +  EXPORT AsmLfence
>> +  AREA BaseLib_LowLevel, CODE, READONLY
>> +  # IMPORT
>> +  GCC_ASM_IMPORT(MemoryFence)
>> +
>> +;/**
>> +;  Used to serialize load and store operations.
>> +;
>> +;  All loads and stores that proceed calls to this function are guaranteed to
>be
>> +;  globally visible when this function returns.
>> +;
>> +;**/
>> +;VOID
>> +;EFIAPI
>> +;AsmLfence (
>> +;  VOID
>> +;  );
>> +;
>> +AsmLfence
>> +    stp   x29, x30, [sp, #-16]!
>> +    bl MemoryFence
>> +    ldp   x29, x30, [sp], #0x10
>> +    ret
>> +
>> +  END
>> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
>b/MdePkg/Library/BaseLib/BaseLib.inf
>> index b84e583..b7d7bcb 100644
>> --- a/MdePkg/Library/BaseLib/BaseLib.inf
>> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
>> @@ -585,6 +585,7 @@
>>    Math64.c
>>
>>    AArch64/MemoryFence.S             | GCC
>> +  AArch64/AsmLfence.S               | GCC
>>    AArch64/SwitchStack.S             | GCC
>>    AArch64/EnableInterrupts.S        | GCC
>>    AArch64/DisableInterrupts.S       | GCC
>> @@ -593,6 +594,7 @@
>>    AArch64/CpuBreakpoint.S           | GCC
>>
>>    AArch64/MemoryFence.asm           | MSFT
>> +  AArch64/AsmLfence.asm             | MSFT
>>    AArch64/SwitchStack.asm           | MSFT
>>    AArch64/EnableInterrupts.asm      | MSFT
>>    AArch64/DisableInterrupts.asm     | MSFT
>> --
>> 2.7.4
>>

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
  2018-12-17  2:04     ` Gao, Liming
@ 2018-12-17  3:29       ` Yao, Jiewen
  2018-12-17  7:45         ` Ard Biesheuvel
  0 siblings, 1 reply; 52+ messages in thread
From: Yao, Jiewen @ 2018-12-17  3:29 UTC (permalink / raw)
  To: Gao, Liming, Ard Biesheuvel, Jagadeesh Ujja, Leif Lindholm
  Cc: edk2-devel@lists.01.org, Zhang, Chao B

I think we have below definition.
-- MemoryFence: Serialize load and store operations.
-- LoadFence: Serialize load operations.
-- StoreFence: Serialize store operations.

According to IA32 SDM, Intel has MFENCE, LFENCE and SFENCE.
If ARM only has DMB, it is possible to use DMB for MemoryFence, LoadFence or StoreFence.

Maybe it is better to use LoadFence, instead of AsmLFence?
Then we can align with MemoryFence.

Thank you
Yao Jiewen


> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Gao, Liming
> Sent: Monday, December 17, 2018 10:04 AM
> To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Jagadeesh Ujja
> <jagadeesh.ujja@arm.com>; Leif Lindholm <leif.lindholm@linaro.org>
> Cc: edk2-devel@lists.01.org; Zhang, Chao B <chao.b.zhang@intel.com>
> Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> AsmLfence function
> 
> Ard:
>   My first comment is to suggest updating the caller code for the arch
> specific code.  But, there are two drivers that have the same usage. This
> way will introduce the duplicated code logic. So, I suggest another way to
> extend  AsmLfence() API scope for the different ARCHs. If you think it brings
> the confuse, I just think another way to resolve this case in the caller code.
> 
> #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> AsmLfence();
> #else
> MemoryFence()
> #endif
> 
> Thanks
> Liming
> >-----Original Message-----
> >From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> >Sent: Friday, December 14, 2018 9:54 PM
> >To: Jagadeesh Ujja <jagadeesh.ujja@arm.com>; Leif Lindholm
> ><leif.lindholm@linaro.org>
> >Cc: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>; Zhang,
> >Chao B <chao.b.zhang@intel.com>
> >Subject: Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> >AsmLfence function
> >
> >On Fri, 14 Dec 2018 at 13:13, Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> >wrote:
> >>
> >> Variable service driver includes a call to AsmLfence. To reuse this
> >> driver on AArch64 based platforms, add an implementation of AsmLfence
> >> that acts as a wrapper on the AArch64 specific MemoryFence function.
> >>
> >> Contributed-under: TianoCore Contribution Agreement 1.1
> >> Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> >> ---
> >>  MdePkg/Include/Library/BaseLib.h             | 33 +++++++++------
> >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.S   | 42
> >++++++++++++++++++++
> >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.asm | 41
> >+++++++++++++++++++
> >>  MdePkg/Library/BaseLib/BaseLib.inf           |  2 +
> >>  4 files changed, 105 insertions(+), 13 deletions(-)
> >>
> >> diff --git a/MdePkg/Include/Library/BaseLib.h
> >b/MdePkg/Include/Library/BaseLib.h
> >> index 8cc0869..ca961ee 100644
> >> --- a/MdePkg/Include/Library/BaseLib.h
> >> +++ b/MdePkg/Include/Library/BaseLib.h
> >> @@ -7697,19 +7697,6 @@ AsmWriteTr (
> >>    );
> >>
> >>  /**
> >> -  Performs a serializing operation on all load-from-memory instructions
> that
> >> -  were issued prior the AsmLfence function.
> >> -
> >> -  Executes a LFENCE instruction. This function is only available on IA-32
> and
> >x64.
> >> -
> >> -**/
> >> -VOID
> >> -EFIAPI
> >> -AsmLfence (
> >> -  VOID
> >> -  );
> >> -
> >> -/**
> >>    Patch the immediate operand of an IA32 or X64 instruction such that
> the
> >byte,
> >>    word, dword or qword operand is encoded at the end of the
> instruction's
> >>    binary representation.
> >> @@ -7752,4 +7739,24 @@ PatchInstructionX86 (
> >>    );
> >>
> >>  #endif // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> >> +
> >> +#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) || defined
> >(MDE_CPU_AARCH64)
> >> +
> >> +/**
> >> +  Performs a serializing operation on all load-from-memory instructions
> that
> >> +  were issued prior the AsmLfence function.
> >> +
> >> +  In case of IA-32 and x64, Executes a LFENCE instruction.
> >> +
> >> +  In case of AArch64 this acts as a wrapper on the AArch64
> >> +  specific MemoryFence function
> >> +
> >> +**/
> >> +VOID
> >> +EFIAPI
> >> +AsmLfence (
> >> +  VOID
> >> +  );
> >> +
> >> +#endif  // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) ||
> >defined (MDE_CPU_AARCH64)
> >>  #endif // !defined (__BASE_LIB__)
> >> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> >> new file mode 100644
> >> index 0000000..2fd804b
> >> --- /dev/null
> >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> >> @@ -0,0 +1,42 @@
> >> +##------------------------------------------------------------------------------
> >> +#
> >> +# AsmLfence() for AArch64
> >> +#
> >> +# Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> >> +#
> >> +# This program and the accompanying materials
> >> +# are licensed and made available under the terms and conditions of the
> >BSD License
> >> +# which accompanies this distribution.  The full text of the license may
> be
> >found at
> >> +# http://opensource.org/licenses/bsd-license.php.
> >> +#
> >> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS
> IS"
> >BASIS,
> >> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> >EXPRESS OR IMPLIED.
> >> +#
> >> +##------------------------------------------------------------------------------
> >> +
> >> +.text
> >> +.p2align 2
> >> +
> >> +GCC_ASM_EXPORT(AsmLfence)
> >> +
> >> +# IMPORT
> >> +GCC_ASM_IMPORT(MemoryFence)
> >> +
> >> +#/**
> >> +#  Used to serialize load and store operations.
> >> +#
> >> +#  All loads and stores that proceed calls to this function are
> guaranteed to
> >be
> >> +#  globally visible when this function returns.
> >> +#
> >> +#**/
> >> +#VOID
> >> +#EFIAPI
> >> +#AsmLfence (
> >> +#  VOID
> >> +#  );
> >> +#
> >> +ASM_PFX(AsmLfence):
> >> +    stp   x29, x30, [sp, #-16]!
> >> +    bl MemoryFence
> >> +    ldp   x29, x30, [sp], #0x10
> >> +    ret
> >
> >Any reason we can't simply do
> >
> >b MemoryFence
> >
> >here?
> >
> >Also, why I understand the rationale, I still think it would be better
> >to change callers of the [x86 specific] AsmLfence() than to introduce
> >an alias of MemoryFence() for architectures where Lfence is not
> >defined.
> >
> >This is not only about tidiness, but also about potentially having
> >different semantics, which we can't provide in general on ARM, but
> >only in particular cases [such as the code that is modified in this
> >series]
> >
> >In other words, newly introduced occurrences of AsmLfence() now have
> >to be audited for being appropriate on AArc64 if they are added to
> >generic code.
> >
> >
> >> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> >> new file mode 100644
> >> index 0000000..7dd5659
> >> --- /dev/null
> >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> >> @@ -0,0 +1,41 @@
> >> +;------------------------------------------------------------------------------
> >> +;
> >> +; AsmLfence() for AArch64
> >> +;
> >> +; Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> >> +;
> >> +; This program and the accompanying materials
> >> +; are licensed and made available under the terms and conditions of the
> >BSD License
> >> +; which accompanies this distribution.  The full text of the license may
> be
> >found at
> >> +; http://opensource.org/licenses/bsd-license.php.
> >> +;
> >> +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS
> IS"
> >BASIS,
> >> +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> >EXPRESS OR IMPLIED.
> >> +;
> >> +;------------------------------------------------------------------------------
> >> +
> >> +  EXPORT AsmLfence
> >> +  AREA BaseLib_LowLevel, CODE, READONLY
> >> +  # IMPORT
> >> +  GCC_ASM_IMPORT(MemoryFence)
> >> +
> >> +;/**
> >> +;  Used to serialize load and store operations.
> >> +;
> >> +;  All loads and stores that proceed calls to this function are guaranteed
> to
> >be
> >> +;  globally visible when this function returns.
> >> +;
> >> +;**/
> >> +;VOID
> >> +;EFIAPI
> >> +;AsmLfence (
> >> +;  VOID
> >> +;  );
> >> +;
> >> +AsmLfence
> >> +    stp   x29, x30, [sp, #-16]!
> >> +    bl MemoryFence
> >> +    ldp   x29, x30, [sp], #0x10
> >> +    ret
> >> +
> >> +  END
> >> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
> >b/MdePkg/Library/BaseLib/BaseLib.inf
> >> index b84e583..b7d7bcb 100644
> >> --- a/MdePkg/Library/BaseLib/BaseLib.inf
> >> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> >> @@ -585,6 +585,7 @@
> >>    Math64.c
> >>
> >>    AArch64/MemoryFence.S             | GCC
> >> +  AArch64/AsmLfence.S               | GCC
> >>    AArch64/SwitchStack.S             | GCC
> >>    AArch64/EnableInterrupts.S        | GCC
> >>    AArch64/DisableInterrupts.S       | GCC
> >> @@ -593,6 +594,7 @@
> >>    AArch64/CpuBreakpoint.S           | GCC
> >>
> >>    AArch64/MemoryFence.asm           | MSFT
> >> +  AArch64/AsmLfence.asm             | MSFT
> >>    AArch64/SwitchStack.asm           | MSFT
> >>    AArch64/EnableInterrupts.asm      | MSFT
> >>    AArch64/DisableInterrupts.asm     | MSFT
> >> --
> >> 2.7.4
> >>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
  2018-12-17  3:29       ` Yao, Jiewen
@ 2018-12-17  7:45         ` Ard Biesheuvel
  2018-12-17  8:10           ` Ard Biesheuvel
  0 siblings, 1 reply; 52+ messages in thread
From: Ard Biesheuvel @ 2018-12-17  7:45 UTC (permalink / raw)
  To: Yao, Jiewen, Leif Lindholm
  Cc: Gao, Liming, Jagadeesh Ujja, edk2-devel@lists.01.org,
	Zhang, Chao B

On Mon, 17 Dec 2018 at 04:29, Yao, Jiewen <jiewen.yao@intel.com> wrote:
>
> I think we have below definition.
> -- MemoryFence: Serialize load and store operations.
> -- LoadFence: Serialize load operations.
> -- StoreFence: Serialize store operations.
>
> According to IA32 SDM, Intel has MFENCE, LFENCE and SFENCE.
> If ARM only has DMB, it is possible to use DMB for MemoryFence, LoadFence or StoreFence.
>
> Maybe it is better to use LoadFence, instead of AsmLFence?
> Then we can align with MemoryFence.
>

I think using AsmLfence() all over the code to limit speculation was a
mistake, and I am disappointed nobody from the ARM side was involved
at all when these changes were proposed.

The code changes rely on specific semantics of the x86 Lfence
instructions, i.e., that beyond load serialization, they ensure that
all instructions (not just loads) complete before the lfence
completes. This is a much stronger notion than a load barrier, and so
the abstraction should have been defined as something like a
ExecFence() or pipeline barrier etc, and the x86 specific
implementation would have been mapped onto Lfence. For the ARM side,
we probably need an ISB instruction here as well as some kind of other
barrier. Calling it LoadFence() makes no sense whatsoever.





>
> > -----Original Message-----
> > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> > Gao, Liming
> > Sent: Monday, December 17, 2018 10:04 AM
> > To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Jagadeesh Ujja
> > <jagadeesh.ujja@arm.com>; Leif Lindholm <leif.lindholm@linaro.org>
> > Cc: edk2-devel@lists.01.org; Zhang, Chao B <chao.b.zhang@intel.com>
> > Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> > AsmLfence function
> >
> > Ard:
> >   My first comment is to suggest updating the caller code for the arch
> > specific code.  But, there are two drivers that have the same usage. This
> > way will introduce the duplicated code logic. So, I suggest another way to
> > extend  AsmLfence() API scope for the different ARCHs. If you think it brings
> > the confuse, I just think another way to resolve this case in the caller code.
> >
> > #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> > AsmLfence();
> > #else
> > MemoryFence()
> > #endif
> >
> > Thanks
> > Liming
> > >-----Original Message-----
> > >From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> > >Sent: Friday, December 14, 2018 9:54 PM
> > >To: Jagadeesh Ujja <jagadeesh.ujja@arm.com>; Leif Lindholm
> > ><leif.lindholm@linaro.org>
> > >Cc: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>; Zhang,
> > >Chao B <chao.b.zhang@intel.com>
> > >Subject: Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> > >AsmLfence function
> > >
> > >On Fri, 14 Dec 2018 at 13:13, Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> > >wrote:
> > >>
> > >> Variable service driver includes a call to AsmLfence. To reuse this
> > >> driver on AArch64 based platforms, add an implementation of AsmLfence
> > >> that acts as a wrapper on the AArch64 specific MemoryFence function.
> > >>
> > >> Contributed-under: TianoCore Contribution Agreement 1.1
> > >> Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> > >> ---
> > >>  MdePkg/Include/Library/BaseLib.h             | 33 +++++++++------
> > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.S   | 42
> > >++++++++++++++++++++
> > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.asm | 41
> > >+++++++++++++++++++
> > >>  MdePkg/Library/BaseLib/BaseLib.inf           |  2 +
> > >>  4 files changed, 105 insertions(+), 13 deletions(-)
> > >>
> > >> diff --git a/MdePkg/Include/Library/BaseLib.h
> > >b/MdePkg/Include/Library/BaseLib.h
> > >> index 8cc0869..ca961ee 100644
> > >> --- a/MdePkg/Include/Library/BaseLib.h
> > >> +++ b/MdePkg/Include/Library/BaseLib.h
> > >> @@ -7697,19 +7697,6 @@ AsmWriteTr (
> > >>    );
> > >>
> > >>  /**
> > >> -  Performs a serializing operation on all load-from-memory instructions
> > that
> > >> -  were issued prior the AsmLfence function.
> > >> -
> > >> -  Executes a LFENCE instruction. This function is only available on IA-32
> > and
> > >x64.
> > >> -
> > >> -**/
> > >> -VOID
> > >> -EFIAPI
> > >> -AsmLfence (
> > >> -  VOID
> > >> -  );
> > >> -
> > >> -/**
> > >>    Patch the immediate operand of an IA32 or X64 instruction such that
> > the
> > >byte,
> > >>    word, dword or qword operand is encoded at the end of the
> > instruction's
> > >>    binary representation.
> > >> @@ -7752,4 +7739,24 @@ PatchInstructionX86 (
> > >>    );
> > >>
> > >>  #endif // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> > >> +
> > >> +#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) || defined
> > >(MDE_CPU_AARCH64)
> > >> +
> > >> +/**
> > >> +  Performs a serializing operation on all load-from-memory instructions
> > that
> > >> +  were issued prior the AsmLfence function.
> > >> +
> > >> +  In case of IA-32 and x64, Executes a LFENCE instruction.
> > >> +
> > >> +  In case of AArch64 this acts as a wrapper on the AArch64
> > >> +  specific MemoryFence function
> > >> +
> > >> +**/
> > >> +VOID
> > >> +EFIAPI
> > >> +AsmLfence (
> > >> +  VOID
> > >> +  );
> > >> +
> > >> +#endif  // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) ||
> > >defined (MDE_CPU_AARCH64)
> > >>  #endif // !defined (__BASE_LIB__)
> > >> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > >> new file mode 100644
> > >> index 0000000..2fd804b
> > >> --- /dev/null
> > >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > >> @@ -0,0 +1,42 @@
> > >> +##------------------------------------------------------------------------------
> > >> +#
> > >> +# AsmLfence() for AArch64
> > >> +#
> > >> +# Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> > >> +#
> > >> +# This program and the accompanying materials
> > >> +# are licensed and made available under the terms and conditions of the
> > >BSD License
> > >> +# which accompanies this distribution.  The full text of the license may
> > be
> > >found at
> > >> +# http://opensource.org/licenses/bsd-license.php.
> > >> +#
> > >> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS
> > IS"
> > >BASIS,
> > >> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> > >EXPRESS OR IMPLIED.
> > >> +#
> > >> +##------------------------------------------------------------------------------
> > >> +
> > >> +.text
> > >> +.p2align 2
> > >> +
> > >> +GCC_ASM_EXPORT(AsmLfence)
> > >> +
> > >> +# IMPORT
> > >> +GCC_ASM_IMPORT(MemoryFence)
> > >> +
> > >> +#/**
> > >> +#  Used to serialize load and store operations.
> > >> +#
> > >> +#  All loads and stores that proceed calls to this function are
> > guaranteed to
> > >be
> > >> +#  globally visible when this function returns.
> > >> +#
> > >> +#**/
> > >> +#VOID
> > >> +#EFIAPI
> > >> +#AsmLfence (
> > >> +#  VOID
> > >> +#  );
> > >> +#
> > >> +ASM_PFX(AsmLfence):
> > >> +    stp   x29, x30, [sp, #-16]!
> > >> +    bl MemoryFence
> > >> +    ldp   x29, x30, [sp], #0x10
> > >> +    ret
> > >
> > >Any reason we can't simply do
> > >
> > >b MemoryFence
> > >
> > >here?
> > >
> > >Also, why I understand the rationale, I still think it would be better
> > >to change callers of the [x86 specific] AsmLfence() than to introduce
> > >an alias of MemoryFence() for architectures where Lfence is not
> > >defined.
> > >
> > >This is not only about tidiness, but also about potentially having
> > >different semantics, which we can't provide in general on ARM, but
> > >only in particular cases [such as the code that is modified in this
> > >series]
> > >
> > >In other words, newly introduced occurrences of AsmLfence() now have
> > >to be audited for being appropriate on AArc64 if they are added to
> > >generic code.
> > >
> > >
> > >> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > >> new file mode 100644
> > >> index 0000000..7dd5659
> > >> --- /dev/null
> > >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > >> @@ -0,0 +1,41 @@
> > >> +;------------------------------------------------------------------------------
> > >> +;
> > >> +; AsmLfence() for AArch64
> > >> +;
> > >> +; Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> > >> +;
> > >> +; This program and the accompanying materials
> > >> +; are licensed and made available under the terms and conditions of the
> > >BSD License
> > >> +; which accompanies this distribution.  The full text of the license may
> > be
> > >found at
> > >> +; http://opensource.org/licenses/bsd-license.php.
> > >> +;
> > >> +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS
> > IS"
> > >BASIS,
> > >> +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> > >EXPRESS OR IMPLIED.
> > >> +;
> > >> +;------------------------------------------------------------------------------
> > >> +
> > >> +  EXPORT AsmLfence
> > >> +  AREA BaseLib_LowLevel, CODE, READONLY
> > >> +  # IMPORT
> > >> +  GCC_ASM_IMPORT(MemoryFence)
> > >> +
> > >> +;/**
> > >> +;  Used to serialize load and store operations.
> > >> +;
> > >> +;  All loads and stores that proceed calls to this function are guaranteed
> > to
> > >be
> > >> +;  globally visible when this function returns.
> > >> +;
> > >> +;**/
> > >> +;VOID
> > >> +;EFIAPI
> > >> +;AsmLfence (
> > >> +;  VOID
> > >> +;  );
> > >> +;
> > >> +AsmLfence
> > >> +    stp   x29, x30, [sp, #-16]!
> > >> +    bl MemoryFence
> > >> +    ldp   x29, x30, [sp], #0x10
> > >> +    ret
> > >> +
> > >> +  END
> > >> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
> > >b/MdePkg/Library/BaseLib/BaseLib.inf
> > >> index b84e583..b7d7bcb 100644
> > >> --- a/MdePkg/Library/BaseLib/BaseLib.inf
> > >> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> > >> @@ -585,6 +585,7 @@
> > >>    Math64.c
> > >>
> > >>    AArch64/MemoryFence.S             | GCC
> > >> +  AArch64/AsmLfence.S               | GCC
> > >>    AArch64/SwitchStack.S             | GCC
> > >>    AArch64/EnableInterrupts.S        | GCC
> > >>    AArch64/DisableInterrupts.S       | GCC
> > >> @@ -593,6 +594,7 @@
> > >>    AArch64/CpuBreakpoint.S           | GCC
> > >>
> > >>    AArch64/MemoryFence.asm           | MSFT
> > >> +  AArch64/AsmLfence.asm             | MSFT
> > >>    AArch64/SwitchStack.asm           | MSFT
> > >>    AArch64/EnableInterrupts.asm      | MSFT
> > >>    AArch64/DisableInterrupts.asm     | MSFT
> > >> --
> > >> 2.7.4
> > >>
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
  2018-12-17  7:45         ` Ard Biesheuvel
@ 2018-12-17  8:10           ` Ard Biesheuvel
  2018-12-17  8:24             ` Yao, Jiewen
  0 siblings, 1 reply; 52+ messages in thread
From: Ard Biesheuvel @ 2018-12-17  8:10 UTC (permalink / raw)
  To: Yao, Jiewen, Leif Lindholm
  Cc: Gao, Liming, Jagadeesh Ujja, edk2-devel@lists.01.org,
	Zhang, Chao B

On Mon, 17 Dec 2018 at 08:45, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>
> On Mon, 17 Dec 2018 at 04:29, Yao, Jiewen <jiewen.yao@intel.com> wrote:
> >
> > I think we have below definition.
> > -- MemoryFence: Serialize load and store operations.
> > -- LoadFence: Serialize load operations.
> > -- StoreFence: Serialize store operations.
> >
> > According to IA32 SDM, Intel has MFENCE, LFENCE and SFENCE.
> > If ARM only has DMB, it is possible to use DMB for MemoryFence, LoadFence or StoreFence.
> >
> > Maybe it is better to use LoadFence, instead of AsmLFence?
> > Then we can align with MemoryFence.
> >
>
> I think using AsmLfence() all over the code to limit speculation was a
> mistake, and I am disappointed nobody from the ARM side was involved
> at all when these changes were proposed.
>

OK, I have to apologize here. Hao did cc us on these patches, and so
we did have the opportunity to respond at the time.

But that doesn't change the fact that AsmLfence() should be replaced
by an abstraction that describes the specific semantics of the x86
Lfence implemetation beyond memory ordering that we are relying on
here.



> The code changes rely on specific semantics of the x86 Lfence
> instructions, i.e., that beyond load serialization, they ensure that
> all instructions (not just loads) complete before the lfence
> completes. This is a much stronger notion than a load barrier, and so
> the abstraction should have been defined as something like a
> ExecFence() or pipeline barrier etc, and the x86 specific
> implementation would have been mapped onto Lfence. For the ARM side,
> we probably need an ISB instruction here as well as some kind of other
> barrier. Calling it LoadFence() makes no sense whatsoever.
>
>
>
>
>
> >
> > > -----Original Message-----
> > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> > > Gao, Liming
> > > Sent: Monday, December 17, 2018 10:04 AM
> > > To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Jagadeesh Ujja
> > > <jagadeesh.ujja@arm.com>; Leif Lindholm <leif.lindholm@linaro.org>
> > > Cc: edk2-devel@lists.01.org; Zhang, Chao B <chao.b.zhang@intel.com>
> > > Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> > > AsmLfence function
> > >
> > > Ard:
> > >   My first comment is to suggest updating the caller code for the arch
> > > specific code.  But, there are two drivers that have the same usage. This
> > > way will introduce the duplicated code logic. So, I suggest another way to
> > > extend  AsmLfence() API scope for the different ARCHs. If you think it brings
> > > the confuse, I just think another way to resolve this case in the caller code.
> > >
> > > #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> > > AsmLfence();
> > > #else
> > > MemoryFence()
> > > #endif
> > >
> > > Thanks
> > > Liming
> > > >-----Original Message-----
> > > >From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> > > >Sent: Friday, December 14, 2018 9:54 PM
> > > >To: Jagadeesh Ujja <jagadeesh.ujja@arm.com>; Leif Lindholm
> > > ><leif.lindholm@linaro.org>
> > > >Cc: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>; Zhang,
> > > >Chao B <chao.b.zhang@intel.com>
> > > >Subject: Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> > > >AsmLfence function
> > > >
> > > >On Fri, 14 Dec 2018 at 13:13, Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> > > >wrote:
> > > >>
> > > >> Variable service driver includes a call to AsmLfence. To reuse this
> > > >> driver on AArch64 based platforms, add an implementation of AsmLfence
> > > >> that acts as a wrapper on the AArch64 specific MemoryFence function.
> > > >>
> > > >> Contributed-under: TianoCore Contribution Agreement 1.1
> > > >> Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> > > >> ---
> > > >>  MdePkg/Include/Library/BaseLib.h             | 33 +++++++++------
> > > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.S   | 42
> > > >++++++++++++++++++++
> > > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.asm | 41
> > > >+++++++++++++++++++
> > > >>  MdePkg/Library/BaseLib/BaseLib.inf           |  2 +
> > > >>  4 files changed, 105 insertions(+), 13 deletions(-)
> > > >>
> > > >> diff --git a/MdePkg/Include/Library/BaseLib.h
> > > >b/MdePkg/Include/Library/BaseLib.h
> > > >> index 8cc0869..ca961ee 100644
> > > >> --- a/MdePkg/Include/Library/BaseLib.h
> > > >> +++ b/MdePkg/Include/Library/BaseLib.h
> > > >> @@ -7697,19 +7697,6 @@ AsmWriteTr (
> > > >>    );
> > > >>
> > > >>  /**
> > > >> -  Performs a serializing operation on all load-from-memory instructions
> > > that
> > > >> -  were issued prior the AsmLfence function.
> > > >> -
> > > >> -  Executes a LFENCE instruction. This function is only available on IA-32
> > > and
> > > >x64.
> > > >> -
> > > >> -**/
> > > >> -VOID
> > > >> -EFIAPI
> > > >> -AsmLfence (
> > > >> -  VOID
> > > >> -  );
> > > >> -
> > > >> -/**
> > > >>    Patch the immediate operand of an IA32 or X64 instruction such that
> > > the
> > > >byte,
> > > >>    word, dword or qword operand is encoded at the end of the
> > > instruction's
> > > >>    binary representation.
> > > >> @@ -7752,4 +7739,24 @@ PatchInstructionX86 (
> > > >>    );
> > > >>
> > > >>  #endif // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> > > >> +
> > > >> +#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) || defined
> > > >(MDE_CPU_AARCH64)
> > > >> +
> > > >> +/**
> > > >> +  Performs a serializing operation on all load-from-memory instructions
> > > that
> > > >> +  were issued prior the AsmLfence function.
> > > >> +
> > > >> +  In case of IA-32 and x64, Executes a LFENCE instruction.
> > > >> +
> > > >> +  In case of AArch64 this acts as a wrapper on the AArch64
> > > >> +  specific MemoryFence function
> > > >> +
> > > >> +**/
> > > >> +VOID
> > > >> +EFIAPI
> > > >> +AsmLfence (
> > > >> +  VOID
> > > >> +  );
> > > >> +
> > > >> +#endif  // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) ||
> > > >defined (MDE_CPU_AARCH64)
> > > >>  #endif // !defined (__BASE_LIB__)
> > > >> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > >> new file mode 100644
> > > >> index 0000000..2fd804b
> > > >> --- /dev/null
> > > >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > >> @@ -0,0 +1,42 @@
> > > >> +##------------------------------------------------------------------------------
> > > >> +#
> > > >> +# AsmLfence() for AArch64
> > > >> +#
> > > >> +# Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> > > >> +#
> > > >> +# This program and the accompanying materials
> > > >> +# are licensed and made available under the terms and conditions of the
> > > >BSD License
> > > >> +# which accompanies this distribution.  The full text of the license may
> > > be
> > > >found at
> > > >> +# http://opensource.org/licenses/bsd-license.php.
> > > >> +#
> > > >> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS
> > > IS"
> > > >BASIS,
> > > >> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> > > >EXPRESS OR IMPLIED.
> > > >> +#
> > > >> +##------------------------------------------------------------------------------
> > > >> +
> > > >> +.text
> > > >> +.p2align 2
> > > >> +
> > > >> +GCC_ASM_EXPORT(AsmLfence)
> > > >> +
> > > >> +# IMPORT
> > > >> +GCC_ASM_IMPORT(MemoryFence)
> > > >> +
> > > >> +#/**
> > > >> +#  Used to serialize load and store operations.
> > > >> +#
> > > >> +#  All loads and stores that proceed calls to this function are
> > > guaranteed to
> > > >be
> > > >> +#  globally visible when this function returns.
> > > >> +#
> > > >> +#**/
> > > >> +#VOID
> > > >> +#EFIAPI
> > > >> +#AsmLfence (
> > > >> +#  VOID
> > > >> +#  );
> > > >> +#
> > > >> +ASM_PFX(AsmLfence):
> > > >> +    stp   x29, x30, [sp, #-16]!
> > > >> +    bl MemoryFence
> > > >> +    ldp   x29, x30, [sp], #0x10
> > > >> +    ret
> > > >
> > > >Any reason we can't simply do
> > > >
> > > >b MemoryFence
> > > >
> > > >here?
> > > >
> > > >Also, why I understand the rationale, I still think it would be better
> > > >to change callers of the [x86 specific] AsmLfence() than to introduce
> > > >an alias of MemoryFence() for architectures where Lfence is not
> > > >defined.
> > > >
> > > >This is not only about tidiness, but also about potentially having
> > > >different semantics, which we can't provide in general on ARM, but
> > > >only in particular cases [such as the code that is modified in this
> > > >series]
> > > >
> > > >In other words, newly introduced occurrences of AsmLfence() now have
> > > >to be audited for being appropriate on AArc64 if they are added to
> > > >generic code.
> > > >
> > > >
> > > >> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > >> new file mode 100644
> > > >> index 0000000..7dd5659
> > > >> --- /dev/null
> > > >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > >> @@ -0,0 +1,41 @@
> > > >> +;------------------------------------------------------------------------------
> > > >> +;
> > > >> +; AsmLfence() for AArch64
> > > >> +;
> > > >> +; Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> > > >> +;
> > > >> +; This program and the accompanying materials
> > > >> +; are licensed and made available under the terms and conditions of the
> > > >BSD License
> > > >> +; which accompanies this distribution.  The full text of the license may
> > > be
> > > >found at
> > > >> +; http://opensource.org/licenses/bsd-license.php.
> > > >> +;
> > > >> +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS
> > > IS"
> > > >BASIS,
> > > >> +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> > > >EXPRESS OR IMPLIED.
> > > >> +;
> > > >> +;------------------------------------------------------------------------------
> > > >> +
> > > >> +  EXPORT AsmLfence
> > > >> +  AREA BaseLib_LowLevel, CODE, READONLY
> > > >> +  # IMPORT
> > > >> +  GCC_ASM_IMPORT(MemoryFence)
> > > >> +
> > > >> +;/**
> > > >> +;  Used to serialize load and store operations.
> > > >> +;
> > > >> +;  All loads and stores that proceed calls to this function are guaranteed
> > > to
> > > >be
> > > >> +;  globally visible when this function returns.
> > > >> +;
> > > >> +;**/
> > > >> +;VOID
> > > >> +;EFIAPI
> > > >> +;AsmLfence (
> > > >> +;  VOID
> > > >> +;  );
> > > >> +;
> > > >> +AsmLfence
> > > >> +    stp   x29, x30, [sp, #-16]!
> > > >> +    bl MemoryFence
> > > >> +    ldp   x29, x30, [sp], #0x10
> > > >> +    ret
> > > >> +
> > > >> +  END
> > > >> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
> > > >b/MdePkg/Library/BaseLib/BaseLib.inf
> > > >> index b84e583..b7d7bcb 100644
> > > >> --- a/MdePkg/Library/BaseLib/BaseLib.inf
> > > >> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> > > >> @@ -585,6 +585,7 @@
> > > >>    Math64.c
> > > >>
> > > >>    AArch64/MemoryFence.S             | GCC
> > > >> +  AArch64/AsmLfence.S               | GCC
> > > >>    AArch64/SwitchStack.S             | GCC
> > > >>    AArch64/EnableInterrupts.S        | GCC
> > > >>    AArch64/DisableInterrupts.S       | GCC
> > > >> @@ -593,6 +594,7 @@
> > > >>    AArch64/CpuBreakpoint.S           | GCC
> > > >>
> > > >>    AArch64/MemoryFence.asm           | MSFT
> > > >> +  AArch64/AsmLfence.asm             | MSFT
> > > >>    AArch64/SwitchStack.asm           | MSFT
> > > >>    AArch64/EnableInterrupts.asm      | MSFT
> > > >>    AArch64/DisableInterrupts.asm     | MSFT
> > > >> --
> > > >> 2.7.4
> > > >>
> > > _______________________________________________
> > > edk2-devel mailing list
> > > edk2-devel@lists.01.org
> > > https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
  2018-12-17  8:10           ` Ard Biesheuvel
@ 2018-12-17  8:24             ` Yao, Jiewen
  2018-12-17  8:30               ` Yao, Jiewen
  0 siblings, 1 reply; 52+ messages in thread
From: Yao, Jiewen @ 2018-12-17  8:24 UTC (permalink / raw)
  To: Ard Biesheuvel, Leif Lindholm
  Cc: Gao, Liming, Jagadeesh Ujja, edk2-devel@lists.01.org,
	Zhang, Chao B

Hi Ard
I am OK to refine it now.

Do you have any proposal on the naming from ARM side?

Thank you
Yao Jiewen

> -----Original Message-----
> From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> Sent: Monday, December 17, 2018 4:11 PM
> To: Yao, Jiewen <jiewen.yao@intel.com>; Leif Lindholm
> <leif.lindholm@linaro.org>
> Cc: Gao, Liming <liming.gao@intel.com>; Jagadeesh Ujja
> <jagadeesh.ujja@arm.com>; edk2-devel@lists.01.org; Zhang, Chao B
> <chao.b.zhang@intel.com>
> Subject: Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> AsmLfence function
> 
> On Mon, 17 Dec 2018 at 08:45, Ard Biesheuvel <ard.biesheuvel@linaro.org>
> wrote:
> >
> > On Mon, 17 Dec 2018 at 04:29, Yao, Jiewen <jiewen.yao@intel.com>
> wrote:
> > >
> > > I think we have below definition.
> > > -- MemoryFence: Serialize load and store operations.
> > > -- LoadFence: Serialize load operations.
> > > -- StoreFence: Serialize store operations.
> > >
> > > According to IA32 SDM, Intel has MFENCE, LFENCE and SFENCE.
> > > If ARM only has DMB, it is possible to use DMB for MemoryFence,
> LoadFence or StoreFence.
> > >
> > > Maybe it is better to use LoadFence, instead of AsmLFence?
> > > Then we can align with MemoryFence.
> > >
> >
> > I think using AsmLfence() all over the code to limit speculation was a
> > mistake, and I am disappointed nobody from the ARM side was involved
> > at all when these changes were proposed.
> >
> 
> OK, I have to apologize here. Hao did cc us on these patches, and so
> we did have the opportunity to respond at the time.
> 
> But that doesn't change the fact that AsmLfence() should be replaced
> by an abstraction that describes the specific semantics of the x86
> Lfence implemetation beyond memory ordering that we are relying on
> here.
> 
> 
> 
> > The code changes rely on specific semantics of the x86 Lfence
> > instructions, i.e., that beyond load serialization, they ensure that
> > all instructions (not just loads) complete before the lfence
> > completes. This is a much stronger notion than a load barrier, and so
> > the abstraction should have been defined as something like a
> > ExecFence() or pipeline barrier etc, and the x86 specific
> > implementation would have been mapped onto Lfence. For the ARM side,
> > we probably need an ISB instruction here as well as some kind of other
> > barrier. Calling it LoadFence() makes no sense whatsoever.
> >
> >
> >
> >
> >
> > >
> > > > -----Original Message-----
> > > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf
> Of
> > > > Gao, Liming
> > > > Sent: Monday, December 17, 2018 10:04 AM
> > > > To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Jagadeesh Ujja
> > > > <jagadeesh.ujja@arm.com>; Leif Lindholm <leif.lindholm@linaro.org>
> > > > Cc: edk2-devel@lists.01.org; Zhang, Chao B
> <chao.b.zhang@intel.com>
> > > > Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64:
> Add
> > > > AsmLfence function
> > > >
> > > > Ard:
> > > >   My first comment is to suggest updating the caller code for the arch
> > > > specific code.  But, there are two drivers that have the same usage.
> This
> > > > way will introduce the duplicated code logic. So, I suggest another way
> to
> > > > extend  AsmLfence() API scope for the different ARCHs. If you think it
> brings
> > > > the confuse, I just think another way to resolve this case in the caller
> code.
> > > >
> > > > #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> > > > AsmLfence();
> > > > #else
> > > > MemoryFence()
> > > > #endif
> > > >
> > > > Thanks
> > > > Liming
> > > > >-----Original Message-----
> > > > >From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> > > > >Sent: Friday, December 14, 2018 9:54 PM
> > > > >To: Jagadeesh Ujja <jagadeesh.ujja@arm.com>; Leif Lindholm
> > > > ><leif.lindholm@linaro.org>
> > > > >Cc: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>;
> Zhang,
> > > > >Chao B <chao.b.zhang@intel.com>
> > > > >Subject: Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> > > > >AsmLfence function
> > > > >
> > > > >On Fri, 14 Dec 2018 at 13:13, Jagadeesh Ujja
> <jagadeesh.ujja@arm.com>
> > > > >wrote:
> > > > >>
> > > > >> Variable service driver includes a call to AsmLfence. To reuse this
> > > > >> driver on AArch64 based platforms, add an implementation of
> AsmLfence
> > > > >> that acts as a wrapper on the AArch64 specific MemoryFence
> function.
> > > > >>
> > > > >> Contributed-under: TianoCore Contribution Agreement 1.1
> > > > >> Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> > > > >> ---
> > > > >>  MdePkg/Include/Library/BaseLib.h             | 33
> +++++++++------
> > > > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.S   | 42
> > > > >++++++++++++++++++++
> > > > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.asm | 41
> > > > >+++++++++++++++++++
> > > > >>  MdePkg/Library/BaseLib/BaseLib.inf           |  2 +
> > > > >>  4 files changed, 105 insertions(+), 13 deletions(-)
> > > > >>
> > > > >> diff --git a/MdePkg/Include/Library/BaseLib.h
> > > > >b/MdePkg/Include/Library/BaseLib.h
> > > > >> index 8cc0869..ca961ee 100644
> > > > >> --- a/MdePkg/Include/Library/BaseLib.h
> > > > >> +++ b/MdePkg/Include/Library/BaseLib.h
> > > > >> @@ -7697,19 +7697,6 @@ AsmWriteTr (
> > > > >>    );
> > > > >>
> > > > >>  /**
> > > > >> -  Performs a serializing operation on all load-from-memory
> instructions
> > > > that
> > > > >> -  were issued prior the AsmLfence function.
> > > > >> -
> > > > >> -  Executes a LFENCE instruction. This function is only available on
> IA-32
> > > > and
> > > > >x64.
> > > > >> -
> > > > >> -**/
> > > > >> -VOID
> > > > >> -EFIAPI
> > > > >> -AsmLfence (
> > > > >> -  VOID
> > > > >> -  );
> > > > >> -
> > > > >> -/**
> > > > >>    Patch the immediate operand of an IA32 or X64 instruction such
> that
> > > > the
> > > > >byte,
> > > > >>    word, dword or qword operand is encoded at the end of the
> > > > instruction's
> > > > >>    binary representation.
> > > > >> @@ -7752,4 +7739,24 @@ PatchInstructionX86 (
> > > > >>    );
> > > > >>
> > > > >>  #endif // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> > > > >> +
> > > > >> +#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) ||
> defined
> > > > >(MDE_CPU_AARCH64)
> > > > >> +
> > > > >> +/**
> > > > >> +  Performs a serializing operation on all load-from-memory
> instructions
> > > > that
> > > > >> +  were issued prior the AsmLfence function.
> > > > >> +
> > > > >> +  In case of IA-32 and x64, Executes a LFENCE instruction.
> > > > >> +
> > > > >> +  In case of AArch64 this acts as a wrapper on the AArch64
> > > > >> +  specific MemoryFence function
> > > > >> +
> > > > >> +**/
> > > > >> +VOID
> > > > >> +EFIAPI
> > > > >> +AsmLfence (
> > > > >> +  VOID
> > > > >> +  );
> > > > >> +
> > > > >> +#endif  // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> ||
> > > > >defined (MDE_CPU_AARCH64)
> > > > >>  #endif // !defined (__BASE_LIB__)
> > > > >> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > > >> new file mode 100644
> > > > >> index 0000000..2fd804b
> > > > >> --- /dev/null
> > > > >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > > >> @@ -0,0 +1,42 @@
> > > > >> +##------------------------------------------------------------------------------
> > > > >> +#
> > > > >> +# AsmLfence() for AArch64
> > > > >> +#
> > > > >> +# Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> > > > >> +#
> > > > >> +# This program and the accompanying materials
> > > > >> +# are licensed and made available under the terms and conditions
> of the
> > > > >BSD License
> > > > >> +# which accompanies this distribution.  The full text of the license
> may
> > > > be
> > > > >found at
> > > > >> +# http://opensource.org/licenses/bsd-license.php.
> > > > >> +#
> > > > >> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN
> "AS
> > > > IS"
> > > > >BASIS,
> > > > >> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND,
> EITHER
> > > > >EXPRESS OR IMPLIED.
> > > > >> +#
> > > > >> +##------------------------------------------------------------------------------
> > > > >> +
> > > > >> +.text
> > > > >> +.p2align 2
> > > > >> +
> > > > >> +GCC_ASM_EXPORT(AsmLfence)
> > > > >> +
> > > > >> +# IMPORT
> > > > >> +GCC_ASM_IMPORT(MemoryFence)
> > > > >> +
> > > > >> +#/**
> > > > >> +#  Used to serialize load and store operations.
> > > > >> +#
> > > > >> +#  All loads and stores that proceed calls to this function are
> > > > guaranteed to
> > > > >be
> > > > >> +#  globally visible when this function returns.
> > > > >> +#
> > > > >> +#**/
> > > > >> +#VOID
> > > > >> +#EFIAPI
> > > > >> +#AsmLfence (
> > > > >> +#  VOID
> > > > >> +#  );
> > > > >> +#
> > > > >> +ASM_PFX(AsmLfence):
> > > > >> +    stp   x29, x30, [sp, #-16]!
> > > > >> +    bl MemoryFence
> > > > >> +    ldp   x29, x30, [sp], #0x10
> > > > >> +    ret
> > > > >
> > > > >Any reason we can't simply do
> > > > >
> > > > >b MemoryFence
> > > > >
> > > > >here?
> > > > >
> > > > >Also, why I understand the rationale, I still think it would be better
> > > > >to change callers of the [x86 specific] AsmLfence() than to introduce
> > > > >an alias of MemoryFence() for architectures where Lfence is not
> > > > >defined.
> > > > >
> > > > >This is not only about tidiness, but also about potentially having
> > > > >different semantics, which we can't provide in general on ARM, but
> > > > >only in particular cases [such as the code that is modified in this
> > > > >series]
> > > > >
> > > > >In other words, newly introduced occurrences of AsmLfence() now
> have
> > > > >to be audited for being appropriate on AArc64 if they are added to
> > > > >generic code.
> > > > >
> > > > >
> > > > >> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > > >> new file mode 100644
> > > > >> index 0000000..7dd5659
> > > > >> --- /dev/null
> > > > >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > > >> @@ -0,0 +1,41 @@
> > > > >> +;------------------------------------------------------------------------------
> > > > >> +;
> > > > >> +; AsmLfence() for AArch64
> > > > >> +;
> > > > >> +; Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> > > > >> +;
> > > > >> +; This program and the accompanying materials
> > > > >> +; are licensed and made available under the terms and conditions
> of the
> > > > >BSD License
> > > > >> +; which accompanies this distribution.  The full text of the license
> may
> > > > be
> > > > >found at
> > > > >> +; http://opensource.org/licenses/bsd-license.php.
> > > > >> +;
> > > > >> +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN
> "AS
> > > > IS"
> > > > >BASIS,
> > > > >> +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND,
> EITHER
> > > > >EXPRESS OR IMPLIED.
> > > > >> +;
> > > > >> +;------------------------------------------------------------------------------
> > > > >> +
> > > > >> +  EXPORT AsmLfence
> > > > >> +  AREA BaseLib_LowLevel, CODE, READONLY
> > > > >> +  # IMPORT
> > > > >> +  GCC_ASM_IMPORT(MemoryFence)
> > > > >> +
> > > > >> +;/**
> > > > >> +;  Used to serialize load and store operations.
> > > > >> +;
> > > > >> +;  All loads and stores that proceed calls to this function are
> guaranteed
> > > > to
> > > > >be
> > > > >> +;  globally visible when this function returns.
> > > > >> +;
> > > > >> +;**/
> > > > >> +;VOID
> > > > >> +;EFIAPI
> > > > >> +;AsmLfence (
> > > > >> +;  VOID
> > > > >> +;  );
> > > > >> +;
> > > > >> +AsmLfence
> > > > >> +    stp   x29, x30, [sp, #-16]!
> > > > >> +    bl MemoryFence
> > > > >> +    ldp   x29, x30, [sp], #0x10
> > > > >> +    ret
> > > > >> +
> > > > >> +  END
> > > > >> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
> > > > >b/MdePkg/Library/BaseLib/BaseLib.inf
> > > > >> index b84e583..b7d7bcb 100644
> > > > >> --- a/MdePkg/Library/BaseLib/BaseLib.inf
> > > > >> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> > > > >> @@ -585,6 +585,7 @@
> > > > >>    Math64.c
> > > > >>
> > > > >>    AArch64/MemoryFence.S             | GCC
> > > > >> +  AArch64/AsmLfence.S               | GCC
> > > > >>    AArch64/SwitchStack.S             | GCC
> > > > >>    AArch64/EnableInterrupts.S        | GCC
> > > > >>    AArch64/DisableInterrupts.S       | GCC
> > > > >> @@ -593,6 +594,7 @@
> > > > >>    AArch64/CpuBreakpoint.S           | GCC
> > > > >>
> > > > >>    AArch64/MemoryFence.asm           | MSFT
> > > > >> +  AArch64/AsmLfence.asm             | MSFT
> > > > >>    AArch64/SwitchStack.asm           | MSFT
> > > > >>    AArch64/EnableInterrupts.asm      | MSFT
> > > > >>    AArch64/DisableInterrupts.asm     | MSFT
> > > > >> --
> > > > >> 2.7.4
> > > > >>
> > > > _______________________________________________
> > > > edk2-devel mailing list
> > > > edk2-devel@lists.01.org
> > > > https://lists.01.org/mailman/listinfo/edk2-devel

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
  2018-12-17  8:24             ` Yao, Jiewen
@ 2018-12-17  8:30               ` Yao, Jiewen
  2018-12-17  8:35                 ` Ard Biesheuvel
  0 siblings, 1 reply; 52+ messages in thread
From: Yao, Jiewen @ 2018-12-17  8:30 UTC (permalink / raw)
  To: Yao, Jiewen, Ard Biesheuvel, Leif Lindholm
  Cc: edk2-devel@lists.01.org, Zhang, Chao B, Gao, Liming

I reviewed the ARM white paper - file:///C:/Users/jyao1/Downloads/Cache_Speculation_Side-channels-v2.4.pdf

I agree with you that LoadFence might not be the best idea.

How about SpeculationBarrier() ?


Thank you
Yao Jiewen

> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Yao, Jiewen
> Sent: Monday, December 17, 2018 4:25 PM
> To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Leif Lindholm
> <leif.lindholm@linaro.org>
> Cc: edk2-devel@lists.01.org; Zhang, Chao B <chao.b.zhang@intel.com>;
> Gao, Liming <liming.gao@intel.com>
> Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> AsmLfence function
> 
> Hi Ard
> I am OK to refine it now.
> 
> Do you have any proposal on the naming from ARM side?
> 
> Thank you
> Yao Jiewen
> 
> > -----Original Message-----
> > From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> > Sent: Monday, December 17, 2018 4:11 PM
> > To: Yao, Jiewen <jiewen.yao@intel.com>; Leif Lindholm
> > <leif.lindholm@linaro.org>
> > Cc: Gao, Liming <liming.gao@intel.com>; Jagadeesh Ujja
> > <jagadeesh.ujja@arm.com>; edk2-devel@lists.01.org; Zhang, Chao B
> > <chao.b.zhang@intel.com>
> > Subject: Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> > AsmLfence function
> >
> > On Mon, 17 Dec 2018 at 08:45, Ard Biesheuvel
> <ard.biesheuvel@linaro.org>
> > wrote:
> > >
> > > On Mon, 17 Dec 2018 at 04:29, Yao, Jiewen <jiewen.yao@intel.com>
> > wrote:
> > > >
> > > > I think we have below definition.
> > > > -- MemoryFence: Serialize load and store operations.
> > > > -- LoadFence: Serialize load operations.
> > > > -- StoreFence: Serialize store operations.
> > > >
> > > > According to IA32 SDM, Intel has MFENCE, LFENCE and SFENCE.
> > > > If ARM only has DMB, it is possible to use DMB for MemoryFence,
> > LoadFence or StoreFence.
> > > >
> > > > Maybe it is better to use LoadFence, instead of AsmLFence?
> > > > Then we can align with MemoryFence.
> > > >
> > >
> > > I think using AsmLfence() all over the code to limit speculation was a
> > > mistake, and I am disappointed nobody from the ARM side was involved
> > > at all when these changes were proposed.
> > >
> >
> > OK, I have to apologize here. Hao did cc us on these patches, and so
> > we did have the opportunity to respond at the time.
> >
> > But that doesn't change the fact that AsmLfence() should be replaced
> > by an abstraction that describes the specific semantics of the x86
> > Lfence implemetation beyond memory ordering that we are relying on
> > here.
> >
> >
> >
> > > The code changes rely on specific semantics of the x86 Lfence
> > > instructions, i.e., that beyond load serialization, they ensure that
> > > all instructions (not just loads) complete before the lfence
> > > completes. This is a much stronger notion than a load barrier, and so
> > > the abstraction should have been defined as something like a
> > > ExecFence() or pipeline barrier etc, and the x86 specific
> > > implementation would have been mapped onto Lfence. For the ARM
> side,
> > > we probably need an ISB instruction here as well as some kind of other
> > > barrier. Calling it LoadFence() makes no sense whatsoever.
> > >
> > >
> > >
> > >
> > >
> > > >
> > > > > -----Original Message-----
> > > > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On
> Behalf
> > Of
> > > > > Gao, Liming
> > > > > Sent: Monday, December 17, 2018 10:04 AM
> > > > > To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Jagadeesh Ujja
> > > > > <jagadeesh.ujja@arm.com>; Leif Lindholm
> <leif.lindholm@linaro.org>
> > > > > Cc: edk2-devel@lists.01.org; Zhang, Chao B
> > <chao.b.zhang@intel.com>
> > > > > Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64:
> > Add
> > > > > AsmLfence function
> > > > >
> > > > > Ard:
> > > > >   My first comment is to suggest updating the caller code for the
> arch
> > > > > specific code.  But, there are two drivers that have the same usage.
> > This
> > > > > way will introduce the duplicated code logic. So, I suggest another
> way
> > to
> > > > > extend  AsmLfence() API scope for the different ARCHs. If you think
> it
> > brings
> > > > > the confuse, I just think another way to resolve this case in the caller
> > code.
> > > > >
> > > > > #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> > > > > AsmLfence();
> > > > > #else
> > > > > MemoryFence()
> > > > > #endif
> > > > >
> > > > > Thanks
> > > > > Liming
> > > > > >-----Original Message-----
> > > > > >From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> > > > > >Sent: Friday, December 14, 2018 9:54 PM
> > > > > >To: Jagadeesh Ujja <jagadeesh.ujja@arm.com>; Leif Lindholm
> > > > > ><leif.lindholm@linaro.org>
> > > > > >Cc: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>;
> > Zhang,
> > > > > >Chao B <chao.b.zhang@intel.com>
> > > > > >Subject: Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> > > > > >AsmLfence function
> > > > > >
> > > > > >On Fri, 14 Dec 2018 at 13:13, Jagadeesh Ujja
> > <jagadeesh.ujja@arm.com>
> > > > > >wrote:
> > > > > >>
> > > > > >> Variable service driver includes a call to AsmLfence. To reuse this
> > > > > >> driver on AArch64 based platforms, add an implementation of
> > AsmLfence
> > > > > >> that acts as a wrapper on the AArch64 specific MemoryFence
> > function.
> > > > > >>
> > > > > >> Contributed-under: TianoCore Contribution Agreement 1.1
> > > > > >> Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> > > > > >> ---
> > > > > >>  MdePkg/Include/Library/BaseLib.h             | 33
> > +++++++++------
> > > > > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.S   | 42
> > > > > >++++++++++++++++++++
> > > > > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.asm | 41
> > > > > >+++++++++++++++++++
> > > > > >>  MdePkg/Library/BaseLib/BaseLib.inf           |  2 +
> > > > > >>  4 files changed, 105 insertions(+), 13 deletions(-)
> > > > > >>
> > > > > >> diff --git a/MdePkg/Include/Library/BaseLib.h
> > > > > >b/MdePkg/Include/Library/BaseLib.h
> > > > > >> index 8cc0869..ca961ee 100644
> > > > > >> --- a/MdePkg/Include/Library/BaseLib.h
> > > > > >> +++ b/MdePkg/Include/Library/BaseLib.h
> > > > > >> @@ -7697,19 +7697,6 @@ AsmWriteTr (
> > > > > >>    );
> > > > > >>
> > > > > >>  /**
> > > > > >> -  Performs a serializing operation on all load-from-memory
> > instructions
> > > > > that
> > > > > >> -  were issued prior the AsmLfence function.
> > > > > >> -
> > > > > >> -  Executes a LFENCE instruction. This function is only available
> on
> > IA-32
> > > > > and
> > > > > >x64.
> > > > > >> -
> > > > > >> -**/
> > > > > >> -VOID
> > > > > >> -EFIAPI
> > > > > >> -AsmLfence (
> > > > > >> -  VOID
> > > > > >> -  );
> > > > > >> -
> > > > > >> -/**
> > > > > >>    Patch the immediate operand of an IA32 or X64 instruction
> such
> > that
> > > > > the
> > > > > >byte,
> > > > > >>    word, dword or qword operand is encoded at the end of the
> > > > > instruction's
> > > > > >>    binary representation.
> > > > > >> @@ -7752,4 +7739,24 @@ PatchInstructionX86 (
> > > > > >>    );
> > > > > >>
> > > > > >>  #endif // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> > > > > >> +
> > > > > >> +#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) ||
> > defined
> > > > > >(MDE_CPU_AARCH64)
> > > > > >> +
> > > > > >> +/**
> > > > > >> +  Performs a serializing operation on all load-from-memory
> > instructions
> > > > > that
> > > > > >> +  were issued prior the AsmLfence function.
> > > > > >> +
> > > > > >> +  In case of IA-32 and x64, Executes a LFENCE instruction.
> > > > > >> +
> > > > > >> +  In case of AArch64 this acts as a wrapper on the AArch64
> > > > > >> +  specific MemoryFence function
> > > > > >> +
> > > > > >> +**/
> > > > > >> +VOID
> > > > > >> +EFIAPI
> > > > > >> +AsmLfence (
> > > > > >> +  VOID
> > > > > >> +  );
> > > > > >> +
> > > > > >> +#endif  // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> > ||
> > > > > >defined (MDE_CPU_AARCH64)
> > > > > >>  #endif // !defined (__BASE_LIB__)
> > > > > >> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > > > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > > > >> new file mode 100644
> > > > > >> index 0000000..2fd804b
> > > > > >> --- /dev/null
> > > > > >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > > > >> @@ -0,0 +1,42 @@
> > > > > >>
> +##------------------------------------------------------------------------------
> > > > > >> +#
> > > > > >> +# AsmLfence() for AArch64
> > > > > >> +#
> > > > > >> +# Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> > > > > >> +#
> > > > > >> +# This program and the accompanying materials
> > > > > >> +# are licensed and made available under the terms and conditions
> > of the
> > > > > >BSD License
> > > > > >> +# which accompanies this distribution.  The full text of the
> license
> > may
> > > > > be
> > > > > >found at
> > > > > >> +# http://opensource.org/licenses/bsd-license.php.
> > > > > >> +#
> > > > > >> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON
> AN
> > "AS
> > > > > IS"
> > > > > >BASIS,
> > > > > >> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND,
> > EITHER
> > > > > >EXPRESS OR IMPLIED.
> > > > > >> +#
> > > > > >>
> +##------------------------------------------------------------------------------
> > > > > >> +
> > > > > >> +.text
> > > > > >> +.p2align 2
> > > > > >> +
> > > > > >> +GCC_ASM_EXPORT(AsmLfence)
> > > > > >> +
> > > > > >> +# IMPORT
> > > > > >> +GCC_ASM_IMPORT(MemoryFence)
> > > > > >> +
> > > > > >> +#/**
> > > > > >> +#  Used to serialize load and store operations.
> > > > > >> +#
> > > > > >> +#  All loads and stores that proceed calls to this function are
> > > > > guaranteed to
> > > > > >be
> > > > > >> +#  globally visible when this function returns.
> > > > > >> +#
> > > > > >> +#**/
> > > > > >> +#VOID
> > > > > >> +#EFIAPI
> > > > > >> +#AsmLfence (
> > > > > >> +#  VOID
> > > > > >> +#  );
> > > > > >> +#
> > > > > >> +ASM_PFX(AsmLfence):
> > > > > >> +    stp   x29, x30, [sp, #-16]!
> > > > > >> +    bl MemoryFence
> > > > > >> +    ldp   x29, x30, [sp], #0x10
> > > > > >> +    ret
> > > > > >
> > > > > >Any reason we can't simply do
> > > > > >
> > > > > >b MemoryFence
> > > > > >
> > > > > >here?
> > > > > >
> > > > > >Also, why I understand the rationale, I still think it would be better
> > > > > >to change callers of the [x86 specific] AsmLfence() than to introduce
> > > > > >an alias of MemoryFence() for architectures where Lfence is not
> > > > > >defined.
> > > > > >
> > > > > >This is not only about tidiness, but also about potentially having
> > > > > >different semantics, which we can't provide in general on ARM, but
> > > > > >only in particular cases [such as the code that is modified in this
> > > > > >series]
> > > > > >
> > > > > >In other words, newly introduced occurrences of AsmLfence() now
> > have
> > > > > >to be audited for being appropriate on AArc64 if they are added to
> > > > > >generic code.
> > > > > >
> > > > > >
> > > > > >> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > > > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > > > >> new file mode 100644
> > > > > >> index 0000000..7dd5659
> > > > > >> --- /dev/null
> > > > > >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > > > >> @@ -0,0 +1,41 @@
> > > > > >> +;------------------------------------------------------------------------------
> > > > > >> +;
> > > > > >> +; AsmLfence() for AArch64
> > > > > >> +;
> > > > > >> +; Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> > > > > >> +;
> > > > > >> +; This program and the accompanying materials
> > > > > >> +; are licensed and made available under the terms and conditions
> > of the
> > > > > >BSD License
> > > > > >> +; which accompanies this distribution.  The full text of the
> license
> > may
> > > > > be
> > > > > >found at
> > > > > >> +; http://opensource.org/licenses/bsd-license.php.
> > > > > >> +;
> > > > > >> +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON
> AN
> > "AS
> > > > > IS"
> > > > > >BASIS,
> > > > > >> +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND,
> > EITHER
> > > > > >EXPRESS OR IMPLIED.
> > > > > >> +;
> > > > > >> +;------------------------------------------------------------------------------
> > > > > >> +
> > > > > >> +  EXPORT AsmLfence
> > > > > >> +  AREA BaseLib_LowLevel, CODE, READONLY
> > > > > >> +  # IMPORT
> > > > > >> +  GCC_ASM_IMPORT(MemoryFence)
> > > > > >> +
> > > > > >> +;/**
> > > > > >> +;  Used to serialize load and store operations.
> > > > > >> +;
> > > > > >> +;  All loads and stores that proceed calls to this function are
> > guaranteed
> > > > > to
> > > > > >be
> > > > > >> +;  globally visible when this function returns.
> > > > > >> +;
> > > > > >> +;**/
> > > > > >> +;VOID
> > > > > >> +;EFIAPI
> > > > > >> +;AsmLfence (
> > > > > >> +;  VOID
> > > > > >> +;  );
> > > > > >> +;
> > > > > >> +AsmLfence
> > > > > >> +    stp   x29, x30, [sp, #-16]!
> > > > > >> +    bl MemoryFence
> > > > > >> +    ldp   x29, x30, [sp], #0x10
> > > > > >> +    ret
> > > > > >> +
> > > > > >> +  END
> > > > > >> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > >b/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > >> index b84e583..b7d7bcb 100644
> > > > > >> --- a/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > >> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > >> @@ -585,6 +585,7 @@
> > > > > >>    Math64.c
> > > > > >>
> > > > > >>    AArch64/MemoryFence.S             | GCC
> > > > > >> +  AArch64/AsmLfence.S               | GCC
> > > > > >>    AArch64/SwitchStack.S             | GCC
> > > > > >>    AArch64/EnableInterrupts.S        | GCC
> > > > > >>    AArch64/DisableInterrupts.S       | GCC
> > > > > >> @@ -593,6 +594,7 @@
> > > > > >>    AArch64/CpuBreakpoint.S           | GCC
> > > > > >>
> > > > > >>    AArch64/MemoryFence.asm           | MSFT
> > > > > >> +  AArch64/AsmLfence.asm             | MSFT
> > > > > >>    AArch64/SwitchStack.asm           | MSFT
> > > > > >>    AArch64/EnableInterrupts.asm      | MSFT
> > > > > >>    AArch64/DisableInterrupts.asm     | MSFT
> > > > > >> --
> > > > > >> 2.7.4
> > > > > >>
> > > > > _______________________________________________
> > > > > edk2-devel mailing list
> > > > > edk2-devel@lists.01.org
> > > > > https://lists.01.org/mailman/listinfo/edk2-devel
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
  2018-12-17  8:30               ` Yao, Jiewen
@ 2018-12-17  8:35                 ` Ard Biesheuvel
  2018-12-17  8:44                   ` Yao, Jiewen
  0 siblings, 1 reply; 52+ messages in thread
From: Ard Biesheuvel @ 2018-12-17  8:35 UTC (permalink / raw)
  To: Yao, Jiewen
  Cc: Leif Lindholm, edk2-devel@lists.01.org, Zhang, Chao B,
	Gao, Liming

On Mon, 17 Dec 2018 at 09:30, Yao, Jiewen <jiewen.yao@intel.com> wrote:
>
> I reviewed the ARM white paper - file:///C:/Users/jyao1/Downloads/Cache_Speculation_Side-channels-v2.4.pdf
>
> I agree with you that LoadFence might not be the best idea.
>
> How about SpeculationBarrier() ?
>

That works for me. Or SpecFence (). As long as it does not conflate
memory ordering with controlling the side effects of speculative
execution, it is ok with me.

I'll contribute the ARM and AARCH64 implementations asap once the
generic changes are posted on the list.

Thanks,

> > -----Original Message-----
> > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> > Yao, Jiewen
> > Sent: Monday, December 17, 2018 4:25 PM
> > To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Leif Lindholm
> > <leif.lindholm@linaro.org>
> > Cc: edk2-devel@lists.01.org; Zhang, Chao B <chao.b.zhang@intel.com>;
> > Gao, Liming <liming.gao@intel.com>
> > Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> > AsmLfence function
> >
> > Hi Ard
> > I am OK to refine it now.
> >
> > Do you have any proposal on the naming from ARM side?
> >
> > Thank you
> > Yao Jiewen
> >
> > > -----Original Message-----
> > > From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> > > Sent: Monday, December 17, 2018 4:11 PM
> > > To: Yao, Jiewen <jiewen.yao@intel.com>; Leif Lindholm
> > > <leif.lindholm@linaro.org>
> > > Cc: Gao, Liming <liming.gao@intel.com>; Jagadeesh Ujja
> > > <jagadeesh.ujja@arm.com>; edk2-devel@lists.01.org; Zhang, Chao B
> > > <chao.b.zhang@intel.com>
> > > Subject: Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> > > AsmLfence function
> > >
> > > On Mon, 17 Dec 2018 at 08:45, Ard Biesheuvel
> > <ard.biesheuvel@linaro.org>
> > > wrote:
> > > >
> > > > On Mon, 17 Dec 2018 at 04:29, Yao, Jiewen <jiewen.yao@intel.com>
> > > wrote:
> > > > >
> > > > > I think we have below definition.
> > > > > -- MemoryFence: Serialize load and store operations.
> > > > > -- LoadFence: Serialize load operations.
> > > > > -- StoreFence: Serialize store operations.
> > > > >
> > > > > According to IA32 SDM, Intel has MFENCE, LFENCE and SFENCE.
> > > > > If ARM only has DMB, it is possible to use DMB for MemoryFence,
> > > LoadFence or StoreFence.
> > > > >
> > > > > Maybe it is better to use LoadFence, instead of AsmLFence?
> > > > > Then we can align with MemoryFence.
> > > > >
> > > >
> > > > I think using AsmLfence() all over the code to limit speculation was a
> > > > mistake, and I am disappointed nobody from the ARM side was involved
> > > > at all when these changes were proposed.
> > > >
> > >
> > > OK, I have to apologize here. Hao did cc us on these patches, and so
> > > we did have the opportunity to respond at the time.
> > >
> > > But that doesn't change the fact that AsmLfence() should be replaced
> > > by an abstraction that describes the specific semantics of the x86
> > > Lfence implemetation beyond memory ordering that we are relying on
> > > here.
> > >
> > >
> > >
> > > > The code changes rely on specific semantics of the x86 Lfence
> > > > instructions, i.e., that beyond load serialization, they ensure that
> > > > all instructions (not just loads) complete before the lfence
> > > > completes. This is a much stronger notion than a load barrier, and so
> > > > the abstraction should have been defined as something like a
> > > > ExecFence() or pipeline barrier etc, and the x86 specific
> > > > implementation would have been mapped onto Lfence. For the ARM
> > side,
> > > > we probably need an ISB instruction here as well as some kind of other
> > > > barrier. Calling it LoadFence() makes no sense whatsoever.
> > > >
> > > >
> > > >
> > > >
> > > >
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On
> > Behalf
> > > Of
> > > > > > Gao, Liming
> > > > > > Sent: Monday, December 17, 2018 10:04 AM
> > > > > > To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Jagadeesh Ujja
> > > > > > <jagadeesh.ujja@arm.com>; Leif Lindholm
> > <leif.lindholm@linaro.org>
> > > > > > Cc: edk2-devel@lists.01.org; Zhang, Chao B
> > > <chao.b.zhang@intel.com>
> > > > > > Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64:
> > > Add
> > > > > > AsmLfence function
> > > > > >
> > > > > > Ard:
> > > > > >   My first comment is to suggest updating the caller code for the
> > arch
> > > > > > specific code.  But, there are two drivers that have the same usage.
> > > This
> > > > > > way will introduce the duplicated code logic. So, I suggest another
> > way
> > > to
> > > > > > extend  AsmLfence() API scope for the different ARCHs. If you think
> > it
> > > brings
> > > > > > the confuse, I just think another way to resolve this case in the caller
> > > code.
> > > > > >
> > > > > > #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> > > > > > AsmLfence();
> > > > > > #else
> > > > > > MemoryFence()
> > > > > > #endif
> > > > > >
> > > > > > Thanks
> > > > > > Liming
> > > > > > >-----Original Message-----
> > > > > > >From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> > > > > > >Sent: Friday, December 14, 2018 9:54 PM
> > > > > > >To: Jagadeesh Ujja <jagadeesh.ujja@arm.com>; Leif Lindholm
> > > > > > ><leif.lindholm@linaro.org>
> > > > > > >Cc: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>;
> > > Zhang,
> > > > > > >Chao B <chao.b.zhang@intel.com>
> > > > > > >Subject: Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> > > > > > >AsmLfence function
> > > > > > >
> > > > > > >On Fri, 14 Dec 2018 at 13:13, Jagadeesh Ujja
> > > <jagadeesh.ujja@arm.com>
> > > > > > >wrote:
> > > > > > >>
> > > > > > >> Variable service driver includes a call to AsmLfence. To reuse this
> > > > > > >> driver on AArch64 based platforms, add an implementation of
> > > AsmLfence
> > > > > > >> that acts as a wrapper on the AArch64 specific MemoryFence
> > > function.
> > > > > > >>
> > > > > > >> Contributed-under: TianoCore Contribution Agreement 1.1
> > > > > > >> Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> > > > > > >> ---
> > > > > > >>  MdePkg/Include/Library/BaseLib.h             | 33
> > > +++++++++------
> > > > > > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.S   | 42
> > > > > > >++++++++++++++++++++
> > > > > > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.asm | 41
> > > > > > >+++++++++++++++++++
> > > > > > >>  MdePkg/Library/BaseLib/BaseLib.inf           |  2 +
> > > > > > >>  4 files changed, 105 insertions(+), 13 deletions(-)
> > > > > > >>
> > > > > > >> diff --git a/MdePkg/Include/Library/BaseLib.h
> > > > > > >b/MdePkg/Include/Library/BaseLib.h
> > > > > > >> index 8cc0869..ca961ee 100644
> > > > > > >> --- a/MdePkg/Include/Library/BaseLib.h
> > > > > > >> +++ b/MdePkg/Include/Library/BaseLib.h
> > > > > > >> @@ -7697,19 +7697,6 @@ AsmWriteTr (
> > > > > > >>    );
> > > > > > >>
> > > > > > >>  /**
> > > > > > >> -  Performs a serializing operation on all load-from-memory
> > > instructions
> > > > > > that
> > > > > > >> -  were issued prior the AsmLfence function.
> > > > > > >> -
> > > > > > >> -  Executes a LFENCE instruction. This function is only available
> > on
> > > IA-32
> > > > > > and
> > > > > > >x64.
> > > > > > >> -
> > > > > > >> -**/
> > > > > > >> -VOID
> > > > > > >> -EFIAPI
> > > > > > >> -AsmLfence (
> > > > > > >> -  VOID
> > > > > > >> -  );
> > > > > > >> -
> > > > > > >> -/**
> > > > > > >>    Patch the immediate operand of an IA32 or X64 instruction
> > such
> > > that
> > > > > > the
> > > > > > >byte,
> > > > > > >>    word, dword or qword operand is encoded at the end of the
> > > > > > instruction's
> > > > > > >>    binary representation.
> > > > > > >> @@ -7752,4 +7739,24 @@ PatchInstructionX86 (
> > > > > > >>    );
> > > > > > >>
> > > > > > >>  #endif // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> > > > > > >> +
> > > > > > >> +#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) ||
> > > defined
> > > > > > >(MDE_CPU_AARCH64)
> > > > > > >> +
> > > > > > >> +/**
> > > > > > >> +  Performs a serializing operation on all load-from-memory
> > > instructions
> > > > > > that
> > > > > > >> +  were issued prior the AsmLfence function.
> > > > > > >> +
> > > > > > >> +  In case of IA-32 and x64, Executes a LFENCE instruction.
> > > > > > >> +
> > > > > > >> +  In case of AArch64 this acts as a wrapper on the AArch64
> > > > > > >> +  specific MemoryFence function
> > > > > > >> +
> > > > > > >> +**/
> > > > > > >> +VOID
> > > > > > >> +EFIAPI
> > > > > > >> +AsmLfence (
> > > > > > >> +  VOID
> > > > > > >> +  );
> > > > > > >> +
> > > > > > >> +#endif  // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> > > ||
> > > > > > >defined (MDE_CPU_AARCH64)
> > > > > > >>  #endif // !defined (__BASE_LIB__)
> > > > > > >> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > > > > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > > > > >> new file mode 100644
> > > > > > >> index 0000000..2fd804b
> > > > > > >> --- /dev/null
> > > > > > >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > > > > >> @@ -0,0 +1,42 @@
> > > > > > >>
> > +##------------------------------------------------------------------------------
> > > > > > >> +#
> > > > > > >> +# AsmLfence() for AArch64
> > > > > > >> +#
> > > > > > >> +# Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> > > > > > >> +#
> > > > > > >> +# This program and the accompanying materials
> > > > > > >> +# are licensed and made available under the terms and conditions
> > > of the
> > > > > > >BSD License
> > > > > > >> +# which accompanies this distribution.  The full text of the
> > license
> > > may
> > > > > > be
> > > > > > >found at
> > > > > > >> +# http://opensource.org/licenses/bsd-license.php.
> > > > > > >> +#
> > > > > > >> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON
> > AN
> > > "AS
> > > > > > IS"
> > > > > > >BASIS,
> > > > > > >> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND,
> > > EITHER
> > > > > > >EXPRESS OR IMPLIED.
> > > > > > >> +#
> > > > > > >>
> > +##------------------------------------------------------------------------------
> > > > > > >> +
> > > > > > >> +.text
> > > > > > >> +.p2align 2
> > > > > > >> +
> > > > > > >> +GCC_ASM_EXPORT(AsmLfence)
> > > > > > >> +
> > > > > > >> +# IMPORT
> > > > > > >> +GCC_ASM_IMPORT(MemoryFence)
> > > > > > >> +
> > > > > > >> +#/**
> > > > > > >> +#  Used to serialize load and store operations.
> > > > > > >> +#
> > > > > > >> +#  All loads and stores that proceed calls to this function are
> > > > > > guaranteed to
> > > > > > >be
> > > > > > >> +#  globally visible when this function returns.
> > > > > > >> +#
> > > > > > >> +#**/
> > > > > > >> +#VOID
> > > > > > >> +#EFIAPI
> > > > > > >> +#AsmLfence (
> > > > > > >> +#  VOID
> > > > > > >> +#  );
> > > > > > >> +#
> > > > > > >> +ASM_PFX(AsmLfence):
> > > > > > >> +    stp   x29, x30, [sp, #-16]!
> > > > > > >> +    bl MemoryFence
> > > > > > >> +    ldp   x29, x30, [sp], #0x10
> > > > > > >> +    ret
> > > > > > >
> > > > > > >Any reason we can't simply do
> > > > > > >
> > > > > > >b MemoryFence
> > > > > > >
> > > > > > >here?
> > > > > > >
> > > > > > >Also, why I understand the rationale, I still think it would be better
> > > > > > >to change callers of the [x86 specific] AsmLfence() than to introduce
> > > > > > >an alias of MemoryFence() for architectures where Lfence is not
> > > > > > >defined.
> > > > > > >
> > > > > > >This is not only about tidiness, but also about potentially having
> > > > > > >different semantics, which we can't provide in general on ARM, but
> > > > > > >only in particular cases [such as the code that is modified in this
> > > > > > >series]
> > > > > > >
> > > > > > >In other words, newly introduced occurrences of AsmLfence() now
> > > have
> > > > > > >to be audited for being appropriate on AArc64 if they are added to
> > > > > > >generic code.
> > > > > > >
> > > > > > >
> > > > > > >> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > > > > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > > > > >> new file mode 100644
> > > > > > >> index 0000000..7dd5659
> > > > > > >> --- /dev/null
> > > > > > >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > > > > >> @@ -0,0 +1,41 @@
> > > > > > >> +;------------------------------------------------------------------------------
> > > > > > >> +;
> > > > > > >> +; AsmLfence() for AArch64
> > > > > > >> +;
> > > > > > >> +; Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> > > > > > >> +;
> > > > > > >> +; This program and the accompanying materials
> > > > > > >> +; are licensed and made available under the terms and conditions
> > > of the
> > > > > > >BSD License
> > > > > > >> +; which accompanies this distribution.  The full text of the
> > license
> > > may
> > > > > > be
> > > > > > >found at
> > > > > > >> +; http://opensource.org/licenses/bsd-license.php.
> > > > > > >> +;
> > > > > > >> +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON
> > AN
> > > "AS
> > > > > > IS"
> > > > > > >BASIS,
> > > > > > >> +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND,
> > > EITHER
> > > > > > >EXPRESS OR IMPLIED.
> > > > > > >> +;
> > > > > > >> +;------------------------------------------------------------------------------
> > > > > > >> +
> > > > > > >> +  EXPORT AsmLfence
> > > > > > >> +  AREA BaseLib_LowLevel, CODE, READONLY
> > > > > > >> +  # IMPORT
> > > > > > >> +  GCC_ASM_IMPORT(MemoryFence)
> > > > > > >> +
> > > > > > >> +;/**
> > > > > > >> +;  Used to serialize load and store operations.
> > > > > > >> +;
> > > > > > >> +;  All loads and stores that proceed calls to this function are
> > > guaranteed
> > > > > > to
> > > > > > >be
> > > > > > >> +;  globally visible when this function returns.
> > > > > > >> +;
> > > > > > >> +;**/
> > > > > > >> +;VOID
> > > > > > >> +;EFIAPI
> > > > > > >> +;AsmLfence (
> > > > > > >> +;  VOID
> > > > > > >> +;  );
> > > > > > >> +;
> > > > > > >> +AsmLfence
> > > > > > >> +    stp   x29, x30, [sp, #-16]!
> > > > > > >> +    bl MemoryFence
> > > > > > >> +    ldp   x29, x30, [sp], #0x10
> > > > > > >> +    ret
> > > > > > >> +
> > > > > > >> +  END
> > > > > > >> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > > >b/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > > >> index b84e583..b7d7bcb 100644
> > > > > > >> --- a/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > > >> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > > >> @@ -585,6 +585,7 @@
> > > > > > >>    Math64.c
> > > > > > >>
> > > > > > >>    AArch64/MemoryFence.S             | GCC
> > > > > > >> +  AArch64/AsmLfence.S               | GCC
> > > > > > >>    AArch64/SwitchStack.S             | GCC
> > > > > > >>    AArch64/EnableInterrupts.S        | GCC
> > > > > > >>    AArch64/DisableInterrupts.S       | GCC
> > > > > > >> @@ -593,6 +594,7 @@
> > > > > > >>    AArch64/CpuBreakpoint.S           | GCC
> > > > > > >>
> > > > > > >>    AArch64/MemoryFence.asm           | MSFT
> > > > > > >> +  AArch64/AsmLfence.asm             | MSFT
> > > > > > >>    AArch64/SwitchStack.asm           | MSFT
> > > > > > >>    AArch64/EnableInterrupts.asm      | MSFT
> > > > > > >>    AArch64/DisableInterrupts.asm     | MSFT
> > > > > > >> --
> > > > > > >> 2.7.4
> > > > > > >>
> > > > > > _______________________________________________
> > > > > > edk2-devel mailing list
> > > > > > edk2-devel@lists.01.org
> > > > > > https://lists.01.org/mailman/listinfo/edk2-devel
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
  2018-12-17  8:35                 ` Ard Biesheuvel
@ 2018-12-17  8:44                   ` Yao, Jiewen
  2018-12-17  9:27                     ` Ard Biesheuvel
  0 siblings, 1 reply; 52+ messages in thread
From: Yao, Jiewen @ 2018-12-17  8:44 UTC (permalink / raw)
  To: Ard Biesheuvel; +Cc: edk2-devel@lists.01.org, Gao, Liming, Zhang, Chao B

Thanks Ard.
I have little concern about "Spec", because people may read it as "Specification", especially in our team. :)

Thank you
Yao Jiewen

> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Ard Biesheuvel
> Sent: Monday, December 17, 2018 4:35 PM
> To: Yao, Jiewen <jiewen.yao@intel.com>
> Cc: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>; Zhang,
> Chao B <chao.b.zhang@intel.com>
> Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> AsmLfence function
> 
> On Mon, 17 Dec 2018 at 09:30, Yao, Jiewen <jiewen.yao@intel.com> wrote:
> >
> > I reviewed the ARM white paper -
> file:///C:/Users/jyao1/Downloads/Cache_Speculation_Side-channels-v2.4.p
> df
> >
> > I agree with you that LoadFence might not be the best idea.
> >
> > How about SpeculationBarrier() ?
> >
> 
> That works for me. Or SpecFence (). As long as it does not conflate
> memory ordering with controlling the side effects of speculative
> execution, it is ok with me.
> 
> I'll contribute the ARM and AARCH64 implementations asap once the
> generic changes are posted on the list.
> 
> Thanks,
> 
> > > -----Original Message-----
> > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf
> Of
> > > Yao, Jiewen
> > > Sent: Monday, December 17, 2018 4:25 PM
> > > To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Leif Lindholm
> > > <leif.lindholm@linaro.org>
> > > Cc: edk2-devel@lists.01.org; Zhang, Chao B <chao.b.zhang@intel.com>;
> > > Gao, Liming <liming.gao@intel.com>
> > > Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64:
> Add
> > > AsmLfence function
> > >
> > > Hi Ard
> > > I am OK to refine it now.
> > >
> > > Do you have any proposal on the naming from ARM side?
> > >
> > > Thank you
> > > Yao Jiewen
> > >
> > > > -----Original Message-----
> > > > From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> > > > Sent: Monday, December 17, 2018 4:11 PM
> > > > To: Yao, Jiewen <jiewen.yao@intel.com>; Leif Lindholm
> > > > <leif.lindholm@linaro.org>
> > > > Cc: Gao, Liming <liming.gao@intel.com>; Jagadeesh Ujja
> > > > <jagadeesh.ujja@arm.com>; edk2-devel@lists.01.org; Zhang, Chao B
> > > > <chao.b.zhang@intel.com>
> > > > Subject: Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> > > > AsmLfence function
> > > >
> > > > On Mon, 17 Dec 2018 at 08:45, Ard Biesheuvel
> > > <ard.biesheuvel@linaro.org>
> > > > wrote:
> > > > >
> > > > > On Mon, 17 Dec 2018 at 04:29, Yao, Jiewen <jiewen.yao@intel.com>
> > > > wrote:
> > > > > >
> > > > > > I think we have below definition.
> > > > > > -- MemoryFence: Serialize load and store operations.
> > > > > > -- LoadFence: Serialize load operations.
> > > > > > -- StoreFence: Serialize store operations.
> > > > > >
> > > > > > According to IA32 SDM, Intel has MFENCE, LFENCE and SFENCE.
> > > > > > If ARM only has DMB, it is possible to use DMB for MemoryFence,
> > > > LoadFence or StoreFence.
> > > > > >
> > > > > > Maybe it is better to use LoadFence, instead of AsmLFence?
> > > > > > Then we can align with MemoryFence.
> > > > > >
> > > > >
> > > > > I think using AsmLfence() all over the code to limit speculation was a
> > > > > mistake, and I am disappointed nobody from the ARM side was
> involved
> > > > > at all when these changes were proposed.
> > > > >
> > > >
> > > > OK, I have to apologize here. Hao did cc us on these patches, and so
> > > > we did have the opportunity to respond at the time.
> > > >
> > > > But that doesn't change the fact that AsmLfence() should be replaced
> > > > by an abstraction that describes the specific semantics of the x86
> > > > Lfence implemetation beyond memory ordering that we are relying on
> > > > here.
> > > >
> > > >
> > > >
> > > > > The code changes rely on specific semantics of the x86 Lfence
> > > > > instructions, i.e., that beyond load serialization, they ensure that
> > > > > all instructions (not just loads) complete before the lfence
> > > > > completes. This is a much stronger notion than a load barrier, and so
> > > > > the abstraction should have been defined as something like a
> > > > > ExecFence() or pipeline barrier etc, and the x86 specific
> > > > > implementation would have been mapped onto Lfence. For the ARM
> > > side,
> > > > > we probably need an ISB instruction here as well as some kind of
> other
> > > > > barrier. Calling it LoadFence() makes no sense whatsoever.
> > > > >
> > > > >
> > > > >
> > > > >
> > > > >
> > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On
> > > Behalf
> > > > Of
> > > > > > > Gao, Liming
> > > > > > > Sent: Monday, December 17, 2018 10:04 AM
> > > > > > > To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Jagadeesh Ujja
> > > > > > > <jagadeesh.ujja@arm.com>; Leif Lindholm
> > > <leif.lindholm@linaro.org>
> > > > > > > Cc: edk2-devel@lists.01.org; Zhang, Chao B
> > > > <chao.b.zhang@intel.com>
> > > > > > > Subject: Re: [edk2] [PATCH 05/13]
> MdePkg/Library/BaseLib/AArch64:
> > > > Add
> > > > > > > AsmLfence function
> > > > > > >
> > > > > > > Ard:
> > > > > > >   My first comment is to suggest updating the caller code for the
> > > arch
> > > > > > > specific code.  But, there are two drivers that have the same
> usage.
> > > > This
> > > > > > > way will introduce the duplicated code logic. So, I suggest another
> > > way
> > > > to
> > > > > > > extend  AsmLfence() API scope for the different ARCHs. If you
> think
> > > it
> > > > brings
> > > > > > > the confuse, I just think another way to resolve this case in the
> caller
> > > > code.
> > > > > > >
> > > > > > > #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> > > > > > > AsmLfence();
> > > > > > > #else
> > > > > > > MemoryFence()
> > > > > > > #endif
> > > > > > >
> > > > > > > Thanks
> > > > > > > Liming
> > > > > > > >-----Original Message-----
> > > > > > > >From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> > > > > > > >Sent: Friday, December 14, 2018 9:54 PM
> > > > > > > >To: Jagadeesh Ujja <jagadeesh.ujja@arm.com>; Leif Lindholm
> > > > > > > ><leif.lindholm@linaro.org>
> > > > > > > >Cc: edk2-devel@lists.01.org; Gao, Liming
> <liming.gao@intel.com>;
> > > > Zhang,
> > > > > > > >Chao B <chao.b.zhang@intel.com>
> > > > > > > >Subject: Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64:
> Add
> > > > > > > >AsmLfence function
> > > > > > > >
> > > > > > > >On Fri, 14 Dec 2018 at 13:13, Jagadeesh Ujja
> > > > <jagadeesh.ujja@arm.com>
> > > > > > > >wrote:
> > > > > > > >>
> > > > > > > >> Variable service driver includes a call to AsmLfence. To reuse
> this
> > > > > > > >> driver on AArch64 based platforms, add an implementation of
> > > > AsmLfence
> > > > > > > >> that acts as a wrapper on the AArch64 specific MemoryFence
> > > > function.
> > > > > > > >>
> > > > > > > >> Contributed-under: TianoCore Contribution Agreement 1.1
> > > > > > > >> Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> > > > > > > >> ---
> > > > > > > >>  MdePkg/Include/Library/BaseLib.h             | 33
> > > > +++++++++------
> > > > > > > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.S   | 42
> > > > > > > >++++++++++++++++++++
> > > > > > > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.asm | 41
> > > > > > > >+++++++++++++++++++
> > > > > > > >>  MdePkg/Library/BaseLib/BaseLib.inf           |  2 +
> > > > > > > >>  4 files changed, 105 insertions(+), 13 deletions(-)
> > > > > > > >>
> > > > > > > >> diff --git a/MdePkg/Include/Library/BaseLib.h
> > > > > > > >b/MdePkg/Include/Library/BaseLib.h
> > > > > > > >> index 8cc0869..ca961ee 100644
> > > > > > > >> --- a/MdePkg/Include/Library/BaseLib.h
> > > > > > > >> +++ b/MdePkg/Include/Library/BaseLib.h
> > > > > > > >> @@ -7697,19 +7697,6 @@ AsmWriteTr (
> > > > > > > >>    );
> > > > > > > >>
> > > > > > > >>  /**
> > > > > > > >> -  Performs a serializing operation on all load-from-memory
> > > > instructions
> > > > > > > that
> > > > > > > >> -  were issued prior the AsmLfence function.
> > > > > > > >> -
> > > > > > > >> -  Executes a LFENCE instruction. This function is only
> available
> > > on
> > > > IA-32
> > > > > > > and
> > > > > > > >x64.
> > > > > > > >> -
> > > > > > > >> -**/
> > > > > > > >> -VOID
> > > > > > > >> -EFIAPI
> > > > > > > >> -AsmLfence (
> > > > > > > >> -  VOID
> > > > > > > >> -  );
> > > > > > > >> -
> > > > > > > >> -/**
> > > > > > > >>    Patch the immediate operand of an IA32 or X64 instruction
> > > such
> > > > that
> > > > > > > the
> > > > > > > >byte,
> > > > > > > >>    word, dword or qword operand is encoded at the end of
> the
> > > > > > > instruction's
> > > > > > > >>    binary representation.
> > > > > > > >> @@ -7752,4 +7739,24 @@ PatchInstructionX86 (
> > > > > > > >>    );
> > > > > > > >>
> > > > > > > >>  #endif // defined (MDE_CPU_IA32) || defined
> (MDE_CPU_X64)
> > > > > > > >> +
> > > > > > > >> +#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) ||
> > > > defined
> > > > > > > >(MDE_CPU_AARCH64)
> > > > > > > >> +
> > > > > > > >> +/**
> > > > > > > >> +  Performs a serializing operation on all load-from-memory
> > > > instructions
> > > > > > > that
> > > > > > > >> +  were issued prior the AsmLfence function.
> > > > > > > >> +
> > > > > > > >> +  In case of IA-32 and x64, Executes a LFENCE instruction.
> > > > > > > >> +
> > > > > > > >> +  In case of AArch64 this acts as a wrapper on the AArch64
> > > > > > > >> +  specific MemoryFence function
> > > > > > > >> +
> > > > > > > >> +**/
> > > > > > > >> +VOID
> > > > > > > >> +EFIAPI
> > > > > > > >> +AsmLfence (
> > > > > > > >> +  VOID
> > > > > > > >> +  );
> > > > > > > >> +
> > > > > > > >> +#endif  // defined (MDE_CPU_IA32) || defined
> (MDE_CPU_X64)
> > > > ||
> > > > > > > >defined (MDE_CPU_AARCH64)
> > > > > > > >>  #endif // !defined (__BASE_LIB__)
> > > > > > > >> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > > > > > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > > > > > >> new file mode 100644
> > > > > > > >> index 0000000..2fd804b
> > > > > > > >> --- /dev/null
> > > > > > > >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > > > > > >> @@ -0,0 +1,42 @@
> > > > > > > >>
> > > +##------------------------------------------------------------------------------
> > > > > > > >> +#
> > > > > > > >> +# AsmLfence() for AArch64
> > > > > > > >> +#
> > > > > > > >> +# Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> > > > > > > >> +#
> > > > > > > >> +# This program and the accompanying materials
> > > > > > > >> +# are licensed and made available under the terms and
> conditions
> > > > of the
> > > > > > > >BSD License
> > > > > > > >> +# which accompanies this distribution.  The full text of the
> > > license
> > > > may
> > > > > > > be
> > > > > > > >found at
> > > > > > > >> +# http://opensource.org/licenses/bsd-license.php.
> > > > > > > >> +#
> > > > > > > >> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE
> ON
> > > AN
> > > > "AS
> > > > > > > IS"
> > > > > > > >BASIS,
> > > > > > > >> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY
> KIND,
> > > > EITHER
> > > > > > > >EXPRESS OR IMPLIED.
> > > > > > > >> +#
> > > > > > > >>
> > > +##------------------------------------------------------------------------------
> > > > > > > >> +
> > > > > > > >> +.text
> > > > > > > >> +.p2align 2
> > > > > > > >> +
> > > > > > > >> +GCC_ASM_EXPORT(AsmLfence)
> > > > > > > >> +
> > > > > > > >> +# IMPORT
> > > > > > > >> +GCC_ASM_IMPORT(MemoryFence)
> > > > > > > >> +
> > > > > > > >> +#/**
> > > > > > > >> +#  Used to serialize load and store operations.
> > > > > > > >> +#
> > > > > > > >> +#  All loads and stores that proceed calls to this function are
> > > > > > > guaranteed to
> > > > > > > >be
> > > > > > > >> +#  globally visible when this function returns.
> > > > > > > >> +#
> > > > > > > >> +#**/
> > > > > > > >> +#VOID
> > > > > > > >> +#EFIAPI
> > > > > > > >> +#AsmLfence (
> > > > > > > >> +#  VOID
> > > > > > > >> +#  );
> > > > > > > >> +#
> > > > > > > >> +ASM_PFX(AsmLfence):
> > > > > > > >> +    stp   x29, x30, [sp, #-16]!
> > > > > > > >> +    bl MemoryFence
> > > > > > > >> +    ldp   x29, x30, [sp], #0x10
> > > > > > > >> +    ret
> > > > > > > >
> > > > > > > >Any reason we can't simply do
> > > > > > > >
> > > > > > > >b MemoryFence
> > > > > > > >
> > > > > > > >here?
> > > > > > > >
> > > > > > > >Also, why I understand the rationale, I still think it would be
> better
> > > > > > > >to change callers of the [x86 specific] AsmLfence() than to
> introduce
> > > > > > > >an alias of MemoryFence() for architectures where Lfence is not
> > > > > > > >defined.
> > > > > > > >
> > > > > > > >This is not only about tidiness, but also about potentially having
> > > > > > > >different semantics, which we can't provide in general on ARM,
> but
> > > > > > > >only in particular cases [such as the code that is modified in this
> > > > > > > >series]
> > > > > > > >
> > > > > > > >In other words, newly introduced occurrences of AsmLfence()
> now
> > > > have
> > > > > > > >to be audited for being appropriate on AArc64 if they are added
> to
> > > > > > > >generic code.
> > > > > > > >
> > > > > > > >
> > > > > > > >> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > > > > > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > > > > > >> new file mode 100644
> > > > > > > >> index 0000000..7dd5659
> > > > > > > >> --- /dev/null
> > > > > > > >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > > > > > >> @@ -0,0 +1,41 @@
> > > > > > > >>
> +;------------------------------------------------------------------------------
> > > > > > > >> +;
> > > > > > > >> +; AsmLfence() for AArch64
> > > > > > > >> +;
> > > > > > > >> +; Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> > > > > > > >> +;
> > > > > > > >> +; This program and the accompanying materials
> > > > > > > >> +; are licensed and made available under the terms and
> conditions
> > > > of the
> > > > > > > >BSD License
> > > > > > > >> +; which accompanies this distribution.  The full text of the
> > > license
> > > > may
> > > > > > > be
> > > > > > > >found at
> > > > > > > >> +; http://opensource.org/licenses/bsd-license.php.
> > > > > > > >> +;
> > > > > > > >> +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE
> ON
> > > AN
> > > > "AS
> > > > > > > IS"
> > > > > > > >BASIS,
> > > > > > > >> +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY
> KIND,
> > > > EITHER
> > > > > > > >EXPRESS OR IMPLIED.
> > > > > > > >> +;
> > > > > > > >>
> +;------------------------------------------------------------------------------
> > > > > > > >> +
> > > > > > > >> +  EXPORT AsmLfence
> > > > > > > >> +  AREA BaseLib_LowLevel, CODE, READONLY
> > > > > > > >> +  # IMPORT
> > > > > > > >> +  GCC_ASM_IMPORT(MemoryFence)
> > > > > > > >> +
> > > > > > > >> +;/**
> > > > > > > >> +;  Used to serialize load and store operations.
> > > > > > > >> +;
> > > > > > > >> +;  All loads and stores that proceed calls to this function are
> > > > guaranteed
> > > > > > > to
> > > > > > > >be
> > > > > > > >> +;  globally visible when this function returns.
> > > > > > > >> +;
> > > > > > > >> +;**/
> > > > > > > >> +;VOID
> > > > > > > >> +;EFIAPI
> > > > > > > >> +;AsmLfence (
> > > > > > > >> +;  VOID
> > > > > > > >> +;  );
> > > > > > > >> +;
> > > > > > > >> +AsmLfence
> > > > > > > >> +    stp   x29, x30, [sp, #-16]!
> > > > > > > >> +    bl MemoryFence
> > > > > > > >> +    ldp   x29, x30, [sp], #0x10
> > > > > > > >> +    ret
> > > > > > > >> +
> > > > > > > >> +  END
> > > > > > > >> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > > > >b/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > > > >> index b84e583..b7d7bcb 100644
> > > > > > > >> --- a/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > > > >> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > > > >> @@ -585,6 +585,7 @@
> > > > > > > >>    Math64.c
> > > > > > > >>
> > > > > > > >>    AArch64/MemoryFence.S             | GCC
> > > > > > > >> +  AArch64/AsmLfence.S               | GCC
> > > > > > > >>    AArch64/SwitchStack.S             | GCC
> > > > > > > >>    AArch64/EnableInterrupts.S        | GCC
> > > > > > > >>    AArch64/DisableInterrupts.S       | GCC
> > > > > > > >> @@ -593,6 +594,7 @@
> > > > > > > >>    AArch64/CpuBreakpoint.S           | GCC
> > > > > > > >>
> > > > > > > >>    AArch64/MemoryFence.asm           | MSFT
> > > > > > > >> +  AArch64/AsmLfence.asm             | MSFT
> > > > > > > >>    AArch64/SwitchStack.asm           | MSFT
> > > > > > > >>    AArch64/EnableInterrupts.asm      | MSFT
> > > > > > > >>    AArch64/DisableInterrupts.asm     | MSFT
> > > > > > > >> --
> > > > > > > >> 2.7.4
> > > > > > > >>
> > > > > > > _______________________________________________
> > > > > > > edk2-devel mailing list
> > > > > > > edk2-devel@lists.01.org
> > > > > > > https://lists.01.org/mailman/listinfo/edk2-devel
> > > _______________________________________________
> > > edk2-devel mailing list
> > > edk2-devel@lists.01.org
> > > https://lists.01.org/mailman/listinfo/edk2-devel
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
  2018-12-17  8:44                   ` Yao, Jiewen
@ 2018-12-17  9:27                     ` Ard Biesheuvel
  2018-12-18  2:08                       ` Yao, Jiewen
  0 siblings, 1 reply; 52+ messages in thread
From: Ard Biesheuvel @ 2018-12-17  9:27 UTC (permalink / raw)
  To: Yao, Jiewen; +Cc: edk2-devel@lists.01.org, Gao, Liming, Zhang, Chao B

On Mon, 17 Dec 2018 at 09:44, Yao, Jiewen <jiewen.yao@intel.com> wrote:
>
> Thanks Ard.
> I have little concern about "Spec", because people may read it as "Specification", especially in our team. :)
>

I understand :-)

SpeculationBarrier() is fine with me.


>
> > -----Original Message-----
> > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> > Ard Biesheuvel
> > Sent: Monday, December 17, 2018 4:35 PM
> > To: Yao, Jiewen <jiewen.yao@intel.com>
> > Cc: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>; Zhang,
> > Chao B <chao.b.zhang@intel.com>
> > Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> > AsmLfence function
> >
> > On Mon, 17 Dec 2018 at 09:30, Yao, Jiewen <jiewen.yao@intel.com> wrote:
> > >
> > > I reviewed the ARM white paper -
> > file:///C:/Users/jyao1/Downloads/Cache_Speculation_Side-channels-v2.4.p
> > df
> > >
> > > I agree with you that LoadFence might not be the best idea.
> > >
> > > How about SpeculationBarrier() ?
> > >
> >
> > That works for me. Or SpecFence (). As long as it does not conflate
> > memory ordering with controlling the side effects of speculative
> > execution, it is ok with me.
> >
> > I'll contribute the ARM and AARCH64 implementations asap once the
> > generic changes are posted on the list.
> >
> > Thanks,
> >
> > > > -----Original Message-----
> > > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf
> > Of
> > > > Yao, Jiewen
> > > > Sent: Monday, December 17, 2018 4:25 PM
> > > > To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Leif Lindholm
> > > > <leif.lindholm@linaro.org>
> > > > Cc: edk2-devel@lists.01.org; Zhang, Chao B <chao.b.zhang@intel.com>;
> > > > Gao, Liming <liming.gao@intel.com>
> > > > Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64:
> > Add
> > > > AsmLfence function
> > > >
> > > > Hi Ard
> > > > I am OK to refine it now.
> > > >
> > > > Do you have any proposal on the naming from ARM side?
> > > >
> > > > Thank you
> > > > Yao Jiewen
> > > >
> > > > > -----Original Message-----
> > > > > From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> > > > > Sent: Monday, December 17, 2018 4:11 PM
> > > > > To: Yao, Jiewen <jiewen.yao@intel.com>; Leif Lindholm
> > > > > <leif.lindholm@linaro.org>
> > > > > Cc: Gao, Liming <liming.gao@intel.com>; Jagadeesh Ujja
> > > > > <jagadeesh.ujja@arm.com>; edk2-devel@lists.01.org; Zhang, Chao B
> > > > > <chao.b.zhang@intel.com>
> > > > > Subject: Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> > > > > AsmLfence function
> > > > >
> > > > > On Mon, 17 Dec 2018 at 08:45, Ard Biesheuvel
> > > > <ard.biesheuvel@linaro.org>
> > > > > wrote:
> > > > > >
> > > > > > On Mon, 17 Dec 2018 at 04:29, Yao, Jiewen <jiewen.yao@intel.com>
> > > > > wrote:
> > > > > > >
> > > > > > > I think we have below definition.
> > > > > > > -- MemoryFence: Serialize load and store operations.
> > > > > > > -- LoadFence: Serialize load operations.
> > > > > > > -- StoreFence: Serialize store operations.
> > > > > > >
> > > > > > > According to IA32 SDM, Intel has MFENCE, LFENCE and SFENCE.
> > > > > > > If ARM only has DMB, it is possible to use DMB for MemoryFence,
> > > > > LoadFence or StoreFence.
> > > > > > >
> > > > > > > Maybe it is better to use LoadFence, instead of AsmLFence?
> > > > > > > Then we can align with MemoryFence.
> > > > > > >
> > > > > >
> > > > > > I think using AsmLfence() all over the code to limit speculation was a
> > > > > > mistake, and I am disappointed nobody from the ARM side was
> > involved
> > > > > > at all when these changes were proposed.
> > > > > >
> > > > >
> > > > > OK, I have to apologize here. Hao did cc us on these patches, and so
> > > > > we did have the opportunity to respond at the time.
> > > > >
> > > > > But that doesn't change the fact that AsmLfence() should be replaced
> > > > > by an abstraction that describes the specific semantics of the x86
> > > > > Lfence implemetation beyond memory ordering that we are relying on
> > > > > here.
> > > > >
> > > > >
> > > > >
> > > > > > The code changes rely on specific semantics of the x86 Lfence
> > > > > > instructions, i.e., that beyond load serialization, they ensure that
> > > > > > all instructions (not just loads) complete before the lfence
> > > > > > completes. This is a much stronger notion than a load barrier, and so
> > > > > > the abstraction should have been defined as something like a
> > > > > > ExecFence() or pipeline barrier etc, and the x86 specific
> > > > > > implementation would have been mapped onto Lfence. For the ARM
> > > > side,
> > > > > > we probably need an ISB instruction here as well as some kind of
> > other
> > > > > > barrier. Calling it LoadFence() makes no sense whatsoever.
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > >
> > > > > > > > -----Original Message-----
> > > > > > > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On
> > > > Behalf
> > > > > Of
> > > > > > > > Gao, Liming
> > > > > > > > Sent: Monday, December 17, 2018 10:04 AM
> > > > > > > > To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Jagadeesh Ujja
> > > > > > > > <jagadeesh.ujja@arm.com>; Leif Lindholm
> > > > <leif.lindholm@linaro.org>
> > > > > > > > Cc: edk2-devel@lists.01.org; Zhang, Chao B
> > > > > <chao.b.zhang@intel.com>
> > > > > > > > Subject: Re: [edk2] [PATCH 05/13]
> > MdePkg/Library/BaseLib/AArch64:
> > > > > Add
> > > > > > > > AsmLfence function
> > > > > > > >
> > > > > > > > Ard:
> > > > > > > >   My first comment is to suggest updating the caller code for the
> > > > arch
> > > > > > > > specific code.  But, there are two drivers that have the same
> > usage.
> > > > > This
> > > > > > > > way will introduce the duplicated code logic. So, I suggest another
> > > > way
> > > > > to
> > > > > > > > extend  AsmLfence() API scope for the different ARCHs. If you
> > think
> > > > it
> > > > > brings
> > > > > > > > the confuse, I just think another way to resolve this case in the
> > caller
> > > > > code.
> > > > > > > >
> > > > > > > > #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> > > > > > > > AsmLfence();
> > > > > > > > #else
> > > > > > > > MemoryFence()
> > > > > > > > #endif
> > > > > > > >
> > > > > > > > Thanks
> > > > > > > > Liming
> > > > > > > > >-----Original Message-----
> > > > > > > > >From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> > > > > > > > >Sent: Friday, December 14, 2018 9:54 PM
> > > > > > > > >To: Jagadeesh Ujja <jagadeesh.ujja@arm.com>; Leif Lindholm
> > > > > > > > ><leif.lindholm@linaro.org>
> > > > > > > > >Cc: edk2-devel@lists.01.org; Gao, Liming
> > <liming.gao@intel.com>;
> > > > > Zhang,
> > > > > > > > >Chao B <chao.b.zhang@intel.com>
> > > > > > > > >Subject: Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64:
> > Add
> > > > > > > > >AsmLfence function
> > > > > > > > >
> > > > > > > > >On Fri, 14 Dec 2018 at 13:13, Jagadeesh Ujja
> > > > > <jagadeesh.ujja@arm.com>
> > > > > > > > >wrote:
> > > > > > > > >>
> > > > > > > > >> Variable service driver includes a call to AsmLfence. To reuse
> > this
> > > > > > > > >> driver on AArch64 based platforms, add an implementation of
> > > > > AsmLfence
> > > > > > > > >> that acts as a wrapper on the AArch64 specific MemoryFence
> > > > > function.
> > > > > > > > >>
> > > > > > > > >> Contributed-under: TianoCore Contribution Agreement 1.1
> > > > > > > > >> Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> > > > > > > > >> ---
> > > > > > > > >>  MdePkg/Include/Library/BaseLib.h             | 33
> > > > > +++++++++------
> > > > > > > > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.S   | 42
> > > > > > > > >++++++++++++++++++++
> > > > > > > > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.asm | 41
> > > > > > > > >+++++++++++++++++++
> > > > > > > > >>  MdePkg/Library/BaseLib/BaseLib.inf           |  2 +
> > > > > > > > >>  4 files changed, 105 insertions(+), 13 deletions(-)
> > > > > > > > >>
> > > > > > > > >> diff --git a/MdePkg/Include/Library/BaseLib.h
> > > > > > > > >b/MdePkg/Include/Library/BaseLib.h
> > > > > > > > >> index 8cc0869..ca961ee 100644
> > > > > > > > >> --- a/MdePkg/Include/Library/BaseLib.h
> > > > > > > > >> +++ b/MdePkg/Include/Library/BaseLib.h
> > > > > > > > >> @@ -7697,19 +7697,6 @@ AsmWriteTr (
> > > > > > > > >>    );
> > > > > > > > >>
> > > > > > > > >>  /**
> > > > > > > > >> -  Performs a serializing operation on all load-from-memory
> > > > > instructions
> > > > > > > > that
> > > > > > > > >> -  were issued prior the AsmLfence function.
> > > > > > > > >> -
> > > > > > > > >> -  Executes a LFENCE instruction. This function is only
> > available
> > > > on
> > > > > IA-32
> > > > > > > > and
> > > > > > > > >x64.
> > > > > > > > >> -
> > > > > > > > >> -**/
> > > > > > > > >> -VOID
> > > > > > > > >> -EFIAPI
> > > > > > > > >> -AsmLfence (
> > > > > > > > >> -  VOID
> > > > > > > > >> -  );
> > > > > > > > >> -
> > > > > > > > >> -/**
> > > > > > > > >>    Patch the immediate operand of an IA32 or X64 instruction
> > > > such
> > > > > that
> > > > > > > > the
> > > > > > > > >byte,
> > > > > > > > >>    word, dword or qword operand is encoded at the end of
> > the
> > > > > > > > instruction's
> > > > > > > > >>    binary representation.
> > > > > > > > >> @@ -7752,4 +7739,24 @@ PatchInstructionX86 (
> > > > > > > > >>    );
> > > > > > > > >>
> > > > > > > > >>  #endif // defined (MDE_CPU_IA32) || defined
> > (MDE_CPU_X64)
> > > > > > > > >> +
> > > > > > > > >> +#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) ||
> > > > > defined
> > > > > > > > >(MDE_CPU_AARCH64)
> > > > > > > > >> +
> > > > > > > > >> +/**
> > > > > > > > >> +  Performs a serializing operation on all load-from-memory
> > > > > instructions
> > > > > > > > that
> > > > > > > > >> +  were issued prior the AsmLfence function.
> > > > > > > > >> +
> > > > > > > > >> +  In case of IA-32 and x64, Executes a LFENCE instruction.
> > > > > > > > >> +
> > > > > > > > >> +  In case of AArch64 this acts as a wrapper on the AArch64
> > > > > > > > >> +  specific MemoryFence function
> > > > > > > > >> +
> > > > > > > > >> +**/
> > > > > > > > >> +VOID
> > > > > > > > >> +EFIAPI
> > > > > > > > >> +AsmLfence (
> > > > > > > > >> +  VOID
> > > > > > > > >> +  );
> > > > > > > > >> +
> > > > > > > > >> +#endif  // defined (MDE_CPU_IA32) || defined
> > (MDE_CPU_X64)
> > > > > ||
> > > > > > > > >defined (MDE_CPU_AARCH64)
> > > > > > > > >>  #endif // !defined (__BASE_LIB__)
> > > > > > > > >> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > > > > > > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > > > > > > >> new file mode 100644
> > > > > > > > >> index 0000000..2fd804b
> > > > > > > > >> --- /dev/null
> > > > > > > > >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > > > > > > >> @@ -0,0 +1,42 @@
> > > > > > > > >>
> > > > +##------------------------------------------------------------------------------
> > > > > > > > >> +#
> > > > > > > > >> +# AsmLfence() for AArch64
> > > > > > > > >> +#
> > > > > > > > >> +# Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> > > > > > > > >> +#
> > > > > > > > >> +# This program and the accompanying materials
> > > > > > > > >> +# are licensed and made available under the terms and
> > conditions
> > > > > of the
> > > > > > > > >BSD License
> > > > > > > > >> +# which accompanies this distribution.  The full text of the
> > > > license
> > > > > may
> > > > > > > > be
> > > > > > > > >found at
> > > > > > > > >> +# http://opensource.org/licenses/bsd-license.php.
> > > > > > > > >> +#
> > > > > > > > >> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE
> > ON
> > > > AN
> > > > > "AS
> > > > > > > > IS"
> > > > > > > > >BASIS,
> > > > > > > > >> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY
> > KIND,
> > > > > EITHER
> > > > > > > > >EXPRESS OR IMPLIED.
> > > > > > > > >> +#
> > > > > > > > >>
> > > > +##------------------------------------------------------------------------------
> > > > > > > > >> +
> > > > > > > > >> +.text
> > > > > > > > >> +.p2align 2
> > > > > > > > >> +
> > > > > > > > >> +GCC_ASM_EXPORT(AsmLfence)
> > > > > > > > >> +
> > > > > > > > >> +# IMPORT
> > > > > > > > >> +GCC_ASM_IMPORT(MemoryFence)
> > > > > > > > >> +
> > > > > > > > >> +#/**
> > > > > > > > >> +#  Used to serialize load and store operations.
> > > > > > > > >> +#
> > > > > > > > >> +#  All loads and stores that proceed calls to this function are
> > > > > > > > guaranteed to
> > > > > > > > >be
> > > > > > > > >> +#  globally visible when this function returns.
> > > > > > > > >> +#
> > > > > > > > >> +#**/
> > > > > > > > >> +#VOID
> > > > > > > > >> +#EFIAPI
> > > > > > > > >> +#AsmLfence (
> > > > > > > > >> +#  VOID
> > > > > > > > >> +#  );
> > > > > > > > >> +#
> > > > > > > > >> +ASM_PFX(AsmLfence):
> > > > > > > > >> +    stp   x29, x30, [sp, #-16]!
> > > > > > > > >> +    bl MemoryFence
> > > > > > > > >> +    ldp   x29, x30, [sp], #0x10
> > > > > > > > >> +    ret
> > > > > > > > >
> > > > > > > > >Any reason we can't simply do
> > > > > > > > >
> > > > > > > > >b MemoryFence
> > > > > > > > >
> > > > > > > > >here?
> > > > > > > > >
> > > > > > > > >Also, why I understand the rationale, I still think it would be
> > better
> > > > > > > > >to change callers of the [x86 specific] AsmLfence() than to
> > introduce
> > > > > > > > >an alias of MemoryFence() for architectures where Lfence is not
> > > > > > > > >defined.
> > > > > > > > >
> > > > > > > > >This is not only about tidiness, but also about potentially having
> > > > > > > > >different semantics, which we can't provide in general on ARM,
> > but
> > > > > > > > >only in particular cases [such as the code that is modified in this
> > > > > > > > >series]
> > > > > > > > >
> > > > > > > > >In other words, newly introduced occurrences of AsmLfence()
> > now
> > > > > have
> > > > > > > > >to be audited for being appropriate on AArc64 if they are added
> > to
> > > > > > > > >generic code.
> > > > > > > > >
> > > > > > > > >
> > > > > > > > >> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > > > > > > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > > > > > > >> new file mode 100644
> > > > > > > > >> index 0000000..7dd5659
> > > > > > > > >> --- /dev/null
> > > > > > > > >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > > > > > > >> @@ -0,0 +1,41 @@
> > > > > > > > >>
> > +;------------------------------------------------------------------------------
> > > > > > > > >> +;
> > > > > > > > >> +; AsmLfence() for AArch64
> > > > > > > > >> +;
> > > > > > > > >> +; Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> > > > > > > > >> +;
> > > > > > > > >> +; This program and the accompanying materials
> > > > > > > > >> +; are licensed and made available under the terms and
> > conditions
> > > > > of the
> > > > > > > > >BSD License
> > > > > > > > >> +; which accompanies this distribution.  The full text of the
> > > > license
> > > > > may
> > > > > > > > be
> > > > > > > > >found at
> > > > > > > > >> +; http://opensource.org/licenses/bsd-license.php.
> > > > > > > > >> +;
> > > > > > > > >> +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE
> > ON
> > > > AN
> > > > > "AS
> > > > > > > > IS"
> > > > > > > > >BASIS,
> > > > > > > > >> +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY
> > KIND,
> > > > > EITHER
> > > > > > > > >EXPRESS OR IMPLIED.
> > > > > > > > >> +;
> > > > > > > > >>
> > +;------------------------------------------------------------------------------
> > > > > > > > >> +
> > > > > > > > >> +  EXPORT AsmLfence
> > > > > > > > >> +  AREA BaseLib_LowLevel, CODE, READONLY
> > > > > > > > >> +  # IMPORT
> > > > > > > > >> +  GCC_ASM_IMPORT(MemoryFence)
> > > > > > > > >> +
> > > > > > > > >> +;/**
> > > > > > > > >> +;  Used to serialize load and store operations.
> > > > > > > > >> +;
> > > > > > > > >> +;  All loads and stores that proceed calls to this function are
> > > > > guaranteed
> > > > > > > > to
> > > > > > > > >be
> > > > > > > > >> +;  globally visible when this function returns.
> > > > > > > > >> +;
> > > > > > > > >> +;**/
> > > > > > > > >> +;VOID
> > > > > > > > >> +;EFIAPI
> > > > > > > > >> +;AsmLfence (
> > > > > > > > >> +;  VOID
> > > > > > > > >> +;  );
> > > > > > > > >> +;
> > > > > > > > >> +AsmLfence
> > > > > > > > >> +    stp   x29, x30, [sp, #-16]!
> > > > > > > > >> +    bl MemoryFence
> > > > > > > > >> +    ldp   x29, x30, [sp], #0x10
> > > > > > > > >> +    ret
> > > > > > > > >> +
> > > > > > > > >> +  END
> > > > > > > > >> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > > > > >b/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > > > > >> index b84e583..b7d7bcb 100644
> > > > > > > > >> --- a/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > > > > >> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > > > > >> @@ -585,6 +585,7 @@
> > > > > > > > >>    Math64.c
> > > > > > > > >>
> > > > > > > > >>    AArch64/MemoryFence.S             | GCC
> > > > > > > > >> +  AArch64/AsmLfence.S               | GCC
> > > > > > > > >>    AArch64/SwitchStack.S             | GCC
> > > > > > > > >>    AArch64/EnableInterrupts.S        | GCC
> > > > > > > > >>    AArch64/DisableInterrupts.S       | GCC
> > > > > > > > >> @@ -593,6 +594,7 @@
> > > > > > > > >>    AArch64/CpuBreakpoint.S           | GCC
> > > > > > > > >>
> > > > > > > > >>    AArch64/MemoryFence.asm           | MSFT
> > > > > > > > >> +  AArch64/AsmLfence.asm             | MSFT
> > > > > > > > >>    AArch64/SwitchStack.asm           | MSFT
> > > > > > > > >>    AArch64/EnableInterrupts.asm      | MSFT
> > > > > > > > >>    AArch64/DisableInterrupts.asm     | MSFT
> > > > > > > > >> --
> > > > > > > > >> 2.7.4
> > > > > > > > >>
> > > > > > > > _______________________________________________
> > > > > > > > edk2-devel mailing list
> > > > > > > > edk2-devel@lists.01.org
> > > > > > > > https://lists.01.org/mailman/listinfo/edk2-devel
> > > > _______________________________________________
> > > > edk2-devel mailing list
> > > > edk2-devel@lists.01.org
> > > > https://lists.01.org/mailman/listinfo/edk2-devel
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 00/13] Extend secure variable service to be usable from Standalone MM
  2018-12-17  1:45 ` [PATCH 00/13] Extend secure variable service to be usable from Standalone MM Gao, Liming
@ 2018-12-17 11:46   ` Jagadeesh Ujja
  2018-12-18  4:37     ` Gao, Liming
  0 siblings, 1 reply; 52+ messages in thread
From: Jagadeesh Ujja @ 2018-12-17 11:46 UTC (permalink / raw)
  To: Gao, Liming
  Cc: edk2-devel@lists.01.org, Zhang, Chao B, leif.lindholm@linaro.org,
	ard.biesheuvel@linaro.org

Hi Liming,

On Mon, Dec 17, 2018 at 7:15 AM Gao, Liming <liming.gao@intel.com> wrote:
>
> One question here. Why separate StandaloneMmServicesTableLib to two library classes? Current MdePkg\Include\Library\SmmServicesTableLib.h is one library class. MdePkg\Library\SmmServicesTableLib\SmmServicesTableLib.inf is its implementation. StandaloneMmServicesTableLib should be same to it.
> StandaloneMmServicesTableLib is the library class. MdePkg\Library\StandaloneMmRuntimeDxe is its library instance.
>
Thanks for your review.

The implementation of the "StandaloneMmServicesTableLib" library class
is at "StandaloneMmPkg/Library/StandaloneMmServicesTableLib/". As this
patchset reuses some of the DXE_DRIVER drivers as MM_STANDALONE
drivers, the "StandaloneMmServicesTableLib" library class definition
was placed within MdePkg. The reason for splitting the library class
definition (in MdePkg) and its implementation (in StandaloneMmPkg) was
due to your comment that "edk2 packages" should not have any reference
to StandaloneMmPkg.dec.

The "StandaloneMmRuntimeDxe" library now just has an implementation of
InMm(). And so, this can be kept as a separate library with no
dependency on StandaloneMmPkg. So this was the reason to split
"StandaloneMmRuntimeDxe" and "StandaloneMmServicesTableLib" into two
separate libraries.

thanks
Jagadeesh
> Thanks
> Liming
> >-----Original Message-----
> >From: Jagadeesh Ujja [mailto:jagadeesh.ujja@arm.com]
> >Sent: Friday, December 14, 2018 8:13 PM
> >To: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>; Zhang,
> >Chao B <chao.b.zhang@intel.com>; leif.lindholm@linaro.org;
> >ard.biesheuvel@linaro.org
> >Subject: [PATCH 00/13] Extend secure variable service to be usable from
> >Standalone MM
> >
> >Changes since RFC v4:
> >- Addressed all the comments from Liming Gao
> >  - Added an additional PCD 'PcdStandaloneMmCodeEnabled' to indicate
> >    presence of StandaloneMM support.
> >  - MdePkg.dec file updated to include StandaloneMmServiceTableLib and
> >    StandaloneMmRuntimeDxe library.
> >  - Platform specific changes will be posted in a seperate patchset.
> >  - AsmLfence wrapper function is supported for AArch64 platforms.
> >  - All the patches in this series can be pulled from
> >    https://github.com/jagadeeshujja/edk2 (branch:
> >topics/aarch64_secure_vars)
> >
> >Changes since RFC v3:
> >- Addressed all the comments from Liming Gao
> >  - Added a AArch64 implementation of AsmLfence which is a wrapper for
> >    MemoryFence. The changes in variable service driver in v3 of this
> >    patchset that used MemoryFence instead of AsmLfence have been
> >removed.
> >  - Added StandaloneMmServicesTableLib.h and StandaloneMmRuntimeDxe
> >    library into MdePkg.
> >  - Renamed PcdStandaloneMmEnable as PcdStandaloneMmVariableEnabled
> >and
> >    added to in to MdePkg.
> >  - Now with above changes, edk2 packages don't need to depend on
> >    StandaloneMmPkg/StandaloneMmPkg.dec
> >- Addressed comments from Ting Ye
> >  - Removed the hacks in the v3 version.
> >  - Will relook into the “TimerWrapp.c” file and add a appropriate
> >    implementation of this for MM Standalone mode code.
> >
> >Changes since RFC v2:
> >- Added 'Contributed-under' tag, removed Change-ID tag and
> >  maintained a single signed-off-by for the all the patches.
> >
> >Changes since RFC v1:
> >- Addressed all the comments from Liming Gao
> >  - Removed the use of #ifdef/#else/#endif and used a Pcd instead to
> >    select between MM and non-MM paths.
> >  - Removed all dependencies on edk2-platforms.
> >  - Dropped the use of mMmst and used gSmst instead.
> >  - Added a dummy implementation UefiRuntimeServiceTableLib for
> >    MM_STANDALONE usage
> >- Replaced all uses of AsmLfence with MemoryFence from variable
> >  service code.
> >- Add a new StandaloneMmRuntimeDxe library to for use by non-MM code.
> >
> >This patch series extends the existing secure variable service support for
> >use with Standalone MM. This is applicable to paltforms that use Standalone
> >Management Mode to protect access to non-volatile memory (NOR flash in
> >case
> >of these patches) used to store the secure EFI variables.
> >
> >The first patch pulls in additional libraries from the staging branch of
> >StandaloneMmPkg into the edk2's StandaloneMmPkg. The existing secure
> >variable
> >service implementation supports only the traditional MM mode and so the
> >rest
> >of the patches extends the existing secure variable service support to be
> >useable with Standalone MM mode as well.
> >
> >Jagadeesh Ujja (13):
> >  StandaloneMmPkg: Pull in additonal libraries from staging branch
> >  MdePkg: Add a PCD that indicates presence of Standalone MM mode
> >  MdeModulePkg: Add a PCD to indicate Standalone MM supports secure
> >    variable
> >  MdePkg/Include: add StandaloneMmServicesTableLib header file
> >  MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
> >  MdePkg/Library: Add StandaloneMmRuntimeDxe library
> >  MdeModulePkg/FaultTolerantWriteDxe: allow reusability as a MM driver
> >  MdeModulePkg/Variable/RuntimeDxe: adapt for usability with MM
> >    Standalone
> >  MdeModulePkg/Variable/RuntimeDxe: adapt as a MM Standalone driver
> >  MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this
> >    library
> >  ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver
> >  SecurityPkg/AuthVariableLib: allow MM_STANDALONE drivers to use this
> >    library
> >  CryptoPkg/BaseCryptLib: allow MM_STANDALONE drivers to use this
> >    library
> >
> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c
> >|   2 +-
> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c                                            |
> >210 ++++-
> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h                                            |
> >5 +-
> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf                                          |
> >2 +
> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c
> >|  96 +--
> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
> >|  76 ++
> > CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf                                             |   7
> >+-
> > CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf                                          |   4
> >+
> > CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c                                       |
> >15 +-
> > MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf                                            |
> >5 +-
> > MdeModulePkg/MdeModulePkg.dec                                                               |   5 +
> > MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
> >|   1 +
> > MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
> >| 203 +++--
> >
> >MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandal
> >oneMm.inf             | 101 +++
> > MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c
> >|  27 +-
> > MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
> >|  37 +-
> > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> >|   1 +
> > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
> >| 201 ++++-
> > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
> >|  31 +-
> >
> >MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.i
> >nf                        |   3 +
> > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
> >| 132 ++++
> > MdePkg/Include/Library/BaseLib.h                                                            |  33 +-
> > MdePkg/Include/Library/StandaloneMmRuntimeDxe.h
> >|  39 +
> > MdePkg/Include/Library/StandaloneMmServicesTableLib.h
> >|  25 +
> > MdePkg/Library/BaseLib/AArch64/AsmLfence.S                                                  |  42
> >+
> > MdePkg/Library/BaseLib/AArch64/AsmLfence.asm                                                |
> >41 +
> > MdePkg/Library/BaseLib/BaseLib.inf                                                          |   2 +
> > MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c
> >|  36 +
> > MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf
> >|  36 +
> > MdePkg/MdePkg.dec                                                                           |  12 +
> > SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf                                     |
> >5 +-
> >
> >StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreH
> >obLib.inf                   |   2 +-
> >
> >StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmC
> >oreHobLibInternal.c         |  64 ++
> > StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
> >| 655 ++++++++++++++++
> > StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
> >|  48 ++
> >
> >StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalone
> >MmMemoryAllocationLib.c   | 824 ++++++++++++++++++++
> >
> >StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalone
> >MmMemoryAllocationLib.inf |  45 ++
> >
> >StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmS
> >ervicesTableLib.c         |  64 ++
> >
> >StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmS
> >ervicesTableLib.inf       |  36 +
> > 39 files changed, 2929 insertions(+), 244 deletions(-)
> > create mode 100644
> >ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
> > create mode 100644
> >MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandal
> >oneMm.inf
> > create mode 100644
> >MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
> > create mode 100644 MdePkg/Include/Library/StandaloneMmRuntimeDxe.h
> > create mode 100644
> >MdePkg/Include/Library/StandaloneMmServicesTableLib.h
> > create mode 100644 MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > create mode 100644 MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > create mode 100644
> >MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c
> > create mode 100644
> >MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf
> > create mode 100644
> >StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmC
> >oreHobLibInternal.c
> > create mode 100644
> >StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
> > create mode 100644
> >StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
> > create mode 100644
> >StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalone
> >MmMemoryAllocationLib.c
> > create mode 100644
> >StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalone
> >MmMemoryAllocationLib.inf
> > create mode 100644
> >StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmS
> >ervicesTableLib.c
> > create mode 100644
> >StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmS
> >ervicesTableLib.inf
> >
> >--
> >2.7.4
>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
  2018-12-17  9:27                     ` Ard Biesheuvel
@ 2018-12-18  2:08                       ` Yao, Jiewen
  2018-12-18  2:12                         ` Gao, Liming
  2018-12-20  9:00                         ` Jagadeesh Ujja
  0 siblings, 2 replies; 52+ messages in thread
From: Yao, Jiewen @ 2018-12-18  2:08 UTC (permalink / raw)
  To: Ard Biesheuvel, Wu, Hao A
  Cc: edk2-devel@lists.01.org, Gao, Liming, Zhang, Chao B

+ Wu Hao, since he contributed the original patch.

Ard
Would you please file a Bugzilla for that? Then we can start working on that.

Thank you
Yao Jiewen

> -----Original Message-----
> From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> Sent: Monday, December 17, 2018 5:28 PM
> To: Yao, Jiewen <jiewen.yao@intel.com>
> Cc: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>; Zhang,
> Chao B <chao.b.zhang@intel.com>
> Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> AsmLfence function
> 
> On Mon, 17 Dec 2018 at 09:44, Yao, Jiewen <jiewen.yao@intel.com> wrote:
> >
> > Thanks Ard.
> > I have little concern about "Spec", because people may read it as
> "Specification", especially in our team. :)
> >
> 
> I understand :-)
> 
> SpeculationBarrier() is fine with me.
> 
> 
> >
> > > -----Original Message-----
> > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf
> Of
> > > Ard Biesheuvel
> > > Sent: Monday, December 17, 2018 4:35 PM
> > > To: Yao, Jiewen <jiewen.yao@intel.com>
> > > Cc: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>;
> Zhang,
> > > Chao B <chao.b.zhang@intel.com>
> > > Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64:
> Add
> > > AsmLfence function
> > >
> > > On Mon, 17 Dec 2018 at 09:30, Yao, Jiewen <jiewen.yao@intel.com>
> wrote:
> > > >
> > > > I reviewed the ARM white paper -
> > >
> file:///C:/Users/jyao1/Downloads/Cache_Speculation_Side-channels-v2.4.p
> > > df
> > > >
> > > > I agree with you that LoadFence might not be the best idea.
> > > >
> > > > How about SpeculationBarrier() ?
> > > >
> > >
> > > That works for me. Or SpecFence (). As long as it does not conflate
> > > memory ordering with controlling the side effects of speculative
> > > execution, it is ok with me.
> > >
> > > I'll contribute the ARM and AARCH64 implementations asap once the
> > > generic changes are posted on the list.
> > >
> > > Thanks,
> > >
> > > > > -----Original Message-----
> > > > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On
> Behalf
> > > Of
> > > > > Yao, Jiewen
> > > > > Sent: Monday, December 17, 2018 4:25 PM
> > > > > To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Leif Lindholm
> > > > > <leif.lindholm@linaro.org>
> > > > > Cc: edk2-devel@lists.01.org; Zhang, Chao B
> <chao.b.zhang@intel.com>;
> > > > > Gao, Liming <liming.gao@intel.com>
> > > > > Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64:
> > > Add
> > > > > AsmLfence function
> > > > >
> > > > > Hi Ard
> > > > > I am OK to refine it now.
> > > > >
> > > > > Do you have any proposal on the naming from ARM side?
> > > > >
> > > > > Thank you
> > > > > Yao Jiewen
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> > > > > > Sent: Monday, December 17, 2018 4:11 PM
> > > > > > To: Yao, Jiewen <jiewen.yao@intel.com>; Leif Lindholm
> > > > > > <leif.lindholm@linaro.org>
> > > > > > Cc: Gao, Liming <liming.gao@intel.com>; Jagadeesh Ujja
> > > > > > <jagadeesh.ujja@arm.com>; edk2-devel@lists.01.org; Zhang, Chao
> B
> > > > > > <chao.b.zhang@intel.com>
> > > > > > Subject: Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> > > > > > AsmLfence function
> > > > > >
> > > > > > On Mon, 17 Dec 2018 at 08:45, Ard Biesheuvel
> > > > > <ard.biesheuvel@linaro.org>
> > > > > > wrote:
> > > > > > >
> > > > > > > On Mon, 17 Dec 2018 at 04:29, Yao, Jiewen
> <jiewen.yao@intel.com>
> > > > > > wrote:
> > > > > > > >
> > > > > > > > I think we have below definition.
> > > > > > > > -- MemoryFence: Serialize load and store operations.
> > > > > > > > -- LoadFence: Serialize load operations.
> > > > > > > > -- StoreFence: Serialize store operations.
> > > > > > > >
> > > > > > > > According to IA32 SDM, Intel has MFENCE, LFENCE and SFENCE.
> > > > > > > > If ARM only has DMB, it is possible to use DMB for
> MemoryFence,
> > > > > > LoadFence or StoreFence.
> > > > > > > >
> > > > > > > > Maybe it is better to use LoadFence, instead of AsmLFence?
> > > > > > > > Then we can align with MemoryFence.
> > > > > > > >
> > > > > > >
> > > > > > > I think using AsmLfence() all over the code to limit speculation
> was a
> > > > > > > mistake, and I am disappointed nobody from the ARM side was
> > > involved
> > > > > > > at all when these changes were proposed.
> > > > > > >
> > > > > >
> > > > > > OK, I have to apologize here. Hao did cc us on these patches, and so
> > > > > > we did have the opportunity to respond at the time.
> > > > > >
> > > > > > But that doesn't change the fact that AsmLfence() should be
> replaced
> > > > > > by an abstraction that describes the specific semantics of the x86
> > > > > > Lfence implemetation beyond memory ordering that we are relying
> on
> > > > > > here.
> > > > > >
> > > > > >
> > > > > >
> > > > > > > The code changes rely on specific semantics of the x86 Lfence
> > > > > > > instructions, i.e., that beyond load serialization, they ensure that
> > > > > > > all instructions (not just loads) complete before the lfence
> > > > > > > completes. This is a much stronger notion than a load barrier, and
> so
> > > > > > > the abstraction should have been defined as something like a
> > > > > > > ExecFence() or pipeline barrier etc, and the x86 specific
> > > > > > > implementation would have been mapped onto Lfence. For the
> ARM
> > > > > side,
> > > > > > > we probably need an ISB instruction here as well as some kind of
> > > other
> > > > > > > barrier. Calling it LoadFence() makes no sense whatsoever.
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > >
> > > > > > > > > -----Original Message-----
> > > > > > > > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org]
> On
> > > > > Behalf
> > > > > > Of
> > > > > > > > > Gao, Liming
> > > > > > > > > Sent: Monday, December 17, 2018 10:04 AM
> > > > > > > > > To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Jagadeesh
> Ujja
> > > > > > > > > <jagadeesh.ujja@arm.com>; Leif Lindholm
> > > > > <leif.lindholm@linaro.org>
> > > > > > > > > Cc: edk2-devel@lists.01.org; Zhang, Chao B
> > > > > > <chao.b.zhang@intel.com>
> > > > > > > > > Subject: Re: [edk2] [PATCH 05/13]
> > > MdePkg/Library/BaseLib/AArch64:
> > > > > > Add
> > > > > > > > > AsmLfence function
> > > > > > > > >
> > > > > > > > > Ard:
> > > > > > > > >   My first comment is to suggest updating the caller code for
> the
> > > > > arch
> > > > > > > > > specific code.  But, there are two drivers that have the same
> > > usage.
> > > > > > This
> > > > > > > > > way will introduce the duplicated code logic. So, I suggest
> another
> > > > > way
> > > > > > to
> > > > > > > > > extend  AsmLfence() API scope for the different ARCHs. If
> you
> > > think
> > > > > it
> > > > > > brings
> > > > > > > > > the confuse, I just think another way to resolve this case in the
> > > caller
> > > > > > code.
> > > > > > > > >
> > > > > > > > > #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> > > > > > > > > AsmLfence();
> > > > > > > > > #else
> > > > > > > > > MemoryFence()
> > > > > > > > > #endif
> > > > > > > > >
> > > > > > > > > Thanks
> > > > > > > > > Liming
> > > > > > > > > >-----Original Message-----
> > > > > > > > > >From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> > > > > > > > > >Sent: Friday, December 14, 2018 9:54 PM
> > > > > > > > > >To: Jagadeesh Ujja <jagadeesh.ujja@arm.com>; Leif
> Lindholm
> > > > > > > > > ><leif.lindholm@linaro.org>
> > > > > > > > > >Cc: edk2-devel@lists.01.org; Gao, Liming
> > > <liming.gao@intel.com>;
> > > > > > Zhang,
> > > > > > > > > >Chao B <chao.b.zhang@intel.com>
> > > > > > > > > >Subject: Re: [PATCH 05/13]
> MdePkg/Library/BaseLib/AArch64:
> > > Add
> > > > > > > > > >AsmLfence function
> > > > > > > > > >
> > > > > > > > > >On Fri, 14 Dec 2018 at 13:13, Jagadeesh Ujja
> > > > > > <jagadeesh.ujja@arm.com>
> > > > > > > > > >wrote:
> > > > > > > > > >>
> > > > > > > > > >> Variable service driver includes a call to AsmLfence. To
> reuse
> > > this
> > > > > > > > > >> driver on AArch64 based platforms, add an implementation
> of
> > > > > > AsmLfence
> > > > > > > > > >> that acts as a wrapper on the AArch64 specific
> MemoryFence
> > > > > > function.
> > > > > > > > > >>
> > > > > > > > > >> Contributed-under: TianoCore Contribution Agreement 1.1
> > > > > > > > > >> Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> > > > > > > > > >> ---
> > > > > > > > > >>  MdePkg/Include/Library/BaseLib.h             | 33
> > > > > > +++++++++------
> > > > > > > > > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.S   | 42
> > > > > > > > > >++++++++++++++++++++
> > > > > > > > > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.asm | 41
> > > > > > > > > >+++++++++++++++++++
> > > > > > > > > >>  MdePkg/Library/BaseLib/BaseLib.inf           |  2 +
> > > > > > > > > >>  4 files changed, 105 insertions(+), 13 deletions(-)
> > > > > > > > > >>
> > > > > > > > > >> diff --git a/MdePkg/Include/Library/BaseLib.h
> > > > > > > > > >b/MdePkg/Include/Library/BaseLib.h
> > > > > > > > > >> index 8cc0869..ca961ee 100644
> > > > > > > > > >> --- a/MdePkg/Include/Library/BaseLib.h
> > > > > > > > > >> +++ b/MdePkg/Include/Library/BaseLib.h
> > > > > > > > > >> @@ -7697,19 +7697,6 @@ AsmWriteTr (
> > > > > > > > > >>    );
> > > > > > > > > >>
> > > > > > > > > >>  /**
> > > > > > > > > >> -  Performs a serializing operation on all
> load-from-memory
> > > > > > instructions
> > > > > > > > > that
> > > > > > > > > >> -  were issued prior the AsmLfence function.
> > > > > > > > > >> -
> > > > > > > > > >> -  Executes a LFENCE instruction. This function is only
> > > available
> > > > > on
> > > > > > IA-32
> > > > > > > > > and
> > > > > > > > > >x64.
> > > > > > > > > >> -
> > > > > > > > > >> -**/
> > > > > > > > > >> -VOID
> > > > > > > > > >> -EFIAPI
> > > > > > > > > >> -AsmLfence (
> > > > > > > > > >> -  VOID
> > > > > > > > > >> -  );
> > > > > > > > > >> -
> > > > > > > > > >> -/**
> > > > > > > > > >>    Patch the immediate operand of an IA32 or X64
> instruction
> > > > > such
> > > > > > that
> > > > > > > > > the
> > > > > > > > > >byte,
> > > > > > > > > >>    word, dword or qword operand is encoded at the end
> of
> > > the
> > > > > > > > > instruction's
> > > > > > > > > >>    binary representation.
> > > > > > > > > >> @@ -7752,4 +7739,24 @@ PatchInstructionX86 (
> > > > > > > > > >>    );
> > > > > > > > > >>
> > > > > > > > > >>  #endif // defined (MDE_CPU_IA32) || defined
> > > (MDE_CPU_X64)
> > > > > > > > > >> +
> > > > > > > > > >> +#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> ||
> > > > > > defined
> > > > > > > > > >(MDE_CPU_AARCH64)
> > > > > > > > > >> +
> > > > > > > > > >> +/**
> > > > > > > > > >> +  Performs a serializing operation on all
> load-from-memory
> > > > > > instructions
> > > > > > > > > that
> > > > > > > > > >> +  were issued prior the AsmLfence function.
> > > > > > > > > >> +
> > > > > > > > > >> +  In case of IA-32 and x64, Executes a LFENCE
> instruction.
> > > > > > > > > >> +
> > > > > > > > > >> +  In case of AArch64 this acts as a wrapper on the
> AArch64
> > > > > > > > > >> +  specific MemoryFence function
> > > > > > > > > >> +
> > > > > > > > > >> +**/
> > > > > > > > > >> +VOID
> > > > > > > > > >> +EFIAPI
> > > > > > > > > >> +AsmLfence (
> > > > > > > > > >> +  VOID
> > > > > > > > > >> +  );
> > > > > > > > > >> +
> > > > > > > > > >> +#endif  // defined (MDE_CPU_IA32) || defined
> > > (MDE_CPU_X64)
> > > > > > ||
> > > > > > > > > >defined (MDE_CPU_AARCH64)
> > > > > > > > > >>  #endif // !defined (__BASE_LIB__)
> > > > > > > > > >> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > > > > > > > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > > > > > > > >> new file mode 100644
> > > > > > > > > >> index 0000000..2fd804b
> > > > > > > > > >> --- /dev/null
> > > > > > > > > >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > > > > > > > >> @@ -0,0 +1,42 @@
> > > > > > > > > >>
> > > > > +##------------------------------------------------------------------------------
> > > > > > > > > >> +#
> > > > > > > > > >> +# AsmLfence() for AArch64
> > > > > > > > > >> +#
> > > > > > > > > >> +# Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> > > > > > > > > >> +#
> > > > > > > > > >> +# This program and the accompanying materials
> > > > > > > > > >> +# are licensed and made available under the terms and
> > > conditions
> > > > > > of the
> > > > > > > > > >BSD License
> > > > > > > > > >> +# which accompanies this distribution.  The full text of
> the
> > > > > license
> > > > > > may
> > > > > > > > > be
> > > > > > > > > >found at
> > > > > > > > > >> +# http://opensource.org/licenses/bsd-license.php.
> > > > > > > > > >> +#
> > > > > > > > > >> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD
> LICENSE
> > > ON
> > > > > AN
> > > > > > "AS
> > > > > > > > > IS"
> > > > > > > > > >BASIS,
> > > > > > > > > >> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY
> > > KIND,
> > > > > > EITHER
> > > > > > > > > >EXPRESS OR IMPLIED.
> > > > > > > > > >> +#
> > > > > > > > > >>
> > > > > +##------------------------------------------------------------------------------
> > > > > > > > > >> +
> > > > > > > > > >> +.text
> > > > > > > > > >> +.p2align 2
> > > > > > > > > >> +
> > > > > > > > > >> +GCC_ASM_EXPORT(AsmLfence)
> > > > > > > > > >> +
> > > > > > > > > >> +# IMPORT
> > > > > > > > > >> +GCC_ASM_IMPORT(MemoryFence)
> > > > > > > > > >> +
> > > > > > > > > >> +#/**
> > > > > > > > > >> +#  Used to serialize load and store operations.
> > > > > > > > > >> +#
> > > > > > > > > >> +#  All loads and stores that proceed calls to this function
> are
> > > > > > > > > guaranteed to
> > > > > > > > > >be
> > > > > > > > > >> +#  globally visible when this function returns.
> > > > > > > > > >> +#
> > > > > > > > > >> +#**/
> > > > > > > > > >> +#VOID
> > > > > > > > > >> +#EFIAPI
> > > > > > > > > >> +#AsmLfence (
> > > > > > > > > >> +#  VOID
> > > > > > > > > >> +#  );
> > > > > > > > > >> +#
> > > > > > > > > >> +ASM_PFX(AsmLfence):
> > > > > > > > > >> +    stp   x29, x30, [sp, #-16]!
> > > > > > > > > >> +    bl MemoryFence
> > > > > > > > > >> +    ldp   x29, x30, [sp], #0x10
> > > > > > > > > >> +    ret
> > > > > > > > > >
> > > > > > > > > >Any reason we can't simply do
> > > > > > > > > >
> > > > > > > > > >b MemoryFence
> > > > > > > > > >
> > > > > > > > > >here?
> > > > > > > > > >
> > > > > > > > > >Also, why I understand the rationale, I still think it would be
> > > better
> > > > > > > > > >to change callers of the [x86 specific] AsmLfence() than to
> > > introduce
> > > > > > > > > >an alias of MemoryFence() for architectures where Lfence is
> not
> > > > > > > > > >defined.
> > > > > > > > > >
> > > > > > > > > >This is not only about tidiness, but also about potentially
> having
> > > > > > > > > >different semantics, which we can't provide in general on
> ARM,
> > > but
> > > > > > > > > >only in particular cases [such as the code that is modified in
> this
> > > > > > > > > >series]
> > > > > > > > > >
> > > > > > > > > >In other words, newly introduced occurrences of
> AsmLfence()
> > > now
> > > > > > have
> > > > > > > > > >to be audited for being appropriate on AArc64 if they are
> added
> > > to
> > > > > > > > > >generic code.
> > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > >> diff --git
> a/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > > > > > > > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > > > > > > > >> new file mode 100644
> > > > > > > > > >> index 0000000..7dd5659
> > > > > > > > > >> --- /dev/null
> > > > > > > > > >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > > > > > > > >> @@ -0,0 +1,41 @@
> > > > > > > > > >>
> > > +;------------------------------------------------------------------------------
> > > > > > > > > >> +;
> > > > > > > > > >> +; AsmLfence() for AArch64
> > > > > > > > > >> +;
> > > > > > > > > >> +; Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> > > > > > > > > >> +;
> > > > > > > > > >> +; This program and the accompanying materials
> > > > > > > > > >> +; are licensed and made available under the terms and
> > > conditions
> > > > > > of the
> > > > > > > > > >BSD License
> > > > > > > > > >> +; which accompanies this distribution.  The full text of
> the
> > > > > license
> > > > > > may
> > > > > > > > > be
> > > > > > > > > >found at
> > > > > > > > > >> +; http://opensource.org/licenses/bsd-license.php.
> > > > > > > > > >> +;
> > > > > > > > > >> +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD
> LICENSE
> > > ON
> > > > > AN
> > > > > > "AS
> > > > > > > > > IS"
> > > > > > > > > >BASIS,
> > > > > > > > > >> +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY
> > > KIND,
> > > > > > EITHER
> > > > > > > > > >EXPRESS OR IMPLIED.
> > > > > > > > > >> +;
> > > > > > > > > >>
> > > +;------------------------------------------------------------------------------
> > > > > > > > > >> +
> > > > > > > > > >> +  EXPORT AsmLfence
> > > > > > > > > >> +  AREA BaseLib_LowLevel, CODE, READONLY
> > > > > > > > > >> +  # IMPORT
> > > > > > > > > >> +  GCC_ASM_IMPORT(MemoryFence)
> > > > > > > > > >> +
> > > > > > > > > >> +;/**
> > > > > > > > > >> +;  Used to serialize load and store operations.
> > > > > > > > > >> +;
> > > > > > > > > >> +;  All loads and stores that proceed calls to this function
> are
> > > > > > guaranteed
> > > > > > > > > to
> > > > > > > > > >be
> > > > > > > > > >> +;  globally visible when this function returns.
> > > > > > > > > >> +;
> > > > > > > > > >> +;**/
> > > > > > > > > >> +;VOID
> > > > > > > > > >> +;EFIAPI
> > > > > > > > > >> +;AsmLfence (
> > > > > > > > > >> +;  VOID
> > > > > > > > > >> +;  );
> > > > > > > > > >> +;
> > > > > > > > > >> +AsmLfence
> > > > > > > > > >> +    stp   x29, x30, [sp, #-16]!
> > > > > > > > > >> +    bl MemoryFence
> > > > > > > > > >> +    ldp   x29, x30, [sp], #0x10
> > > > > > > > > >> +    ret
> > > > > > > > > >> +
> > > > > > > > > >> +  END
> > > > > > > > > >> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > > > > > >b/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > > > > > >> index b84e583..b7d7bcb 100644
> > > > > > > > > >> --- a/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > > > > > >> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > > > > > >> @@ -585,6 +585,7 @@
> > > > > > > > > >>    Math64.c
> > > > > > > > > >>
> > > > > > > > > >>    AArch64/MemoryFence.S             | GCC
> > > > > > > > > >> +  AArch64/AsmLfence.S               | GCC
> > > > > > > > > >>    AArch64/SwitchStack.S             | GCC
> > > > > > > > > >>    AArch64/EnableInterrupts.S        | GCC
> > > > > > > > > >>    AArch64/DisableInterrupts.S       | GCC
> > > > > > > > > >> @@ -593,6 +594,7 @@
> > > > > > > > > >>    AArch64/CpuBreakpoint.S           | GCC
> > > > > > > > > >>
> > > > > > > > > >>    AArch64/MemoryFence.asm           | MSFT
> > > > > > > > > >> +  AArch64/AsmLfence.asm             | MSFT
> > > > > > > > > >>    AArch64/SwitchStack.asm           | MSFT
> > > > > > > > > >>    AArch64/EnableInterrupts.asm      | MSFT
> > > > > > > > > >>    AArch64/DisableInterrupts.asm     | MSFT
> > > > > > > > > >> --
> > > > > > > > > >> 2.7.4
> > > > > > > > > >>
> > > > > > > > > _______________________________________________
> > > > > > > > > edk2-devel mailing list
> > > > > > > > > edk2-devel@lists.01.org
> > > > > > > > > https://lists.01.org/mailman/listinfo/edk2-devel
> > > > > _______________________________________________
> > > > > edk2-devel mailing list
> > > > > edk2-devel@lists.01.org
> > > > > https://lists.01.org/mailman/listinfo/edk2-devel
> > > _______________________________________________
> > > edk2-devel mailing list
> > > edk2-devel@lists.01.org
> > > https://lists.01.org/mailman/listinfo/edk2-devel

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
  2018-12-18  2:08                       ` Yao, Jiewen
@ 2018-12-18  2:12                         ` Gao, Liming
  2018-12-18  2:19                           ` Yao, Jiewen
  2018-12-20  9:00                         ` Jagadeesh Ujja
  1 sibling, 1 reply; 52+ messages in thread
From: Gao, Liming @ 2018-12-18  2:12 UTC (permalink / raw)
  To: Yao, Jiewen, Ard Biesheuvel, Wu, Hao A
  Cc: edk2-devel@lists.01.org, Zhang, Chao B

Jiewen:
  New SpeculationBarrier() will be for all ARCHs. IA32 and X64 implementation will be same to AsmLfence(). ARM and AARCH64 will have their own implementation. Right? 

  After this API is added, the consumer code to use AsmLfence() can be updated to use SpeculationBarrier(). 

Thanks
Liming
>-----Original Message-----
>From: Yao, Jiewen
>Sent: Tuesday, December 18, 2018 10:08 AM
>To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Wu, Hao A
><hao.a.wu@intel.com>
>Cc: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>; Zhang,
>Chao B <chao.b.zhang@intel.com>
>Subject: RE: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
>AsmLfence function
>
>+ Wu Hao, since he contributed the original patch.
>
>Ard
>Would you please file a Bugzilla for that? Then we can start working on that.
>
>Thank you
>Yao Jiewen
>
>> -----Original Message-----
>> From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
>> Sent: Monday, December 17, 2018 5:28 PM
>> To: Yao, Jiewen <jiewen.yao@intel.com>
>> Cc: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>; Zhang,
>> Chao B <chao.b.zhang@intel.com>
>> Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
>> AsmLfence function
>>
>> On Mon, 17 Dec 2018 at 09:44, Yao, Jiewen <jiewen.yao@intel.com> wrote:
>> >
>> > Thanks Ard.
>> > I have little concern about "Spec", because people may read it as
>> "Specification", especially in our team. :)
>> >
>>
>> I understand :-)
>>
>> SpeculationBarrier() is fine with me.
>>
>>
>> >
>> > > -----Original Message-----
>> > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf
>> Of
>> > > Ard Biesheuvel
>> > > Sent: Monday, December 17, 2018 4:35 PM
>> > > To: Yao, Jiewen <jiewen.yao@intel.com>
>> > > Cc: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>;
>> Zhang,
>> > > Chao B <chao.b.zhang@intel.com>
>> > > Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64:
>> Add
>> > > AsmLfence function
>> > >
>> > > On Mon, 17 Dec 2018 at 09:30, Yao, Jiewen <jiewen.yao@intel.com>
>> wrote:
>> > > >
>> > > > I reviewed the ARM white paper -
>> > >
>> file:///C:/Users/jyao1/Downloads/Cache_Speculation_Side-channels-v2.4.p
>> > > df
>> > > >
>> > > > I agree with you that LoadFence might not be the best idea.
>> > > >
>> > > > How about SpeculationBarrier() ?
>> > > >
>> > >
>> > > That works for me. Or SpecFence (). As long as it does not conflate
>> > > memory ordering with controlling the side effects of speculative
>> > > execution, it is ok with me.
>> > >
>> > > I'll contribute the ARM and AARCH64 implementations asap once the
>> > > generic changes are posted on the list.
>> > >
>> > > Thanks,
>> > >
>> > > > > -----Original Message-----
>> > > > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On
>> Behalf
>> > > Of
>> > > > > Yao, Jiewen
>> > > > > Sent: Monday, December 17, 2018 4:25 PM
>> > > > > To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Leif Lindholm
>> > > > > <leif.lindholm@linaro.org>
>> > > > > Cc: edk2-devel@lists.01.org; Zhang, Chao B
>> <chao.b.zhang@intel.com>;
>> > > > > Gao, Liming <liming.gao@intel.com>
>> > > > > Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64:
>> > > Add
>> > > > > AsmLfence function
>> > > > >
>> > > > > Hi Ard
>> > > > > I am OK to refine it now.
>> > > > >
>> > > > > Do you have any proposal on the naming from ARM side?
>> > > > >
>> > > > > Thank you
>> > > > > Yao Jiewen
>> > > > >
>> > > > > > -----Original Message-----
>> > > > > > From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
>> > > > > > Sent: Monday, December 17, 2018 4:11 PM
>> > > > > > To: Yao, Jiewen <jiewen.yao@intel.com>; Leif Lindholm
>> > > > > > <leif.lindholm@linaro.org>
>> > > > > > Cc: Gao, Liming <liming.gao@intel.com>; Jagadeesh Ujja
>> > > > > > <jagadeesh.ujja@arm.com>; edk2-devel@lists.01.org; Zhang, Chao
>> B
>> > > > > > <chao.b.zhang@intel.com>
>> > > > > > Subject: Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
>> > > > > > AsmLfence function
>> > > > > >
>> > > > > > On Mon, 17 Dec 2018 at 08:45, Ard Biesheuvel
>> > > > > <ard.biesheuvel@linaro.org>
>> > > > > > wrote:
>> > > > > > >
>> > > > > > > On Mon, 17 Dec 2018 at 04:29, Yao, Jiewen
>> <jiewen.yao@intel.com>
>> > > > > > wrote:
>> > > > > > > >
>> > > > > > > > I think we have below definition.
>> > > > > > > > -- MemoryFence: Serialize load and store operations.
>> > > > > > > > -- LoadFence: Serialize load operations.
>> > > > > > > > -- StoreFence: Serialize store operations.
>> > > > > > > >
>> > > > > > > > According to IA32 SDM, Intel has MFENCE, LFENCE and SFENCE.
>> > > > > > > > If ARM only has DMB, it is possible to use DMB for
>> MemoryFence,
>> > > > > > LoadFence or StoreFence.
>> > > > > > > >
>> > > > > > > > Maybe it is better to use LoadFence, instead of AsmLFence?
>> > > > > > > > Then we can align with MemoryFence.
>> > > > > > > >
>> > > > > > >
>> > > > > > > I think using AsmLfence() all over the code to limit speculation
>> was a
>> > > > > > > mistake, and I am disappointed nobody from the ARM side was
>> > > involved
>> > > > > > > at all when these changes were proposed.
>> > > > > > >
>> > > > > >
>> > > > > > OK, I have to apologize here. Hao did cc us on these patches, and
>so
>> > > > > > we did have the opportunity to respond at the time.
>> > > > > >
>> > > > > > But that doesn't change the fact that AsmLfence() should be
>> replaced
>> > > > > > by an abstraction that describes the specific semantics of the x86
>> > > > > > Lfence implemetation beyond memory ordering that we are
>relying
>> on
>> > > > > > here.
>> > > > > >
>> > > > > >
>> > > > > >
>> > > > > > > The code changes rely on specific semantics of the x86 Lfence
>> > > > > > > instructions, i.e., that beyond load serialization, they ensure that
>> > > > > > > all instructions (not just loads) complete before the lfence
>> > > > > > > completes. This is a much stronger notion than a load barrier, and
>> so
>> > > > > > > the abstraction should have been defined as something like a
>> > > > > > > ExecFence() or pipeline barrier etc, and the x86 specific
>> > > > > > > implementation would have been mapped onto Lfence. For the
>> ARM
>> > > > > side,
>> > > > > > > we probably need an ISB instruction here as well as some kind of
>> > > other
>> > > > > > > barrier. Calling it LoadFence() makes no sense whatsoever.
>> > > > > > >
>> > > > > > >
>> > > > > > >
>> > > > > > >
>> > > > > > >
>> > > > > > > >
>> > > > > > > > > -----Original Message-----
>> > > > > > > > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org]
>> On
>> > > > > Behalf
>> > > > > > Of
>> > > > > > > > > Gao, Liming
>> > > > > > > > > Sent: Monday, December 17, 2018 10:04 AM
>> > > > > > > > > To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Jagadeesh
>> Ujja
>> > > > > > > > > <jagadeesh.ujja@arm.com>; Leif Lindholm
>> > > > > <leif.lindholm@linaro.org>
>> > > > > > > > > Cc: edk2-devel@lists.01.org; Zhang, Chao B
>> > > > > > <chao.b.zhang@intel.com>
>> > > > > > > > > Subject: Re: [edk2] [PATCH 05/13]
>> > > MdePkg/Library/BaseLib/AArch64:
>> > > > > > Add
>> > > > > > > > > AsmLfence function
>> > > > > > > > >
>> > > > > > > > > Ard:
>> > > > > > > > >   My first comment is to suggest updating the caller code for
>> the
>> > > > > arch
>> > > > > > > > > specific code.  But, there are two drivers that have the same
>> > > usage.
>> > > > > > This
>> > > > > > > > > way will introduce the duplicated code logic. So, I suggest
>> another
>> > > > > way
>> > > > > > to
>> > > > > > > > > extend  AsmLfence() API scope for the different ARCHs. If
>> you
>> > > think
>> > > > > it
>> > > > > > brings
>> > > > > > > > > the confuse, I just think another way to resolve this case in
>the
>> > > caller
>> > > > > > code.
>> > > > > > > > >
>> > > > > > > > > #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
>> > > > > > > > > AsmLfence();
>> > > > > > > > > #else
>> > > > > > > > > MemoryFence()
>> > > > > > > > > #endif
>> > > > > > > > >
>> > > > > > > > > Thanks
>> > > > > > > > > Liming
>> > > > > > > > > >-----Original Message-----
>> > > > > > > > > >From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
>> > > > > > > > > >Sent: Friday, December 14, 2018 9:54 PM
>> > > > > > > > > >To: Jagadeesh Ujja <jagadeesh.ujja@arm.com>; Leif
>> Lindholm
>> > > > > > > > > ><leif.lindholm@linaro.org>
>> > > > > > > > > >Cc: edk2-devel@lists.01.org; Gao, Liming
>> > > <liming.gao@intel.com>;
>> > > > > > Zhang,
>> > > > > > > > > >Chao B <chao.b.zhang@intel.com>
>> > > > > > > > > >Subject: Re: [PATCH 05/13]
>> MdePkg/Library/BaseLib/AArch64:
>> > > Add
>> > > > > > > > > >AsmLfence function
>> > > > > > > > > >
>> > > > > > > > > >On Fri, 14 Dec 2018 at 13:13, Jagadeesh Ujja
>> > > > > > <jagadeesh.ujja@arm.com>
>> > > > > > > > > >wrote:
>> > > > > > > > > >>
>> > > > > > > > > >> Variable service driver includes a call to AsmLfence. To
>> reuse
>> > > this
>> > > > > > > > > >> driver on AArch64 based platforms, add an
>implementation
>> of
>> > > > > > AsmLfence
>> > > > > > > > > >> that acts as a wrapper on the AArch64 specific
>> MemoryFence
>> > > > > > function.
>> > > > > > > > > >>
>> > > > > > > > > >> Contributed-under: TianoCore Contribution Agreement
>1.1
>> > > > > > > > > >> Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
>> > > > > > > > > >> ---
>> > > > > > > > > >>  MdePkg/Include/Library/BaseLib.h             | 33
>> > > > > > +++++++++------
>> > > > > > > > > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.S   | 42
>> > > > > > > > > >++++++++++++++++++++
>> > > > > > > > > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.asm | 41
>> > > > > > > > > >+++++++++++++++++++
>> > > > > > > > > >>  MdePkg/Library/BaseLib/BaseLib.inf           |  2 +
>> > > > > > > > > >>  4 files changed, 105 insertions(+), 13 deletions(-)
>> > > > > > > > > >>
>> > > > > > > > > >> diff --git a/MdePkg/Include/Library/BaseLib.h
>> > > > > > > > > >b/MdePkg/Include/Library/BaseLib.h
>> > > > > > > > > >> index 8cc0869..ca961ee 100644
>> > > > > > > > > >> --- a/MdePkg/Include/Library/BaseLib.h
>> > > > > > > > > >> +++ b/MdePkg/Include/Library/BaseLib.h
>> > > > > > > > > >> @@ -7697,19 +7697,6 @@ AsmWriteTr (
>> > > > > > > > > >>    );
>> > > > > > > > > >>
>> > > > > > > > > >>  /**
>> > > > > > > > > >> -  Performs a serializing operation on all
>> load-from-memory
>> > > > > > instructions
>> > > > > > > > > that
>> > > > > > > > > >> -  were issued prior the AsmLfence function.
>> > > > > > > > > >> -
>> > > > > > > > > >> -  Executes a LFENCE instruction. This function is only
>> > > available
>> > > > > on
>> > > > > > IA-32
>> > > > > > > > > and
>> > > > > > > > > >x64.
>> > > > > > > > > >> -
>> > > > > > > > > >> -**/
>> > > > > > > > > >> -VOID
>> > > > > > > > > >> -EFIAPI
>> > > > > > > > > >> -AsmLfence (
>> > > > > > > > > >> -  VOID
>> > > > > > > > > >> -  );
>> > > > > > > > > >> -
>> > > > > > > > > >> -/**
>> > > > > > > > > >>    Patch the immediate operand of an IA32 or X64
>> instruction
>> > > > > such
>> > > > > > that
>> > > > > > > > > the
>> > > > > > > > > >byte,
>> > > > > > > > > >>    word, dword or qword operand is encoded at the end
>> of
>> > > the
>> > > > > > > > > instruction's
>> > > > > > > > > >>    binary representation.
>> > > > > > > > > >> @@ -7752,4 +7739,24 @@ PatchInstructionX86 (
>> > > > > > > > > >>    );
>> > > > > > > > > >>
>> > > > > > > > > >>  #endif // defined (MDE_CPU_IA32) || defined
>> > > (MDE_CPU_X64)
>> > > > > > > > > >> +
>> > > > > > > > > >> +#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
>> ||
>> > > > > > defined
>> > > > > > > > > >(MDE_CPU_AARCH64)
>> > > > > > > > > >> +
>> > > > > > > > > >> +/**
>> > > > > > > > > >> +  Performs a serializing operation on all
>> load-from-memory
>> > > > > > instructions
>> > > > > > > > > that
>> > > > > > > > > >> +  were issued prior the AsmLfence function.
>> > > > > > > > > >> +
>> > > > > > > > > >> +  In case of IA-32 and x64, Executes a LFENCE
>> instruction.
>> > > > > > > > > >> +
>> > > > > > > > > >> +  In case of AArch64 this acts as a wrapper on the
>> AArch64
>> > > > > > > > > >> +  specific MemoryFence function
>> > > > > > > > > >> +
>> > > > > > > > > >> +**/
>> > > > > > > > > >> +VOID
>> > > > > > > > > >> +EFIAPI
>> > > > > > > > > >> +AsmLfence (
>> > > > > > > > > >> +  VOID
>> > > > > > > > > >> +  );
>> > > > > > > > > >> +
>> > > > > > > > > >> +#endif  // defined (MDE_CPU_IA32) || defined
>> > > (MDE_CPU_X64)
>> > > > > > ||
>> > > > > > > > > >defined (MDE_CPU_AARCH64)
>> > > > > > > > > >>  #endif // !defined (__BASE_LIB__)
>> > > > > > > > > >> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
>> > > > > > > > > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
>> > > > > > > > > >> new file mode 100644
>> > > > > > > > > >> index 0000000..2fd804b
>> > > > > > > > > >> --- /dev/null
>> > > > > > > > > >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
>> > > > > > > > > >> @@ -0,0 +1,42 @@
>> > > > > > > > > >>
>> > > > > +##------------------------------------------------------------------------------
>> > > > > > > > > >> +#
>> > > > > > > > > >> +# AsmLfence() for AArch64
>> > > > > > > > > >> +#
>> > > > > > > > > >> +# Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
>> > > > > > > > > >> +#
>> > > > > > > > > >> +# This program and the accompanying materials
>> > > > > > > > > >> +# are licensed and made available under the terms and
>> > > conditions
>> > > > > > of the
>> > > > > > > > > >BSD License
>> > > > > > > > > >> +# which accompanies this distribution.  The full text of
>> the
>> > > > > license
>> > > > > > may
>> > > > > > > > > be
>> > > > > > > > > >found at
>> > > > > > > > > >> +# http://opensource.org/licenses/bsd-license.php.
>> > > > > > > > > >> +#
>> > > > > > > > > >> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD
>> LICENSE
>> > > ON
>> > > > > AN
>> > > > > > "AS
>> > > > > > > > > IS"
>> > > > > > > > > >BASIS,
>> > > > > > > > > >> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY
>> > > KIND,
>> > > > > > EITHER
>> > > > > > > > > >EXPRESS OR IMPLIED.
>> > > > > > > > > >> +#
>> > > > > > > > > >>
>> > > > > +##------------------------------------------------------------------------------
>> > > > > > > > > >> +
>> > > > > > > > > >> +.text
>> > > > > > > > > >> +.p2align 2
>> > > > > > > > > >> +
>> > > > > > > > > >> +GCC_ASM_EXPORT(AsmLfence)
>> > > > > > > > > >> +
>> > > > > > > > > >> +# IMPORT
>> > > > > > > > > >> +GCC_ASM_IMPORT(MemoryFence)
>> > > > > > > > > >> +
>> > > > > > > > > >> +#/**
>> > > > > > > > > >> +#  Used to serialize load and store operations.
>> > > > > > > > > >> +#
>> > > > > > > > > >> +#  All loads and stores that proceed calls to this function
>> are
>> > > > > > > > > guaranteed to
>> > > > > > > > > >be
>> > > > > > > > > >> +#  globally visible when this function returns.
>> > > > > > > > > >> +#
>> > > > > > > > > >> +#**/
>> > > > > > > > > >> +#VOID
>> > > > > > > > > >> +#EFIAPI
>> > > > > > > > > >> +#AsmLfence (
>> > > > > > > > > >> +#  VOID
>> > > > > > > > > >> +#  );
>> > > > > > > > > >> +#
>> > > > > > > > > >> +ASM_PFX(AsmLfence):
>> > > > > > > > > >> +    stp   x29, x30, [sp, #-16]!
>> > > > > > > > > >> +    bl MemoryFence
>> > > > > > > > > >> +    ldp   x29, x30, [sp], #0x10
>> > > > > > > > > >> +    ret
>> > > > > > > > > >
>> > > > > > > > > >Any reason we can't simply do
>> > > > > > > > > >
>> > > > > > > > > >b MemoryFence
>> > > > > > > > > >
>> > > > > > > > > >here?
>> > > > > > > > > >
>> > > > > > > > > >Also, why I understand the rationale, I still think it would be
>> > > better
>> > > > > > > > > >to change callers of the [x86 specific] AsmLfence() than to
>> > > introduce
>> > > > > > > > > >an alias of MemoryFence() for architectures where Lfence is
>> not
>> > > > > > > > > >defined.
>> > > > > > > > > >
>> > > > > > > > > >This is not only about tidiness, but also about potentially
>> having
>> > > > > > > > > >different semantics, which we can't provide in general on
>> ARM,
>> > > but
>> > > > > > > > > >only in particular cases [such as the code that is modified in
>> this
>> > > > > > > > > >series]
>> > > > > > > > > >
>> > > > > > > > > >In other words, newly introduced occurrences of
>> AsmLfence()
>> > > now
>> > > > > > have
>> > > > > > > > > >to be audited for being appropriate on AArc64 if they are
>> added
>> > > to
>> > > > > > > > > >generic code.
>> > > > > > > > > >
>> > > > > > > > > >
>> > > > > > > > > >> diff --git
>> a/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
>> > > > > > > > > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
>> > > > > > > > > >> new file mode 100644
>> > > > > > > > > >> index 0000000..7dd5659
>> > > > > > > > > >> --- /dev/null
>> > > > > > > > > >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
>> > > > > > > > > >> @@ -0,0 +1,41 @@
>> > > > > > > > > >>
>> > > +;------------------------------------------------------------------------------
>> > > > > > > > > >> +;
>> > > > > > > > > >> +; AsmLfence() for AArch64
>> > > > > > > > > >> +;
>> > > > > > > > > >> +; Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
>> > > > > > > > > >> +;
>> > > > > > > > > >> +; This program and the accompanying materials
>> > > > > > > > > >> +; are licensed and made available under the terms and
>> > > conditions
>> > > > > > of the
>> > > > > > > > > >BSD License
>> > > > > > > > > >> +; which accompanies this distribution.  The full text of
>> the
>> > > > > license
>> > > > > > may
>> > > > > > > > > be
>> > > > > > > > > >found at
>> > > > > > > > > >> +; http://opensource.org/licenses/bsd-license.php.
>> > > > > > > > > >> +;
>> > > > > > > > > >> +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD
>> LICENSE
>> > > ON
>> > > > > AN
>> > > > > > "AS
>> > > > > > > > > IS"
>> > > > > > > > > >BASIS,
>> > > > > > > > > >> +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY
>> > > KIND,
>> > > > > > EITHER
>> > > > > > > > > >EXPRESS OR IMPLIED.
>> > > > > > > > > >> +;
>> > > > > > > > > >>
>> > > +;------------------------------------------------------------------------------
>> > > > > > > > > >> +
>> > > > > > > > > >> +  EXPORT AsmLfence
>> > > > > > > > > >> +  AREA BaseLib_LowLevel, CODE, READONLY
>> > > > > > > > > >> +  # IMPORT
>> > > > > > > > > >> +  GCC_ASM_IMPORT(MemoryFence)
>> > > > > > > > > >> +
>> > > > > > > > > >> +;/**
>> > > > > > > > > >> +;  Used to serialize load and store operations.
>> > > > > > > > > >> +;
>> > > > > > > > > >> +;  All loads and stores that proceed calls to this function
>> are
>> > > > > > guaranteed
>> > > > > > > > > to
>> > > > > > > > > >be
>> > > > > > > > > >> +;  globally visible when this function returns.
>> > > > > > > > > >> +;
>> > > > > > > > > >> +;**/
>> > > > > > > > > >> +;VOID
>> > > > > > > > > >> +;EFIAPI
>> > > > > > > > > >> +;AsmLfence (
>> > > > > > > > > >> +;  VOID
>> > > > > > > > > >> +;  );
>> > > > > > > > > >> +;
>> > > > > > > > > >> +AsmLfence
>> > > > > > > > > >> +    stp   x29, x30, [sp, #-16]!
>> > > > > > > > > >> +    bl MemoryFence
>> > > > > > > > > >> +    ldp   x29, x30, [sp], #0x10
>> > > > > > > > > >> +    ret
>> > > > > > > > > >> +
>> > > > > > > > > >> +  END
>> > > > > > > > > >> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
>> > > > > > > > > >b/MdePkg/Library/BaseLib/BaseLib.inf
>> > > > > > > > > >> index b84e583..b7d7bcb 100644
>> > > > > > > > > >> --- a/MdePkg/Library/BaseLib/BaseLib.inf
>> > > > > > > > > >> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
>> > > > > > > > > >> @@ -585,6 +585,7 @@
>> > > > > > > > > >>    Math64.c
>> > > > > > > > > >>
>> > > > > > > > > >>    AArch64/MemoryFence.S             | GCC
>> > > > > > > > > >> +  AArch64/AsmLfence.S               | GCC
>> > > > > > > > > >>    AArch64/SwitchStack.S             | GCC
>> > > > > > > > > >>    AArch64/EnableInterrupts.S        | GCC
>> > > > > > > > > >>    AArch64/DisableInterrupts.S       | GCC
>> > > > > > > > > >> @@ -593,6 +594,7 @@
>> > > > > > > > > >>    AArch64/CpuBreakpoint.S           | GCC
>> > > > > > > > > >>
>> > > > > > > > > >>    AArch64/MemoryFence.asm           | MSFT
>> > > > > > > > > >> +  AArch64/AsmLfence.asm             | MSFT
>> > > > > > > > > >>    AArch64/SwitchStack.asm           | MSFT
>> > > > > > > > > >>    AArch64/EnableInterrupts.asm      | MSFT
>> > > > > > > > > >>    AArch64/DisableInterrupts.asm     | MSFT
>> > > > > > > > > >> --
>> > > > > > > > > >> 2.7.4
>> > > > > > > > > >>
>> > > > > > > > > _______________________________________________
>> > > > > > > > > edk2-devel mailing list
>> > > > > > > > > edk2-devel@lists.01.org
>> > > > > > > > > https://lists.01.org/mailman/listinfo/edk2-devel
>> > > > > _______________________________________________
>> > > > > edk2-devel mailing list
>> > > > > edk2-devel@lists.01.org
>> > > > > https://lists.01.org/mailman/listinfo/edk2-devel
>> > > _______________________________________________
>> > > edk2-devel mailing list
>> > > edk2-devel@lists.01.org
>> > > https://lists.01.org/mailman/listinfo/edk2-devel

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
  2018-12-18  2:12                         ` Gao, Liming
@ 2018-12-18  2:19                           ` Yao, Jiewen
  0 siblings, 0 replies; 52+ messages in thread
From: Yao, Jiewen @ 2018-12-18  2:19 UTC (permalink / raw)
  To: Gao, Liming, Ard Biesheuvel, Wu, Hao A
  Cc: edk2-devel@lists.01.org, Zhang, Chao B

Yes. That is my understanding.
If the consumer code is architecture independent and it wants to bring barrier to mitigate spectre variant 1, it should use the new name SpeculationBarrier ().
I recommend each update need both X86 and ARM expert to review to make sure the place is good enough to mitigate variant 1 for both X86 and ARM.

Unless some X86 specific code, if the purpose is just to serialize the load operation, it can still use AsmLFence(). I guess it will be few.

Thank you
Yao Jiewen

> -----Original Message-----
> From: Gao, Liming
> Sent: Tuesday, December 18, 2018 10:12 AM
> To: Yao, Jiewen <jiewen.yao@intel.com>; Ard Biesheuvel
> <ard.biesheuvel@linaro.org>; Wu, Hao A <hao.a.wu@intel.com>
> Cc: edk2-devel@lists.01.org; Zhang, Chao B <chao.b.zhang@intel.com>
> Subject: RE: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> AsmLfence function
> 
> Jiewen:
>   New SpeculationBarrier() will be for all ARCHs. IA32 and X64
> implementation will be same to AsmLfence(). ARM and AARCH64 will have
> their own implementation. Right?
> 
>   After this API is added, the consumer code to use AsmLfence() can be
> updated to use SpeculationBarrier().
> 
> Thanks
> Liming
> >-----Original Message-----
> >From: Yao, Jiewen
> >Sent: Tuesday, December 18, 2018 10:08 AM
> >To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Wu, Hao A
> ><hao.a.wu@intel.com>
> >Cc: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>; Zhang,
> >Chao B <chao.b.zhang@intel.com>
> >Subject: RE: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> >AsmLfence function
> >
> >+ Wu Hao, since he contributed the original patch.
> >
> >Ard
> >Would you please file a Bugzilla for that? Then we can start working on
> that.
> >
> >Thank you
> >Yao Jiewen
> >
> >> -----Original Message-----
> >> From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> >> Sent: Monday, December 17, 2018 5:28 PM
> >> To: Yao, Jiewen <jiewen.yao@intel.com>
> >> Cc: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>;
> Zhang,
> >> Chao B <chao.b.zhang@intel.com>
> >> Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> >> AsmLfence function
> >>
> >> On Mon, 17 Dec 2018 at 09:44, Yao, Jiewen <jiewen.yao@intel.com>
> wrote:
> >> >
> >> > Thanks Ard.
> >> > I have little concern about "Spec", because people may read it as
> >> "Specification", especially in our team. :)
> >> >
> >>
> >> I understand :-)
> >>
> >> SpeculationBarrier() is fine with me.
> >>
> >>
> >> >
> >> > > -----Original Message-----
> >> > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On
> Behalf
> >> Of
> >> > > Ard Biesheuvel
> >> > > Sent: Monday, December 17, 2018 4:35 PM
> >> > > To: Yao, Jiewen <jiewen.yao@intel.com>
> >> > > Cc: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>;
> >> Zhang,
> >> > > Chao B <chao.b.zhang@intel.com>
> >> > > Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64:
> >> Add
> >> > > AsmLfence function
> >> > >
> >> > > On Mon, 17 Dec 2018 at 09:30, Yao, Jiewen <jiewen.yao@intel.com>
> >> wrote:
> >> > > >
> >> > > > I reviewed the ARM white paper -
> >> > >
> >>
> file:///C:/Users/jyao1/Downloads/Cache_Speculation_Side-channels-v2.4.p
> >> > > df
> >> > > >
> >> > > > I agree with you that LoadFence might not be the best idea.
> >> > > >
> >> > > > How about SpeculationBarrier() ?
> >> > > >
> >> > >
> >> > > That works for me. Or SpecFence (). As long as it does not conflate
> >> > > memory ordering with controlling the side effects of speculative
> >> > > execution, it is ok with me.
> >> > >
> >> > > I'll contribute the ARM and AARCH64 implementations asap once the
> >> > > generic changes are posted on the list.
> >> > >
> >> > > Thanks,
> >> > >
> >> > > > > -----Original Message-----
> >> > > > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On
> >> Behalf
> >> > > Of
> >> > > > > Yao, Jiewen
> >> > > > > Sent: Monday, December 17, 2018 4:25 PM
> >> > > > > To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Leif Lindholm
> >> > > > > <leif.lindholm@linaro.org>
> >> > > > > Cc: edk2-devel@lists.01.org; Zhang, Chao B
> >> <chao.b.zhang@intel.com>;
> >> > > > > Gao, Liming <liming.gao@intel.com>
> >> > > > > Subject: Re: [edk2] [PATCH 05/13]
> MdePkg/Library/BaseLib/AArch64:
> >> > > Add
> >> > > > > AsmLfence function
> >> > > > >
> >> > > > > Hi Ard
> >> > > > > I am OK to refine it now.
> >> > > > >
> >> > > > > Do you have any proposal on the naming from ARM side?
> >> > > > >
> >> > > > > Thank you
> >> > > > > Yao Jiewen
> >> > > > >
> >> > > > > > -----Original Message-----
> >> > > > > > From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> >> > > > > > Sent: Monday, December 17, 2018 4:11 PM
> >> > > > > > To: Yao, Jiewen <jiewen.yao@intel.com>; Leif Lindholm
> >> > > > > > <leif.lindholm@linaro.org>
> >> > > > > > Cc: Gao, Liming <liming.gao@intel.com>; Jagadeesh Ujja
> >> > > > > > <jagadeesh.ujja@arm.com>; edk2-devel@lists.01.org; Zhang,
> Chao
> >> B
> >> > > > > > <chao.b.zhang@intel.com>
> >> > > > > > Subject: Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64:
> Add
> >> > > > > > AsmLfence function
> >> > > > > >
> >> > > > > > On Mon, 17 Dec 2018 at 08:45, Ard Biesheuvel
> >> > > > > <ard.biesheuvel@linaro.org>
> >> > > > > > wrote:
> >> > > > > > >
> >> > > > > > > On Mon, 17 Dec 2018 at 04:29, Yao, Jiewen
> >> <jiewen.yao@intel.com>
> >> > > > > > wrote:
> >> > > > > > > >
> >> > > > > > > > I think we have below definition.
> >> > > > > > > > -- MemoryFence: Serialize load and store operations.
> >> > > > > > > > -- LoadFence: Serialize load operations.
> >> > > > > > > > -- StoreFence: Serialize store operations.
> >> > > > > > > >
> >> > > > > > > > According to IA32 SDM, Intel has MFENCE, LFENCE and
> SFENCE.
> >> > > > > > > > If ARM only has DMB, it is possible to use DMB for
> >> MemoryFence,
> >> > > > > > LoadFence or StoreFence.
> >> > > > > > > >
> >> > > > > > > > Maybe it is better to use LoadFence, instead of AsmLFence?
> >> > > > > > > > Then we can align with MemoryFence.
> >> > > > > > > >
> >> > > > > > >
> >> > > > > > > I think using AsmLfence() all over the code to limit speculation
> >> was a
> >> > > > > > > mistake, and I am disappointed nobody from the ARM side was
> >> > > involved
> >> > > > > > > at all when these changes were proposed.
> >> > > > > > >
> >> > > > > >
> >> > > > > > OK, I have to apologize here. Hao did cc us on these patches,
> and
> >so
> >> > > > > > we did have the opportunity to respond at the time.
> >> > > > > >
> >> > > > > > But that doesn't change the fact that AsmLfence() should be
> >> replaced
> >> > > > > > by an abstraction that describes the specific semantics of the x86
> >> > > > > > Lfence implemetation beyond memory ordering that we are
> >relying
> >> on
> >> > > > > > here.
> >> > > > > >
> >> > > > > >
> >> > > > > >
> >> > > > > > > The code changes rely on specific semantics of the x86 Lfence
> >> > > > > > > instructions, i.e., that beyond load serialization, they ensure
> that
> >> > > > > > > all instructions (not just loads) complete before the lfence
> >> > > > > > > completes. This is a much stronger notion than a load barrier,
> and
> >> so
> >> > > > > > > the abstraction should have been defined as something like a
> >> > > > > > > ExecFence() or pipeline barrier etc, and the x86 specific
> >> > > > > > > implementation would have been mapped onto Lfence. For the
> >> ARM
> >> > > > > side,
> >> > > > > > > we probably need an ISB instruction here as well as some kind
> of
> >> > > other
> >> > > > > > > barrier. Calling it LoadFence() makes no sense whatsoever.
> >> > > > > > >
> >> > > > > > >
> >> > > > > > >
> >> > > > > > >
> >> > > > > > >
> >> > > > > > > >
> >> > > > > > > > > -----Original Message-----
> >> > > > > > > > > From: edk2-devel
> [mailto:edk2-devel-bounces@lists.01.org]
> >> On
> >> > > > > Behalf
> >> > > > > > Of
> >> > > > > > > > > Gao, Liming
> >> > > > > > > > > Sent: Monday, December 17, 2018 10:04 AM
> >> > > > > > > > > To: Ard Biesheuvel <ard.biesheuvel@linaro.org>;
> Jagadeesh
> >> Ujja
> >> > > > > > > > > <jagadeesh.ujja@arm.com>; Leif Lindholm
> >> > > > > <leif.lindholm@linaro.org>
> >> > > > > > > > > Cc: edk2-devel@lists.01.org; Zhang, Chao B
> >> > > > > > <chao.b.zhang@intel.com>
> >> > > > > > > > > Subject: Re: [edk2] [PATCH 05/13]
> >> > > MdePkg/Library/BaseLib/AArch64:
> >> > > > > > Add
> >> > > > > > > > > AsmLfence function
> >> > > > > > > > >
> >> > > > > > > > > Ard:
> >> > > > > > > > >   My first comment is to suggest updating the caller code
> for
> >> the
> >> > > > > arch
> >> > > > > > > > > specific code.  But, there are two drivers that have the
> same
> >> > > usage.
> >> > > > > > This
> >> > > > > > > > > way will introduce the duplicated code logic. So, I suggest
> >> another
> >> > > > > way
> >> > > > > > to
> >> > > > > > > > > extend  AsmLfence() API scope for the different ARCHs. If
> >> you
> >> > > think
> >> > > > > it
> >> > > > > > brings
> >> > > > > > > > > the confuse, I just think another way to resolve this case in
> >the
> >> > > caller
> >> > > > > > code.
> >> > > > > > > > >
> >> > > > > > > > > #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> >> > > > > > > > > AsmLfence();
> >> > > > > > > > > #else
> >> > > > > > > > > MemoryFence()
> >> > > > > > > > > #endif
> >> > > > > > > > >
> >> > > > > > > > > Thanks
> >> > > > > > > > > Liming
> >> > > > > > > > > >-----Original Message-----
> >> > > > > > > > > >From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> >> > > > > > > > > >Sent: Friday, December 14, 2018 9:54 PM
> >> > > > > > > > > >To: Jagadeesh Ujja <jagadeesh.ujja@arm.com>; Leif
> >> Lindholm
> >> > > > > > > > > ><leif.lindholm@linaro.org>
> >> > > > > > > > > >Cc: edk2-devel@lists.01.org; Gao, Liming
> >> > > <liming.gao@intel.com>;
> >> > > > > > Zhang,
> >> > > > > > > > > >Chao B <chao.b.zhang@intel.com>
> >> > > > > > > > > >Subject: Re: [PATCH 05/13]
> >> MdePkg/Library/BaseLib/AArch64:
> >> > > Add
> >> > > > > > > > > >AsmLfence function
> >> > > > > > > > > >
> >> > > > > > > > > >On Fri, 14 Dec 2018 at 13:13, Jagadeesh Ujja
> >> > > > > > <jagadeesh.ujja@arm.com>
> >> > > > > > > > > >wrote:
> >> > > > > > > > > >>
> >> > > > > > > > > >> Variable service driver includes a call to AsmLfence. To
> >> reuse
> >> > > this
> >> > > > > > > > > >> driver on AArch64 based platforms, add an
> >implementation
> >> of
> >> > > > > > AsmLfence
> >> > > > > > > > > >> that acts as a wrapper on the AArch64 specific
> >> MemoryFence
> >> > > > > > function.
> >> > > > > > > > > >>
> >> > > > > > > > > >> Contributed-under: TianoCore Contribution Agreement
> >1.1
> >> > > > > > > > > >> Signed-off-by: Jagadeesh Ujja
> <jagadeesh.ujja@arm.com>
> >> > > > > > > > > >> ---
> >> > > > > > > > > >>  MdePkg/Include/Library/BaseLib.h             |
> 33
> >> > > > > > +++++++++------
> >> > > > > > > > > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.S   |
> 42
> >> > > > > > > > > >++++++++++++++++++++
> >> > > > > > > > > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.asm |
> 41
> >> > > > > > > > > >+++++++++++++++++++
> >> > > > > > > > > >>  MdePkg/Library/BaseLib/BaseLib.inf           |
> 2 +
> >> > > > > > > > > >>  4 files changed, 105 insertions(+), 13 deletions(-)
> >> > > > > > > > > >>
> >> > > > > > > > > >> diff --git a/MdePkg/Include/Library/BaseLib.h
> >> > > > > > > > > >b/MdePkg/Include/Library/BaseLib.h
> >> > > > > > > > > >> index 8cc0869..ca961ee 100644
> >> > > > > > > > > >> --- a/MdePkg/Include/Library/BaseLib.h
> >> > > > > > > > > >> +++ b/MdePkg/Include/Library/BaseLib.h
> >> > > > > > > > > >> @@ -7697,19 +7697,6 @@ AsmWriteTr (
> >> > > > > > > > > >>    );
> >> > > > > > > > > >>
> >> > > > > > > > > >>  /**
> >> > > > > > > > > >> -  Performs a serializing operation on all
> >> load-from-memory
> >> > > > > > instructions
> >> > > > > > > > > that
> >> > > > > > > > > >> -  were issued prior the AsmLfence function.
> >> > > > > > > > > >> -
> >> > > > > > > > > >> -  Executes a LFENCE instruction. This function is only
> >> > > available
> >> > > > > on
> >> > > > > > IA-32
> >> > > > > > > > > and
> >> > > > > > > > > >x64.
> >> > > > > > > > > >> -
> >> > > > > > > > > >> -**/
> >> > > > > > > > > >> -VOID
> >> > > > > > > > > >> -EFIAPI
> >> > > > > > > > > >> -AsmLfence (
> >> > > > > > > > > >> -  VOID
> >> > > > > > > > > >> -  );
> >> > > > > > > > > >> -
> >> > > > > > > > > >> -/**
> >> > > > > > > > > >>    Patch the immediate operand of an IA32 or X64
> >> instruction
> >> > > > > such
> >> > > > > > that
> >> > > > > > > > > the
> >> > > > > > > > > >byte,
> >> > > > > > > > > >>    word, dword or qword operand is encoded at the
> end
> >> of
> >> > > the
> >> > > > > > > > > instruction's
> >> > > > > > > > > >>    binary representation.
> >> > > > > > > > > >> @@ -7752,4 +7739,24 @@ PatchInstructionX86 (
> >> > > > > > > > > >>    );
> >> > > > > > > > > >>
> >> > > > > > > > > >>  #endif // defined (MDE_CPU_IA32) || defined
> >> > > (MDE_CPU_X64)
> >> > > > > > > > > >> +
> >> > > > > > > > > >> +#if defined (MDE_CPU_IA32) || defined
> (MDE_CPU_X64)
> >> ||
> >> > > > > > defined
> >> > > > > > > > > >(MDE_CPU_AARCH64)
> >> > > > > > > > > >> +
> >> > > > > > > > > >> +/**
> >> > > > > > > > > >> +  Performs a serializing operation on all
> >> load-from-memory
> >> > > > > > instructions
> >> > > > > > > > > that
> >> > > > > > > > > >> +  were issued prior the AsmLfence function.
> >> > > > > > > > > >> +
> >> > > > > > > > > >> +  In case of IA-32 and x64, Executes a LFENCE
> >> instruction.
> >> > > > > > > > > >> +
> >> > > > > > > > > >> +  In case of AArch64 this acts as a wrapper on the
> >> AArch64
> >> > > > > > > > > >> +  specific MemoryFence function
> >> > > > > > > > > >> +
> >> > > > > > > > > >> +**/
> >> > > > > > > > > >> +VOID
> >> > > > > > > > > >> +EFIAPI
> >> > > > > > > > > >> +AsmLfence (
> >> > > > > > > > > >> +  VOID
> >> > > > > > > > > >> +  );
> >> > > > > > > > > >> +
> >> > > > > > > > > >> +#endif  // defined (MDE_CPU_IA32) || defined
> >> > > (MDE_CPU_X64)
> >> > > > > > ||
> >> > > > > > > > > >defined (MDE_CPU_AARCH64)
> >> > > > > > > > > >>  #endif // !defined (__BASE_LIB__)
> >> > > > > > > > > >> diff --git
> a/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> >> > > > > > > > > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> >> > > > > > > > > >> new file mode 100644
> >> > > > > > > > > >> index 0000000..2fd804b
> >> > > > > > > > > >> --- /dev/null
> >> > > > > > > > > >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> >> > > > > > > > > >> @@ -0,0 +1,42 @@
> >> > > > > > > > > >>
> >> > > > >
> +##------------------------------------------------------------------------------
> >> > > > > > > > > >> +#
> >> > > > > > > > > >> +# AsmLfence() for AArch64
> >> > > > > > > > > >> +#
> >> > > > > > > > > >> +# Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> >> > > > > > > > > >> +#
> >> > > > > > > > > >> +# This program and the accompanying materials
> >> > > > > > > > > >> +# are licensed and made available under the terms and
> >> > > conditions
> >> > > > > > of the
> >> > > > > > > > > >BSD License
> >> > > > > > > > > >> +# which accompanies this distribution.  The full text of
> >> the
> >> > > > > license
> >> > > > > > may
> >> > > > > > > > > be
> >> > > > > > > > > >found at
> >> > > > > > > > > >> +# http://opensource.org/licenses/bsd-license.php.
> >> > > > > > > > > >> +#
> >> > > > > > > > > >> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD
> >> LICENSE
> >> > > ON
> >> > > > > AN
> >> > > > > > "AS
> >> > > > > > > > > IS"
> >> > > > > > > > > >BASIS,
> >> > > > > > > > > >> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF
> ANY
> >> > > KIND,
> >> > > > > > EITHER
> >> > > > > > > > > >EXPRESS OR IMPLIED.
> >> > > > > > > > > >> +#
> >> > > > > > > > > >>
> >> > > > >
> +##------------------------------------------------------------------------------
> >> > > > > > > > > >> +
> >> > > > > > > > > >> +.text
> >> > > > > > > > > >> +.p2align 2
> >> > > > > > > > > >> +
> >> > > > > > > > > >> +GCC_ASM_EXPORT(AsmLfence)
> >> > > > > > > > > >> +
> >> > > > > > > > > >> +# IMPORT
> >> > > > > > > > > >> +GCC_ASM_IMPORT(MemoryFence)
> >> > > > > > > > > >> +
> >> > > > > > > > > >> +#/**
> >> > > > > > > > > >> +#  Used to serialize load and store operations.
> >> > > > > > > > > >> +#
> >> > > > > > > > > >> +#  All loads and stores that proceed calls to this
> function
> >> are
> >> > > > > > > > > guaranteed to
> >> > > > > > > > > >be
> >> > > > > > > > > >> +#  globally visible when this function returns.
> >> > > > > > > > > >> +#
> >> > > > > > > > > >> +#**/
> >> > > > > > > > > >> +#VOID
> >> > > > > > > > > >> +#EFIAPI
> >> > > > > > > > > >> +#AsmLfence (
> >> > > > > > > > > >> +#  VOID
> >> > > > > > > > > >> +#  );
> >> > > > > > > > > >> +#
> >> > > > > > > > > >> +ASM_PFX(AsmLfence):
> >> > > > > > > > > >> +    stp   x29, x30, [sp, #-16]!
> >> > > > > > > > > >> +    bl MemoryFence
> >> > > > > > > > > >> +    ldp   x29, x30, [sp], #0x10
> >> > > > > > > > > >> +    ret
> >> > > > > > > > > >
> >> > > > > > > > > >Any reason we can't simply do
> >> > > > > > > > > >
> >> > > > > > > > > >b MemoryFence
> >> > > > > > > > > >
> >> > > > > > > > > >here?
> >> > > > > > > > > >
> >> > > > > > > > > >Also, why I understand the rationale, I still think it would
> be
> >> > > better
> >> > > > > > > > > >to change callers of the [x86 specific] AsmLfence() than to
> >> > > introduce
> >> > > > > > > > > >an alias of MemoryFence() for architectures where Lfence
> is
> >> not
> >> > > > > > > > > >defined.
> >> > > > > > > > > >
> >> > > > > > > > > >This is not only about tidiness, but also about potentially
> >> having
> >> > > > > > > > > >different semantics, which we can't provide in general on
> >> ARM,
> >> > > but
> >> > > > > > > > > >only in particular cases [such as the code that is modified
> in
> >> this
> >> > > > > > > > > >series]
> >> > > > > > > > > >
> >> > > > > > > > > >In other words, newly introduced occurrences of
> >> AsmLfence()
> >> > > now
> >> > > > > > have
> >> > > > > > > > > >to be audited for being appropriate on AArc64 if they are
> >> added
> >> > > to
> >> > > > > > > > > >generic code.
> >> > > > > > > > > >
> >> > > > > > > > > >
> >> > > > > > > > > >> diff --git
> >> a/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> >> > > > > > > > > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> >> > > > > > > > > >> new file mode 100644
> >> > > > > > > > > >> index 0000000..7dd5659
> >> > > > > > > > > >> --- /dev/null
> >> > > > > > > > > >> +++
> b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> >> > > > > > > > > >> @@ -0,0 +1,41 @@
> >> > > > > > > > > >>
> >> > > +;------------------------------------------------------------------------------
> >> > > > > > > > > >> +;
> >> > > > > > > > > >> +; AsmLfence() for AArch64
> >> > > > > > > > > >> +;
> >> > > > > > > > > >> +; Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> >> > > > > > > > > >> +;
> >> > > > > > > > > >> +; This program and the accompanying materials
> >> > > > > > > > > >> +; are licensed and made available under the terms and
> >> > > conditions
> >> > > > > > of the
> >> > > > > > > > > >BSD License
> >> > > > > > > > > >> +; which accompanies this distribution.  The full text of
> >> the
> >> > > > > license
> >> > > > > > may
> >> > > > > > > > > be
> >> > > > > > > > > >found at
> >> > > > > > > > > >> +; http://opensource.org/licenses/bsd-license.php.
> >> > > > > > > > > >> +;
> >> > > > > > > > > >> +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD
> >> LICENSE
> >> > > ON
> >> > > > > AN
> >> > > > > > "AS
> >> > > > > > > > > IS"
> >> > > > > > > > > >BASIS,
> >> > > > > > > > > >> +; WITHOUT WARRANTIES OR REPRESENTATIONS OF
> ANY
> >> > > KIND,
> >> > > > > > EITHER
> >> > > > > > > > > >EXPRESS OR IMPLIED.
> >> > > > > > > > > >> +;
> >> > > > > > > > > >>
> >> > > +;------------------------------------------------------------------------------
> >> > > > > > > > > >> +
> >> > > > > > > > > >> +  EXPORT AsmLfence
> >> > > > > > > > > >> +  AREA BaseLib_LowLevel, CODE, READONLY
> >> > > > > > > > > >> +  # IMPORT
> >> > > > > > > > > >> +  GCC_ASM_IMPORT(MemoryFence)
> >> > > > > > > > > >> +
> >> > > > > > > > > >> +;/**
> >> > > > > > > > > >> +;  Used to serialize load and store operations.
> >> > > > > > > > > >> +;
> >> > > > > > > > > >> +;  All loads and stores that proceed calls to this
> function
> >> are
> >> > > > > > guaranteed
> >> > > > > > > > > to
> >> > > > > > > > > >be
> >> > > > > > > > > >> +;  globally visible when this function returns.
> >> > > > > > > > > >> +;
> >> > > > > > > > > >> +;**/
> >> > > > > > > > > >> +;VOID
> >> > > > > > > > > >> +;EFIAPI
> >> > > > > > > > > >> +;AsmLfence (
> >> > > > > > > > > >> +;  VOID
> >> > > > > > > > > >> +;  );
> >> > > > > > > > > >> +;
> >> > > > > > > > > >> +AsmLfence
> >> > > > > > > > > >> +    stp   x29, x30, [sp, #-16]!
> >> > > > > > > > > >> +    bl MemoryFence
> >> > > > > > > > > >> +    ldp   x29, x30, [sp], #0x10
> >> > > > > > > > > >> +    ret
> >> > > > > > > > > >> +
> >> > > > > > > > > >> +  END
> >> > > > > > > > > >> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
> >> > > > > > > > > >b/MdePkg/Library/BaseLib/BaseLib.inf
> >> > > > > > > > > >> index b84e583..b7d7bcb 100644
> >> > > > > > > > > >> --- a/MdePkg/Library/BaseLib/BaseLib.inf
> >> > > > > > > > > >> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> >> > > > > > > > > >> @@ -585,6 +585,7 @@
> >> > > > > > > > > >>    Math64.c
> >> > > > > > > > > >>
> >> > > > > > > > > >>    AArch64/MemoryFence.S             | GCC
> >> > > > > > > > > >> +  AArch64/AsmLfence.S               | GCC
> >> > > > > > > > > >>    AArch64/SwitchStack.S             | GCC
> >> > > > > > > > > >>    AArch64/EnableInterrupts.S        | GCC
> >> > > > > > > > > >>    AArch64/DisableInterrupts.S       | GCC
> >> > > > > > > > > >> @@ -593,6 +594,7 @@
> >> > > > > > > > > >>    AArch64/CpuBreakpoint.S           | GCC
> >> > > > > > > > > >>
> >> > > > > > > > > >>    AArch64/MemoryFence.asm           | MSFT
> >> > > > > > > > > >> +  AArch64/AsmLfence.asm             | MSFT
> >> > > > > > > > > >>    AArch64/SwitchStack.asm           | MSFT
> >> > > > > > > > > >>    AArch64/EnableInterrupts.asm      | MSFT
> >> > > > > > > > > >>    AArch64/DisableInterrupts.asm     | MSFT
> >> > > > > > > > > >> --
> >> > > > > > > > > >> 2.7.4
> >> > > > > > > > > >>
> >> > > > > > > > > _______________________________________________
> >> > > > > > > > > edk2-devel mailing list
> >> > > > > > > > > edk2-devel@lists.01.org
> >> > > > > > > > > https://lists.01.org/mailman/listinfo/edk2-devel
> >> > > > > _______________________________________________
> >> > > > > edk2-devel mailing list
> >> > > > > edk2-devel@lists.01.org
> >> > > > > https://lists.01.org/mailman/listinfo/edk2-devel
> >> > > _______________________________________________
> >> > > edk2-devel mailing list
> >> > > edk2-devel@lists.01.org
> >> > > https://lists.01.org/mailman/listinfo/edk2-devel

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 00/13] Extend secure variable service to be usable from Standalone MM
  2018-12-17 11:46   ` Jagadeesh Ujja
@ 2018-12-18  4:37     ` Gao, Liming
  2018-12-18 11:19       ` Jagadeesh Ujja
  0 siblings, 1 reply; 52+ messages in thread
From: Gao, Liming @ 2018-12-18  4:37 UTC (permalink / raw)
  To: Jagadeesh Ujja
  Cc: edk2-devel@lists.01.org, Zhang, Chao B, leif.lindholm@linaro.org,
	ard.biesheuvel@linaro.org

Jagadeesh:
  StandaloneMmServicesTableLib library class header file is added into MdePkg. Its library implementation is in MdePkg and StandaloneMmPkg. The one in MdePkg produces the dummy implementation, and the one in StandaloneMmPkg produces the real implementation. I don't see the reason to separate this library class. 

Thanks
Liming
>-----Original Message-----
>From: Jagadeesh Ujja [mailto:jagadeesh.ujja@arm.com]
>Sent: Monday, December 17, 2018 7:47 PM
>To: Gao, Liming <liming.gao@intel.com>
>Cc: edk2-devel@lists.01.org; Zhang, Chao B <chao.b.zhang@intel.com>;
>leif.lindholm@linaro.org; ard.biesheuvel@linaro.org
>Subject: Re: [edk2] [PATCH 00/13] Extend secure variable service to be usable
>from Standalone MM
>
>Hi Liming,
>
>On Mon, Dec 17, 2018 at 7:15 AM Gao, Liming <liming.gao@intel.com> wrote:
>>
>> One question here. Why separate StandaloneMmServicesTableLib to two
>library classes? Current MdePkg\Include\Library\SmmServicesTableLib.h is
>one library class.
>MdePkg\Library\SmmServicesTableLib\SmmServicesTableLib.inf is its
>implementation. StandaloneMmServicesTableLib should be same to it.
>> StandaloneMmServicesTableLib is the library class.
>MdePkg\Library\StandaloneMmRuntimeDxe is its library instance.
>>
>Thanks for your review.
>
>The implementation of the "StandaloneMmServicesTableLib" library class
>is at "StandaloneMmPkg/Library/StandaloneMmServicesTableLib/". As this
>patchset reuses some of the DXE_DRIVER drivers as MM_STANDALONE
>drivers, the "StandaloneMmServicesTableLib" library class definition
>was placed within MdePkg. The reason for splitting the library class
>definition (in MdePkg) and its implementation (in StandaloneMmPkg) was
>due to your comment that "edk2 packages" should not have any reference
>to StandaloneMmPkg.dec.
>
>The "StandaloneMmRuntimeDxe" library now just has an implementation of
>InMm(). And so, this can be kept as a separate library with no
>dependency on StandaloneMmPkg. So this was the reason to split
>"StandaloneMmRuntimeDxe" and "StandaloneMmServicesTableLib" into two
>separate libraries.
>
>thanks
>Jagadeesh
>> Thanks
>> Liming
>> >-----Original Message-----
>> >From: Jagadeesh Ujja [mailto:jagadeesh.ujja@arm.com]
>> >Sent: Friday, December 14, 2018 8:13 PM
>> >To: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>; Zhang,
>> >Chao B <chao.b.zhang@intel.com>; leif.lindholm@linaro.org;
>> >ard.biesheuvel@linaro.org
>> >Subject: [PATCH 00/13] Extend secure variable service to be usable from
>> >Standalone MM
>> >
>> >Changes since RFC v4:
>> >- Addressed all the comments from Liming Gao
>> >  - Added an additional PCD 'PcdStandaloneMmCodeEnabled' to indicate
>> >    presence of StandaloneMM support.
>> >  - MdePkg.dec file updated to include StandaloneMmServiceTableLib and
>> >    StandaloneMmRuntimeDxe library.
>> >  - Platform specific changes will be posted in a seperate patchset.
>> >  - AsmLfence wrapper function is supported for AArch64 platforms.
>> >  - All the patches in this series can be pulled from
>> >    https://github.com/jagadeeshujja/edk2 (branch:
>> >topics/aarch64_secure_vars)
>> >
>> >Changes since RFC v3:
>> >- Addressed all the comments from Liming Gao
>> >  - Added a AArch64 implementation of AsmLfence which is a wrapper for
>> >    MemoryFence. The changes in variable service driver in v3 of this
>> >    patchset that used MemoryFence instead of AsmLfence have been
>> >removed.
>> >  - Added StandaloneMmServicesTableLib.h and
>StandaloneMmRuntimeDxe
>> >    library into MdePkg.
>> >  - Renamed PcdStandaloneMmEnable as
>PcdStandaloneMmVariableEnabled
>> >and
>> >    added to in to MdePkg.
>> >  - Now with above changes, edk2 packages don't need to depend on
>> >    StandaloneMmPkg/StandaloneMmPkg.dec
>> >- Addressed comments from Ting Ye
>> >  - Removed the hacks in the v3 version.
>> >  - Will relook into the “TimerWrapp.c” file and add a appropriate
>> >    implementation of this for MM Standalone mode code.
>> >
>> >Changes since RFC v2:
>> >- Added 'Contributed-under' tag, removed Change-ID tag and
>> >  maintained a single signed-off-by for the all the patches.
>> >
>> >Changes since RFC v1:
>> >- Addressed all the comments from Liming Gao
>> >  - Removed the use of #ifdef/#else/#endif and used a Pcd instead to
>> >    select between MM and non-MM paths.
>> >  - Removed all dependencies on edk2-platforms.
>> >  - Dropped the use of mMmst and used gSmst instead.
>> >  - Added a dummy implementation UefiRuntimeServiceTableLib for
>> >    MM_STANDALONE usage
>> >- Replaced all uses of AsmLfence with MemoryFence from variable
>> >  service code.
>> >- Add a new StandaloneMmRuntimeDxe library to for use by non-MM
>code.
>> >
>> >This patch series extends the existing secure variable service support for
>> >use with Standalone MM. This is applicable to paltforms that use
>Standalone
>> >Management Mode to protect access to non-volatile memory (NOR flash
>in
>> >case
>> >of these patches) used to store the secure EFI variables.
>> >
>> >The first patch pulls in additional libraries from the staging branch of
>> >StandaloneMmPkg into the edk2's StandaloneMmPkg. The existing secure
>> >variable
>> >service implementation supports only the traditional MM mode and so the
>> >rest
>> >of the patches extends the existing secure variable service support to be
>> >useable with Standalone MM mode as well.
>> >
>> >Jagadeesh Ujja (13):
>> >  StandaloneMmPkg: Pull in additonal libraries from staging branch
>> >  MdePkg: Add a PCD that indicates presence of Standalone MM mode
>> >  MdeModulePkg: Add a PCD to indicate Standalone MM supports secure
>> >    variable
>> >  MdePkg/Include: add StandaloneMmServicesTableLib header file
>> >  MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
>> >  MdePkg/Library: Add StandaloneMmRuntimeDxe library
>> >  MdeModulePkg/FaultTolerantWriteDxe: allow reusability as a MM driver
>> >  MdeModulePkg/Variable/RuntimeDxe: adapt for usability with MM
>> >    Standalone
>> >  MdeModulePkg/Variable/RuntimeDxe: adapt as a MM Standalone driver
>> >  MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this
>> >    library
>> >  ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver
>> >  SecurityPkg/AuthVariableLib: allow MM_STANDALONE drivers to use this
>> >    library
>> >  CryptoPkg/BaseCryptLib: allow MM_STANDALONE drivers to use this
>> >    library
>> >
>> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c
>> >|   2 +-
>> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c
>|
>> >210 ++++-
>> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h
>|
>> >5 +-
>> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
>|
>> >2 +
>> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c
>> >|  96 +--
>> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
>> >|  76 ++
>> > CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf                                             |
>7
>> >+-
>> > CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
>|   4
>> >+
>> > CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
>|
>> >15 +-
>> > MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
>|
>> >5 +-
>> > MdeModulePkg/MdeModulePkg.dec                                                               |   5 +
>> >
>MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
>> >|   1 +
>> >
>MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
>> >| 203 +++--
>> >
>> >MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStan
>dal
>> >oneMm.inf             | 101 +++
>> > MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c
>> >|  27 +-
>> > MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
>> >|  37 +-
>> > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
>> >|   1 +
>> > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
>> >| 201 ++++-
>> >
>MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
>> >|  31 +-
>> >
>> >MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDx
>e.i
>> >nf                        |   3 +
>> >
>MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
>> >| 132 ++++
>> > MdePkg/Include/Library/BaseLib.h                                                            |  33 +-
>> > MdePkg/Include/Library/StandaloneMmRuntimeDxe.h
>> >|  39 +
>> > MdePkg/Include/Library/StandaloneMmServicesTableLib.h
>> >|  25 +
>> > MdePkg/Library/BaseLib/AArch64/AsmLfence.S                                                  |
>42
>> >+
>> > MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
>|
>> >41 +
>> > MdePkg/Library/BaseLib/BaseLib.inf                                                          |   2 +
>> >
>MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c
>> >|  36 +
>> >
>MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf
>> >|  36 +
>> > MdePkg/MdePkg.dec                                                                           |  12 +
>> > SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
>|
>> >5 +-
>> >
>> >StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCor
>eH
>> >obLib.inf                   |   2 +-
>> >
>> >StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneM
>mC
>> >oreHobLibInternal.c         |  64 ++
>> >
>StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
>> >| 655 ++++++++++++++++
>> >
>StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
>> >|  48 ++
>> >
>> >StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalo
>ne
>> >MmMemoryAllocationLib.c   | 824 ++++++++++++++++++++
>> >
>> >StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalo
>ne
>> >MmMemoryAllocationLib.inf |  45 ++
>> >
>> >StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneM
>mS
>> >ervicesTableLib.c         |  64 ++
>> >
>> >StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneM
>mS
>> >ervicesTableLib.inf       |  36 +
>> > 39 files changed, 2929 insertions(+), 244 deletions(-)
>> > create mode 100644
>> >ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
>> > create mode 100644
>> >MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStan
>dal
>> >oneMm.inf
>> > create mode 100644
>> >MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.i
>nf
>> > create mode 100644
>MdePkg/Include/Library/StandaloneMmRuntimeDxe.h
>> > create mode 100644
>> >MdePkg/Include/Library/StandaloneMmServicesTableLib.h
>> > create mode 100644 MdePkg/Library/BaseLib/AArch64/AsmLfence.S
>> > create mode 100644 MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
>> > create mode 100644
>> >MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.
>c
>> > create mode 100644
>> >MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.i
>nf
>> > create mode 100644
>> >StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneM
>mC
>> >oreHobLibInternal.c
>> > create mode 100644
>> >StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
>> > create mode 100644
>> >StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.i
>nf
>> > create mode 100644
>> >StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalo
>ne
>> >MmMemoryAllocationLib.c
>> > create mode 100644
>> >StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalo
>ne
>> >MmMemoryAllocationLib.inf
>> > create mode 100644
>> >StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneM
>mS
>> >ervicesTableLib.c
>> > create mode 100644
>> >StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneM
>mS
>> >ervicesTableLib.inf
>> >
>> >--
>> >2.7.4
>>
>> _______________________________________________
>> edk2-devel mailing list
>> edk2-devel@lists.01.org
>> https://lists.01.org/mailman/listinfo/edk2-devel

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 00/13] Extend secure variable service to be usable from Standalone MM
  2018-12-18  4:37     ` Gao, Liming
@ 2018-12-18 11:19       ` Jagadeesh Ujja
  2018-12-20 14:23         ` Gao, Liming
  0 siblings, 1 reply; 52+ messages in thread
From: Jagadeesh Ujja @ 2018-12-18 11:19 UTC (permalink / raw)
  To: Gao, Liming; +Cc: edk2-devel@lists.01.org, Zhang, Chao B

Hi Liming,

On Tue, Dec 18, 2018 at 10:07 AM Gao, Liming <liming.gao@intel.com> wrote:
>
> Jagadeesh:
>   StandaloneMmServicesTableLib library class header file is added into MdePkg. Its library implementation is in MdePkg and StandaloneMmPkg. The one in MdePkg produces the dummy implementation, and the one in StandaloneMmPkg produces the real implementation. I don't see the reason to separate this library class.
>

In this patchset series, the Variable service/Fault tolerant/Nor Flash
driver are refactored to be usable as MM_STANDALONE driver. These
drivers uses the following libraries from “StandaloneMmPkg”.

- MmServicesTableLib|StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf
- MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf

Variable MM_STANDALONE driver is located at
- MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
- MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf

FaultTolerant MM_STANDALONE is driver located at
- MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
- MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf

These drivers look for “gMmst” which is defined in
“MmServicesTableLib”. Ideally,
“StandaloneMmPkg/Include/Library/StandaloneMmServicesTableLib.h”
should have defined “gMmst” as an “extern EFI_MM_SYSTEM_TABLE
*gMmst;”.
In which case, we would have to add
“StandaloneMmPkg/StandaloneMmPkg.dec” in other drivers listed below.

- MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
- MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf

This will make “edk2 packages” to be depended on
"StandaloneMmPkg/StandaloneMmPkg.dec".

To avoid this, “StandaloneMmPkg/Include/Library/StandaloneMmServicesTableLib.h”
is moved to “MdePkg/Include/Library/StandaloneMmServicesTableLib.h”.
But, the implementation of “MmServicesTableLib” comes from
“StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf”.

Thanks
Jagadeesh

> Thanks
> Liming
> >-----Original Message-----
> >From: Jagadeesh Ujja [mailto:jagadeesh.ujja@arm.com]
> >Sent: Monday, December 17, 2018 7:47 PM
> >To: Gao, Liming <liming.gao@intel.com>
> >Cc: edk2-devel@lists.01.org; Zhang, Chao B <chao.b.zhang@intel.com>;
> >leif.lindholm@linaro.org; ard.biesheuvel@linaro.org
> >Subject: Re: [edk2] [PATCH 00/13] Extend secure variable service to be usable
> >from Standalone MM
> >
> >Hi Liming,
> >
> >On Mon, Dec 17, 2018 at 7:15 AM Gao, Liming <liming.gao@intel.com> wrote:
> >>
> >> One question here. Why separate StandaloneMmServicesTableLib to two
> >library classes? Current MdePkg\Include\Library\SmmServicesTableLib.h is
> >one library class.
> >MdePkg\Library\SmmServicesTableLib\SmmServicesTableLib.inf is its
> >implementation. StandaloneMmServicesTableLib should be same to it.
> >> StandaloneMmServicesTableLib is the library class.
> >MdePkg\Library\StandaloneMmRuntimeDxe is its library instance.
> >>
> >Thanks for your review.
> >
> >The implementation of the "StandaloneMmServicesTableLib" library class
> >is at "StandaloneMmPkg/Library/StandaloneMmServicesTableLib/". As this
> >patchset reuses some of the DXE_DRIVER drivers as MM_STANDALONE
> >drivers, the "StandaloneMmServicesTableLib" library class definition
> >was placed within MdePkg. The reason for splitting the library class
> >definition (in MdePkg) and its implementation (in StandaloneMmPkg) was
> >due to your comment that "edk2 packages" should not have any reference
> >to StandaloneMmPkg.dec.
> >
> >The "StandaloneMmRuntimeDxe" library now just has an implementation of
> >InMm(). And so, this can be kept as a separate library with no
> >dependency on StandaloneMmPkg. So this was the reason to split
> >"StandaloneMmRuntimeDxe" and "StandaloneMmServicesTableLib" into two
> >separate libraries.
> >
> >thanks
> >Jagadeesh
> >> Thanks
> >> Liming
> >> >-----Original Message-----
> >> >From: Jagadeesh Ujja [mailto:jagadeesh.ujja@arm.com]
> >> >Sent: Friday, December 14, 2018 8:13 PM
> >> >To: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>; Zhang,
> >> >Chao B <chao.b.zhang@intel.com>; leif.lindholm@linaro.org;
> >> >ard.biesheuvel@linaro.org
> >> >Subject: [PATCH 00/13] Extend secure variable service to be usable from
> >> >Standalone MM
> >> >
> >> >Changes since RFC v4:
> >> >- Addressed all the comments from Liming Gao
> >> >  - Added an additional PCD 'PcdStandaloneMmCodeEnabled' to indicate
> >> >    presence of StandaloneMM support.
> >> >  - MdePkg.dec file updated to include StandaloneMmServiceTableLib and
> >> >    StandaloneMmRuntimeDxe library.
> >> >  - Platform specific changes will be posted in a seperate patchset.
> >> >  - AsmLfence wrapper function is supported for AArch64 platforms.
> >> >  - All the patches in this series can be pulled from
> >> >    https://github.com/jagadeeshujja/edk2 (branch:
> >> >topics/aarch64_secure_vars)
> >> >
> >> >Changes since RFC v3:
> >> >- Addressed all the comments from Liming Gao
> >> >  - Added a AArch64 implementation of AsmLfence which is a wrapper for
> >> >    MemoryFence. The changes in variable service driver in v3 of this
> >> >    patchset that used MemoryFence instead of AsmLfence have been
> >> >removed.
> >> >  - Added StandaloneMmServicesTableLib.h and
> >StandaloneMmRuntimeDxe
> >> >    library into MdePkg.
> >> >  - Renamed PcdStandaloneMmEnable as
> >PcdStandaloneMmVariableEnabled
> >> >and
> >> >    added to in to MdePkg.
> >> >  - Now with above changes, edk2 packages don't need to depend on
> >> >    StandaloneMmPkg/StandaloneMmPkg.dec
> >> >- Addressed comments from Ting Ye
> >> >  - Removed the hacks in the v3 version.
> >> >  - Will relook into the “TimerWrapp.c” file and add a appropriate
> >> >    implementation of this for MM Standalone mode code.
> >> >
> >> >Changes since RFC v2:
> >> >- Added 'Contributed-under' tag, removed Change-ID tag and
> >> >  maintained a single signed-off-by for the all the patches.
> >> >
> >> >Changes since RFC v1:
> >> >- Addressed all the comments from Liming Gao
> >> >  - Removed the use of #ifdef/#else/#endif and used a Pcd instead to
> >> >    select between MM and non-MM paths.
> >> >  - Removed all dependencies on edk2-platforms.
> >> >  - Dropped the use of mMmst and used gSmst instead.
> >> >  - Added a dummy implementation UefiRuntimeServiceTableLib for
> >> >    MM_STANDALONE usage
> >> >- Replaced all uses of AsmLfence with MemoryFence from variable
> >> >  service code.
> >> >- Add a new StandaloneMmRuntimeDxe library to for use by non-MM
> >code.
> >> >
> >> >This patch series extends the existing secure variable service support for
> >> >use with Standalone MM. This is applicable to paltforms that use
> >Standalone
> >> >Management Mode to protect access to non-volatile memory (NOR flash
> >in
> >> >case
> >> >of these patches) used to store the secure EFI variables.
> >> >
> >> >The first patch pulls in additional libraries from the staging branch of
> >> >StandaloneMmPkg into the edk2's StandaloneMmPkg. The existing secure
> >> >variable
> >> >service implementation supports only the traditional MM mode and so the
> >> >rest
> >> >of the patches extends the existing secure variable service support to be
> >> >useable with Standalone MM mode as well.
> >> >
> >> >Jagadeesh Ujja (13):
> >> >  StandaloneMmPkg: Pull in additonal libraries from staging branch
> >> >  MdePkg: Add a PCD that indicates presence of Standalone MM mode
> >> >  MdeModulePkg: Add a PCD to indicate Standalone MM supports secure
> >> >    variable
> >> >  MdePkg/Include: add StandaloneMmServicesTableLib header file
> >> >  MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
> >> >  MdePkg/Library: Add StandaloneMmRuntimeDxe library
> >> >  MdeModulePkg/FaultTolerantWriteDxe: allow reusability as a MM driver
> >> >  MdeModulePkg/Variable/RuntimeDxe: adapt for usability with MM
> >> >    Standalone
> >> >  MdeModulePkg/Variable/RuntimeDxe: adapt as a MM Standalone driver
> >> >  MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this
> >> >    library
> >> >  ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver
> >> >  SecurityPkg/AuthVariableLib: allow MM_STANDALONE drivers to use this
> >> >    library
> >> >  CryptoPkg/BaseCryptLib: allow MM_STANDALONE drivers to use this
> >> >    library
> >> >
> >> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c
> >> >|   2 +-
> >> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c
> >|
> >> >210 ++++-
> >> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h
> >|
> >> >5 +-
> >> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
> >|
> >> >2 +
> >> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c
> >> >|  96 +--
> >> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
> >> >|  76 ++
> >> > CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf                                             |
> >7
> >> >+-
> >> > CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
> >|   4
> >> >+
> >> > CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
> >|
> >> >15 +-
> >> > MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
> >|
> >> >5 +-
> >> > MdeModulePkg/MdeModulePkg.dec                                                               |   5 +
> >> >
> >MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
> >> >|   1 +
> >> >
> >MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
> >> >| 203 +++--
> >> >
> >> >MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStan
> >dal
> >> >oneMm.inf             | 101 +++
> >> > MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c
> >> >|  27 +-
> >> > MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
> >> >|  37 +-
> >> > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> >> >|   1 +
> >> > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
> >> >| 201 ++++-
> >> >
> >MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
> >> >|  31 +-
> >> >
> >> >MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDx
> >e.i
> >> >nf                        |   3 +
> >> >
> >MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
> >> >| 132 ++++
> >> > MdePkg/Include/Library/BaseLib.h                                                            |  33 +-
> >> > MdePkg/Include/Library/StandaloneMmRuntimeDxe.h
> >> >|  39 +
> >> > MdePkg/Include/Library/StandaloneMmServicesTableLib.h
> >> >|  25 +
> >> > MdePkg/Library/BaseLib/AArch64/AsmLfence.S                                                  |
> >42
> >> >+
> >> > MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> >|
> >> >41 +
> >> > MdePkg/Library/BaseLib/BaseLib.inf                                                          |   2 +
> >> >
> >MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c
> >> >|  36 +
> >> >
> >MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf
> >> >|  36 +
> >> > MdePkg/MdePkg.dec                                                                           |  12 +
> >> > SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
> >|
> >> >5 +-
> >> >
> >> >StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCor
> >eH
> >> >obLib.inf                   |   2 +-
> >> >
> >> >StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneM
> >mC
> >> >oreHobLibInternal.c         |  64 ++
> >> >
> >StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
> >> >| 655 ++++++++++++++++
> >> >
> >StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
> >> >|  48 ++
> >> >
> >> >StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalo
> >ne
> >> >MmMemoryAllocationLib.c   | 824 ++++++++++++++++++++
> >> >
> >> >StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalo
> >ne
> >> >MmMemoryAllocationLib.inf |  45 ++
> >> >
> >> >StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneM
> >mS
> >> >ervicesTableLib.c         |  64 ++
> >> >
> >> >StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneM
> >mS
> >> >ervicesTableLib.inf       |  36 +
> >> > 39 files changed, 2929 insertions(+), 244 deletions(-)
> >> > create mode 100644
> >> >ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
> >> > create mode 100644
> >> >MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStan
> >dal
> >> >oneMm.inf
> >> > create mode 100644
> >> >MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.i
> >nf
> >> > create mode 100644
> >MdePkg/Include/Library/StandaloneMmRuntimeDxe.h
> >> > create mode 100644
> >> >MdePkg/Include/Library/StandaloneMmServicesTableLib.h
> >> > create mode 100644 MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> >> > create mode 100644 MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> >> > create mode 100644
> >> >MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.
> >c
> >> > create mode 100644
> >> >MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.i
> >nf
> >> > create mode 100644
> >> >StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneM
> >mC
> >> >oreHobLibInternal.c
> >> > create mode 100644
> >> >StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
> >> > create mode 100644
> >> >StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.i
> >nf
> >> > create mode 100644
> >> >StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalo
> >ne
> >> >MmMemoryAllocationLib.c
> >> > create mode 100644
> >> >StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalo
> >ne
> >> >MmMemoryAllocationLib.inf
> >> > create mode 100644
> >> >StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneM
> >mS
> >> >ervicesTableLib.c
> >> > create mode 100644
> >> >StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneM
> >mS
> >> >ervicesTableLib.inf
> >> >
> >> >--
> >> >2.7.4
> >>
> >> _______________________________________________
> >> edk2-devel mailing list
> >> edk2-devel@lists.01.org
> >> https://lists.01.org/mailman/listinfo/edk2-devel
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
  2018-12-18  2:08                       ` Yao, Jiewen
  2018-12-18  2:12                         ` Gao, Liming
@ 2018-12-20  9:00                         ` Jagadeesh Ujja
  2018-12-20  9:10                           ` Ard Biesheuvel
  1 sibling, 1 reply; 52+ messages in thread
From: Jagadeesh Ujja @ 2018-12-20  9:00 UTC (permalink / raw)
  To: Yao, Jiewen
  Cc: Ard Biesheuvel, Wu, Hao A, edk2-devel@lists.01.org, Zhang, Chao B,
	Gao, Liming

hi Ard,

On Tue, Dec 18, 2018 at 7:38 AM Yao, Jiewen <jiewen.yao@intel.com> wrote:
>
> + Wu Hao, since he contributed the original patch.
>
> Ard
> Would you please file a Bugzilla for that? Then we can start working on that.
>

Can you please file the Bugzilla, please do let me know, I am happy to
file Bugzilla

Thanks
Ujja


> Thank you
> Yao Jiewen
>
> > -----Original Message-----
> > From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> > Sent: Monday, December 17, 2018 5:28 PM
> > To: Yao, Jiewen <jiewen.yao@intel.com>
> > Cc: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>; Zhang,
> > Chao B <chao.b.zhang@intel.com>
> > Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> > AsmLfence function
> >
> > On Mon, 17 Dec 2018 at 09:44, Yao, Jiewen <jiewen.yao@intel.com> wrote:
> > >
> > > Thanks Ard.
> > > I have little concern about "Spec", because people may read it as
> > "Specification", especially in our team. :)
> > >
> >
> > I understand :-)
> >
> > SpeculationBarrier() is fine with me.
> >
> >
> > >
> > > > -----Original Message-----
> > > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf
> > Of
> > > > Ard Biesheuvel
> > > > Sent: Monday, December 17, 2018 4:35 PM
> > > > To: Yao, Jiewen <jiewen.yao@intel.com>
> > > > Cc: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>;
> > Zhang,
> > > > Chao B <chao.b.zhang@intel.com>
> > > > Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64:
> > Add
> > > > AsmLfence function
> > > >
> > > > On Mon, 17 Dec 2018 at 09:30, Yao, Jiewen <jiewen.yao@intel.com>
> > wrote:
> > > > >
> > > > > I reviewed the ARM white paper -
> > > >
> > file:///C:/Users/jyao1/Downloads/Cache_Speculation_Side-channels-v2.4.p
> > > > df
> > > > >
> > > > > I agree with you that LoadFence might not be the best idea.
> > > > >
> > > > > How about SpeculationBarrier() ?
> > > > >
> > > >
> > > > That works for me. Or SpecFence (). As long as it does not conflate
> > > > memory ordering with controlling the side effects of speculative
> > > > execution, it is ok with me.
> > > >
> > > > I'll contribute the ARM and AARCH64 implementations asap once the
> > > > generic changes are posted on the list.
> > > >
> > > > Thanks,
> > > >
> > > > > > -----Original Message-----
> > > > > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On
> > Behalf
> > > > Of
> > > > > > Yao, Jiewen
> > > > > > Sent: Monday, December 17, 2018 4:25 PM
> > > > > > To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Leif Lindholm
> > > > > > <leif.lindholm@linaro.org>
> > > > > > Cc: edk2-devel@lists.01.org; Zhang, Chao B
> > <chao.b.zhang@intel.com>;
> > > > > > Gao, Liming <liming.gao@intel.com>
> > > > > > Subject: Re: [edk2] [PATCH 05/13] MdePkg/Library/BaseLib/AArch64:
> > > > Add
> > > > > > AsmLfence function
> > > > > >
> > > > > > Hi Ard
> > > > > > I am OK to refine it now.
> > > > > >
> > > > > > Do you have any proposal on the naming from ARM side?
> > > > > >
> > > > > > Thank you
> > > > > > Yao Jiewen
> > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> > > > > > > Sent: Monday, December 17, 2018 4:11 PM
> > > > > > > To: Yao, Jiewen <jiewen.yao@intel.com>; Leif Lindholm
> > > > > > > <leif.lindholm@linaro.org>
> > > > > > > Cc: Gao, Liming <liming.gao@intel.com>; Jagadeesh Ujja
> > > > > > > <jagadeesh.ujja@arm.com>; edk2-devel@lists.01.org; Zhang, Chao
> > B
> > > > > > > <chao.b.zhang@intel.com>
> > > > > > > Subject: Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add
> > > > > > > AsmLfence function
> > > > > > >
> > > > > > > On Mon, 17 Dec 2018 at 08:45, Ard Biesheuvel
> > > > > > <ard.biesheuvel@linaro.org>
> > > > > > > wrote:
> > > > > > > >
> > > > > > > > On Mon, 17 Dec 2018 at 04:29, Yao, Jiewen
> > <jiewen.yao@intel.com>
> > > > > > > wrote:
> > > > > > > > >
> > > > > > > > > I think we have below definition.
> > > > > > > > > -- MemoryFence: Serialize load and store operations.
> > > > > > > > > -- LoadFence: Serialize load operations.
> > > > > > > > > -- StoreFence: Serialize store operations.
> > > > > > > > >
> > > > > > > > > According to IA32 SDM, Intel has MFENCE, LFENCE and SFENCE.
> > > > > > > > > If ARM only has DMB, it is possible to use DMB for
> > MemoryFence,
> > > > > > > LoadFence or StoreFence.
> > > > > > > > >
> > > > > > > > > Maybe it is better to use LoadFence, instead of AsmLFence?
> > > > > > > > > Then we can align with MemoryFence.
> > > > > > > > >
> > > > > > > >
> > > > > > > > I think using AsmLfence() all over the code to limit speculation
> > was a
> > > > > > > > mistake, and I am disappointed nobody from the ARM side was
> > > > involved
> > > > > > > > at all when these changes were proposed.
> > > > > > > >
> > > > > > >
> > > > > > > OK, I have to apologize here. Hao did cc us on these patches, and so
> > > > > > > we did have the opportunity to respond at the time.
> > > > > > >
> > > > > > > But that doesn't change the fact that AsmLfence() should be
> > replaced
> > > > > > > by an abstraction that describes the specific semantics of the x86
> > > > > > > Lfence implemetation beyond memory ordering that we are relying
> > on
> > > > > > > here.
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > > The code changes rely on specific semantics of the x86 Lfence
> > > > > > > > instructions, i.e., that beyond load serialization, they ensure that
> > > > > > > > all instructions (not just loads) complete before the lfence
> > > > > > > > completes. This is a much stronger notion than a load barrier, and
> > so
> > > > > > > > the abstraction should have been defined as something like a
> > > > > > > > ExecFence() or pipeline barrier etc, and the x86 specific
> > > > > > > > implementation would have been mapped onto Lfence. For the
> > ARM
> > > > > > side,
> > > > > > > > we probably need an ISB instruction here as well as some kind of
> > > > other
> > > > > > > > barrier. Calling it LoadFence() makes no sense whatsoever.
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > > >
> > > > > > > > > > -----Original Message-----
> > > > > > > > > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org]
> > On
> > > > > > Behalf
> > > > > > > Of
> > > > > > > > > > Gao, Liming
> > > > > > > > > > Sent: Monday, December 17, 2018 10:04 AM
> > > > > > > > > > To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Jagadeesh
> > Ujja
> > > > > > > > > > <jagadeesh.ujja@arm.com>; Leif Lindholm
> > > > > > <leif.lindholm@linaro.org>
> > > > > > > > > > Cc: edk2-devel@lists.01.org; Zhang, Chao B
> > > > > > > <chao.b.zhang@intel.com>
> > > > > > > > > > Subject: Re: [edk2] [PATCH 05/13]
> > > > MdePkg/Library/BaseLib/AArch64:
> > > > > > > Add
> > > > > > > > > > AsmLfence function
> > > > > > > > > >
> > > > > > > > > > Ard:
> > > > > > > > > >   My first comment is to suggest updating the caller code for
> > the
> > > > > > arch
> > > > > > > > > > specific code.  But, there are two drivers that have the same
> > > > usage.
> > > > > > > This
> > > > > > > > > > way will introduce the duplicated code logic. So, I suggest
> > another
> > > > > > way
> > > > > > > to
> > > > > > > > > > extend  AsmLfence() API scope for the different ARCHs. If
> > you
> > > > think
> > > > > > it
> > > > > > > brings
> > > > > > > > > > the confuse, I just think another way to resolve this case in the
> > > > caller
> > > > > > > code.
> > > > > > > > > >
> > > > > > > > > > #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> > > > > > > > > > AsmLfence();
> > > > > > > > > > #else
> > > > > > > > > > MemoryFence()
> > > > > > > > > > #endif
> > > > > > > > > >
> > > > > > > > > > Thanks
> > > > > > > > > > Liming
> > > > > > > > > > >-----Original Message-----
> > > > > > > > > > >From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> > > > > > > > > > >Sent: Friday, December 14, 2018 9:54 PM
> > > > > > > > > > >To: Jagadeesh Ujja <jagadeesh.ujja@arm.com>; Leif
> > Lindholm
> > > > > > > > > > ><leif.lindholm@linaro.org>
> > > > > > > > > > >Cc: edk2-devel@lists.01.org; Gao, Liming
> > > > <liming.gao@intel.com>;
> > > > > > > Zhang,
> > > > > > > > > > >Chao B <chao.b.zhang@intel.com>
> > > > > > > > > > >Subject: Re: [PATCH 05/13]
> > MdePkg/Library/BaseLib/AArch64:
> > > > Add
> > > > > > > > > > >AsmLfence function
> > > > > > > > > > >
> > > > > > > > > > >On Fri, 14 Dec 2018 at 13:13, Jagadeesh Ujja
> > > > > > > <jagadeesh.ujja@arm.com>
> > > > > > > > > > >wrote:
> > > > > > > > > > >>
> > > > > > > > > > >> Variable service driver includes a call to AsmLfence. To
> > reuse
> > > > this
> > > > > > > > > > >> driver on AArch64 based platforms, add an implementation
> > of
> > > > > > > AsmLfence
> > > > > > > > > > >> that acts as a wrapper on the AArch64 specific
> > MemoryFence
> > > > > > > function.
> > > > > > > > > > >>
> > > > > > > > > > >> Contributed-under: TianoCore Contribution Agreement 1.1
> > > > > > > > > > >> Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> > > > > > > > > > >> ---
> > > > > > > > > > >>  MdePkg/Include/Library/BaseLib.h             | 33
> > > > > > > +++++++++------
> > > > > > > > > > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.S   | 42
> > > > > > > > > > >++++++++++++++++++++
> > > > > > > > > > >>  MdePkg/Library/BaseLib/AArch64/AsmLfence.asm | 41
> > > > > > > > > > >+++++++++++++++++++
> > > > > > > > > > >>  MdePkg/Library/BaseLib/BaseLib.inf           |  2 +
> > > > > > > > > > >>  4 files changed, 105 insertions(+), 13 deletions(-)
> > > > > > > > > > >>
> > > > > > > > > > >> diff --git a/MdePkg/Include/Library/BaseLib.h
> > > > > > > > > > >b/MdePkg/Include/Library/BaseLib.h
> > > > > > > > > > >> index 8cc0869..ca961ee 100644
> > > > > > > > > > >> --- a/MdePkg/Include/Library/BaseLib.h
> > > > > > > > > > >> +++ b/MdePkg/Include/Library/BaseLib.h
> > > > > > > > > > >> @@ -7697,19 +7697,6 @@ AsmWriteTr (
> > > > > > > > > > >>    );
> > > > > > > > > > >>
> > > > > > > > > > >>  /**
> > > > > > > > > > >> -  Performs a serializing operation on all
> > load-from-memory
> > > > > > > instructions
> > > > > > > > > > that
> > > > > > > > > > >> -  were issued prior the AsmLfence function.
> > > > > > > > > > >> -
> > > > > > > > > > >> -  Executes a LFENCE instruction. This function is only
> > > > available
> > > > > > on
> > > > > > > IA-32
> > > > > > > > > > and
> > > > > > > > > > >x64.
> > > > > > > > > > >> -
> > > > > > > > > > >> -**/
> > > > > > > > > > >> -VOID
> > > > > > > > > > >> -EFIAPI
> > > > > > > > > > >> -AsmLfence (
> > > > > > > > > > >> -  VOID
> > > > > > > > > > >> -  );
> > > > > > > > > > >> -
> > > > > > > > > > >> -/**
> > > > > > > > > > >>    Patch the immediate operand of an IA32 or X64
> > instruction
> > > > > > such
> > > > > > > that
> > > > > > > > > > the
> > > > > > > > > > >byte,
> > > > > > > > > > >>    word, dword or qword operand is encoded at the end
> > of
> > > > the
> > > > > > > > > > instruction's
> > > > > > > > > > >>    binary representation.
> > > > > > > > > > >> @@ -7752,4 +7739,24 @@ PatchInstructionX86 (
> > > > > > > > > > >>    );
> > > > > > > > > > >>
> > > > > > > > > > >>  #endif // defined (MDE_CPU_IA32) || defined
> > > > (MDE_CPU_X64)
> > > > > > > > > > >> +
> > > > > > > > > > >> +#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> > ||
> > > > > > > defined
> > > > > > > > > > >(MDE_CPU_AARCH64)
> > > > > > > > > > >> +
> > > > > > > > > > >> +/**
> > > > > > > > > > >> +  Performs a serializing operation on all
> > load-from-memory
> > > > > > > instructions
> > > > > > > > > > that
> > > > > > > > > > >> +  were issued prior the AsmLfence function.
> > > > > > > > > > >> +
> > > > > > > > > > >> +  In case of IA-32 and x64, Executes a LFENCE
> > instruction.
> > > > > > > > > > >> +
> > > > > > > > > > >> +  In case of AArch64 this acts as a wrapper on the
> > AArch64
> > > > > > > > > > >> +  specific MemoryFence function
> > > > > > > > > > >> +
> > > > > > > > > > >> +**/
> > > > > > > > > > >> +VOID
> > > > > > > > > > >> +EFIAPI
> > > > > > > > > > >> +AsmLfence (
> > > > > > > > > > >> +  VOID
> > > > > > > > > > >> +  );
> > > > > > > > > > >> +
> > > > > > > > > > >> +#endif  // defined (MDE_CPU_IA32) || defined
> > > > (MDE_CPU_X64)
> > > > > > > ||
> > > > > > > > > > >defined (MDE_CPU_AARCH64)
> > > > > > > > > > >>  #endif // !defined (__BASE_LIB__)
> > > > > > > > > > >> diff --git a/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > > > > > > > > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > > > > > > > > >> new file mode 100644
> > > > > > > > > > >> index 0000000..2fd804b
> > > > > > > > > > >> --- /dev/null
> > > > > > > > > > >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > > > > > > > > > >> @@ -0,0 +1,42 @@
> > > > > > > > > > >>
> > > > > > +##------------------------------------------------------------------------------
> > > > > > > > > > >> +#
> > > > > > > > > > >> +# AsmLfence() for AArch64
> > > > > > > > > > >> +#
> > > > > > > > > > >> +# Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> > > > > > > > > > >> +#
> > > > > > > > > > >> +# This program and the accompanying materials
> > > > > > > > > > >> +# are licensed and made available under the terms and
> > > > conditions
> > > > > > > of the
> > > > > > > > > > >BSD License
> > > > > > > > > > >> +# which accompanies this distribution.  The full text of
> > the
> > > > > > license
> > > > > > > may
> > > > > > > > > > be
> > > > > > > > > > >found at
> > > > > > > > > > >> +# http://opensource.org/licenses/bsd-license.php.
> > > > > > > > > > >> +#
> > > > > > > > > > >> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD
> > LICENSE
> > > > ON
> > > > > > AN
> > > > > > > "AS
> > > > > > > > > > IS"
> > > > > > > > > > >BASIS,
> > > > > > > > > > >> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY
> > > > KIND,
> > > > > > > EITHER
> > > > > > > > > > >EXPRESS OR IMPLIED.
> > > > > > > > > > >> +#
> > > > > > > > > > >>
> > > > > > +##------------------------------------------------------------------------------
> > > > > > > > > > >> +
> > > > > > > > > > >> +.text
> > > > > > > > > > >> +.p2align 2
> > > > > > > > > > >> +
> > > > > > > > > > >> +GCC_ASM_EXPORT(AsmLfence)
> > > > > > > > > > >> +
> > > > > > > > > > >> +# IMPORT
> > > > > > > > > > >> +GCC_ASM_IMPORT(MemoryFence)
> > > > > > > > > > >> +
> > > > > > > > > > >> +#/**
> > > > > > > > > > >> +#  Used to serialize load and store operations.
> > > > > > > > > > >> +#
> > > > > > > > > > >> +#  All loads and stores that proceed calls to this function
> > are
> > > > > > > > > > guaranteed to
> > > > > > > > > > >be
> > > > > > > > > > >> +#  globally visible when this function returns.
> > > > > > > > > > >> +#
> > > > > > > > > > >> +#**/
> > > > > > > > > > >> +#VOID
> > > > > > > > > > >> +#EFIAPI
> > > > > > > > > > >> +#AsmLfence (
> > > > > > > > > > >> +#  VOID
> > > > > > > > > > >> +#  );
> > > > > > > > > > >> +#
> > > > > > > > > > >> +ASM_PFX(AsmLfence):
> > > > > > > > > > >> +    stp   x29, x30, [sp, #-16]!
> > > > > > > > > > >> +    bl MemoryFence
> > > > > > > > > > >> +    ldp   x29, x30, [sp], #0x10
> > > > > > > > > > >> +    ret
> > > > > > > > > > >
> > > > > > > > > > >Any reason we can't simply do
> > > > > > > > > > >
> > > > > > > > > > >b MemoryFence
> > > > > > > > > > >
> > > > > > > > > > >here?
> > > > > > > > > > >
> > > > > > > > > > >Also, why I understand the rationale, I still think it would be
> > > > better
> > > > > > > > > > >to change callers of the [x86 specific] AsmLfence() than to
> > > > introduce
> > > > > > > > > > >an alias of MemoryFence() for architectures where Lfence is
> > not
> > > > > > > > > > >defined.
> > > > > > > > > > >
> > > > > > > > > > >This is not only about tidiness, but also about potentially
> > having
> > > > > > > > > > >different semantics, which we can't provide in general on
> > ARM,
> > > > but
> > > > > > > > > > >only in particular cases [such as the code that is modified in
> > this
> > > > > > > > > > >series]
> > > > > > > > > > >
> > > > > > > > > > >In other words, newly introduced occurrences of
> > AsmLfence()
> > > > now
> > > > > > > have
> > > > > > > > > > >to be audited for being appropriate on AArc64 if they are
> > added
> > > > to
> > > > > > > > > > >generic code.
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > >> diff --git
> > a/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > > > > > > > > >b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > > > > > > > > >> new file mode 100644
> > > > > > > > > > >> index 0000000..7dd5659
> > > > > > > > > > >> --- /dev/null
> > > > > > > > > > >> +++ b/MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > > > > > > > > > >> @@ -0,0 +1,41 @@
> > > > > > > > > > >>
> > > > +;------------------------------------------------------------------------------
> > > > > > > > > > >> +;
> > > > > > > > > > >> +; AsmLfence() for AArch64
> > > > > > > > > > >> +;
> > > > > > > > > > >> +; Copyright (c) 2013-2018, ARM Ltd. All rights reserved.
> > > > > > > > > > >> +;
> > > > > > > > > > >> +; This program and the accompanying materials
> > > > > > > > > > >> +; are licensed and made available under the terms and
> > > > conditions
> > > > > > > of the
> > > > > > > > > > >BSD License
> > > > > > > > > > >> +; which accompanies this distribution.  The full text of
> > the
> > > > > > license
> > > > > > > may
> > > > > > > > > > be
> > > > > > > > > > >found at
> > > > > > > > > > >> +; http://opensource.org/licenses/bsd-license.php.
> > > > > > > > > > >> +;
> > > > > > > > > > >> +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD
> > LICENSE
> > > > ON
> > > > > > AN
> > > > > > > "AS
> > > > > > > > > > IS"
> > > > > > > > > > >BASIS,
> > > > > > > > > > >> +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY
> > > > KIND,
> > > > > > > EITHER
> > > > > > > > > > >EXPRESS OR IMPLIED.
> > > > > > > > > > >> +;
> > > > > > > > > > >>
> > > > +;------------------------------------------------------------------------------
> > > > > > > > > > >> +
> > > > > > > > > > >> +  EXPORT AsmLfence
> > > > > > > > > > >> +  AREA BaseLib_LowLevel, CODE, READONLY
> > > > > > > > > > >> +  # IMPORT
> > > > > > > > > > >> +  GCC_ASM_IMPORT(MemoryFence)
> > > > > > > > > > >> +
> > > > > > > > > > >> +;/**
> > > > > > > > > > >> +;  Used to serialize load and store operations.
> > > > > > > > > > >> +;
> > > > > > > > > > >> +;  All loads and stores that proceed calls to this function
> > are
> > > > > > > guaranteed
> > > > > > > > > > to
> > > > > > > > > > >be
> > > > > > > > > > >> +;  globally visible when this function returns.
> > > > > > > > > > >> +;
> > > > > > > > > > >> +;**/
> > > > > > > > > > >> +;VOID
> > > > > > > > > > >> +;EFIAPI
> > > > > > > > > > >> +;AsmLfence (
> > > > > > > > > > >> +;  VOID
> > > > > > > > > > >> +;  );
> > > > > > > > > > >> +;
> > > > > > > > > > >> +AsmLfence
> > > > > > > > > > >> +    stp   x29, x30, [sp, #-16]!
> > > > > > > > > > >> +    bl MemoryFence
> > > > > > > > > > >> +    ldp   x29, x30, [sp], #0x10
> > > > > > > > > > >> +    ret
> > > > > > > > > > >> +
> > > > > > > > > > >> +  END
> > > > > > > > > > >> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > > > > > > >b/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > > > > > > >> index b84e583..b7d7bcb 100644
> > > > > > > > > > >> --- a/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > > > > > > >> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> > > > > > > > > > >> @@ -585,6 +585,7 @@
> > > > > > > > > > >>    Math64.c
> > > > > > > > > > >>
> > > > > > > > > > >>    AArch64/MemoryFence.S             | GCC
> > > > > > > > > > >> +  AArch64/AsmLfence.S               | GCC
> > > > > > > > > > >>    AArch64/SwitchStack.S             | GCC
> > > > > > > > > > >>    AArch64/EnableInterrupts.S        | GCC
> > > > > > > > > > >>    AArch64/DisableInterrupts.S       | GCC
> > > > > > > > > > >> @@ -593,6 +594,7 @@
> > > > > > > > > > >>    AArch64/CpuBreakpoint.S           | GCC
> > > > > > > > > > >>
> > > > > > > > > > >>    AArch64/MemoryFence.asm           | MSFT
> > > > > > > > > > >> +  AArch64/AsmLfence.asm             | MSFT
> > > > > > > > > > >>    AArch64/SwitchStack.asm           | MSFT
> > > > > > > > > > >>    AArch64/EnableInterrupts.asm      | MSFT
> > > > > > > > > > >>    AArch64/DisableInterrupts.asm     | MSFT
> > > > > > > > > > >> --
> > > > > > > > > > >> 2.7.4
> > > > > > > > > > >>
> > > > > > > > > > _______________________________________________
> > > > > > > > > > edk2-devel mailing list
> > > > > > > > > > edk2-devel@lists.01.org
> > > > > > > > > > https://lists.01.org/mailman/listinfo/edk2-devel
> > > > > > _______________________________________________
> > > > > > edk2-devel mailing list
> > > > > > edk2-devel@lists.01.org
> > > > > > https://lists.01.org/mailman/listinfo/edk2-devel
> > > > _______________________________________________
> > > > edk2-devel mailing list
> > > > edk2-devel@lists.01.org
> > > > https://lists.01.org/mailman/listinfo/edk2-devel
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
  2018-12-20  9:00                         ` Jagadeesh Ujja
@ 2018-12-20  9:10                           ` Ard Biesheuvel
  0 siblings, 0 replies; 52+ messages in thread
From: Ard Biesheuvel @ 2018-12-20  9:10 UTC (permalink / raw)
  To: Jagadeesh Ujja
  Cc: Yao, Jiewen, Wu, Hao A, edk2-devel@lists.01.org, Zhang, Chao B,
	Gao, Liming

On Thu, 20 Dec 2018 at 10:01, Jagadeesh Ujja <jagadeesh.ujja@arm.com> wrote:
>
> hi Ard,
>
> On Tue, Dec 18, 2018 at 7:38 AM Yao, Jiewen <jiewen.yao@intel.com> wrote:
> >
> > + Wu Hao, since he contributed the original patch.
> >
> > Ard
> > Would you please file a Bugzilla for that? Then we can start working on that.
> >
>
> Can you please file the Bugzilla, please do let me know, I am happy to
> file Bugzilla
>

Done.

https://bugzilla.tianocore.org/show_bug.cgi?id=1417


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 00/13] Extend secure variable service to be usable from Standalone MM
  2018-12-18 11:19       ` Jagadeesh Ujja
@ 2018-12-20 14:23         ` Gao, Liming
  2019-01-02 17:15           ` Ard Biesheuvel
  0 siblings, 1 reply; 52+ messages in thread
From: Gao, Liming @ 2018-12-20 14:23 UTC (permalink / raw)
  To: Jagadeesh Ujja; +Cc: edk2-devel@lists.01.org, Zhang, Chao B

Jagadeesh:
  MdeModulePkg Variable service/Fault tolerant/Nor Flash driver depends on StandaloneMmServicesTableLib library class header file. This header file is added into MdePkg. It has two interfaces. One is global gMmst, another is function InMm(). So, there is no dependency issue here. 
And, MdePkg adds one StandaloneMmServicesTableLib library INF with empty implementation, this library is just for build. It sets gMmst=NULL, and always return FASLE in InMm(). This library can be used in MdeModulePkg.dsc to make Variable driver pass build. There is also no dependency issue here. Last, Platform DSC file will refer to the real StandaloneMmServicesTableLib library INF from StandaloneMmPkg. 

Thanks
Liming
> -----Original Message-----
> From: Jagadeesh Ujja [mailto:jagadeesh.ujja@arm.com]
> Sent: Tuesday, December 18, 2018 7:19 PM
> To: Gao, Liming <liming.gao@intel.com>
> Cc: edk2-devel@lists.01.org; Zhang, Chao B <chao.b.zhang@intel.com>
> Subject: Re: [edk2] [PATCH 00/13] Extend secure variable service to be usable from Standalone MM
> 
> Hi Liming,
> 
> On Tue, Dec 18, 2018 at 10:07 AM Gao, Liming <liming.gao@intel.com> wrote:
> >	
> > Jagadeesh:
> >   StandaloneMmServicesTableLib library class header file is added into MdePkg. Its library implementation is in MdePkg and
> StandaloneMmPkg. The one in MdePkg produces the dummy implementation, and the one in StandaloneMmPkg produces the real
> implementation. I don't see the reason to separate this library class.
> >
> 
> In this patchset series, the Variable service/Fault tolerant/Nor Flash
> driver are refactored to be usable as MM_STANDALONE driver. These
> drivers uses the following libraries from “StandaloneMmPkg”.
> 
> - MmServicesTableLib|StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf
> - MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf
> 
> Variable MM_STANDALONE driver is located at
> - MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
> - MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
> 
> FaultTolerant MM_STANDALONE is driver located at
> - MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
> - MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf
> 
> These drivers look for “gMmst” which is defined in
> “MmServicesTableLib”. Ideally,
> “StandaloneMmPkg/Include/Library/StandaloneMmServicesTableLib.h”
> should have defined “gMmst” as an “extern EFI_MM_SYSTEM_TABLE
> *gMmst;”.
> In which case, we would have to add
> “StandaloneMmPkg/StandaloneMmPkg.dec” in other drivers listed below.
> 
> - MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> - MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
> 
> This will make “edk2 packages” to be depended on
> "StandaloneMmPkg/StandaloneMmPkg.dec".
> 
> To avoid this, “StandaloneMmPkg/Include/Library/StandaloneMmServicesTableLib.h”
> is moved to “MdePkg/Include/Library/StandaloneMmServicesTableLib.h”.
> But, the implementation of “MmServicesTableLib” comes from
> “StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf”.
> 
> Thanks
> Jagadeesh
> 
> > Thanks
> > Liming
> > >-----Original Message-----
> > >From: Jagadeesh Ujja [mailto:jagadeesh.ujja@arm.com]
> > >Sent: Monday, December 17, 2018 7:47 PM
> > >To: Gao, Liming <liming.gao@intel.com>
> > >Cc: edk2-devel@lists.01.org; Zhang, Chao B <chao.b.zhang@intel.com>;
> > >leif.lindholm@linaro.org; ard.biesheuvel@linaro.org
> > >Subject: Re: [edk2] [PATCH 00/13] Extend secure variable service to be usable
> > >from Standalone MM
> > >
> > >Hi Liming,
> > >
> > >On Mon, Dec 17, 2018 at 7:15 AM Gao, Liming <liming.gao@intel.com> wrote:
> > >>
> > >> One question here. Why separate StandaloneMmServicesTableLib to two
> > >library classes? Current MdePkg\Include\Library\SmmServicesTableLib.h is
> > >one library class.
> > >MdePkg\Library\SmmServicesTableLib\SmmServicesTableLib.inf is its
> > >implementation. StandaloneMmServicesTableLib should be same to it.
> > >> StandaloneMmServicesTableLib is the library class.
> > >MdePkg\Library\StandaloneMmRuntimeDxe is its library instance.
> > >>
> > >Thanks for your review.
> > >
> > >The implementation of the "StandaloneMmServicesTableLib" library class
> > >is at "StandaloneMmPkg/Library/StandaloneMmServicesTableLib/". As this
> > >patchset reuses some of the DXE_DRIVER drivers as MM_STANDALONE
> > >drivers, the "StandaloneMmServicesTableLib" library class definition
> > >was placed within MdePkg. The reason for splitting the library class
> > >definition (in MdePkg) and its implementation (in StandaloneMmPkg) was
> > >due to your comment that "edk2 packages" should not have any reference
> > >to StandaloneMmPkg.dec.
> > >
> > >The "StandaloneMmRuntimeDxe" library now just has an implementation of
> > >InMm(). And so, this can be kept as a separate library with no
> > >dependency on StandaloneMmPkg. So this was the reason to split
> > >"StandaloneMmRuntimeDxe" and "StandaloneMmServicesTableLib" into two
> > >separate libraries.
> > >
> > >thanks
> > >Jagadeesh
> > >> Thanks
> > >> Liming
> > >> >-----Original Message-----
> > >> >From: Jagadeesh Ujja [mailto:jagadeesh.ujja@arm.com]
> > >> >Sent: Friday, December 14, 2018 8:13 PM
> > >> >To: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>; Zhang,
> > >> >Chao B <chao.b.zhang@intel.com>; leif.lindholm@linaro.org;
> > >> >ard.biesheuvel@linaro.org
> > >> >Subject: [PATCH 00/13] Extend secure variable service to be usable from
> > >> >Standalone MM
> > >> >
> > >> >Changes since RFC v4:
> > >> >- Addressed all the comments from Liming Gao
> > >> >  - Added an additional PCD 'PcdStandaloneMmCodeEnabled' to indicate
> > >> >    presence of StandaloneMM support.
> > >> >  - MdePkg.dec file updated to include StandaloneMmServiceTableLib and
> > >> >    StandaloneMmRuntimeDxe library.
> > >> >  - Platform specific changes will be posted in a seperate patchset.
> > >> >  - AsmLfence wrapper function is supported for AArch64 platforms.
> > >> >  - All the patches in this series can be pulled from
> > >> >    https://github.com/jagadeeshujja/edk2 (branch:
> > >> >topics/aarch64_secure_vars)
> > >> >
> > >> >Changes since RFC v3:
> > >> >- Addressed all the comments from Liming Gao
> > >> >  - Added a AArch64 implementation of AsmLfence which is a wrapper for
> > >> >    MemoryFence. The changes in variable service driver in v3 of this
> > >> >    patchset that used MemoryFence instead of AsmLfence have been
> > >> >removed.
> > >> >  - Added StandaloneMmServicesTableLib.h and
> > >StandaloneMmRuntimeDxe
> > >> >    library into MdePkg.
> > >> >  - Renamed PcdStandaloneMmEnable as
> > >PcdStandaloneMmVariableEnabled
> > >> >and
> > >> >    added to in to MdePkg.
> > >> >  - Now with above changes, edk2 packages don't need to depend on
> > >> >    StandaloneMmPkg/StandaloneMmPkg.dec
> > >> >- Addressed comments from Ting Ye
> > >> >  - Removed the hacks in the v3 version.
> > >> >  - Will relook into the “TimerWrapp.c” file and add a appropriate
> > >> >    implementation of this for MM Standalone mode code.
> > >> >
> > >> >Changes since RFC v2:
> > >> >- Added 'Contributed-under' tag, removed Change-ID tag and
> > >> >  maintained a single signed-off-by for the all the patches.
> > >> >
> > >> >Changes since RFC v1:
> > >> >- Addressed all the comments from Liming Gao
> > >> >  - Removed the use of #ifdef/#else/#endif and used a Pcd instead to
> > >> >    select between MM and non-MM paths.
> > >> >  - Removed all dependencies on edk2-platforms.
> > >> >  - Dropped the use of mMmst and used gSmst instead.
> > >> >  - Added a dummy implementation UefiRuntimeServiceTableLib for
> > >> >    MM_STANDALONE usage
> > >> >- Replaced all uses of AsmLfence with MemoryFence from variable
> > >> >  service code.
> > >> >- Add a new StandaloneMmRuntimeDxe library to for use by non-MM
> > >code.
> > >> >
> > >> >This patch series extends the existing secure variable service support for
> > >> >use with Standalone MM. This is applicable to paltforms that use
> > >Standalone
> > >> >Management Mode to protect access to non-volatile memory (NOR flash
> > >in
> > >> >case
> > >> >of these patches) used to store the secure EFI variables.
> > >> >
> > >> >The first patch pulls in additional libraries from the staging branch of
> > >> >StandaloneMmPkg into the edk2's StandaloneMmPkg. The existing secure
> > >> >variable
> > >> >service implementation supports only the traditional MM mode and so the
> > >> >rest
> > >> >of the patches extends the existing secure variable service support to be
> > >> >useable with Standalone MM mode as well.
> > >> >
> > >> >Jagadeesh Ujja (13):
> > >> >  StandaloneMmPkg: Pull in additonal libraries from staging branch
> > >> >  MdePkg: Add a PCD that indicates presence of Standalone MM mode
> > >> >  MdeModulePkg: Add a PCD to indicate Standalone MM supports secure
> > >> >    variable
> > >> >  MdePkg/Include: add StandaloneMmServicesTableLib header file
> > >> >  MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
> > >> >  MdePkg/Library: Add StandaloneMmRuntimeDxe library
> > >> >  MdeModulePkg/FaultTolerantWriteDxe: allow reusability as a MM driver
> > >> >  MdeModulePkg/Variable/RuntimeDxe: adapt for usability with MM
> > >> >    Standalone
> > >> >  MdeModulePkg/Variable/RuntimeDxe: adapt as a MM Standalone driver
> > >> >  MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this
> > >> >    library
> > >> >  ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver
> > >> >  SecurityPkg/AuthVariableLib: allow MM_STANDALONE drivers to use this
> > >> >    library
> > >> >  CryptoPkg/BaseCryptLib: allow MM_STANDALONE drivers to use this
> > >> >    library
> > >> >
> > >> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c
> > >> >|   2 +-
> > >> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c
> > >|
> > >> >210 ++++-
> > >> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h
> > >|
> > >> >5 +-
> > >> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
> > >|
> > >> >2 +
> > >> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c
> > >> >|  96 +--
> > >> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
> > >> >|  76 ++
> > >> > CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf                                             |
> > >7
> > >> >+-
> > >> > CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
> > >|   4
> > >> >+
> > >> > CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
> > >|
> > >> >15 +-
> > >> > MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
> > >|
> > >> >5 +-
> > >> > MdeModulePkg/MdeModulePkg.dec                                                               |   5 +
> > >> >
> > >MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
> > >> >|   1 +
> > >> >
> > >MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
> > >> >| 203 +++--
> > >> >
> > >> >MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStan
> > >dal
> > >> >oneMm.inf             | 101 +++
> > >> > MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c
> > >> >|  27 +-
> > >> > MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
> > >> >|  37 +-
> > >> > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> > >> >|   1 +
> > >> > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
> > >> >| 201 ++++-
> > >> >
> > >MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
> > >> >|  31 +-
> > >> >
> > >> >MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDx
> > >e.i
> > >> >nf                        |   3 +
> > >> >
> > >MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
> > >> >| 132 ++++
> > >> > MdePkg/Include/Library/BaseLib.h                                                            |  33 +-
> > >> > MdePkg/Include/Library/StandaloneMmRuntimeDxe.h
> > >> >|  39 +
> > >> > MdePkg/Include/Library/StandaloneMmServicesTableLib.h
> > >> >|  25 +
> > >> > MdePkg/Library/BaseLib/AArch64/AsmLfence.S                                                  |
> > >42
> > >> >+
> > >> > MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > >|
> > >> >41 +
> > >> > MdePkg/Library/BaseLib/BaseLib.inf                                                          |   2 +
> > >> >
> > >MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c
> > >> >|  36 +
> > >> >
> > >MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf
> > >> >|  36 +
> > >> > MdePkg/MdePkg.dec                                                                           |  12 +
> > >> > SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
> > >|
> > >> >5 +-
> > >> >
> > >> >StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCor
> > >eH
> > >> >obLib.inf                   |   2 +-
> > >> >
> > >> >StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneM
> > >mC
> > >> >oreHobLibInternal.c         |  64 ++
> > >> >
> > >StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
> > >> >| 655 ++++++++++++++++
> > >> >
> > >StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
> > >> >|  48 ++
> > >> >
> > >> >StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalo
> > >ne
> > >> >MmMemoryAllocationLib.c   | 824 ++++++++++++++++++++
> > >> >
> > >> >StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalo
> > >ne
> > >> >MmMemoryAllocationLib.inf |  45 ++
> > >> >
> > >> >StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneM
> > >mS
> > >> >ervicesTableLib.c         |  64 ++
> > >> >
> > >> >StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneM
> > >mS
> > >> >ervicesTableLib.inf       |  36 +
> > >> > 39 files changed, 2929 insertions(+), 244 deletions(-)
> > >> > create mode 100644
> > >> >ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
> > >> > create mode 100644
> > >> >MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStan
> > >dal
> > >> >oneMm.inf
> > >> > create mode 100644
> > >> >MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.i
> > >nf
> > >> > create mode 100644
> > >MdePkg/Include/Library/StandaloneMmRuntimeDxe.h
> > >> > create mode 100644
> > >> >MdePkg/Include/Library/StandaloneMmServicesTableLib.h
> > >> > create mode 100644 MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > >> > create mode 100644 MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > >> > create mode 100644
> > >> >MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.
> > >c
> > >> > create mode 100644
> > >> >MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.i
> > >nf
> > >> > create mode 100644
> > >> >StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneM
> > >mC
> > >> >oreHobLibInternal.c
> > >> > create mode 100644
> > >> >StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
> > >> > create mode 100644
> > >> >StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.i
> > >nf
> > >> > create mode 100644
> > >> >StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalo
> > >ne
> > >> >MmMemoryAllocationLib.c
> > >> > create mode 100644
> > >> >StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalo
> > >ne
> > >> >MmMemoryAllocationLib.inf
> > >> > create mode 100644
> > >> >StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneM
> > >mS
> > >> >ervicesTableLib.c
> > >> > create mode 100644
> > >> >StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneM
> > >mS
> > >> >ervicesTableLib.inf
> > >> >
> > >> >--
> > >> >2.7.4
> > >>
> > >> _______________________________________________
> > >> edk2-devel mailing list
> > >> edk2-devel@lists.01.org
> > >> https://lists.01.org/mailman/listinfo/edk2-devel
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://lists.01.org/mailman/listinfo/edk2-devel

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 00/13] Extend secure variable service to be usable from Standalone MM
  2018-12-14 12:13 [PATCH 00/13] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
                   ` (13 preceding siblings ...)
  2018-12-17  1:45 ` [PATCH 00/13] Extend secure variable service to be usable from Standalone MM Gao, Liming
@ 2018-12-21  2:57 ` Wang, Jian J
  2019-01-02 13:19   ` Jagadeesh Ujja
  14 siblings, 1 reply; 52+ messages in thread
From: Wang, Jian J @ 2018-12-21  2:57 UTC (permalink / raw)
  To: Jagadeesh Ujja, edk2-devel@lists.01.org, Gao, Liming,
	Zhang, Chao B, leif.lindholm@linaro.org,
	ard.biesheuvel@linaro.org

Jagadeesh,

There're many places in this patch series where code similar to following is added.
It'd better to wrap them into module private functions or even a library, if necessary.
This can make the code cleaner (no if/else) and easier (central place) to maintain in
the future. 

+  if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) {
+    Status = gSmst->SmmLocateProtocol (
+                      &gEfiSmmSwapAddressRangeProtocolGuid,
+                      NULL,
+                      SarProtocol
+                      );
+  } else {
+    Status = gMmst->MmLocateProtocol (
+                      &gEfiSmmSwapAddressRangeProtocolGuid,
+                      NULL,
+                      SarProtocol
+                      );
+  }

Regards,
Jian


> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Jagadeesh Ujja
> Sent: Friday, December 14, 2018 8:13 PM
> To: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>; Zhang, Chao
> B <chao.b.zhang@intel.com>; leif.lindholm@linaro.org;
> ard.biesheuvel@linaro.org
> Subject: [edk2] [PATCH 00/13] Extend secure variable service to be usable from
> Standalone MM
> 
> Changes since RFC v4:
> - Addressed all the comments from Liming Gao
>   - Added an additional PCD 'PcdStandaloneMmCodeEnabled' to indicate
>     presence of StandaloneMM support.
>   - MdePkg.dec file updated to include StandaloneMmServiceTableLib and
>     StandaloneMmRuntimeDxe library.
>   - Platform specific changes will be posted in a seperate patchset.
>   - AsmLfence wrapper function is supported for AArch64 platforms.
>   - All the patches in this series can be pulled from
>     https://github.com/jagadeeshujja/edk2 (branch: topics/aarch64_secure_vars)
> 
> Changes since RFC v3:
> - Addressed all the comments from Liming Gao
>   - Added a AArch64 implementation of AsmLfence which is a wrapper for
>     MemoryFence. The changes in variable service driver in v3 of this
>     patchset that used MemoryFence instead of AsmLfence have been removed.
>   - Added StandaloneMmServicesTableLib.h and StandaloneMmRuntimeDxe
>     library into MdePkg.
>   - Renamed PcdStandaloneMmEnable as PcdStandaloneMmVariableEnabled and
>     added to in to MdePkg.
>   - Now with above changes, edk2 packages don't need to depend on
>     StandaloneMmPkg/StandaloneMmPkg.dec
> - Addressed comments from Ting Ye
>   - Removed the hacks in the v3 version.
>   - Will relook into the “TimerWrapp.c” file and add a appropriate
>     implementation of this for MM Standalone mode code.
> 
> Changes since RFC v2:
> - Added 'Contributed-under' tag, removed Change-ID tag and
>   maintained a single signed-off-by for the all the patches.
> 
> Changes since RFC v1:
> - Addressed all the comments from Liming Gao
>   - Removed the use of #ifdef/#else/#endif and used a Pcd instead to
>     select between MM and non-MM paths.
>   - Removed all dependencies on edk2-platforms.
>   - Dropped the use of mMmst and used gSmst instead.
>   - Added a dummy implementation UefiRuntimeServiceTableLib for
>     MM_STANDALONE usage
> - Replaced all uses of AsmLfence with MemoryFence from variable
>   service code.
> - Add a new StandaloneMmRuntimeDxe library to for use by non-MM code.
> 
> This patch series extends the existing secure variable service support for
> use with Standalone MM. This is applicable to paltforms that use Standalone
> Management Mode to protect access to non-volatile memory (NOR flash in case
> of these patches) used to store the secure EFI variables.
> 
> The first patch pulls in additional libraries from the staging branch of
> StandaloneMmPkg into the edk2's StandaloneMmPkg. The existing secure
> variable
> service implementation supports only the traditional MM mode and so the rest
> of the patches extends the existing secure variable service support to be
> useable with Standalone MM mode as well.
> 
> Jagadeesh Ujja (13):
>   StandaloneMmPkg: Pull in additonal libraries from staging branch
>   MdePkg: Add a PCD that indicates presence of Standalone MM mode
>   MdeModulePkg: Add a PCD to indicate Standalone MM supports secure
>     variable
>   MdePkg/Include: add StandaloneMmServicesTableLib header file
>   MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
>   MdePkg/Library: Add StandaloneMmRuntimeDxe library
>   MdeModulePkg/FaultTolerantWriteDxe: allow reusability as a MM driver
>   MdeModulePkg/Variable/RuntimeDxe: adapt for usability with MM
>     Standalone
>   MdeModulePkg/Variable/RuntimeDxe: adapt as a MM Standalone driver
>   MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this
>     library
>   ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver
>   SecurityPkg/AuthVariableLib: allow MM_STANDALONE drivers to use this
>     library
>   CryptoPkg/BaseCryptLib: allow MM_STANDALONE drivers to use this
>     library
> 
>  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c
> |   2 +-
>  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c                                            |
> 210 ++++-
>  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h                                            |
> 5 +-
>  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf                                          |
> 2 +
>  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c
> |  96 +--
>  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
> |  76 ++
>  CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf                                             |   7
> +-
>  CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf                                          |   4
> +
>  CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c                                       |
> 15 +-
>  MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf                                            |
> 5 +-
>  MdeModulePkg/MdeModulePkg.dec                                                               |   5 +
>  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
> |   1 +
>  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
> | 203 +++--
> 
> MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandalon
> eMm.inf             | 101 +++
>  MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c
> |  27 +-
>  MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
> |  37 +-
>  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> |   1 +
>  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
> | 201 ++++-
>  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
> |  31 +-
>  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
> |   3 +
>  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
> | 132 ++++
>  MdePkg/Include/Library/BaseLib.h                                                            |  33 +-
>  MdePkg/Include/Library/StandaloneMmRuntimeDxe.h
> |  39 +
>  MdePkg/Include/Library/StandaloneMmServicesTableLib.h
> |  25 +
>  MdePkg/Library/BaseLib/AArch64/AsmLfence.S                                                  |  42
> +
>  MdePkg/Library/BaseLib/AArch64/AsmLfence.asm                                                |
> 41 +
>  MdePkg/Library/BaseLib/BaseLib.inf                                                          |   2 +
>  MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c
> |  36 +
>  MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf
> |  36 +
>  MdePkg/MdePkg.dec                                                                           |  12 +
>  SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf                                     |
> 5 +-
> 
> StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHob
> Lib.inf                   |   2 +-
> 
> StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmCore
> HobLibInternal.c         |  64 ++
>  StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
> | 655 ++++++++++++++++
>  StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
> |  48 ++
> 
> StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMm
> MemoryAllocationLib.c   | 824 ++++++++++++++++++++
> 
> StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMm
> MemoryAllocationLib.inf |  45 ++
> 
> StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServi
> cesTableLib.c         |  64 ++
> 
> StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServi
> cesTableLib.inf       |  36 +
>  39 files changed, 2929 insertions(+), 244 deletions(-)
>  create mode 100644
> ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
>  create mode 100644
> MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandalon
> eMm.inf
>  create mode 100644
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
>  create mode 100644 MdePkg/Include/Library/StandaloneMmRuntimeDxe.h
>  create mode 100644 MdePkg/Include/Library/StandaloneMmServicesTableLib.h
>  create mode 100644 MdePkg/Library/BaseLib/AArch64/AsmLfence.S
>  create mode 100644 MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
>  create mode 100644
> MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c
>  create mode 100644
> MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf
>  create mode 100644
> StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmCore
> HobLibInternal.c
>  create mode 100644
> StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
>  create mode 100644
> StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
>  create mode 100644
> StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMm
> MemoryAllocationLib.c
>  create mode 100644
> StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMm
> MemoryAllocationLib.inf
>  create mode 100644
> StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServi
> cesTableLib.c
>  create mode 100644
> StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServi
> cesTableLib.inf
> 
> --
> 2.7.4
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 01/13] StandaloneMmPkg: Pull in additonal libraries from staging branch
  2018-12-14 12:13 ` [PATCH 01/13] StandaloneMmPkg: Pull in additonal libraries from staging branch Jagadeesh Ujja
@ 2018-12-21  8:58   ` Ard Biesheuvel
  0 siblings, 0 replies; 52+ messages in thread
From: Ard Biesheuvel @ 2018-12-21  8:58 UTC (permalink / raw)
  To: Jagadeesh Ujja
  Cc: edk2-devel@lists.01.org, Gao, Liming, Zhang, Chao B,
	Leif Lindholm

Hello Jagadeesh,

Please drop the reference to the staging branch from the subject and
from below, it is not relevant.

On Fri, 14 Dec 2018 at 13:13, Jagadeesh Ujja <jagadeesh.ujja@arm.com> wrote:
>
> Three additional library packages are being pulled into StandaloneMmPkg
> from the staging area in order to support the secure variable service.
> The three packages being pulled in are
>   - StandaloneMmHobLib
>   - StandaloneMmMemoryAllocationLib
>   - StandaloneMmServicesTableLib
>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> ---
>  StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf                   |   2 +-
>  StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmCoreHobLibInternal.c         |  64 ++
>  StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c                             | 655 ++++++++++++++++
>  StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf                           |  48 ++
>  StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c   | 824 ++++++++++++++++++++
>  StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf |  45 ++
>  StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.c         |  64 ++
>  StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf       |  36 +
>  8 files changed, 1737 insertions(+), 1 deletion(-)
>
> diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf b/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf
> index db19d3c..ac036e3 100644
> --- a/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf
> +++ b/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf
> @@ -24,7 +24,7 @@
>    MODULE_TYPE                    = MM_CORE_STANDALONE
>    VERSION_STRING                 = 1.0
>    PI_SPECIFICATION_VERSION       = 0x00010032
> -  LIBRARY_CLASS                  = HobLib|MM_CORE_STANDALONE MM_STANDALONE
> +  LIBRARY_CLASS                  = HobLib|MM_CORE_STANDALONE
>
>  #
>  #  VALID_ARCHITECTURES           = AARCH64

This is an unrelated change.

> diff --git a/StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmCoreHobLibInternal.c b/StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmCoreHobLibInternal.c
> new file mode 100644
> index 0000000..ac5a1c0
> --- /dev/null
> +++ b/StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmCoreHobLibInternal.c
> @@ -0,0 +1,64 @@
> +/** @file
> +  HOB Library implementation for Standalone MM Core.
> +
> +Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.<BR>
> +
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD License
> +which accompanies this distribution.  The full text of the license may be found at
> +http://opensource.org/licenses/bsd-license.php.
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include <PiMm.h>
> +
> +#include <Library/HobLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +
> +#include <Guid/MemoryAllocationHob.h>
> +
> +//
> +// Cache copy of HobList pointer.
> +//
> +extern VOID *gHobList;
> +
> +EFI_HOB_HANDOFF_INFO_TABLE*
> +HobConstructor (
> +  IN VOID   *EfiMemoryBegin,
> +  IN UINTN  EfiMemoryLength,
> +  IN VOID   *EfiFreeMemoryBottom,
> +  IN VOID   *EfiFreeMemoryTop
> +  )
> +{
> +  EFI_HOB_HANDOFF_INFO_TABLE  *Hob;
> +  EFI_HOB_GENERIC_HEADER      *HobEnd;
> +
> +  Hob    = EfiFreeMemoryBottom;
> +  HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1);
> +
> +  Hob->Header.HobType     = EFI_HOB_TYPE_HANDOFF;
> +  Hob->Header.HobLength   = sizeof(EFI_HOB_HANDOFF_INFO_TABLE);
> +  Hob->Header.Reserved    = 0;
> +
> +  HobEnd->HobType     = EFI_HOB_TYPE_END_OF_HOB_LIST;
> +  HobEnd->HobLength   = sizeof(EFI_HOB_GENERIC_HEADER);
> +  HobEnd->Reserved    = 0;
> +
> +  Hob->Version             = EFI_HOB_HANDOFF_TABLE_VERSION;
> +  Hob->BootMode            = BOOT_WITH_FULL_CONFIGURATION;
> +
> +  Hob->EfiMemoryTop        = (UINTN)EfiMemoryBegin + EfiMemoryLength;
> +  Hob->EfiMemoryBottom     = (UINTN)EfiMemoryBegin;
> +  Hob->EfiFreeMemoryTop    = (UINTN)EfiFreeMemoryTop;
> +  Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd+1);
> +  Hob->EfiEndOfHobList     = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
> +
> +  gHobList = Hob;
> +
> +  return Hob;
> +}
> diff --git a/StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c b/StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
> new file mode 100644
> index 0000000..591a78c
> --- /dev/null
> +++ b/StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
> @@ -0,0 +1,655 @@
> +/** @file
> +  HOB Library implementation for Standalone MM Core.
> +
> +Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.<BR>
> +
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD License
> +which accompanies this distribution.  The full text of the license may be found at
> +http://opensource.org/licenses/bsd-license.php.
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include <PiMm.h>
> +
> +#include <Library/HobLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +
> +#include <Guid/MemoryAllocationHob.h>
> +
> +//
> +// Cache copy of HobList pointer.
> +//
> +VOID *gHobList = NULL;
> +
> +EFI_MM_SYSTEM_TABLE   *gMmst = NULL;
> +
> +/**
> +  The constructor function caches the pointer to HOB list.
> +
> +  The constructor function gets the start address of HOB list from system configuration table.
> +  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
> +
> +  @param  ImageHandle   The firmware allocated handle for the EFI image.
> +  @param  SystemTable   A pointer to the EFI System Table.
> +
> +  @retval EFI_SUCCESS   The constructor successfully gets HobList.
> +  @retval Other value   The constructor can't get HobList.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +HobLibConstructor (
> +  IN EFI_HANDLE             ImageHandle,
> +  IN EFI_MM_SYSTEM_TABLE  *SmmSystemTable
> +  )
> +{
> +  UINTN       Index;
> +
> +  for (Index = 0; Index < gMmst->NumberOfTableEntries; Index++) {
> +    if (CompareGuid (&gEfiHobListGuid, &gMmst->MmConfigurationTable[Index].VendorGuid)) {
> +      gHobList = gMmst->MmConfigurationTable[Index].VendorTable;
> +      break;
> +    }
> +  }
> +
> +  /* HACK: Use the ImageHandle to smuggle the hoblist into the library constructor */

Please elaborate. Can we do this properly instead?

> +  if (ImageHandle)
> +         gHobList = (VOID *) ImageHandle;

No spaces after casts please (throughout the file)

> +
> +  return EFI_SUCCESS;
> +}
> +/**
> +  Returns the pointer to the HOB list.
> +
> +  This function returns the pointer to first HOB in the list.
> +  If the pointer to the HOB list is NULL, then ASSERT().
> +
> +  @return The pointer to the HOB list.
> +
> +**/
> +VOID *
> +EFIAPI
> +GetHobList (
> +  VOID
> +  )
> +{
> +  UINTN       Index;
> +
> +  if (gHobList == NULL) {
> +    for (Index = 0; Index < gMmst->NumberOfTableEntries; Index++) {
> +      if (CompareGuid (&gEfiHobListGuid, &gMmst->MmConfigurationTable[Index].VendorGuid)) {
> +        gHobList = gMmst->MmConfigurationTable[Index].VendorTable;
> +        break;
> +      }
> +    }
> +  }
> +  ASSERT (gHobList != NULL);
> +  return gHobList;
> +}
> +
> +/**
> +  Returns the next instance of a HOB type from the starting HOB.
> +
> +  This function searches the first instance of a HOB type from the starting HOB pointer.
> +  If there does not exist such HOB type from the starting HOB pointer, it will return NULL.
> +  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
> +  unconditionally: it returns HobStart back if HobStart itself meets the requirement;
> +  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
> +
> +  If HobStart is NULL, then ASSERT().
> +
> +  @param  Type          The HOB type to return.
> +  @param  HobStart      The starting HOB pointer to search from.
> +
> +  @return The next instance of a HOB type from the starting HOB.
> +
> +**/
> +VOID *
> +EFIAPI
> +GetNextHob (
> +  IN UINT16                 Type,
> +  IN CONST VOID             *HobStart
> +  )
> +{
> +  EFI_PEI_HOB_POINTERS  Hob;
> +
> +  ASSERT (HobStart != NULL);
> +
> +  Hob.Raw = (UINT8 *) HobStart;
> +  //
> +  // Parse the HOB list until end of list or matching type is found.
> +  //
> +  while (!END_OF_HOB_LIST (Hob)) {
> +    if (Hob.Header->HobType == Type) {
> +      return Hob.Raw;
> +    }
> +    Hob.Raw = GET_NEXT_HOB (Hob);
> +  }
> +  return NULL;
> +}
> +
> +/**
> +  Returns the first instance of a HOB type among the whole HOB list.
> +
> +  This function searches the first instance of a HOB type among the whole HOB list.
> +  If there does not exist such HOB type in the HOB list, it will return NULL.
> +
> +  If the pointer to the HOB list is NULL, then ASSERT().
> +
> +  @param  Type          The HOB type to return.
> +
> +  @return The next instance of a HOB type from the starting HOB.
> +
> +**/
> +VOID *
> +EFIAPI
> +GetFirstHob (
> +  IN UINT16                 Type
> +  )
> +{
> +  VOID      *HobList;
> +
> +  HobList = GetHobList ();
> +  return GetNextHob (Type, HobList);
> +}
> +
> +/**
> +  Returns the next instance of the matched GUID HOB from the starting HOB.
> +
> +  This function searches the first instance of a HOB from the starting HOB pointer.
> +  Such HOB should satisfy two conditions:
> +  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION, and its GUID Name equals to the input Guid.
> +  If such a HOB from the starting HOB pointer does not exist, it will return NULL.
> +  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
> +  to extract the data section and its size information, respectively.
> +  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
> +  unconditionally: it returns HobStart back if HobStart itself meets the requirement;
> +  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
> +
> +  If Guid is NULL, then ASSERT().
> +  If HobStart is NULL, then ASSERT().
> +
> +  @param  Guid          The GUID to match with in the HOB list.
> +  @param  HobStart      A pointer to a Guid.
> +
> +  @return The next instance of the matched GUID HOB from the starting HOB.
> +
> +**/
> +VOID *
> +EFIAPI
> +GetNextGuidHob (
> +  IN CONST EFI_GUID         *Guid,
> +  IN CONST VOID             *HobStart
> +  )
> +{
> +  EFI_PEI_HOB_POINTERS  GuidHob;
> +
> +  GuidHob.Raw = (UINT8 *) HobStart;
> +  while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {
> +    if (CompareGuid (Guid, &GuidHob.Guid->Name)) {
> +      break;
> +    }
> +    GuidHob.Raw = GET_NEXT_HOB (GuidHob);
> +  }
> +  return GuidHob.Raw;
> +}
> +
> +/**
> +  Returns the first instance of the matched GUID HOB among the whole HOB list.
> +
> +  This function searches the first instance of a HOB among the whole HOB list.
> +  Such HOB should satisfy two conditions:
> +  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
> +  If such a HOB from the starting HOB pointer does not exist, it will return NULL.
> +  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
> +  to extract the data section and its size information, respectively.
> +
> +  If the pointer to the HOB list is NULL, then ASSERT().
> +  If Guid is NULL, then ASSERT().
> +
> +  @param  Guid          The GUID to match with in the HOB list.
> +
> +  @return The first instance of the matched GUID HOB among the whole HOB list.
> +
> +**/
> +VOID *
> +EFIAPI
> +GetFirstGuidHob (
> +  IN CONST EFI_GUID         *Guid
> +  )
> +{
> +  VOID      *HobList;
> +
> +  HobList = GetHobList ();
> +  return GetNextGuidHob (Guid, HobList);
> +}
> +
> +/**
> +  Get the system boot mode from the HOB list.
> +
> +  This function returns the system boot mode information from the
> +  PHIT HOB in HOB list.
> +
> +  If the pointer to the HOB list is NULL, then ASSERT().
> +
> +  @param  VOID
> +
> +  @return The Boot Mode.
> +
> +**/
> +EFI_BOOT_MODE
> +EFIAPI
> +GetBootModeHob (
> +  VOID
> +  )
> +{
> +  EFI_HOB_HANDOFF_INFO_TABLE    *HandOffHob;
> +
> +  HandOffHob = (EFI_HOB_HANDOFF_INFO_TABLE *) GetHobList ();
> +
> +  return  HandOffHob->BootMode;
> +}
> +
> +VOID *
> +CreateHob (
> +  IN  UINT16    HobType,
> +  IN  UINT16    HobLength
> +  )
> +{
> +  EFI_HOB_HANDOFF_INFO_TABLE  *HandOffHob;
> +  EFI_HOB_GENERIC_HEADER      *HobEnd;
> +  EFI_PHYSICAL_ADDRESS        FreeMemory;
> +  VOID                        *Hob;
> +
> +  HandOffHob = GetHobList ();
> +
> +  HobLength = (UINT16)((HobLength + 0x7) & (~0x7));
> +
> +  FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom;
> +
> +  if (FreeMemory < HobLength) {
> +      return NULL;
> +  }
> +
> +  Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;
> +  ((EFI_HOB_GENERIC_HEADER*) Hob)->HobType = HobType;
> +  ((EFI_HOB_GENERIC_HEADER*) Hob)->HobLength = HobLength;
> +  ((EFI_HOB_GENERIC_HEADER*) Hob)->Reserved = 0;
> +
> +  HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN)Hob + HobLength);
> +  HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
> +
> +  HobEnd->HobType   = EFI_HOB_TYPE_END_OF_HOB_LIST;
> +  HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
> +  HobEnd->Reserved  = 0;
> +  HobEnd++;
> +  HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
> +
> +  return Hob;
> +}
> +
> +/**
> +  Builds a HOB for a loaded PE32 module.
> +
> +  This function builds a HOB for a loaded PE32 module.
> +  If ModuleName is NULL, then ASSERT().
> +  If there is no additional space for HOB creation, then ASSERT().
> +
> +  @param  ModuleName              The GUID File Name of the module.
> +  @param  MemoryAllocationModule  The 64 bit physical address of the module.
> +  @param  ModuleLength            The length of the module in bytes.
> +  @param  EntryPoint              The 64 bit physical address of the module entry point.
> +
> +**/
> +VOID
> +EFIAPI
> +BuildModuleHob (
> +  IN CONST EFI_GUID         *ModuleName,
> +  IN EFI_PHYSICAL_ADDRESS   MemoryAllocationModule,
> +  IN UINT64                 ModuleLength,
> +  IN EFI_PHYSICAL_ADDRESS   EntryPoint
> +  )
> +{
> +  EFI_HOB_MEMORY_ALLOCATION_MODULE  *Hob;
> +
> +  ASSERT (((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&
> +          ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0));
> +
> +  Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));
> +
> +  CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);
> +  Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;
> +  Hob->MemoryAllocationHeader.MemoryLength      = ModuleLength;
> +  Hob->MemoryAllocationHeader.MemoryType        = EfiBootServicesCode;
> +
> +  //
> +  // Zero the reserved space to match HOB spec
> +  //
> +  ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved));
> +
> +  CopyGuid (&Hob->ModuleName, ModuleName);
> +  Hob->EntryPoint = EntryPoint;
> +}
> +
> +/**
> +  Builds a HOB that describes a chunk of system memory.
> +
> +  This function builds a HOB that describes a chunk of system memory.
> +  If there is no additional space for HOB creation, then ASSERT().
> +
> +  @param  ResourceType        The type of resource described by this HOB.
> +  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.
> +  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.
> +  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.
> +
> +**/
> +VOID
> +EFIAPI
> +BuildResourceDescriptorHob (
> +  IN EFI_RESOURCE_TYPE            ResourceType,
> +  IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,
> +  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,
> +  IN UINT64                       NumberOfBytes
> +  )
> +{
> +  EFI_HOB_RESOURCE_DESCRIPTOR  *Hob;
> +
> +  Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
> +  ASSERT(Hob != NULL);
> +
> +  Hob->ResourceType      = ResourceType;
> +  Hob->ResourceAttribute = ResourceAttribute;
> +  Hob->PhysicalStart     = PhysicalStart;
> +  Hob->ResourceLength    = NumberOfBytes;
> +}
> +
> +/**
> +  Builds a GUID HOB with a certain data length.
> +
> +  This function builds a customized HOB tagged with a GUID for identification
> +  and returns the start address of GUID HOB data so that caller can fill the customized data.
> +  The HOB Header and Name field is already stripped.
> +  If Guid is NULL, then ASSERT().
> +  If there is no additional space for HOB creation, then ASSERT().
> +  If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
> +
> +  @param  Guid          The GUID to tag the customized HOB.
> +  @param  DataLength    The size of the data payload for the GUID HOB.
> +
> +  @return The start address of GUID HOB data.
> +
> +**/
> +VOID *
> +EFIAPI
> +BuildGuidHob (
> +  IN CONST EFI_GUID              *Guid,
> +  IN UINTN                       DataLength
> +  )
> +{
> +  EFI_HOB_GUID_TYPE *Hob;
> +
> +  //
> +  // Make sure that data length is not too long.
> +  //
> +  ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));
> +
> +  Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength));
> +  CopyGuid (&Hob->Name, Guid);
> +  return Hob + 1;
> +}
> +
> +
> +/**
> +  Copies a data buffer to a newly-built HOB.
> +
> +  This function builds a customized HOB tagged with a GUID for identification,
> +  copies the input data to the HOB data field and returns the start address of the GUID HOB data.
> +  The HOB Header and Name field is already stripped.
> +  If Guid is NULL, then ASSERT().
> +  If Data is NULL and DataLength > 0, then ASSERT().
> +  If there is no additional space for HOB creation, then ASSERT().
> +  If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
> +
> +  @param  Guid          The GUID to tag the customized HOB.
> +  @param  Data          The data to be copied into the data field of the GUID HOB.
> +  @param  DataLength    The size of the data payload for the GUID HOB.
> +
> +  @return The start address of GUID HOB data.
> +
> +**/
> +VOID *
> +EFIAPI
> +BuildGuidDataHob (
> +  IN CONST EFI_GUID              *Guid,
> +  IN VOID                        *Data,
> +  IN UINTN                       DataLength
> +  )
> +{
> +  VOID  *HobData;
> +
> +  ASSERT (Data != NULL || DataLength == 0);
> +
> +  HobData = BuildGuidHob (Guid, DataLength);
> +
> +  return CopyMem (HobData, Data, DataLength);
> +}
> +
> +/**
> +  Builds a Firmware Volume HOB.
> +
> +  This function builds a Firmware Volume HOB.
> +  If there is no additional space for HOB creation, then ASSERT().
> +
> +  @param  BaseAddress   The base address of the Firmware Volume.
> +  @param  Length        The size of the Firmware Volume in bytes.
> +
> +**/
> +VOID
> +EFIAPI
> +BuildFvHob (
> +  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
> +  IN UINT64                      Length
> +  )
> +{
> +  EFI_HOB_FIRMWARE_VOLUME  *Hob;
> +
> +  Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));
> +
> +  Hob->BaseAddress = BaseAddress;
> +  Hob->Length      = Length;
> +}
> +
> +
> +/**
> +  Builds a EFI_HOB_TYPE_FV2 HOB.
> +
> +  This function builds a EFI_HOB_TYPE_FV2 HOB.
> +  If there is no additional space for HOB creation, then ASSERT().
> +
> +  @param  BaseAddress   The base address of the Firmware Volume.
> +  @param  Length        The size of the Firmware Volume in bytes.
> +  @param  FvName       The name of the Firmware Volume.
> +  @param  FileName      The name of the file.
> +
> +**/
> +VOID
> +EFIAPI
> +BuildFv2Hob (
> +  IN          EFI_PHYSICAL_ADDRESS        BaseAddress,
> +  IN          UINT64                      Length,
> +  IN CONST    EFI_GUID                    *FvName,
> +  IN CONST    EFI_GUID                    *FileName
> +  )
> +{
> +  EFI_HOB_FIRMWARE_VOLUME2  *Hob;
> +
> +  Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));
> +
> +  Hob->BaseAddress = BaseAddress;
> +  Hob->Length      = Length;
> +  CopyGuid (&Hob->FvName, FvName);
> +  CopyGuid (&Hob->FileName, FileName);
> +}
> +
> +
> +/**
> +  Builds a HOB for the CPU.
> +
> +  This function builds a HOB for the CPU.
> +  If there is no additional space for HOB creation, then ASSERT().
> +
> +  @param  SizeOfMemorySpace   The maximum physical memory addressability of the processor.
> +  @param  SizeOfIoSpace       The maximum physical I/O addressability of the processor.
> +
> +**/
> +VOID
> +EFIAPI
> +BuildCpuHob (
> +  IN UINT8                       SizeOfMemorySpace,
> +  IN UINT8                       SizeOfIoSpace
> +  )
> +{
> +  EFI_HOB_CPU  *Hob;
> +
> +  Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));
> +
> +  Hob->SizeOfMemorySpace = SizeOfMemorySpace;
> +  Hob->SizeOfIoSpace     = SizeOfIoSpace;
> +
> +  //
> +  // Zero the reserved space to match HOB spec
> +  //
> +  ZeroMem (Hob->Reserved, sizeof (Hob->Reserved));
> +}
> +
> +/**
> +  Builds a HOB for the memory allocation.
> +
> +  This function builds a HOB for the memory allocation.
> +  If there is no additional space for HOB creation, then ASSERT().
> +
> +  @param  BaseAddress   The 64 bit physical address of the memory.
> +  @param  Length        The length of the memory allocation in bytes.
> +  @param  MemoryType    Type of memory allocated by this HOB.
> +
> +**/
> +VOID
> +EFIAPI
> +BuildMemoryAllocationHob (
> +  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
> +  IN UINT64                      Length,
> +  IN EFI_MEMORY_TYPE             MemoryType
> +  )
> +{
> +  EFI_HOB_MEMORY_ALLOCATION  *Hob;
> +
> +  ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
> +          ((Length & (EFI_PAGE_SIZE - 1)) == 0));
> +
> +  Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));
> +
> +  ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));
> +  Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
> +  Hob->AllocDescriptor.MemoryLength      = Length;
> +  Hob->AllocDescriptor.MemoryType        = MemoryType;
> +  //
> +  // Zero the reserved space to match HOB spec
> +  //
> +  ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
> +}
> +
> +/**
> +  Builds a HOB that describes a chunk of system memory with Owner GUID.
> +
> +  This function builds a HOB that describes a chunk of system memory.
> +  If there is no additional space for HOB creation, then ASSERT().
> +
> +  @param  ResourceType        The type of resource described by this HOB.
> +  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.
> +  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.
> +  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.
> +  @param  OwnerGUID           GUID for the owner of this resource.
> +
> +**/
> +VOID
> +EFIAPI
> +BuildResourceDescriptorWithOwnerHob (
> +  IN EFI_RESOURCE_TYPE            ResourceType,
> +  IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,
> +  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,
> +  IN UINT64                       NumberOfBytes,
> +  IN EFI_GUID                     *OwnerGUID
> +  )
> +{
> +  ASSERT (FALSE);
> +}
> +
> +/**
> +  Builds a Capsule Volume HOB.
> +
> +  This function builds a Capsule Volume HOB.
> +  If the platform does not support Capsule Volume HOBs, then ASSERT().
> +  If there is no additional space for HOB creation, then ASSERT().
> +
> +  @param  BaseAddress   The base address of the Capsule Volume.
> +  @param  Length        The size of the Capsule Volume in bytes.
> +
> +**/
> +VOID
> +EFIAPI
> +BuildCvHob (
> +  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
> +  IN UINT64                      Length
> +  )
> +{
> +  ASSERT (FALSE);
> +}
> +
> +
> +/**
> +  Builds a HOB for the BSP store.
> +
> +  This function builds a HOB for BSP store.
> +  If there is no additional space for HOB creation, then ASSERT().
> +
> +  @param  BaseAddress   The 64 bit physical address of the BSP.
> +  @param  Length        The length of the BSP store in bytes.
> +  @param  MemoryType    Type of memory allocated by this HOB.
> +
> +**/
> +VOID
> +EFIAPI
> +BuildBspStoreHob (
> +  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
> +  IN UINT64                      Length,
> +  IN EFI_MEMORY_TYPE             MemoryType
> +  )
> +{
> +  ASSERT (FALSE);
> +}
> +
> +/**
> +  Builds a HOB for the Stack.
> +
> +  This function builds a HOB for the stack.
> +  If there is no additional space for HOB creation, then ASSERT().
> +
> +  @param  BaseAddress   The 64 bit physical address of the Stack.
> +  @param  Length        The length of the stack in bytes.
> +
> +**/
> +VOID
> +EFIAPI
> +BuildStackHob (
> +  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
> +  IN UINT64                      Length
> +  )
> +{
> +  ASSERT (FALSE);
> +}
> diff --git a/StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf b/StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
> new file mode 100644
> index 0000000..d73188e
> --- /dev/null
> +++ b/StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
> @@ -0,0 +1,48 @@
> +## @file
> +# Instance of HOB Library for Standalone MM Core.
> +#
> +# HOB Library implementation for the Standalone MM Core. Does not have a constructor.
> +#  Uses gHobList defined in the Standalone MM Core Entry Point Library.
> +#
> +# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
> +#
> +#  This program and the accompanying materials
> +#  are licensed and made available under the terms and conditions of the BSD License
> +#  which accompanies this distribution. The full text of the license may be found at
> +#  http://opensource.org/licenses/bsd-license.php.
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001A
> +  BASE_NAME                      = HobLib
> +  FILE_GUID                      = 8262551B-AB2D-4E76-99FC-5EBB83F4988E
> +  MODULE_TYPE                    = MM_STANDALONE
> +  VERSION_STRING                 = 1.0
> +  PI_SPECIFICATION_VERSION       = 0x00010032
> +  LIBRARY_CLASS                  = HobLib|MM_STANDALONE
> +  CONSTRUCTOR                    = HobLibConstructor
> +#
> +#  VALID_ARCHITECTURES           = AARCH64
> +#
> +[Sources.Common]
> +  StandaloneMmHobLib.c
> +
> +[Sources.AARCH64]
> +  AArch64/StandaloneMmCoreHobLibInternal.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +
> +
> +[LibraryClasses]
> +  BaseMemoryLib
> +  DebugLib
> +  MmServicesTableLib
> +
> +[Guids]
> +  gEfiHobListGuid                               ## CONSUMES  ## SystemTable
> diff --git a/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c
> new file mode 100644
> index 0000000..e989f27
> --- /dev/null
> +++ b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c
> @@ -0,0 +1,824 @@
> +/** @file
> +  Support routines for memory allocation routines based on Standalone MM Core internal functions.
> +
> +  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
> +
> +  This program and the accompanying materials
> +  are licensed and made available under the terms and conditions of the BSD License
> +  which accompanies this distribution.  The full text of the license may be found at
> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include <PiMm.h>
> +
> +#include <Guid/MmramMemoryReserve.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +
> +extern EFI_MM_SYSTEM_TABLE   *gMmst;
> +
> +/**
> +  Allocates one or more 4KB pages of a certain memory type.
> +
> +  Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated
> +  buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL is returned.
> +  If there is not enough memory remaining to satisfy the request, then NULL is returned.
> +
> +  @param  MemoryType            The type of memory to allocate.
> +  @param  Pages                 The number of 4 KB pages to allocate.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +InternalAllocatePages (
> +  IN EFI_MEMORY_TYPE  MemoryType,
> +  IN UINTN            Pages
> +  )
> +{
> +  EFI_STATUS            Status;
> +  EFI_PHYSICAL_ADDRESS  Memory;
> +
> +  if (Pages == 0) {
> +    return NULL;
> +  }
> +
> +  Status = gMmst->MmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
> +  if (EFI_ERROR (Status)) {
> +    return NULL;
> +  }
> +  return (VOID *) (UINTN) Memory;
> +}
> +
> +/**
> +  Allocates one or more 4KB pages of type EfiBootServicesData.
> +
> +  Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
> +  allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
> +  is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
> +  returned.
> +
> +  @param  Pages                 The number of 4 KB pages to allocate.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +EFIAPI
> +AllocatePages (
> +  IN UINTN  Pages
> +  )
> +{
> +  return InternalAllocatePages (EfiRuntimeServicesData, Pages);

This type is wrong

> +}
> +
> +/**
> +  Allocates one or more 4KB pages of type EfiRuntimeServicesData.
> +
> +  Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
> +  allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
> +  is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
> +  returned.
> +
> +  @param  Pages                 The number of 4 KB pages to allocate.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +EFIAPI
> +AllocateRuntimePages (
> +  IN UINTN  Pages
> +  )
> +{
> +  return InternalAllocatePages (EfiRuntimeServicesData, Pages);
> +}
> +
> +/**
> +  Allocates one or more 4KB pages of type EfiReservedMemoryType.
> +
> +  Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
> +  allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
> +  is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
> +  returned.
> +
> +  @param  Pages                 The number of 4 KB pages to allocate.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +EFIAPI
> +AllocateReservedPages (
> +  IN UINTN  Pages
> +  )
> +{
> +  return NULL;
> +}
> +
> +/**
> +  Frees one or more 4KB pages that were previously allocated with one of the page allocation
> +  functions in the Memory Allocation Library.
> +
> +  Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.  Buffer
> +  must have been allocated on a previous call to the page allocation services of the Memory
> +  Allocation Library.  If it is not possible to free allocated pages, then this function will
> +  perform no actions.
> +
> +  If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
> +  then ASSERT().
> +  If Pages is zero, then ASSERT().
> +
> +  @param  Buffer                Pointer to the buffer of pages to free.
> +  @param  Pages                 The number of 4 KB pages to free.
> +
> +**/
> +VOID
> +EFIAPI
> +FreePages (
> +  IN VOID   *Buffer,
> +  IN UINTN  Pages
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  ASSERT (Pages != 0);
> +  Status = gMmst->MmFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
> +  ASSERT_EFI_ERROR (Status);
> +}
> +
> +/**
> +  Allocates one or more 4KB pages of a certain memory type at a specified alignment.
> +
> +  Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
> +  specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is returned.
> +  If there is not enough memory at the specified alignment remaining to satisfy the request, then
> +  NULL is returned.
> +  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
> +  If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
> +
> +  @param  MemoryType            The type of memory to allocate.
> +  @param  Pages                 The number of 4 KB pages to allocate.
> +  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
> +                                If Alignment is zero, then byte alignment is used.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +InternalAllocateAlignedPages (
> +  IN EFI_MEMORY_TYPE  MemoryType,
> +  IN UINTN            Pages,
> +  IN UINTN            Alignment
> +  )
> +{
> +  EFI_STATUS            Status;
> +  EFI_PHYSICAL_ADDRESS  Memory;
> +  UINTN                 AlignedMemory;
> +  UINTN                 AlignmentMask;
> +  UINTN                 UnalignedPages;
> +  UINTN                 RealPages;
> +
> +  //
> +  // Alignment must be a power of two or zero.
> +  //
> +  ASSERT ((Alignment & (Alignment - 1)) == 0);
> +
> +  if (Pages == 0) {
> +    return NULL;
> +  }
> +  if (Alignment > EFI_PAGE_SIZE) {
> +    //
> +    // Calculate the total number of pages since alignment is larger than page size.
> +    //
> +    AlignmentMask  = Alignment - 1;
> +    RealPages      = Pages + EFI_SIZE_TO_PAGES (Alignment);
> +    //
> +    // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
> +    //
> +    ASSERT (RealPages > Pages);
> +
> +    Status         = gMmst->MmAllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);
> +    if (EFI_ERROR (Status)) {
> +      return NULL;
> +    }
> +    AlignedMemory  = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;
> +    UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory);
> +    if (UnalignedPages > 0) {
> +      //
> +      // Free first unaligned page(s).
> +      //
> +      Status = gMmst->MmFreePages (Memory, UnalignedPages);
> +      ASSERT_EFI_ERROR (Status);
> +    }
> +    Memory         = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));
> +    UnalignedPages = RealPages - Pages - UnalignedPages;
> +    if (UnalignedPages > 0) {
> +      //
> +      // Free last unaligned page(s).
> +      //
> +      Status = gMmst->MmFreePages (Memory, UnalignedPages);
> +      ASSERT_EFI_ERROR (Status);
> +    }
> +  } else {
> +    //
> +    // Do not over-allocate pages in this case.
> +    //
> +    Status = gMmst->MmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
> +    if (EFI_ERROR (Status)) {
> +      return NULL;
> +    }
> +    AlignedMemory  = (UINTN) Memory;
> +  }
> +  return (VOID *) AlignedMemory;
> +}
> +
> +/**
> +  Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
> +
> +  Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
> +  alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
> +  returned.  If there is not enough memory at the specified alignment remaining to satisfy the
> +  request, then NULL is returned.
> +
> +  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
> +  If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
> +
> +  @param  Pages                 The number of 4 KB pages to allocate.
> +  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
> +                                If Alignment is zero, then byte alignment is used.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +EFIAPI
> +AllocateAlignedPages (
> +  IN UINTN  Pages,
> +  IN UINTN  Alignment
> +  )
> +{
> +  return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
> +}
> +
> +/**
> +  Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
> +
> +  Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
> +  alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
> +  returned.  If there is not enough memory at the specified alignment remaining to satisfy the
> +  request, then NULL is returned.
> +
> +  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
> +  If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
> +
> +  @param  Pages                 The number of 4 KB pages to allocate.
> +  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
> +                                If Alignment is zero, then byte alignment is used.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +EFIAPI
> +AllocateAlignedRuntimePages (
> +  IN UINTN  Pages,
> +  IN UINTN  Alignment
> +  )
> +{
> +  return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
> +}
> +
> +/**
> +  Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
> +
> +  Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
> +  alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
> +  returned.  If there is not enough memory at the specified alignment remaining to satisfy the
> +  request, then NULL is returned.
> +
> +  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
> +  If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
> +
> +  @param  Pages                 The number of 4 KB pages to allocate.
> +  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
> +                                If Alignment is zero, then byte alignment is used.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +EFIAPI
> +AllocateAlignedReservedPages (
> +  IN UINTN  Pages,
> +  IN UINTN  Alignment
> +  )
> +{
> +  return NULL;
> +}
> +
> +/**
> +  Frees one or more 4KB pages that were previously allocated with one of the aligned page
> +  allocation functions in the Memory Allocation Library.
> +
> +  Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.  Buffer
> +  must have been allocated on a previous call to the aligned page allocation services of the Memory
> +  Allocation Library.  If it is not possible to free allocated pages, then this function will
> +  perform no actions.
> +
> +  If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
> +  Library, then ASSERT().
> +  If Pages is zero, then ASSERT().
> +
> +  @param  Buffer                Pointer to the buffer of pages to free.
> +  @param  Pages                 The number of 4 KB pages to free.
> +
> +**/
> +VOID
> +EFIAPI
> +FreeAlignedPages (
> +  IN VOID   *Buffer,
> +  IN UINTN  Pages
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  ASSERT (Pages != 0);
> +  Status = gMmst->MmFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
> +  ASSERT_EFI_ERROR (Status);
> +}
> +
> +/**
> +  Allocates a buffer of a certain pool type.
> +
> +  Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
> +  pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
> +  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
> +
> +  @param  MemoryType            The type of memory to allocate.
> +  @param  AllocationSize        The number of bytes to allocate.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +InternalAllocatePool (
> +  IN EFI_MEMORY_TYPE  MemoryType,
> +  IN UINTN            AllocationSize
> +  )
> +{
> +  EFI_STATUS  Status;
> +  VOID        *Memory;
> +
> +  Memory = NULL;
> +
> +  Status = gMmst->MmAllocatePool (MemoryType, AllocationSize, &Memory);
> +  if (EFI_ERROR (Status)) {
> +    Memory = NULL;
> +  }
> +  return Memory;
> +}
> +
> +/**
> +  Allocates a buffer of type EfiBootServicesData.
> +
> +  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
> +  pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
> +  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
> +
> +  @param  AllocationSize        The number of bytes to allocate.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +EFIAPI
> +AllocatePool (
> +  IN UINTN  AllocationSize
> +  )
> +{
> +  return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
> +}
> +
> +/**
> +  Allocates a buffer of type EfiRuntimeServicesData.
> +
> +  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
> +  a pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
> +  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
> +
> +  @param  AllocationSize        The number of bytes to allocate.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +EFIAPI
> +AllocateRuntimePool (
> +  IN UINTN  AllocationSize
> +  )
> +{
> +  return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
> +}
> +
> +/**
> +  Allocates a buffer of type EfiReservedMemoryType.
> +
> +  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
> +  a pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
> +  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
> +
> +  @param  AllocationSize        The number of bytes to allocate.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +EFIAPI
> +AllocateReservedPool (
> +  IN UINTN  AllocationSize
> +  )
> +{
> +  return NULL;
> +}
> +
> +/**
> +  Allocates and zeros a buffer of a certain pool type.
> +
> +  Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
> +  with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a valid
> +  buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the request,
> +  then NULL is returned.
> +
> +  @param  PoolType              The type of memory to allocate.
> +  @param  AllocationSize        The number of bytes to allocate and zero.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +InternalAllocateZeroPool (
> +  IN EFI_MEMORY_TYPE  PoolType,
> +  IN UINTN            AllocationSize
> +  )
> +{
> +  VOID  *Memory;
> +
> +  Memory = InternalAllocatePool (PoolType, AllocationSize);
> +  if (Memory != NULL) {
> +    Memory = ZeroMem (Memory, AllocationSize);
> +  }
> +  return Memory;
> +}
> +
> +/**
> +  Allocates and zeros a buffer of type EfiBootServicesData.
> +
> +  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
> +  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
> +  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
> +  request, then NULL is returned.
> +
> +  @param  AllocationSize        The number of bytes to allocate and zero.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +EFIAPI
> +AllocateZeroPool (
> +  IN UINTN  AllocationSize
> +  )
> +{
> +  return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
> +}
> +
> +/**
> +  Allocates and zeros a buffer of type EfiRuntimeServicesData.
> +
> +  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
> +  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
> +  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
> +  request, then NULL is returned.
> +
> +  @param  AllocationSize        The number of bytes to allocate and zero.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +EFIAPI
> +AllocateRuntimeZeroPool (
> +  IN UINTN  AllocationSize
> +  )
> +{
> +  return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
> +}
> +
> +/**
> +  Allocates and zeros a buffer of type EfiReservedMemoryType.
> +
> +  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
> +  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
> +  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
> +  request, then NULL is returned.
> +
> +  @param  AllocationSize        The number of bytes to allocate and zero.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +EFIAPI
> +AllocateReservedZeroPool (
> +  IN UINTN  AllocationSize
> +  )
> +{
> +  return NULL;
> +}
> +
> +/**
> +  Copies a buffer to an allocated buffer of a certain pool type.
> +
> +  Allocates the number bytes specified by AllocationSize of a certain pool type, copies
> +  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
> +  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
> +  is not enough memory remaining to satisfy the request, then NULL is returned.
> +  If Buffer is NULL, then ASSERT().
> +  If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
> +
> +  @param  PoolType              The type of pool to allocate.
> +  @param  AllocationSize        The number of bytes to allocate and zero.
> +  @param  Buffer                The buffer to copy to the allocated buffer.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +InternalAllocateCopyPool (
> +  IN EFI_MEMORY_TYPE  PoolType,
> +  IN UINTN            AllocationSize,
> +  IN CONST VOID       *Buffer
> +  )
> +{
> +  VOID  *Memory;
> +
> +  ASSERT (Buffer != NULL);
> +  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
> +
> +  Memory = InternalAllocatePool (PoolType, AllocationSize);
> +  if (Memory != NULL) {
> +     Memory = CopyMem (Memory, Buffer, AllocationSize);
> +  }
> +  return Memory;
> +}
> +
> +/**
> +  Copies a buffer to an allocated buffer of type EfiBootServicesData.
> +
> +  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
> +  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
> +  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
> +  is not enough memory remaining to satisfy the request, then NULL is returned.
> +
> +  If Buffer is NULL, then ASSERT().
> +  If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
> +
> +  @param  AllocationSize        The number of bytes to allocate and zero.
> +  @param  Buffer                The buffer to copy to the allocated buffer.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +EFIAPI
> +AllocateCopyPool (
> +  IN UINTN       AllocationSize,
> +  IN CONST VOID  *Buffer
> +  )
> +{
> +  return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
> +}
> +
> +/**
> +  Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
> +
> +  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
> +  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
> +  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
> +  is not enough memory remaining to satisfy the request, then NULL is returned.
> +
> +  If Buffer is NULL, then ASSERT().
> +  If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
> +
> +  @param  AllocationSize        The number of bytes to allocate and zero.
> +  @param  Buffer                The buffer to copy to the allocated buffer.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +EFIAPI
> +AllocateRuntimeCopyPool (
> +  IN UINTN       AllocationSize,
> +  IN CONST VOID  *Buffer
> +  )
> +{
> +  return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
> +}
> +
> +/**
> +  Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
> +
> +  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
> +  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
> +  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
> +  is not enough memory remaining to satisfy the request, then NULL is returned.
> +
> +  If Buffer is NULL, then ASSERT().
> +  If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
> +
> +  @param  AllocationSize        The number of bytes to allocate and zero.
> +  @param  Buffer                The buffer to copy to the allocated buffer.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +EFIAPI
> +AllocateReservedCopyPool (
> +  IN UINTN       AllocationSize,
> +  IN CONST VOID  *Buffer
> +  )
> +{
> +  return NULL;
> +}
> +
> +/**
> +  Reallocates a buffer of a specified memory type.
> +
> +  Allocates and zeros the number bytes specified by NewSize from memory of the type
> +  specified by PoolType.  If OldBuffer is not NULL, then the smaller of OldSize and
> +  NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
> +  OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
> +  If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
> +  enough memory remaining to satisfy the request, then NULL is returned.
> +
> +  If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
> +  is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
> +
> +  @param  PoolType       The type of pool to allocate.
> +  @param  OldSize        The size, in bytes, of OldBuffer.
> +  @param  NewSize        The size, in bytes, of the buffer to reallocate.
> +  @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
> +                         parameter that may be NULL.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +InternalReallocatePool (
> +  IN EFI_MEMORY_TYPE  PoolType,
> +  IN UINTN            OldSize,
> +  IN UINTN            NewSize,
> +  IN VOID             *OldBuffer  OPTIONAL
> +  )
> +{
> +  VOID  *NewBuffer;
> +
> +  NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);
> +  if (NewBuffer != NULL && OldBuffer != NULL) {
> +    CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
> +    FreePool (OldBuffer);
> +  }
> +  return NewBuffer;
> +}
> +
> +/**
> +  Reallocates a buffer of type EfiBootServicesData.
> +
> +  Allocates and zeros the number bytes specified by NewSize from memory of type
> +  EfiBootServicesData.  If OldBuffer is not NULL, then the smaller of OldSize and
> +  NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
> +  OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
> +  If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
> +  enough memory remaining to satisfy the request, then NULL is returned.
> +
> +  If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
> +  is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
> +
> +  @param  OldSize        The size, in bytes, of OldBuffer.
> +  @param  NewSize        The size, in bytes, of the buffer to reallocate.
> +  @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
> +                         parameter that may be NULL.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +EFIAPI
> +ReallocatePool (
> +  IN UINTN  OldSize,
> +  IN UINTN  NewSize,
> +  IN VOID   *OldBuffer  OPTIONAL
> +  )
> +{
> +  return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);

Same here

> +}
> +
> +/**
> +  Reallocates a buffer of type EfiRuntimeServicesData.
> +
> +  Allocates and zeros the number bytes specified by NewSize from memory of type
> +  EfiRuntimeServicesData.  If OldBuffer is not NULL, then the smaller of OldSize and
> +  NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
> +  OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
> +  If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
> +  enough memory remaining to satisfy the request, then NULL is returned.
> +
> +  If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
> +  is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
> +
> +  @param  OldSize        The size, in bytes, of OldBuffer.
> +  @param  NewSize        The size, in bytes, of the buffer to reallocate.
> +  @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
> +                         parameter that may be NULL.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +EFIAPI
> +ReallocateRuntimePool (
> +  IN UINTN  OldSize,
> +  IN UINTN  NewSize,
> +  IN VOID   *OldBuffer  OPTIONAL
> +  )
> +{
> +  return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);
> +}
> +
> +/**
> +  Reallocates a buffer of type EfiReservedMemoryType.
> +
> +  Allocates and zeros the number bytes specified by NewSize from memory of type
> +  EfiReservedMemoryType.  If OldBuffer is not NULL, then the smaller of OldSize and
> +  NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
> +  OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
> +  If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
> +  enough memory remaining to satisfy the request, then NULL is returned.
> +
> +  If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
> +  is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
> +
> +  @param  OldSize        The size, in bytes, of OldBuffer.
> +  @param  NewSize        The size, in bytes, of the buffer to reallocate.
> +  @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
> +                         parameter that may be NULL.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +EFIAPI
> +ReallocateReservedPool (
> +  IN UINTN  OldSize,
> +  IN UINTN  NewSize,
> +  IN VOID   *OldBuffer  OPTIONAL
> +  )
> +{
> +  return NULL;
> +}
> +
> +/**
> +  Frees a buffer that was previously allocated with one of the pool allocation functions in the
> +  Memory Allocation Library.
> +
> +  Frees the buffer specified by Buffer.  Buffer must have been allocated on a previous call to the
> +  pool allocation services of the Memory Allocation Library.  If it is not possible to free pool
> +  resources, then this function will perform no actions.
> +
> +  If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
> +  then ASSERT().
> +
> +  @param  Buffer                Pointer to the buffer to free.
> +
> +**/
> +VOID
> +EFIAPI
> +FreePool (
> +  IN VOID   *Buffer
> +  )
> +{
> +  EFI_STATUS    Status;
> +
> +  Status = gMmst->MmFreePool (Buffer);
> +  ASSERT_EFI_ERROR (Status);
> +}
> +
> diff --git a/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf
> new file mode 100644
> index 0000000..9ac03df
> --- /dev/null
> +++ b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf
> @@ -0,0 +1,45 @@
> +## @file
> +# Memory Allocation Library instance dedicated to MM Core.
> +# The implementation borrows the MM Core Memory Allocation services as the primitive
> +# for memory allocation instead of using MM System Table servces in an indirect way.
> +# It is assumed that this library instance must be linked with MM Core in this package.
> +#
> +# Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
> +#
> +#  This program and the accompanying materials
> +#  are licensed and made available under the terms and conditions of the BSD License
> +#  which accompanies this distribution. The full text of the license may be found at
> +#  http://opensource.org/licenses/bsd-license.php
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001A
> +  BASE_NAME                      = MemoryAllocationLib
> +  FILE_GUID                      = 54646378-A9DC-473F-9BE1-BD027C4C76DE
> +  MODULE_TYPE                    = MM_CORE_STANDALONE

Should this be BASE?

> +  VERSION_STRING                 = 1.0
> +  PI_SPECIFICATION_VERSION       = 0x00010032
> +  LIBRARY_CLASS                  = MemoryAllocationLib|MM_STANDALONE
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
> +#
> +
> +[Sources]
> +  StandaloneMmMemoryAllocationLib.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  StandaloneMmPkg/StandaloneMmPkg.dec
> +
> +[LibraryClasses]
> +  BaseMemoryLib
> +  DebugLib
> +  MmServicesTableLib
> +  HobLib
> diff --git a/StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.c b/StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.c
> new file mode 100644
> index 0000000..e0e0044
> --- /dev/null
> +++ b/StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.c
> @@ -0,0 +1,64 @@
> +/** @file
> +  MM Core MM Services Table Library.
> +
> +  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
> +
> +  This program and the accompanying materials
> +  are licensed and made available under the terms and conditions of the BSD License
> +  which accompanies this distribution.  The full text of the license may be found at
> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include <PiMm.h>
> +#include <Library/DebugLib.h>
> +
> +extern EFI_MM_SYSTEM_TABLE         *gMmst;
> +
> +/**
> +  The constructor function caches the pointer of MM Services Table.
> +
> +  @param  ImageHandle   The firmware allocated handle for the EFI image.
> +  @param  SystemTable   A pointer to the EFI System Table.
> +
> +  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +StandaloneMmServicesTableLibConstructor (
> +  IN EFI_HANDLE             ImageHandle,
> +  IN EFI_MM_SYSTEM_TABLE  *MmSystemTable
> +  )
> +{
> +  gMmst = MmSystemTable;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function allows the caller to determine if the driver is executing in
> +  Standalone Management Mode(SMM).
> +
> +  This function returns TRUE if the driver is executing in SMM and FALSE if the
> +  driver is not executing in SMM.
> +
> +  @retval  TRUE  The driver is executing in Standalone Management Mode (SMM).
> +  @retval  FALSE The driver is not executing in Standalone Management Mode (SMM).
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +InMm (
> +  VOID
> +  )
> +{
> +  //
> +  // We are already in Standalone MM
> +  //
> +  return TRUE;
> +}
> +
> diff --git a/StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf b/StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf
> new file mode 100644
> index 0000000..c362429
> --- /dev/null
> +++ b/StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf
> @@ -0,0 +1,36 @@
> +## @file
> +# MM Core MM Services Table Library.
> +#
> +# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
> +#
> +#  This program and the accompanying materials
> +#  are licensed and made available under the terms and conditions of the BSD License
> +#  which accompanies this distribution. The full text of the license may be found at
> +#  http://opensource.org/licenses/bsd-license.php
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = StandaloneMmServicesTableLib
> +  FILE_GUID                      = BEE33A2F-F49D-4B71-AF3E-FFCCB9885DEA
> +  MODULE_TYPE                    = MM_STANDALONE
> +  VERSION_STRING                 = 1.0
> +  PI_SPECIFICATION_VERSION       = 0x00010032
> +  LIBRARY_CLASS                  = MmServicesTableLib|MM_STANDALONE
> +  CONSTRUCTOR                    = StandaloneMmServicesTableLibConstructor
> +
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
> +#
> +
> +[Sources]
> +  StandaloneMmServicesTableLib.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +
> --
> 2.7.4
>


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 02/13] MdePkg: Add a PCD that indicates presence of Standalone MM mode
  2018-12-14 12:13 ` [PATCH 02/13] MdePkg: Add a PCD that indicates presence of Standalone MM mode Jagadeesh Ujja
@ 2018-12-21  9:13   ` Ard Biesheuvel
  0 siblings, 0 replies; 52+ messages in thread
From: Ard Biesheuvel @ 2018-12-21  9:13 UTC (permalink / raw)
  To: Jagadeesh Ujja
  Cc: edk2-devel@lists.01.org, Gao, Liming, Zhang, Chao B,
	Leif Lindholm

On Fri, 14 Dec 2018 at 13:13, Jagadeesh Ujja <jagadeesh.ujja@arm.com> wrote:
>
> Add a flag to indicate the presence of Standalone MM mode. For existing
> library and/or drivers that can be refactored to be used as a Standalone
> MM component, this flag can be used to choose the portions of the code
> that gets executed in Standalone MM.
>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> ---
>  MdePkg/MdePkg.dec | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
> index 712bd46..af694fc 100644
> --- a/MdePkg/MdePkg.dec
> +++ b/MdePkg/MdePkg.dec
> @@ -2073,6 +2073,11 @@
>    # @Prompt Fixed Debug Message Print Level.
>    gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel|0xFFFFFFFF|UINT32|0x30001016
>
> +  ## This flag indicates Standalone MM execution mode is enabled
> +  #  TRUE  - Standalone MM execution mode is enabled
> +  #  FALSE - Standalone MM execution mode is not enabled
> +  gEfiMdePkgTokenSpaceGuid.PcdStandaloneMmCodeEnabled|FALSE|BOOLEAN|0x30001017
> +

Shouldn't this be implied by the chosen library resolution?

>  [PcdsFixedAtBuild,PcdsPatchableInModule]
>    ## Indicates the maximum length of unicode string used in the following
>    #  BaseLib functions: StrLen(), StrSize(), StrCmp(), StrnCmp(), StrCpy(), StrnCpy()<BR><BR>
> --
> 2.7.4
>


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 03/13] MdeModulePkg: Add a PCD to indicate Standalone MM supports secure variable
  2018-12-14 12:13 ` [PATCH 03/13] MdeModulePkg: Add a PCD to indicate Standalone MM supports secure variable Jagadeesh Ujja
@ 2018-12-21  9:13   ` Ard Biesheuvel
  0 siblings, 0 replies; 52+ messages in thread
From: Ard Biesheuvel @ 2018-12-21  9:13 UTC (permalink / raw)
  To: Jagadeesh Ujja
  Cc: edk2-devel@lists.01.org, Gao, Liming, Zhang, Chao B,
	Leif Lindholm

On Fri, 14 Dec 2018 at 13:13, Jagadeesh Ujja <jagadeesh.ujja@arm.com> wrote:
>
> Add a flag that indicates whether Standalone MM mode supports
> secure storage of variables.
>

Why? And why does it need to reside in MdeModulePkg?


> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> ---
>  MdeModulePkg/MdeModulePkg.dec | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
> index 41d2b04..badea4a 100644
> --- a/MdeModulePkg/MdeModulePkg.dec
> +++ b/MdeModulePkg/MdeModulePkg.dec
> @@ -1041,6 +1041,11 @@
>    # @Prompt Enable UEFI Stack Guard.
>    gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|FALSE|BOOLEAN|0x30001055
>
> +  ## This flag indicates secure variable functionality is implemented by Standalone MM
> +  #  TRUE  - Secure variable storage supported by Standalone MM code.
> +  #  FALSE - Standalone MM code does not support secure storage of variables
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdStandaloneMmVariableEnabled|FALSE|BOOLEAN|0x30001056
> +
>  [PcdsFixedAtBuild, PcdsPatchableInModule]
>    ## Dynamic type PCD can be registered callback function for Pcd setting action.
>    #  PcdMaxPeiPcdCallBackNumberPerPcdEntry indicates the maximum number of callback function
> --
> 2.7.4
>


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 13/13] CryptoPkg/BaseCryptLib: allow MM_STANDALONE drivers to use this library
  2018-12-14 12:13 ` [PATCH 13/13] CryptoPkg/BaseCryptLib: " Jagadeesh Ujja
@ 2018-12-21 10:13   ` Ard Biesheuvel
  0 siblings, 0 replies; 52+ messages in thread
From: Ard Biesheuvel @ 2018-12-21 10:13 UTC (permalink / raw)
  To: Jagadeesh Ujja
  Cc: edk2-devel@lists.01.org, Gao, Liming, Zhang, Chao B,
	Leif Lindholm

On Fri, 14 Dec 2018 at 13:14, Jagadeesh Ujja <jagadeesh.ujja@arm.com> wrote:
>
> “BaseCryptLib” library can be used by MM_STANDALONE drivers as well.
> So add MM_STANDALONE as the module type this library supports.
>

This patch affects other drivers as well. Also, shouldn't we be using
SmmCryptLib for MM_STANDALONE?

The MODULE_TYPE of SmmCryptLib can be changed to BASE since it doesn't
have a constructor. I think that should also address your time()
issue, no?

> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> ---
>  CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf       |  7 ++++++-
>  CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf    |  4 ++++
>  CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c | 15 +++++++++------
>  3 files changed, 19 insertions(+), 7 deletions(-)
>
> diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> index f29445c..b6ebac5 100644
> --- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> +++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> @@ -7,6 +7,7 @@
>  #  buffer overflow or integer overflow.
>  #
>  #  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
> +#  Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
>  #  This program and the accompanying materials
>  #  are licensed and made available under the terms and conditions of the BSD License
>  #  which accompanies this distribution.  The full text of the license may be found at
> @@ -24,7 +25,7 @@
>    FILE_GUID                      = be3bb803-91b6-4da0-bd91-a8b21c18ca5d
>    MODULE_TYPE                    = DXE_DRIVER
>    VERSION_STRING                 = 1.0
> -  LIBRARY_CLASS                  = BaseCryptLib|DXE_DRIVER DXE_CORE UEFI_APPLICATION UEFI_DRIVER
> +  LIBRARY_CLASS                  = BaseCryptLib|DXE_DRIVER DXE_CORE UEFI_APPLICATION UEFI_DRIVER MM_STANDALONE
>
>  #
>  # The following information is for reference only and not required by the build tools.
> @@ -85,6 +86,10 @@
>    OpensslLib
>    IntrinsicLib
>    PrintLib
> +  PcdLib
> +
> +[Pcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdStandaloneMmCodeEnabled
>
>  #
>  # Remove these [BuildOptions] after this library is cleaned up
> diff --git a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
> index 32628c8..fb16451 100644
> --- a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
> +++ b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
> @@ -91,6 +91,10 @@
>    OpensslLib
>    IntrinsicLib
>    PrintLib
> +  PcdLib
> +
> +[Pcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdStandaloneMmCodeEnabled
>
>  #
>  # Remove these [BuildOptions] after this library is cleaned up
> diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c b/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
> index 5f9b0c2..de8e756 100644
> --- a/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
> +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
> @@ -3,6 +3,7 @@
>    for OpenSSL-based Cryptographic Library (used in DXE & RUNTIME).
>
>  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
>  This program and the accompanying materials
>  are licensed and made available under the terms and conditions of the BSD License
>  which accompanies this distribution.  The full text of the license may be found at
> @@ -77,12 +78,14 @@ time_t time (time_t *timer)
>    time_t      CalTime;
>    UINTN       Year;
>
> -  //
> -  // Get the current time and date information
> -  //
> -  Status = gRT->GetTime (&Time, NULL);
> -  if (EFI_ERROR (Status) || (Time.Year < 1970)) {
> -    return 0;
> +  if (!PcdGetBool (PcdStandaloneMmCodeEnabled)) {
> +    //
> +    // Get the current time and date information
> +    //
> +    Status = gRT->GetTime (&Time, NULL);
> +    if (EFI_ERROR (Status) || (Time.Year < 1970)) {
> +      return 0;
> +    }
>    }
>
>    //
> --
> 2.7.4
>


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 11/13] ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver
  2018-12-14 12:13 ` [PATCH 11/13] ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver Jagadeesh Ujja
@ 2018-12-21 11:07   ` Ard Biesheuvel
  0 siblings, 0 replies; 52+ messages in thread
From: Ard Biesheuvel @ 2018-12-21 11:07 UTC (permalink / raw)
  To: Jagadeesh Ujja
  Cc: edk2-devel@lists.01.org, Gao, Liming, Zhang, Chao B,
	Leif Lindholm

On Fri, 14 Dec 2018 at 13:14, Jagadeesh Ujja <jagadeesh.ujja@arm.com> wrote:
>
> Adapt the NorFlashDxe driver to be used as a MM_STANDALONE driver to
> allow access to NOR flash for code executing in MM_STANDALONE mode.
> This allows storing of EFI variables on NOR flash which is accessible
> only via the MM STANDALONE mode software.
>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> ---
>  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c     |   2 +-
>  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c            | 210 ++++++++++++++++----
>  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h            |   5 +-
>  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf          |   2 +
>  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c         |  96 ++++-----
>  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf |  76 +++++++
>  6 files changed, 302 insertions(+), 89 deletions(-)
>

Instead of these huge if() blocks, could you please factor out the
functionality for each, and put two different versions in
NorFlashDxeBase.c and NorFlashDxeSmm.c, and include the appropriate
one in the .inf files.

> diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c
> index 279b77c..4c002c7 100644
> --- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c
> +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c
> @@ -1,6 +1,6 @@
>  /** @file  NorFlashBlockIoDxe.c
>
> -  Copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>
> +  Copyright (c) 2011-2018, ARM Ltd. All rights reserved.<BR>
>
>    This program and the accompanying materials
>    are licensed and made available under the terms and conditions of the BSD License
> diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c
> index af40a4c..9c56010 100644
> --- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c
> +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c
> @@ -1,6 +1,6 @@
>  /** @file  NorFlashDxe.c
>
> -  Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
> +  Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.<BR>
>
>    This program and the accompanying materials
>    are licensed and made available under the terms and conditions of the BSD License
> @@ -138,29 +138,102 @@ NorFlashCreateInstance (
>
>    if (SupportFvb) {
>      NorFlashFvbInitialize (Instance);
> +    if (!InMm ()) {
> +        Status = gBS->InstallMultipleProtocolInterfaces (
> +                        &Instance->Handle,
> +                        &gEfiDevicePathProtocolGuid, &Instance->DevicePath,
> +                        &gEfiBlockIoProtocolGuid,  &Instance->BlockIoProtocol,
> +                        &gEfiFirmwareVolumeBlockProtocolGuid, &Instance->FvbProtocol,
> +                        NULL
> +                        );
> +        if (EFI_ERROR(Status)) {
> +          FreePool (Instance);
> +          return Status;
> +        }
> +    } else {
> +      //Install DevicePath Protocol
> +      Status = gMmst->MmInstallProtocolInterface (
> +                        &Instance->Handle,
> +                        &gEfiDevicePathProtocolGuid,
> +                        EFI_NATIVE_INTERFACE,
> +                        &Instance->DevicePath
> +                        );
> +      if (EFI_ERROR(Status)) {
> +        FreePool (Instance);
> +        return Status;
> +      }
> +      //Install BlockIo Protocol
> +      Status = gMmst->MmInstallProtocolInterface (
> +                        &Instance->Handle,
> +                        &gEfiBlockIoProtocolGuid,
> +                        EFI_NATIVE_INTERFACE,
> +                        &Instance->BlockIoProtocol
> +                        );
> +      if (EFI_ERROR(Status)) {
> +        FreePool (Instance);
> +        return Status;
> +      }
>
> -    Status = gBS->InstallMultipleProtocolInterfaces (
> -                  &Instance->Handle,
> -                  &gEfiDevicePathProtocolGuid, &Instance->DevicePath,
> -                  &gEfiBlockIoProtocolGuid,  &Instance->BlockIoProtocol,
> -                  &gEfiFirmwareVolumeBlockProtocolGuid, &Instance->FvbProtocol,
> -                  NULL
> -                  );
> -    if (EFI_ERROR(Status)) {
> -      FreePool (Instance);
> -      return Status;
> +      //Install FirmwareVolumeBlock Protocol
> +      Status = gMmst->MmInstallProtocolInterface (
> +                        &Instance->Handle,
> +                        &gEfiSmmFirmwareVolumeBlockProtocolGuid,
> +                        EFI_NATIVE_INTERFACE,
> +                        &Instance->FvbProtocol
> +                        );
> +      if (EFI_ERROR(Status)) {
> +        FreePool (Instance);
> +        return Status;
> +      }
>      }
>    } else {
> -    Status = gBS->InstallMultipleProtocolInterfaces (
> -                    &Instance->Handle,
> -                    &gEfiDevicePathProtocolGuid, &Instance->DevicePath,
> -                    &gEfiBlockIoProtocolGuid,  &Instance->BlockIoProtocol,
> -                    &gEfiDiskIoProtocolGuid, &Instance->DiskIoProtocol,
> -                    NULL
> -                    );
> -    if (EFI_ERROR(Status)) {
> -      FreePool (Instance);
> -      return Status;
> +    if (!InMm ()) {
> +      Status = gBS->InstallMultipleProtocolInterfaces (
> +                      &Instance->Handle,
> +                      &gEfiDevicePathProtocolGuid, &Instance->DevicePath,
> +                      &gEfiBlockIoProtocolGuid,  &Instance->BlockIoProtocol,
> +                      &gEfiDiskIoProtocolGuid, &Instance->DiskIoProtocol,
> +                      NULL
> +                      );
> +      if (EFI_ERROR(Status)) {
> +        FreePool (Instance);
> +        return Status;
> +      }
> +    } else {
> +      //Install DevicePath Protocol
> +      Status = gMmst->MmInstallProtocolInterface (
> +                        &Instance->Handle,
> +                        &gEfiDevicePathProtocolGuid,
> +                        EFI_NATIVE_INTERFACE,
> +                        &Instance->DevicePath
> +                        );
> +      if (EFI_ERROR(Status)) {
> +        FreePool (Instance);
> +        return Status;
> +      }
> +      //Install BlockIo Protocol
> +      Status = gMmst->MmInstallProtocolInterface (
> +                        &Instance->Handle,
> +                        &gEfiBlockIoProtocolGuid,
> +                        EFI_NATIVE_INTERFACE,
> +                        &Instance->BlockIoProtocol
> +                        );
> +      if (EFI_ERROR(Status)) {
> +        FreePool (Instance);
> +        return Status;
> +      }
> +
> +      //Install DiskIO Protocol
> +      Status = gMmst->MmInstallProtocolInterface (
> +                        &Instance->Handle,
> +                        &gEfiDiskIoProtocolGuid,
> +                        EFI_NATIVE_INTERFACE,
> +                        &Instance->DiskIoProtocol
> +                        );
> +      if (EFI_ERROR(Status)) {
> +        FreePool (Instance);
> +        return Status;
> +      }
>      }
>    }
>
> @@ -342,13 +415,15 @@ NorFlashUnlockAndEraseSingleBlock (
>    UINTN           Index;
>    EFI_TPL         OriginalTPL;
>
> -  if (!EfiAtRuntime ()) {
> -    // Raise TPL to TPL_HIGH to stop anyone from interrupting us.
> -    OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
> -  } else {
> -    // This initialization is only to prevent the compiler to complain about the
> -    // use of uninitialized variables
> -    OriginalTPL = TPL_HIGH_LEVEL;
> +  if (!InMm ()) {
> +    if (!EfiAtRuntime ()) {
> +      // Raise TPL to TPL_HIGH to stop anyone from interrupting us.
> +      OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
> +    } else {
> +      // This initialization is only to prevent the compiler to complain about the
> +      // use of uninitialized variables
> +      OriginalTPL = TPL_HIGH_LEVEL;
> +    }
>    }
>
>    Index = 0;
> @@ -367,9 +442,11 @@ NorFlashUnlockAndEraseSingleBlock (
>      DEBUG((EFI_D_ERROR,"EraseSingleBlock(BlockAddress=0x%08x: Block Locked Error (try to erase %d times)\n", BlockAddress,Index));
>    }
>
> -  if (!EfiAtRuntime ()) {
> -    // Interruptions can resume.
> -    gBS->RestoreTPL (OriginalTPL);
> +  if (!InMm ()) {
> +    if (!EfiAtRuntime ()) {
> +      // Interruptions can resume.
> +      gBS->RestoreTPL (OriginalTPL);
> +    }
>    }
>
>    return Status;
> @@ -595,13 +672,15 @@ NorFlashWriteFullBlock (
>    // Start writing from the first address at the start of the block
>    WordAddress = BlockAddress;
>
> -  if (!EfiAtRuntime ()) {
> -    // Raise TPL to TPL_HIGH to stop anyone from interrupting us.
> -    OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
> -  } else {
> -    // This initialization is only to prevent the compiler to complain about the
> -    // use of uninitialized variables
> -    OriginalTPL = TPL_HIGH_LEVEL;
> +  if (!InMm ()) {
> +    if (!EfiAtRuntime ()) {
> +      // Raise TPL to TPL_HIGH to stop anyone from interrupting us.
> +      OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
> +    } else {
> +      // This initialization is only to prevent the compiler to complain about the
> +      // use of uninitialized variables
> +      OriginalTPL = TPL_HIGH_LEVEL;
> +    }
>    }
>
>    Status = NorFlashUnlockAndEraseSingleBlock (Instance, BlockAddress);
> @@ -661,9 +740,11 @@ NorFlashWriteFullBlock (
>    }
>
>  EXIT:
> -  if (!EfiAtRuntime ()) {
> -    // Interruptions can resume.
> -    gBS->RestoreTPL (OriginalTPL);
> +  if (!InMm ()) {
> +    if (!EfiAtRuntime ()) {
> +      // Interruptions can resume.
> +      gBS->RestoreTPL (OriginalTPL);
> +    }
>    }
>
>    if (EFI_ERROR(Status)) {
> @@ -1334,6 +1415,53 @@ NorFlashInitialise (
>                    &mNorFlashVirtualAddrChangeEvent
>                    );
>    ASSERT_EFI_ERROR (Status);
> +  return Status;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +StandaloneMmNorFlashInitialise (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_MM_SYSTEM_TABLE   *SystemTable
> +  )
> +{
> +  EFI_STATUS              Status;
> +  UINT32                  Index;
> +  NOR_FLASH_DESCRIPTION*  NorFlashDevices;
> +  BOOLEAN                 ContainVariableStorage;
> +
> +  Status = NorFlashPlatformInitialization ();
> +  if (EFI_ERROR(Status)) {
> +    DEBUG((EFI_D_ERROR,"NorFlashInitialise: Fail to initialize Nor Flash devices\n"));
> +    return Status;
> +  }
> +
> +  Status = NorFlashPlatformGetDevices (&NorFlashDevices, &mNorFlashDeviceCount);
> +  if (EFI_ERROR(Status)) {
> +    DEBUG((EFI_D_ERROR,"NorFlashInitialise: Fail to get Nor Flash devices\n"));
> +    return Status;
> +  }
> +
> +  mNorFlashInstances = AllocateRuntimePool (sizeof(NOR_FLASH_INSTANCE*) * mNorFlashDeviceCount);
>
> +  for (Index = 0; Index < mNorFlashDeviceCount; Index++) {
> +    // Check if this NOR Flash device contain the variable storage region
> +    ContainVariableStorage =
> +        (NorFlashDevices[Index].RegionBaseAddress <= PcdGet32 (PcdFlashNvStorageVariableBase)) &&
> +        (PcdGet32 (PcdFlashNvStorageVariableBase) + PcdGet32 (PcdFlashNvStorageVariableSize) <= NorFlashDevices[Index].RegionBaseAddress + NorFlashDevices[Index].Size);
> +
> +    Status = NorFlashCreateInstance (
> +      NorFlashDevices[Index].DeviceBaseAddress,
> +      NorFlashDevices[Index].RegionBaseAddress,
> +      NorFlashDevices[Index].Size,
> +      Index,
> +      NorFlashDevices[Index].BlockSize,
> +      ContainVariableStorage,
> +      &mNorFlashInstances[Index]
> +    );
> +    if (EFI_ERROR(Status)) {
> +      DEBUG((EFI_D_ERROR,"NorFlashInitialise: Fail to create instance for NorFlash[%d]\n",Index));
> +    }
> +  }
>    return Status;
>  }
> diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h
> index c0563f6..90929d3 100644
> --- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h
> +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h
> @@ -1,6 +1,6 @@
>  /** @file  NorFlashDxe.h
>
> -  Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
> +  Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.<BR>
>
>    This program and the accompanying materials
>    are licensed and made available under the terms and conditions of the BSD License
> @@ -19,6 +19,7 @@
>  #include <Base.h>
>  #include <PiDxe.h>
>
> +#include <PiMm.h>
>  #include <Guid/EventGroup.h>
>
>  #include <Protocol/BlockIo.h>
> @@ -30,6 +31,8 @@
>  #include <Library/NorFlashPlatformLib.h>
>  #include <Library/UefiLib.h>
>  #include <Library/UefiRuntimeLib.h>
> +#include <Library/StandaloneMmServicesTableLib.h>
> +#include <Library/StandaloneMmRuntimeDxe.h>
>
>  #define NOR_FLASH_ERASE_RETRY                     10
>
> diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
> index a59a21a..cbe740e 100644
> --- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
> +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
> @@ -44,6 +44,7 @@
>    UefiBootServicesTableLib
>    UefiRuntimeLib
>    DxeServicesTableLib
> +  StandaloneMmRuntimeDxe
>
>  [Guids]
>    gEfiSystemNvDataFvGuid
> @@ -57,6 +58,7 @@
>    gEfiDevicePathProtocolGuid
>    gEfiFirmwareVolumeBlockProtocolGuid
>    gEfiDiskIoProtocolGuid
> +  gEfiSmmFirmwareVolumeBlockProtocolGuid
>
>  [Pcd.common]
>    gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
> diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c
> index e62ffbb..e4d7100 100644
> --- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c
> +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c
> @@ -1,6 +1,6 @@
>  /*++ @file  NorFlashFvbDxe.c
>
> - Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
> + Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.<BR>
>
>   This program and the accompanying materials
>   are licensed and made available under the terms and conditions of the BSD License
> @@ -720,27 +720,29 @@ NorFlashFvbInitialize (
>    DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n"));
>    ASSERT((Instance != NULL));
>
> -  //
> -  // Declare the Non-Volatile storage as EFI_MEMORY_RUNTIME
> -  //
> -
> -  // Note: all the NOR Flash region needs to be reserved into the UEFI Runtime memory;
> -  //       even if we only use the small block region at the top of the NOR Flash.
> -  //       The reason is when the NOR Flash memory is set into program mode, the command
> -  //       is written as the base of the flash region (ie: Instance->DeviceBaseAddress)
> -  RuntimeMmioRegionSize = (Instance->RegionBaseAddress - Instance->DeviceBaseAddress) + Instance->Size;
> -
> -  Status = gDS->AddMemorySpace (
> -      EfiGcdMemoryTypeMemoryMappedIo,
> -      Instance->DeviceBaseAddress, RuntimeMmioRegionSize,
> -      EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
> -      );
> -  ASSERT_EFI_ERROR (Status);
> -
> -  Status = gDS->SetMemorySpaceAttributes (
> -      Instance->DeviceBaseAddress, RuntimeMmioRegionSize,
> -      EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);
> -  ASSERT_EFI_ERROR (Status);
> +  if (!InMm ()) {
> +    //
> +    // Declare the Non-Volatile storage as EFI_MEMORY_RUNTIME
> +    //
> +
> +    // Note: all the NOR Flash region needs to be reserved into the UEFI Runtime memory;
> +    //       even if we only use the small block region at the top of the NOR Flash.
> +    //       The reason is when the NOR Flash memory is set into program mode, the command
> +    //       is written as the base of the flash region (ie: Instance->DeviceBaseAddress)
> +    RuntimeMmioRegionSize = (Instance->RegionBaseAddress - Instance->DeviceBaseAddress) + Instance->Size;
> +
> +    Status = gDS->AddMemorySpace (
> +        EfiGcdMemoryTypeMemoryMappedIo,
> +        Instance->DeviceBaseAddress, RuntimeMmioRegionSize,
> +        EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
> +        );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    Status = gDS->SetMemorySpaceAttributes (
> +        Instance->DeviceBaseAddress, RuntimeMmioRegionSize,
> +        EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);
> +    ASSERT_EFI_ERROR (Status);
> +  }
>
>    mFlashNvStorageVariableBase = FixedPcdGet32 (PcdFlashNvStorageVariableBase);
>
> @@ -777,30 +779,32 @@ NorFlashFvbInitialize (
>      }
>    }
>
> -  //
> -  // The driver implementing the variable read service can now be dispatched;
> -  // the varstore headers are in place.
> -  //
> -  Status = gBS->InstallProtocolInterface (
> -                  &gImageHandle,
> -                  &gEdkiiNvVarStoreFormattedGuid,
> -                  EFI_NATIVE_INTERFACE,
> -                  NULL
> -                  );
> -  ASSERT_EFI_ERROR (Status);
> -
> -  //
> -  // Register for the virtual address change event
> -  //
> -  Status = gBS->CreateEventEx (
> -                  EVT_NOTIFY_SIGNAL,
> -                  TPL_NOTIFY,
> -                  FvbVirtualNotifyEvent,
> -                  NULL,
> -                  &gEfiEventVirtualAddressChangeGuid,
> -                  &mFvbVirtualAddrChangeEvent
> -                  );
> -  ASSERT_EFI_ERROR (Status);
> +  if (!InMm ()) {
> +    //
> +    // The driver implementing the variable read service can now be dispatched;
> +    // the varstore headers are in place.
> +    //
> +    Status = gBS->InstallProtocolInterface (
> +                    &gImageHandle,
> +                    &gEdkiiNvVarStoreFormattedGuid,
> +                    EFI_NATIVE_INTERFACE,
> +                    NULL
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    //
> +    // Register for the virtual address change event
> +    //
> +    Status = gBS->CreateEventEx (
> +                    EVT_NOTIFY_SIGNAL,
> +                    TPL_NOTIFY,
> +                    FvbVirtualNotifyEvent,
> +                    NULL,
> +                    &gEfiEventVirtualAddressChangeGuid,
> +                    &mFvbVirtualAddrChangeEvent
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +  }
>
>    return Status;
>  }
> diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
> new file mode 100644
> index 0000000..a6d0581
> --- /dev/null
> +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
> @@ -0,0 +1,76 @@
> +#/** @file
> +#
> +#  Component description file for NorFlashDxe module
> +#
> +#  Copyright (c) 2018, ARM Limited. All rights reserved.
> +#
> +#  This program and the accompanying materials
> +#  are licensed and made available under the terms and conditions of the BSD License
> +#  which accompanies this distribution.  The full text of the license may be found at
> +#  http://opensource.org/licenses/bsd-license.php
> +#
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +#
> +#**/
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = StandaloneMmNorFlash
> +  FILE_GUID                      = 166F677B-DAC9-4AE4-AD34-2FF2504B0637
> +  MODULE_TYPE                    = MM_STANDALONE
> +  VERSION_STRING                 = 1.0
> +  PI_SPECIFICATION_VERSION       = 0x00010032
> +  ENTRY_POINT                    = StandaloneMmNorFlashInitialise
> +
> +[Sources.common]
> +  NorFlashDxe.c
> +  NorFlashFvbDxe.c
> +  NorFlashBlockIoDxe.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  ArmPlatformPkg/ArmPlatformPkg.dec
> +  EmbeddedPkg/EmbeddedPkg.dec
> +  ArmPkg/ArmPkg.dec
> +  StandaloneMmPkg/StandaloneMmPkg.dec
> +
> +[LibraryClasses]
> +  StandaloneMmDriverEntryPoint
> +  BaseMemoryLib
> +  ArmSvcLib
> +  ArmLib
> +  IoLib
> +  BaseLib
> +  DebugLib
> +  HobLib
> +  MemoryAllocationLib
> +  NorFlashPlatformLib
> +  MmServicesTableLib
> +
> +[Guids]
> +  gEfiSystemNvDataFvGuid
> +  gEfiVariableGuid
> +  gEfiAuthenticatedVariableGuid
> +  gEfiEventVirtualAddressChangeGuid
> +  gEdkiiNvVarStoreFormattedGuid     ## PRODUCES ## PROTOCOL
> +
> +[Protocols]
> +  gEfiBlockIoProtocolGuid
> +  gEfiDevicePathProtocolGuid
> +  gEfiSmmFirmwareVolumeBlockProtocolGuid
> +  gEfiDiskIoProtocolGuid
> +
> +[Pcd.common]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
> +
> +  gArmPlatformTokenSpaceGuid.PcdNorFlashCheckBlockLocked
> +
> +[Depex]
> +  TRUE
> --
> 2.7.4
>


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 10/13] MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this library
  2018-12-14 12:13 ` [PATCH 10/13] MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this library Jagadeesh Ujja
@ 2019-01-02 13:05   ` Ard Biesheuvel
  2019-01-02 13:23     ` Gao, Liming
  2019-01-02 13:27     ` Jagadeesh Ujja
  0 siblings, 2 replies; 52+ messages in thread
From: Ard Biesheuvel @ 2019-01-02 13:05 UTC (permalink / raw)
  To: Jagadeesh Ujja
  Cc: edk2-devel@lists.01.org, Gao, Liming, Zhang, Chao B,
	Leif Lindholm

On Fri, 14 Dec 2018 at 13:14, Jagadeesh Ujja <jagadeesh.ujja@arm.com> wrote:
>
> “VarCheckLib” library can be used by MM_STANDALONE drivers as well.
> So add MM_STANDALONE as the module type this library supports.
>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> ---
>  MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf b/MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
> index 099f83d..c8cf810 100644
> --- a/MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
> +++ b/MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
> @@ -2,6 +2,7 @@
>  #  Provides variable check services and database management.
>  #
>  #  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +#  Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
>  #
>  #  This program and the accompanying materials
>  #  are licensed and made available under the terms and conditions
> @@ -21,12 +22,12 @@
>    FILE_GUID                      = 63E12D08-0C5D-47F8-95E4-09F89D7506C5
>    MODULE_TYPE                    = DXE_RUNTIME_DRIVER

Please change the module type to 'BASE' as well. Note that this may
require you to add

#include <Uefi/UefiBaseType.h>

to some source or header files.

With that

Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

>    VERSION_STRING                 = 1.0
> -  LIBRARY_CLASS                  = VarCheckLib|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER
> +  LIBRARY_CLASS                  = VarCheckLib|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER MM_STANDALONE
>
>  #
>  # The following information is for reference only and not required by the build tools.
>  #
> -#  VALID_ARCHITECTURES           = IA32 X64
> +#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
>  #
>
>  [Sources]
> --
> 2.7.4
>


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 12/13] SecurityPkg/AuthVariableLib: allow MM_STANDALONE drivers to use this library
  2018-12-14 12:13 ` [PATCH 12/13] SecurityPkg/AuthVariableLib: allow MM_STANDALONE drivers to use this library Jagadeesh Ujja
@ 2019-01-02 13:05   ` Ard Biesheuvel
  0 siblings, 0 replies; 52+ messages in thread
From: Ard Biesheuvel @ 2019-01-02 13:05 UTC (permalink / raw)
  To: Jagadeesh Ujja
  Cc: edk2-devel@lists.01.org, Gao, Liming, Zhang, Chao B,
	Leif Lindholm

On Fri, 14 Dec 2018 at 13:14, Jagadeesh Ujja <jagadeesh.ujja@arm.com> wrote:
>
> “AuthVariableLib” library can be used by MM_STANDALONE drivers as well.
> So add MM_STANDALONE as the module type this library supports.
>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> Reviewed-by: Chao Zhang <chao.b.zhang@intel.com>
> ---
>  SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
> index 572ba4e..4294d3b 100644
> --- a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
> +++ b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
> @@ -2,6 +2,7 @@
>  #  Provides authenticated variable services.
>  #
>  #  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
> +#  Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
>  #
>  #  This program and the accompanying materials
>  #  are licensed and made available under the terms and conditions
> @@ -21,12 +22,12 @@
>    FILE_GUID                      = B23CF5FB-6FCC-4422-B145-D855DBC05457
>    MODULE_TYPE                    = DXE_RUNTIME_DRIVER

Please change the module type to 'BASE' as well. Note that this may
require you to add

#include <Uefi/UefiBaseType.h>

to some source or header files.

With that

Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

>    VERSION_STRING                 = 1.0
> -  LIBRARY_CLASS                  = AuthVariableLib|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER
> +  LIBRARY_CLASS                  = AuthVariableLib|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER MM_STANDALONE
>
>  #
>  # The following information is for reference only and not required by the build tools.
>  #
> -#  VALID_ARCHITECTURES           = IA32 X64
> +#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
>  #
>
>  [Sources]
> --
> 2.7.4
>


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 00/13] Extend secure variable service to be usable from Standalone MM
  2018-12-21  2:57 ` Wang, Jian J
@ 2019-01-02 13:19   ` Jagadeesh Ujja
  2019-01-03  2:37     ` Wang, Jian J
  0 siblings, 1 reply; 52+ messages in thread
From: Jagadeesh Ujja @ 2019-01-02 13:19 UTC (permalink / raw)
  To: Wang, Jian J
  Cc: edk2-devel@lists.01.org, Gao, Liming, Zhang, Chao B,
	leif.lindholm@linaro.org, ard.biesheuvel@linaro.org

hi Jian,

On Fri, Dec 21, 2018 at 8:27 AM Wang, Jian J <jian.j.wang@intel.com> wrote:
>
> Jagadeesh,
>
> There're many places in this patch series where code similar to following is added.
> It'd better to wrap them into module private functions or even a library, if necessary.
> This can make the code cleaner (no if/else) and easier (central place) to maintain in
> the future.
>
> +  if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) {
> +    Status = gSmst->SmmLocateProtocol (
> +                      &gEfiSmmSwapAddressRangeProtocolGuid,
> +                      NULL,
> +                      SarProtocol
> +                      );
> +  } else {
> +    Status = gMmst->MmLocateProtocol (
> +                      &gEfiSmmSwapAddressRangeProtocolGuid,
> +                      NULL,
> +                      SarProtocol
> +                      );
> +  }
>
Thank you for your comment. This patch series try to reuse code as
much as possible between MM and non-MM code. So, in some changes,
if..else was used which helps to reuse most of the other bits of code.
To address your comment, can you please let me know how we could avoid
this if..else without duplicating the too much code. I am not clear
about " module private functions or even a library" comment that you
have made. Can you please help me with this.

Thanks,
Jagadeesh.

> Regards,
> Jian
>
>
> > -----Original Message-----
> > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> > Jagadeesh Ujja
> > Sent: Friday, December 14, 2018 8:13 PM
> > To: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>; Zhang, Chao
> > B <chao.b.zhang@intel.com>; leif.lindholm@linaro.org;
> > ard.biesheuvel@linaro.org
> > Subject: [edk2] [PATCH 00/13] Extend secure variable service to be usable from
> > Standalone MM
> >
> > Changes since RFC v4:
> > - Addressed all the comments from Liming Gao
> >   - Added an additional PCD 'PcdStandaloneMmCodeEnabled' to indicate
> >     presence of StandaloneMM support.
> >   - MdePkg.dec file updated to include StandaloneMmServiceTableLib and
> >     StandaloneMmRuntimeDxe library.
> >   - Platform specific changes will be posted in a seperate patchset.
> >   - AsmLfence wrapper function is supported for AArch64 platforms.
> >   - All the patches in this series can be pulled from
> >     https://github.com/jagadeeshujja/edk2 (branch: topics/aarch64_secure_vars)
> >
> > Changes since RFC v3:
> > - Addressed all the comments from Liming Gao
> >   - Added a AArch64 implementation of AsmLfence which is a wrapper for
> >     MemoryFence. The changes in variable service driver in v3 of this
> >     patchset that used MemoryFence instead of AsmLfence have been removed.
> >   - Added StandaloneMmServicesTableLib.h and StandaloneMmRuntimeDxe
> >     library into MdePkg.
> >   - Renamed PcdStandaloneMmEnable as PcdStandaloneMmVariableEnabled and
> >     added to in to MdePkg.
> >   - Now with above changes, edk2 packages don't need to depend on
> >     StandaloneMmPkg/StandaloneMmPkg.dec
> > - Addressed comments from Ting Ye
> >   - Removed the hacks in the v3 version.
> >   - Will relook into the “TimerWrapp.c” file and add a appropriate
> >     implementation of this for MM Standalone mode code.
> >
> > Changes since RFC v2:
> > - Added 'Contributed-under' tag, removed Change-ID tag and
> >   maintained a single signed-off-by for the all the patches.
> >
> > Changes since RFC v1:
> > - Addressed all the comments from Liming Gao
> >   - Removed the use of #ifdef/#else/#endif and used a Pcd instead to
> >     select between MM and non-MM paths.
> >   - Removed all dependencies on edk2-platforms.
> >   - Dropped the use of mMmst and used gSmst instead.
> >   - Added a dummy implementation UefiRuntimeServiceTableLib for
> >     MM_STANDALONE usage
> > - Replaced all uses of AsmLfence with MemoryFence from variable
> >   service code.
> > - Add a new StandaloneMmRuntimeDxe library to for use by non-MM code.
> >
> > This patch series extends the existing secure variable service support for
> > use with Standalone MM. This is applicable to paltforms that use Standalone
> > Management Mode to protect access to non-volatile memory (NOR flash in case
> > of these patches) used to store the secure EFI variables.
> >
> > The first patch pulls in additional libraries from the staging branch of
> > StandaloneMmPkg into the edk2's StandaloneMmPkg. The existing secure
> > variable
> > service implementation supports only the traditional MM mode and so the rest
> > of the patches extends the existing secure variable service support to be
> > useable with Standalone MM mode as well.
> >
> > Jagadeesh Ujja (13):
> >   StandaloneMmPkg: Pull in additonal libraries from staging branch
> >   MdePkg: Add a PCD that indicates presence of Standalone MM mode
> >   MdeModulePkg: Add a PCD to indicate Standalone MM supports secure
> >     variable
> >   MdePkg/Include: add StandaloneMmServicesTableLib header file
> >   MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
> >   MdePkg/Library: Add StandaloneMmRuntimeDxe library
> >   MdeModulePkg/FaultTolerantWriteDxe: allow reusability as a MM driver
> >   MdeModulePkg/Variable/RuntimeDxe: adapt for usability with MM
> >     Standalone
> >   MdeModulePkg/Variable/RuntimeDxe: adapt as a MM Standalone driver
> >   MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this
> >     library
> >   ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver
> >   SecurityPkg/AuthVariableLib: allow MM_STANDALONE drivers to use this
> >     library
> >   CryptoPkg/BaseCryptLib: allow MM_STANDALONE drivers to use this
> >     library
> >
> >  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c
> > |   2 +-
> >  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c                                            |
> > 210 ++++-
> >  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h                                            |
> > 5 +-
> >  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf                                          |
> > 2 +
> >  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c
> > |  96 +--
> >  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
> > |  76 ++
> >  CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf                                             |   7
> > +-
> >  CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf                                          |   4
> > +
> >  CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c                                       |
> > 15 +-
> >  MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf                                            |
> > 5 +-
> >  MdeModulePkg/MdeModulePkg.dec                                                               |   5 +
> >  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
> > |   1 +
> >  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
> > | 203 +++--
> >
> > MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandalon
> > eMm.inf             | 101 +++
> >  MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c
> > |  27 +-
> >  MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
> > |  37 +-
> >  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> > |   1 +
> >  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
> > | 201 ++++-
> >  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
> > |  31 +-
> >  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
> > |   3 +
> >  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
> > | 132 ++++
> >  MdePkg/Include/Library/BaseLib.h                                                            |  33 +-
> >  MdePkg/Include/Library/StandaloneMmRuntimeDxe.h
> > |  39 +
> >  MdePkg/Include/Library/StandaloneMmServicesTableLib.h
> > |  25 +
> >  MdePkg/Library/BaseLib/AArch64/AsmLfence.S                                                  |  42
> > +
> >  MdePkg/Library/BaseLib/AArch64/AsmLfence.asm                                                |
> > 41 +
> >  MdePkg/Library/BaseLib/BaseLib.inf                                                          |   2 +
> >  MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c
> > |  36 +
> >  MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf
> > |  36 +
> >  MdePkg/MdePkg.dec                                                                           |  12 +
> >  SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf                                     |
> > 5 +-
> >
> > StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHob
> > Lib.inf                   |   2 +-
> >
> > StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmCore
> > HobLibInternal.c         |  64 ++
> >  StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
> > | 655 ++++++++++++++++
> >  StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
> > |  48 ++
> >
> > StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMm
> > MemoryAllocationLib.c   | 824 ++++++++++++++++++++
> >
> > StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMm
> > MemoryAllocationLib.inf |  45 ++
> >
> > StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServi
> > cesTableLib.c         |  64 ++
> >
> > StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServi
> > cesTableLib.inf       |  36 +
> >  39 files changed, 2929 insertions(+), 244 deletions(-)
> >  create mode 100644
> > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
> >  create mode 100644
> > MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandalon
> > eMm.inf
> >  create mode 100644
> > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
> >  create mode 100644 MdePkg/Include/Library/StandaloneMmRuntimeDxe.h
> >  create mode 100644 MdePkg/Include/Library/StandaloneMmServicesTableLib.h
> >  create mode 100644 MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> >  create mode 100644 MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> >  create mode 100644
> > MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c
> >  create mode 100644
> > MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf
> >  create mode 100644
> > StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmCore
> > HobLibInternal.c
> >  create mode 100644
> > StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
> >  create mode 100644
> > StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
> >  create mode 100644
> > StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMm
> > MemoryAllocationLib.c
> >  create mode 100644
> > StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMm
> > MemoryAllocationLib.inf
> >  create mode 100644
> > StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServi
> > cesTableLib.c
> >  create mode 100644
> > StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServi
> > cesTableLib.inf
> >
> > --
> > 2.7.4
> >
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://lists.01.org/mailman/listinfo/edk2-devel
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 10/13] MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this library
  2019-01-02 13:05   ` Ard Biesheuvel
@ 2019-01-02 13:23     ` Gao, Liming
  2019-01-02 14:23       ` Ard Biesheuvel
  2019-01-02 13:27     ` Jagadeesh Ujja
  1 sibling, 1 reply; 52+ messages in thread
From: Gao, Liming @ 2019-01-02 13:23 UTC (permalink / raw)
  To: Ard Biesheuvel, Jagadeesh Ujja; +Cc: edk2-devel@lists.01.org, Zhang, Chao B

Ard:
  Why need to change module type? The non-base type library can support more than one module types, such as MdeModulePkg\Library\PeiDxeDebugLibReportStatusCode\PeiDxeDebugLibReportStatusCode.inf. Only if this library has constructor and needs to support cross module type, it must be set to BASE. For other case, its module type can be kept as-is. I clarify this rule in https://lists.01.org/pipermail/edk2-devel/2018-December/033523.html.

Thanks
Liming
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Ard Biesheuvel
> Sent: Wednesday, January 2, 2019 9:05 PM
> To: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> Cc: edk2-devel@lists.01.org; Zhang, Chao B <chao.b.zhang@intel.com>; Gao, Liming <liming.gao@intel.com>
> Subject: Re: [edk2] [PATCH 10/13] MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this library
> 
> On Fri, 14 Dec 2018 at 13:14, Jagadeesh Ujja <jagadeesh.ujja@arm.com> wrote:
> >
> > “VarCheckLib” library can be used by MM_STANDALONE drivers as well.
> > So add MM_STANDALONE as the module type this library supports.
> >
> > Contributed-under: TianoCore Contribution Agreement 1.1
> > Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> > ---
> >  MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git a/MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf b/MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
> > index 099f83d..c8cf810 100644
> > --- a/MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
> > +++ b/MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
> > @@ -2,6 +2,7 @@
> >  #  Provides variable check services and database management.
> >  #
> >  #  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> > +#  Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
> >  #
> >  #  This program and the accompanying materials
> >  #  are licensed and made available under the terms and conditions
> > @@ -21,12 +22,12 @@
> >    FILE_GUID                      = 63E12D08-0C5D-47F8-95E4-09F89D7506C5
> >    MODULE_TYPE                    = DXE_RUNTIME_DRIVER
> 
> Please change the module type to 'BASE' as well. Note that this may
> require you to add
> 
> #include <Uefi/UefiBaseType.h>
> 
> to some source or header files.
> 
> With that
> 
> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> 
> >    VERSION_STRING                 = 1.0
> > -  LIBRARY_CLASS                  = VarCheckLib|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER
> > +  LIBRARY_CLASS                  = VarCheckLib|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER MM_STANDALONE
> >
> >  #
> >  # The following information is for reference only and not required by the build tools.
> >  #
> > -#  VALID_ARCHITECTURES           = IA32 X64
> > +#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
> >  #
> >
> >  [Sources]
> > --
> > 2.7.4
> >
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 10/13] MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this library
  2019-01-02 13:05   ` Ard Biesheuvel
  2019-01-02 13:23     ` Gao, Liming
@ 2019-01-02 13:27     ` Jagadeesh Ujja
  1 sibling, 0 replies; 52+ messages in thread
From: Jagadeesh Ujja @ 2019-01-02 13:27 UTC (permalink / raw)
  To: Ard Biesheuvel; +Cc: edk2-devel@lists.01.org, Zhang, Chao B, Gao, Liming

Hi Ard,

On Wed, Jan 2, 2019 at 6:35 PM Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>
> On Fri, 14 Dec 2018 at 13:14, Jagadeesh Ujja <jagadeesh.ujja@arm.com> wrote:
> >
> > “VarCheckLib” library can be used by MM_STANDALONE drivers as well.
> > So add MM_STANDALONE as the module type this library supports.
> >
> > Contributed-under: TianoCore Contribution Agreement 1.1
> > Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> > ---
> >  MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git a/MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf b/MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
> > index 099f83d..c8cf810 100644
> > --- a/MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
> > +++ b/MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
> > @@ -2,6 +2,7 @@
> >  #  Provides variable check services and database management.
> >  #
> >  #  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> > +#  Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
> >  #
> >  #  This program and the accompanying materials
> >  #  are licensed and made available under the terms and conditions
> > @@ -21,12 +22,12 @@
> >    FILE_GUID                      = 63E12D08-0C5D-47F8-95E4-09F89D7506C5
> >    MODULE_TYPE                    = DXE_RUNTIME_DRIVER
>
> Please change the module type to 'BASE' as well. Note that this may
> require you to add
>
> #include <Uefi/UefiBaseType.h>
>
> to some source or header files.
>
> With that
>
> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>
Sorry Just now I submitted patch set v2, will take care of this review
comments in the next patchset

Thanks
Jagadeesh

> >    VERSION_STRING                 = 1.0
> > -  LIBRARY_CLASS                  = VarCheckLib|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER
> > +  LIBRARY_CLASS                  = VarCheckLib|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER MM_STANDALONE
> >
> >  #
> >  # The following information is for reference only and not required by the build tools.
> >  #
> > -#  VALID_ARCHITECTURES           = IA32 X64
> > +#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
> >  #
> >
> >  [Sources]
> > --
> > 2.7.4
> >
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 10/13] MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this library
  2019-01-02 13:23     ` Gao, Liming
@ 2019-01-02 14:23       ` Ard Biesheuvel
  2019-01-02 16:54         ` Ard Biesheuvel
  0 siblings, 1 reply; 52+ messages in thread
From: Ard Biesheuvel @ 2019-01-02 14:23 UTC (permalink / raw)
  To: Gao, Liming; +Cc: Jagadeesh Ujja, edk2-devel@lists.01.org, Zhang, Chao B

On Wed, 2 Jan 2019 at 14:23, Gao, Liming <liming.gao@intel.com> wrote:
>
> Ard:
>   Why need to change module type? The non-base type library can support more than one module types, such as MdeModulePkg\Library\PeiDxeDebugLibReportStatusCode\PeiDxeDebugLibReportStatusCode.inf. Only if this library has constructor and needs to support cross module type, it must be set to BASE. For other case, its module type can be kept as-is. I clarify this rule in https://lists.01.org/pipermail/edk2-devel/2018-December/033523.html.
>

Currently, standalone MM on AArch64 requires strict alignment, and we
only build SEC, PEI_CORE, PEIM and BASE modules with strict alignment.

In general, I think it makes sense to default to BASE type for all
libraries unless there is a need to using something else, i.e, when
the library has a constructor that needs to ImageHandle and/or
SystemTable arguments.


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 10/13] MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this library
  2019-01-02 14:23       ` Ard Biesheuvel
@ 2019-01-02 16:54         ` Ard Biesheuvel
  0 siblings, 0 replies; 52+ messages in thread
From: Ard Biesheuvel @ 2019-01-02 16:54 UTC (permalink / raw)
  To: Gao, Liming; +Cc: Jagadeesh Ujja, edk2-devel@lists.01.org, Zhang, Chao B

On Wed, 2 Jan 2019 at 15:23, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>
> On Wed, 2 Jan 2019 at 14:23, Gao, Liming <liming.gao@intel.com> wrote:
> >
> > Ard:
> >   Why need to change module type? The non-base type library can support more than one module types, such as MdeModulePkg\Library\PeiDxeDebugLibReportStatusCode\PeiDxeDebugLibReportStatusCode.inf. Only if this library has constructor and needs to support cross module type, it must be set to BASE. For other case, its module type can be kept as-is. I clarify this rule in https://lists.01.org/pipermail/edk2-devel/2018-December/033523.html.
> >
>
> Currently, standalone MM on AArch64 requires strict alignment, and we
> only build SEC, PEI_CORE, PEIM and BASE modules with strict alignment.
>
> In general, I think it makes sense to default to BASE type for all
> libraries unless there is a need to using something else, i.e, when
> the library has a constructor that needs to ImageHandle and/or
> SystemTable arguments.

Actually, regardless of whether BASE is more appropriate in general, I
think there is no reason to keep the strict alignment checking in
standalone MM, since the MM core will be invoked with MMU and caches
enabled, and so there is no reason to disallow unaligned accesses
(this is different from SEC and PEI modules on ARM, since they may
execute in place with the caches and MMU off, in which case unaligned
accesses are never permitted)

I will raise this internally. In the mean time, please disregard this
aspect of my feedback. Simply adding MM_STANDALONE to the list of
permitted module types should be sufficient.


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 00/13] Extend secure variable service to be usable from Standalone MM
  2018-12-20 14:23         ` Gao, Liming
@ 2019-01-02 17:15           ` Ard Biesheuvel
  2019-01-03  7:43             ` Jagadeesh Ujja
  0 siblings, 1 reply; 52+ messages in thread
From: Ard Biesheuvel @ 2019-01-02 17:15 UTC (permalink / raw)
  To: Gao, Liming; +Cc: Jagadeesh Ujja, edk2-devel@lists.01.org, Zhang, Chao B

On Thu, 20 Dec 2018 at 15:23, Gao, Liming <liming.gao@intel.com> wrote:
>
> Jagadeesh:
>   MdeModulePkg Variable service/Fault tolerant/Nor Flash driver depends on StandaloneMmServicesTableLib library class header file. This header file is added into MdePkg. It has two interfaces. One is global gMmst, another is function InMm(). So, there is no dependency issue here.
> And, MdePkg adds one StandaloneMmServicesTableLib library INF with empty implementation, this library is just for build. It sets gMmst=NULL, and always return FASLE in InMm(). This library can be used in MdeModulePkg.dsc to make Variable driver pass build. There is also no dependency issue here. Last, Platform DSC file will refer to the real StandaloneMmServicesTableLib library INF from StandaloneMmPkg.
>

I think we should avoid the need for InMm() altogether for standalone
MM. It will always return TRUE for standalone MM modules, and it will
always return FALSE for other modules, so the distinction should be
made at build time.

This means that we need to refactor the SMM 'server' modules and/or
libraries so that any code they cannot share (like boot services
invocations) are only included in the classic SMM versions.

I have pushed my own prototype code here:
https://github.com/ardbiesheuvel/edk2/commits/standalone-mm

There is some overlap with Jagadeesh's work. I will work with him
directly to resolve this before posting any new revisions.


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 00/13] Extend secure variable service to be usable from Standalone MM
  2019-01-02 13:19   ` Jagadeesh Ujja
@ 2019-01-03  2:37     ` Wang, Jian J
  0 siblings, 0 replies; 52+ messages in thread
From: Wang, Jian J @ 2019-01-03  2:37 UTC (permalink / raw)
  To: Jagadeesh Ujja
  Cc: edk2-devel@lists.01.org, Gao, Liming, Zhang, Chao B,
	leif.lindholm@linaro.org, ard.biesheuvel@linaro.org

Hi Jagadeesh,

Since those code are used in different drivers, a new library would be better. For
example, we could have a CommonMmServicesLibrary, in which following interfaces
are defined ((just for example)

EFI_STATUS
MmstLocateProtocol(
  IN  EFI_GUID  *Protocol,
  IN  VOID      *Registration, OPTIONAL
  OUT VOID      **Interface
  )
{
  EFI_STATUS  Status;

  if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) {
    Status = gSmst->SmmLocateProtocol (
                      &gEfiSmmSwapAddressRangeProtocolGuid,
                      NULL,
                      SarProtocol
                      );
  } else {
    Status = gMmst->MmLocateProtocol (
                      &gEfiSmmSwapAddressRangeProtocolGuid,
                      NULL,
                      SarProtocol
                      );
  }

  return Status;
}

Then you can use MmstLocateProtocol() in FaultTolerantWriteDxe, Variable driver, etc.
This applies to other interfaces like InstallProtocolInterface, AllocatePage in SMM/MM
system table.

Regards,
Jian

> -----Original Message-----
> From: Jagadeesh Ujja [mailto:jagadeesh.ujja@arm.com]
> Sent: Wednesday, January 02, 2019 9:19 PM
> To: Wang, Jian J <jian.j.wang@intel.com>
> Cc: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>; Zhang, Chao
> B <chao.b.zhang@intel.com>; leif.lindholm@linaro.org;
> ard.biesheuvel@linaro.org
> Subject: Re: [edk2] [PATCH 00/13] Extend secure variable service to be usable
> from Standalone MM
> 
> hi Jian,
> 
> On Fri, Dec 21, 2018 at 8:27 AM Wang, Jian J <jian.j.wang@intel.com> wrote:
> >
> > Jagadeesh,
> >
> > There're many places in this patch series where code similar to following is
> added.
> > It'd better to wrap them into module private functions or even a library, if
> necessary.
> > This can make the code cleaner (no if/else) and easier (central place) to
> maintain in
> > the future.
> >
> > +  if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) {
> > +    Status = gSmst->SmmLocateProtocol (
> > +                      &gEfiSmmSwapAddressRangeProtocolGuid,
> > +                      NULL,
> > +                      SarProtocol
> > +                      );
> > +  } else {
> > +    Status = gMmst->MmLocateProtocol (
> > +                      &gEfiSmmSwapAddressRangeProtocolGuid,
> > +                      NULL,
> > +                      SarProtocol
> > +                      );
> > +  }
> >
> Thank you for your comment. This patch series try to reuse code as
> much as possible between MM and non-MM code. So, in some changes,
> if..else was used which helps to reuse most of the other bits of code.
> To address your comment, can you please let me know how we could avoid
> this if..else without duplicating the too much code. I am not clear
> about " module private functions or even a library" comment that you
> have made. Can you please help me with this.
> 
> Thanks,
> Jagadeesh.
> 
> > Regards,
> > Jian
> >
> >
> > > -----Original Message-----
> > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> > > Jagadeesh Ujja
> > > Sent: Friday, December 14, 2018 8:13 PM
> > > To: edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>; Zhang,
> Chao
> > > B <chao.b.zhang@intel.com>; leif.lindholm@linaro.org;
> > > ard.biesheuvel@linaro.org
> > > Subject: [edk2] [PATCH 00/13] Extend secure variable service to be usable
> from
> > > Standalone MM
> > >
> > > Changes since RFC v4:
> > > - Addressed all the comments from Liming Gao
> > >   - Added an additional PCD 'PcdStandaloneMmCodeEnabled' to indicate
> > >     presence of StandaloneMM support.
> > >   - MdePkg.dec file updated to include StandaloneMmServiceTableLib and
> > >     StandaloneMmRuntimeDxe library.
> > >   - Platform specific changes will be posted in a seperate patchset.
> > >   - AsmLfence wrapper function is supported for AArch64 platforms.
> > >   - All the patches in this series can be pulled from
> > >     https://github.com/jagadeeshujja/edk2 (branch:
> topics/aarch64_secure_vars)
> > >
> > > Changes since RFC v3:
> > > - Addressed all the comments from Liming Gao
> > >   - Added a AArch64 implementation of AsmLfence which is a wrapper for
> > >     MemoryFence. The changes in variable service driver in v3 of this
> > >     patchset that used MemoryFence instead of AsmLfence have been
> removed.
> > >   - Added StandaloneMmServicesTableLib.h and StandaloneMmRuntimeDxe
> > >     library into MdePkg.
> > >   - Renamed PcdStandaloneMmEnable as PcdStandaloneMmVariableEnabled
> and
> > >     added to in to MdePkg.
> > >   - Now with above changes, edk2 packages don't need to depend on
> > >     StandaloneMmPkg/StandaloneMmPkg.dec
> > > - Addressed comments from Ting Ye
> > >   - Removed the hacks in the v3 version.
> > >   - Will relook into the “TimerWrapp.c” file and add a appropriate
> > >     implementation of this for MM Standalone mode code.
> > >
> > > Changes since RFC v2:
> > > - Added 'Contributed-under' tag, removed Change-ID tag and
> > >   maintained a single signed-off-by for the all the patches.
> > >
> > > Changes since RFC v1:
> > > - Addressed all the comments from Liming Gao
> > >   - Removed the use of #ifdef/#else/#endif and used a Pcd instead to
> > >     select between MM and non-MM paths.
> > >   - Removed all dependencies on edk2-platforms.
> > >   - Dropped the use of mMmst and used gSmst instead.
> > >   - Added a dummy implementation UefiRuntimeServiceTableLib for
> > >     MM_STANDALONE usage
> > > - Replaced all uses of AsmLfence with MemoryFence from variable
> > >   service code.
> > > - Add a new StandaloneMmRuntimeDxe library to for use by non-MM code.
> > >
> > > This patch series extends the existing secure variable service support for
> > > use with Standalone MM. This is applicable to paltforms that use Standalone
> > > Management Mode to protect access to non-volatile memory (NOR flash in
> case
> > > of these patches) used to store the secure EFI variables.
> > >
> > > The first patch pulls in additional libraries from the staging branch of
> > > StandaloneMmPkg into the edk2's StandaloneMmPkg. The existing secure
> > > variable
> > > service implementation supports only the traditional MM mode and so the
> rest
> > > of the patches extends the existing secure variable service support to be
> > > useable with Standalone MM mode as well.
> > >
> > > Jagadeesh Ujja (13):
> > >   StandaloneMmPkg: Pull in additonal libraries from staging branch
> > >   MdePkg: Add a PCD that indicates presence of Standalone MM mode
> > >   MdeModulePkg: Add a PCD to indicate Standalone MM supports secure
> > >     variable
> > >   MdePkg/Include: add StandaloneMmServicesTableLib header file
> > >   MdePkg/Library/BaseLib/AArch64: Add AsmLfence function
> > >   MdePkg/Library: Add StandaloneMmRuntimeDxe library
> > >   MdeModulePkg/FaultTolerantWriteDxe: allow reusability as a MM driver
> > >   MdeModulePkg/Variable/RuntimeDxe: adapt for usability with MM
> > >     Standalone
> > >   MdeModulePkg/Variable/RuntimeDxe: adapt as a MM Standalone driver
> > >   MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this
> > >     library
> > >   ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver
> > >   SecurityPkg/AuthVariableLib: allow MM_STANDALONE drivers to use this
> > >     library
> > >   CryptoPkg/BaseCryptLib: allow MM_STANDALONE drivers to use this
> > >     library
> > >
> > >  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c
> > > |   2 +-
> > >  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c
> |
> > > 210 ++++-
> > >  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h
> |
> > > 5 +-
> > >  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
> |
> > > 2 +
> > >  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c
> > > |  96 +--
> > >  ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
> > > |  76 ++
> > >  CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf                                             |
> 7
> > > +-
> > >  CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
> |   4
> > > +
> > >  CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
> |
> > > 15 +-
> > >  MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
> |
> > > 5 +-
> > >  MdeModulePkg/MdeModulePkg.dec                                                               |   5
> +
> > >
> MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
> > > |   1 +
> > >
> MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
> > > | 203 +++--
> > >
> > >
> MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandalon
> > > eMm.inf             | 101 +++
> > >  MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c
> > > |  27 +-
> > >  MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
> > > |  37 +-
> > >  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> > > |   1 +
> > >  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
> > > | 201 ++++-
> > >  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
> > > |  31 +-
> > >
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
> > > |   3 +
> > >  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
> > > | 132 ++++
> > >  MdePkg/Include/Library/BaseLib.h                                                            |  33 +-
> > >  MdePkg/Include/Library/StandaloneMmRuntimeDxe.h
> > > |  39 +
> > >  MdePkg/Include/Library/StandaloneMmServicesTableLib.h
> > > |  25 +
> > >  MdePkg/Library/BaseLib/AArch64/AsmLfence.S                                                  |
> 42
> > > +
> > >  MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> |
> > > 41 +
> > >  MdePkg/Library/BaseLib/BaseLib.inf                                                          |   2 +
> > >  MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c
> > > |  36 +
> > >  MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf
> > > |  36 +
> > >  MdePkg/MdePkg.dec                                                                           |  12 +
> > >  SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
> |
> > > 5 +-
> > >
> > >
> StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHob
> > > Lib.inf                   |   2 +-
> > >
> > >
> StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmCore
> > > HobLibInternal.c         |  64 ++
> > >  StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
> > > | 655 ++++++++++++++++
> > >  StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
> > > |  48 ++
> > >
> > >
> StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMm
> > > MemoryAllocationLib.c   | 824 ++++++++++++++++++++
> > >
> > >
> StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMm
> > > MemoryAllocationLib.inf |  45 ++
> > >
> > >
> StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServi
> > > cesTableLib.c         |  64 ++
> > >
> > >
> StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServi
> > > cesTableLib.inf       |  36 +
> > >  39 files changed, 2929 insertions(+), 244 deletions(-)
> > >  create mode 100644
> > > ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
> > >  create mode 100644
> > >
> MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandalon
> > > eMm.inf
> > >  create mode 100644
> > > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
> > >  create mode 100644 MdePkg/Include/Library/StandaloneMmRuntimeDxe.h
> > >  create mode 100644
> MdePkg/Include/Library/StandaloneMmServicesTableLib.h
> > >  create mode 100644 MdePkg/Library/BaseLib/AArch64/AsmLfence.S
> > >  create mode 100644 MdePkg/Library/BaseLib/AArch64/AsmLfence.asm
> > >  create mode 100644
> > > MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c
> > >  create mode 100644
> > > MdePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf
> > >  create mode 100644
> > >
> StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmCore
> > > HobLibInternal.c
> > >  create mode 100644
> > > StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
> > >  create mode 100644
> > > StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
> > >  create mode 100644
> > >
> StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMm
> > > MemoryAllocationLib.c
> > >  create mode 100644
> > >
> StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMm
> > > MemoryAllocationLib.inf
> > >  create mode 100644
> > >
> StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServi
> > > cesTableLib.c
> > >  create mode 100644
> > >
> StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServi
> > > cesTableLib.inf
> > >
> > > --
> > > 2.7.4
> > >
> > > _______________________________________________
> > > edk2-devel mailing list
> > > edk2-devel@lists.01.org
> > > https://lists.01.org/mailman/listinfo/edk2-devel
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://lists.01.org/mailman/listinfo/edk2-devel

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 00/13] Extend secure variable service to be usable from Standalone MM
  2019-01-02 17:15           ` Ard Biesheuvel
@ 2019-01-03  7:43             ` Jagadeesh Ujja
  2019-01-03  9:52               ` Ard Biesheuvel
  0 siblings, 1 reply; 52+ messages in thread
From: Jagadeesh Ujja @ 2019-01-03  7:43 UTC (permalink / raw)
  To: Ard Biesheuvel; +Cc: Gao, Liming, edk2-devel@lists.01.org, Zhang, Chao B

hi Ard

On Wed, Jan 2, 2019 at 10:45 PM Ard Biesheuvel
<ard.biesheuvel@linaro.org> wrote:
>
> On Thu, 20 Dec 2018 at 15:23, Gao, Liming <liming.gao@intel.com> wrote:
> >
> > Jagadeesh:
> >   MdeModulePkg Variable service/Fault tolerant/Nor Flash driver depends on StandaloneMmServicesTableLib library class header file. This header file is added into MdePkg. It has two interfaces. One is global gMmst, another is function InMm(). So, there is no dependency issue here.
> > And, MdePkg adds one StandaloneMmServicesTableLib library INF with empty implementation, this library is just for build. It sets gMmst=NULL, and always return FASLE in InMm(). This library can be used in MdeModulePkg.dsc to make Variable driver pass build. There is also no dependency issue here. Last, Platform DSC file will refer to the real StandaloneMmServicesTableLib library INF from StandaloneMmPkg.
> >
>
> I think we should avoid the need for InMm() altogether for standalone
> MM. It will always return TRUE for standalone MM modules, and it will
> always return FALSE for other modules, so the distinction should be
> made at build time.
>
> This means that we need to refactor the SMM 'server' modules and/or
> libraries so that any code they cannot share (like boot services
> invocations) are only included in the classic SMM versions.
>
> I have pushed my own prototype code here:
> https://github.com/ardbiesheuvel/edk2/commits/standalone-mm
>
> There is some overlap with Jagadeesh's work. I will work with him
> directly to resolve this before posting any new revisions.
>
InMm()”  and “PcdStandaloneMmVariableEnabled” are defined to reuse the
existing code as much as possible.
Initially I have done separate copy of the file to avoid “if..else”
but had a comment about “duplicating code primarily due to the
maintenance overhead”

So we are using “InMm()” and “PcdStandaloneMmVariableEnabled” PCD flag
and trying to use the same code as much as possible.

The patchset “Extend secure variable service to be usable from
Standalone MM” as POC was submitted as RFC patches on “October 31,
2018”.
Subsequent comments are fixed and we had 7 version of the patch set
under review.

Thanks
Jagadeesh
____________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 00/13] Extend secure variable service to be usable from Standalone MM
  2019-01-03  7:43             ` Jagadeesh Ujja
@ 2019-01-03  9:52               ` Ard Biesheuvel
  2019-01-03 10:35                 ` Ard Biesheuvel
  0 siblings, 1 reply; 52+ messages in thread
From: Ard Biesheuvel @ 2019-01-03  9:52 UTC (permalink / raw)
  To: Jagadeesh Ujja; +Cc: Gao, Liming, edk2-devel@lists.01.org, Zhang, Chao B

On Thu, 3 Jan 2019 at 08:43, Jagadeesh Ujja <jagadeesh.ujja@arm.com> wrote:
>
> hi Ard
>
> On Wed, Jan 2, 2019 at 10:45 PM Ard Biesheuvel
> <ard.biesheuvel@linaro.org> wrote:
> >
> > On Thu, 20 Dec 2018 at 15:23, Gao, Liming <liming.gao@intel.com> wrote:
> > >
> > > Jagadeesh:
> > >   MdeModulePkg Variable service/Fault tolerant/Nor Flash driver depends on StandaloneMmServicesTableLib library class header file. This header file is added into MdePkg. It has two interfaces. One is global gMmst, another is function InMm(). So, there is no dependency issue here.
> > > And, MdePkg adds one StandaloneMmServicesTableLib library INF with empty implementation, this library is just for build. It sets gMmst=NULL, and always return FASLE in InMm(). This library can be used in MdeModulePkg.dsc to make Variable driver pass build. There is also no dependency issue here. Last, Platform DSC file will refer to the real StandaloneMmServicesTableLib library INF from StandaloneMmPkg.
> > >
> >
> > I think we should avoid the need for InMm() altogether for standalone
> > MM. It will always return TRUE for standalone MM modules, and it will
> > always return FALSE for other modules, so the distinction should be
> > made at build time.
> >
> > This means that we need to refactor the SMM 'server' modules and/or
> > libraries so that any code they cannot share (like boot services
> > invocations) are only included in the classic SMM versions.
> >
> > I have pushed my own prototype code here:
> > https://github.com/ardbiesheuvel/edk2/commits/standalone-mm
> >
> > There is some overlap with Jagadeesh's work. I will work with him
> > directly to resolve this before posting any new revisions.
> >
> InMm()”  and “PcdStandaloneMmVariableEnabled” are defined to reuse the
> existing code as much as possible.
> Initially I have done separate copy of the file to avoid “if..else”
> but had a comment about “duplicating code primarily due to the
> maintenance overhead”
>

We shouldn't rely on runtime functions and PCDs to make build time decision.

Lots of the SMM code can be refactored. As Jian suggested, we could
introduce a helper library with implementations for the MM protocol
handling and memory allocation routines exposed via the system table,
so that the users can invoke the abstract library.

As for the various boot services calls: these just have to be factored
out or replaced.
- gBS->CalculcateCrc32 () in the FTW driver can just be replaced with
the version from BaseLib (but only for the standalone MM version)
- MorLockInitAtEndOfDxe() in the variable driver attempts to locate
some TCG protocols to infer whether the variable may have been set by
platform firmware, this code just needs to be dropped in the
standalone MM version
- the ArmPkg NOR flash driver needs some refactoring in any case,
since all the block I/O and disk I/O routines can be dropped for
standalone MM.

So of course, we have to take the maintenance burden into account, and
so we have to refactor carefully so that we share as much code as
possible. But relying on InMm() and PCDs is not acceptable.

> So we are using “InMm()” and “PcdStandaloneMmVariableEnabled” PCD flag
> and trying to use the same code as much as possible.
>
> The patchset “Extend secure variable service to be usable from
> Standalone MM” as POC was submitted as RFC patches on “October 31,
> 2018”.
> Subsequent comments are fixed and we had 7 version of the patch set
> under review.
>

I'm not sure why you are bringing this up, but it is irrelevant. This
is important stuff that touches a lot of different packages, so if it
takes 20 revisions, so be it.


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 00/13] Extend secure variable service to be usable from Standalone MM
  2019-01-03  9:52               ` Ard Biesheuvel
@ 2019-01-03 10:35                 ` Ard Biesheuvel
  0 siblings, 0 replies; 52+ messages in thread
From: Ard Biesheuvel @ 2019-01-03 10:35 UTC (permalink / raw)
  To: Jagadeesh Ujja; +Cc: Gao, Liming, edk2-devel@lists.01.org, Zhang, Chao B

On Thu, 3 Jan 2019 at 10:52, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>
> On Thu, 3 Jan 2019 at 08:43, Jagadeesh Ujja <jagadeesh.ujja@arm.com> wrote:
> >
> > hi Ard
> >
> > On Wed, Jan 2, 2019 at 10:45 PM Ard Biesheuvel
> > <ard.biesheuvel@linaro.org> wrote:
> > >
> > > On Thu, 20 Dec 2018 at 15:23, Gao, Liming <liming.gao@intel.com> wrote:
> > > >
> > > > Jagadeesh:
> > > >   MdeModulePkg Variable service/Fault tolerant/Nor Flash driver depends on StandaloneMmServicesTableLib library class header file. This header file is added into MdePkg. It has two interfaces. One is global gMmst, another is function InMm(). So, there is no dependency issue here.
> > > > And, MdePkg adds one StandaloneMmServicesTableLib library INF with empty implementation, this library is just for build. It sets gMmst=NULL, and always return FASLE in InMm(). This library can be used in MdeModulePkg.dsc to make Variable driver pass build. There is also no dependency issue here. Last, Platform DSC file will refer to the real StandaloneMmServicesTableLib library INF from StandaloneMmPkg.
> > > >
> > >
> > > I think we should avoid the need for InMm() altogether for standalone
> > > MM. It will always return TRUE for standalone MM modules, and it will
> > > always return FALSE for other modules, so the distinction should be
> > > made at build time.
> > >
> > > This means that we need to refactor the SMM 'server' modules and/or
> > > libraries so that any code they cannot share (like boot services
> > > invocations) are only included in the classic SMM versions.
> > >
> > > I have pushed my own prototype code here:
> > > https://github.com/ardbiesheuvel/edk2/commits/standalone-mm
> > >
> > > There is some overlap with Jagadeesh's work. I will work with him
> > > directly to resolve this before posting any new revisions.
> > >
> > InMm()”  and “PcdStandaloneMmVariableEnabled” are defined to reuse the
> > existing code as much as possible.
> > Initially I have done separate copy of the file to avoid “if..else”
> > but had a comment about “duplicating code primarily due to the
> > maintenance overhead”
> >
>
> We shouldn't rely on runtime functions and PCDs to make build time decision.
>
> Lots of the SMM code can be refactored. As Jian suggested, we could
> introduce a helper library with implementations for the MM protocol
> handling and memory allocation routines exposed via the system table,
> so that the users can invoke the abstract library.
>

Actually, looking at the PI spec, it seems that SMM is deprecated, and
so we should port these drivers to the new MM system table entirely.


^ permalink raw reply	[flat|nested] 52+ messages in thread

end of thread, other threads:[~2019-01-03 10:36 UTC | newest]

Thread overview: 52+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-12-14 12:13 [PATCH 00/13] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
2018-12-14 12:13 ` [PATCH 01/13] StandaloneMmPkg: Pull in additonal libraries from staging branch Jagadeesh Ujja
2018-12-21  8:58   ` Ard Biesheuvel
2018-12-14 12:13 ` [PATCH 02/13] MdePkg: Add a PCD that indicates presence of Standalone MM mode Jagadeesh Ujja
2018-12-21  9:13   ` Ard Biesheuvel
2018-12-14 12:13 ` [PATCH 03/13] MdeModulePkg: Add a PCD to indicate Standalone MM supports secure variable Jagadeesh Ujja
2018-12-21  9:13   ` Ard Biesheuvel
2018-12-14 12:13 ` [PATCH 04/13] MdePkg/Include: add StandaloneMmServicesTableLib header file Jagadeesh Ujja
2018-12-14 12:13 ` [PATCH 05/13] MdePkg/Library/BaseLib/AArch64: Add AsmLfence function Jagadeesh Ujja
2018-12-14 13:53   ` Ard Biesheuvel
2018-12-17  2:04     ` Gao, Liming
2018-12-17  3:29       ` Yao, Jiewen
2018-12-17  7:45         ` Ard Biesheuvel
2018-12-17  8:10           ` Ard Biesheuvel
2018-12-17  8:24             ` Yao, Jiewen
2018-12-17  8:30               ` Yao, Jiewen
2018-12-17  8:35                 ` Ard Biesheuvel
2018-12-17  8:44                   ` Yao, Jiewen
2018-12-17  9:27                     ` Ard Biesheuvel
2018-12-18  2:08                       ` Yao, Jiewen
2018-12-18  2:12                         ` Gao, Liming
2018-12-18  2:19                           ` Yao, Jiewen
2018-12-20  9:00                         ` Jagadeesh Ujja
2018-12-20  9:10                           ` Ard Biesheuvel
2018-12-14 12:13 ` [PATCH 06/13] MdePkg/Library: Add StandaloneMmRuntimeDxe library Jagadeesh Ujja
2018-12-14 12:13 ` [PATCH 07/13] MdeModulePkg/FaultTolerantWriteDxe: allow reusability as a MM driver Jagadeesh Ujja
2018-12-14 12:13 ` [PATCH 08/13] MdeModulePkg/Variable/RuntimeDxe: adapt for usability with MM Standalone Jagadeesh Ujja
2018-12-14 12:13 ` [PATCH 09/13] MdeModulePkg/Variable/RuntimeDxe: adapt as a MM Standalone driver Jagadeesh Ujja
2018-12-14 12:13 ` [PATCH 10/13] MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this library Jagadeesh Ujja
2019-01-02 13:05   ` Ard Biesheuvel
2019-01-02 13:23     ` Gao, Liming
2019-01-02 14:23       ` Ard Biesheuvel
2019-01-02 16:54         ` Ard Biesheuvel
2019-01-02 13:27     ` Jagadeesh Ujja
2018-12-14 12:13 ` [PATCH 11/13] ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver Jagadeesh Ujja
2018-12-21 11:07   ` Ard Biesheuvel
2018-12-14 12:13 ` [PATCH 12/13] SecurityPkg/AuthVariableLib: allow MM_STANDALONE drivers to use this library Jagadeesh Ujja
2019-01-02 13:05   ` Ard Biesheuvel
2018-12-14 12:13 ` [PATCH 13/13] CryptoPkg/BaseCryptLib: " Jagadeesh Ujja
2018-12-21 10:13   ` Ard Biesheuvel
2018-12-17  1:45 ` [PATCH 00/13] Extend secure variable service to be usable from Standalone MM Gao, Liming
2018-12-17 11:46   ` Jagadeesh Ujja
2018-12-18  4:37     ` Gao, Liming
2018-12-18 11:19       ` Jagadeesh Ujja
2018-12-20 14:23         ` Gao, Liming
2019-01-02 17:15           ` Ard Biesheuvel
2019-01-03  7:43             ` Jagadeesh Ujja
2019-01-03  9:52               ` Ard Biesheuvel
2019-01-03 10:35                 ` Ard Biesheuvel
2018-12-21  2:57 ` Wang, Jian J
2019-01-02 13:19   ` Jagadeesh Ujja
2019-01-03  2:37     ` Wang, Jian J

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox