public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH 0/2] Improve hibernation safety
@ 2021-02-18 20:09 Alexander Graf
  2021-02-18 20:09 ` [PATCH 1/2] MdeModulePkg/Core/Dxe: Allow to force runtime allocations at separate range Alexander Graf
  2021-02-18 20:09 ` [PATCH 2/2] OvmfPkg: Make hibernation critical allocations at own ranges Alexander Graf
  0 siblings, 2 replies; 7+ messages in thread
From: Alexander Graf @ 2021-02-18 20:09 UTC (permalink / raw)
  To: devel
  Cc: Leif Lindholm, Laszlo Ersek, Ard Biesheuvel, Jordan Justen,
	David Woodhouse, Hendrik Borghorst

Operating Systems that get hibernated expect all non-boot-time allocations
to be identical before and after hibernation.

In edk2, we create pools and allocate pages starting from the highest
allowed address for the allocation, usually 0xFFFFFFFF. Typically, that
means we allocate a few pages of boot time data, then a few pages of
runtime data, then another few pages of boot time data and again runtime
data. Every allocation has direct impact on the following allocations.

The problem with this scheme is that small code changes in boot time code
already can have significant impact on runtime allocations, which then
break hibernation.

This patch set adds a mechanism to set an upper bound to dynamic memory
allocations for different allocation types. This allows us to move data
that has to stay at the same place across firmware changes at the same
place. The patch set also enables this on OVMF by default.

Alex

Alexander Graf (2):
  MdeModulePkg/Core/Dxe: Allow to force runtime allocations at separate
    range
  OvmfPkg: Make hibernation critical allocations at own ranges

 MdeModulePkg/Core/Dxe/DxeMain.inf |  4 +++
 MdeModulePkg/Core/Dxe/Mem/Page.c  | 70 +++++++++++++++++++++++++++++++++++++++
 MdeModulePkg/MdeModulePkg.dec     | 16 +++++++++
 MdeModulePkg/MdeModulePkg.uni     | 12 +++++++
 OvmfPkg/OvmfPkgIa32.dsc           |  6 ++++
 OvmfPkg/OvmfPkgIa32X64.dsc        |  6 ++++
 OvmfPkg/OvmfPkgX64.dsc            |  6 ++++
 7 files changed, 120 insertions(+)

-- 
2.16.4




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879




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

* [PATCH 1/2] MdeModulePkg/Core/Dxe: Allow to force runtime allocations at separate range
  2021-02-18 20:09 [PATCH 0/2] Improve hibernation safety Alexander Graf
@ 2021-02-18 20:09 ` Alexander Graf
  2021-02-18 22:28   ` [edk2-devel] " Michael D Kinney
  2021-02-18 20:09 ` [PATCH 2/2] OvmfPkg: Make hibernation critical allocations at own ranges Alexander Graf
  1 sibling, 1 reply; 7+ messages in thread
From: Alexander Graf @ 2021-02-18 20:09 UTC (permalink / raw)
  To: devel
  Cc: Leif Lindholm, Laszlo Ersek, Ard Biesheuvel, Jordan Justen,
	David Woodhouse, Hendrik Borghorst

Operating Systems that get hibernated expect all non-boot-time allocations
to be identical before and after hibernation.

In edk2, we create pools and allocate pages starting from the highest
allowed address for the allocation, usually 0xFFFFFFFF. Typically, that
means we allocate a few pages of boot time data, then a few pages of
runtime data, then another few pages of boot time data and again runtime
data. Every allocation has direct impact on the following allocations.

The problem with this scheme is that small code changes in boot time code
already can have significant impact on runtime allocations, which then
break hibernation.

This patch adds a mechanism to override the MaxAddress for runtime
allocations with a target defined Pcd value. With this feature enabled,
we can have different allocation ranges for runtime and boot time
allocations.

This allows us to determine at boot time whether to load an old,
hibernation compatible runtime allocation path or a new, hibernation
unsafe runtime allocation. All within the same edk2 target binary.
It also allows us to modify boot time behavior, such as modifying
buffer allocation mechanisms without compromising on hibernation safety.

Signed-off-by: Alexander Graf <graf@amazon.com>
---
 MdeModulePkg/Core/Dxe/DxeMain.inf |  4 +++
 MdeModulePkg/Core/Dxe/Mem/Page.c  | 70 +++++++++++++++++++++++++++++++++++++++
 MdeModulePkg/MdeModulePkg.dec     | 16 +++++++++
 MdeModulePkg/MdeModulePkg.uni     | 12 +++++++
 4 files changed, 102 insertions(+)

diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf
index e4bca89577..0696246970 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.inf
+++ b/MdeModulePkg/Core/Dxe/DxeMain.inf
@@ -186,6 +186,10 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask                   ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                           ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdFwVolDxeMaxEncapsulationDepth           ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIReclaimMemory             ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIMemoryNVS                 ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesCode        ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesData        ## CONSUMES
 
 # [Hob]
 # RESOURCE_DESCRIPTOR   ## CONSUMES
diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c
index 731bf08bc9..91599adccb 100644
--- a/MdeModulePkg/Core/Dxe/Mem/Page.c
+++ b/MdeModulePkg/Core/Dxe/Mem/Page.c
@@ -1007,6 +1007,74 @@ CoreUpdateMemoryAttributes (
   CoreReleaseMemoryLock ();
 }
 
+UINT64
+EnforceMaxAddress (
+  IN UINT64           MaxAddress,
+  IN EFI_MEMORY_TYPE  NewType,
+  IN UINT64           NumberOfPages
+  )
+{
+  UINT64     NumberOfBytes = LShiftU64 (NumberOfPages, EFI_PAGE_SHIFT);
+  UINT64     LowestPossible = MaxAddress;
+  UINT64     ForceMaxAddress;
+  LIST_ENTRY *Link;
+  MEMORY_MAP *Entry;
+
+  switch (NewType) {
+  case EfiACPIReclaimMemory:
+    ForceMaxAddress = PcdGet64(PcdEnforceMaxACPIReclaimMemory);
+    break;
+  case EfiACPIMemoryNVS:
+    ForceMaxAddress = PcdGet64(PcdEnforceMaxACPIMemoryNVS);
+    break;
+  case EfiRuntimeServicesCode:
+    ForceMaxAddress = PcdGet64(PcdEnforceMaxEfiRuntimeServicesCode);
+    break;
+  case EfiRuntimeServicesData:
+    ForceMaxAddress = PcdGet64(PcdEnforceMaxEfiRuntimeServicesData);
+    break;
+  default:
+    ForceMaxAddress = MaxAddress;
+    break;
+  }
+
+  //
+  // The currently requested address already fits our forced max constraint?
+  // Great, let's use that then.
+  //
+  if (ForceMaxAddress >= MaxAddress) {
+    return MaxAddress;
+  }
+
+  //
+  // Check if the allocation would fit. If not, don't force it.
+  //
+  for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) {
+    Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
+
+    //
+    // If it's not a free entry, don't bother with it
+    //
+    if (Entry->Type != EfiConventionalMemory) {
+      continue;
+    }
+
+    if ((Entry->Start < LowestPossible) &&
+        ((Entry->End - Entry->Start) >= NumberOfBytes)) {
+      LowestPossible = Entry->End;
+    }
+  }
+  DEBUG ((DEBUG_ERROR | DEBUG_PAGE, "Force=%lx Lowest=%lx Max=%lx\n", ForceMaxAddress, LowestPossible, MaxAddress));
+
+  //
+  // We don't have free RAM available in the desired target area? Bail out!
+  //
+  if (ForceMaxAddress < LowestPossible) {
+    return MaxAddress;
+  }
+
+  return ForceMaxAddress;
+}
 
 /**
   Internal function. Finds a consecutive free page range below
@@ -1041,6 +1109,8 @@ CoreFindFreePagesI (
   LIST_ENTRY      *Link;
   MEMORY_MAP      *Entry;
 
+  MaxAddress = EnforceMaxAddress(MaxAddress, NewType, NumberOfPages);
+
   if ((MaxAddress < EFI_PAGE_MASK) ||(NumberOfPages == 0)) {
     return 0;
   }
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 1483955110..cbad48af5e 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -1535,6 +1535,22 @@
   # @Prompt Maximum permitted FwVol section nesting depth (exclusive).
   gEfiMdeModulePkgTokenSpaceGuid.PcdFwVolDxeMaxEncapsulationDepth|0x10|UINT32|0x00000030
 
+  ## Maximum address that a dynamic EfiACPIReclaimMemory allocation can be requested at
+  # @Prompt Maximum address for EfiACPIReclaimMemory allocations
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIReclaimMemory|0xFFFFFFFFFFFFFFFF|UINT64|0x30001016
+
+  ## Maximum address that a dynamic EfiACPIMemoryNVS allocation can be requested at
+  # @Prompt Maximum address for EfiACPIMemoryNVS allocations
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIMemoryNVS|0xFFFFFFFFFFFFFFFF|UINT64|0x30001017
+
+  ## Maximum address that a dynamic EfiRuntimeServicesCode allocation can be requested at
+  # @Prompt Maximum address for EfiRuntimeServicesCode allocations
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesCode|0xFFFFFFFFFFFFFFFF|UINT64|0x30001018
+
+  ## Maximum address that a dynamic EfiRuntimeServicesData allocation can be requested at
+  # @Prompt Maximum address for EfiRuntimeServicesData allocations
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesData|0xFFFFFFFFFFFFFFFF|UINT64|0x30001019
+
 [PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
   ## This PCD defines the Console output row. The default value is 25 according to UEFI spec.
   #  This PCD could be set to 0 then console output would be at max column and max row.
diff --git a/MdeModulePkg/MdeModulePkg.uni b/MdeModulePkg/MdeModulePkg.uni
index ef9f4d97b9..0dc5c1960b 100644
--- a/MdeModulePkg/MdeModulePkg.uni
+++ b/MdeModulePkg/MdeModulePkg.uni
@@ -1330,3 +1330,15 @@
 #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdPcieResizableBarSupport_HELP #language en-US "Indicates if the PCIe Resizable BAR Capability Supported.<BR><BR>\n"
                                                                                             "TRUE  - PCIe Resizable BAR Capability is supported.<BR>\n"
                                                                                             "FALSE - PCIe Resizable BAR Capability is not supported.<BR>"
+
+#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIReclaimMemory_PROMPT #language en-US "Maximum address for EfiACPIReclaimMemory allocations"
+#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIReclaimMemory_HELP #language en-US "Maximum address that a dynamic EfiACPIReclaimMemory allocation can be requested at"
+
+#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIMemoryNVS_PROMPT #language en-US "Maximum address for EfiACPIMemoryNVS allocations"
+#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIMemoryNVS_HELP #language en-US "Maximum address that a dynamic EfiACPIMemoryNVS allocation can be requested at"
+
+#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesCode_PROMPT #language en-US "Maximum address for EfiRuntimeServicesCode allocations"
+#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesCode_HELP #language en-US "Maximum address that a dynamic EfiRuntimeServicesCode allocation can be requested at"
+
+#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesData_PROMPT #language en-US "Maximum address for EfiRuntimeServicesData allocations"
+#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesData_HELP #language en-US "Maximum address that a dynamic EfiRuntimeServicesData allocation can be requested at"
-- 
2.16.4




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879




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

* [PATCH 2/2] OvmfPkg: Make hibernation critical allocations at own ranges
  2021-02-18 20:09 [PATCH 0/2] Improve hibernation safety Alexander Graf
  2021-02-18 20:09 ` [PATCH 1/2] MdeModulePkg/Core/Dxe: Allow to force runtime allocations at separate range Alexander Graf
@ 2021-02-18 20:09 ` Alexander Graf
  1 sibling, 0 replies; 7+ messages in thread
From: Alexander Graf @ 2021-02-18 20:09 UTC (permalink / raw)
  To: devel
  Cc: Leif Lindholm, Laszlo Ersek, Ard Biesheuvel, Jordan Justen,
	David Woodhouse, Hendrik Borghorst

Now that we have a framework available to set memory ranges for
allocations that break hibernation if they move, let's push them
to their own respective memory ranges. This way, they will be
unaffected by boot time data allocation changes and we can thus
still resume hibernated systems.

Signed-off-by: Alexander Graf <graf@amazon.com>
---
 OvmfPkg/OvmfPkgIa32.dsc    | 6 ++++++
 OvmfPkg/OvmfPkgIa32X64.dsc | 6 ++++++
 OvmfPkg/OvmfPkgX64.dsc     | 6 ++++++
 3 files changed, 18 insertions(+)

diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 1b8d34052b..afea65254d 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -575,6 +575,12 @@
   # Point to the MdeModulePkg/Application/UiApp/UiApp.inf
   gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
 
+  # Simplify hibernation safety by putting relevant data into its own memory ranges
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIReclaimMemory|0x19000000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIMemoryNVS|0x19100000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesCode|0x19200000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesData|0x19300000
+
 ################################################################################
 #
 # Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 9c1aee87e7..4d1334554a 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -581,6 +581,12 @@
   # Point to the MdeModulePkg/Application/UiApp/UiApp.inf
   gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
 
+  # Simplify hibernation safety by putting relevant data into its own memory ranges
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIReclaimMemory|0x19000000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIMemoryNVS|0x19100000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesCode|0x19200000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesData|0x19300000
+
 ################################################################################
 #
 # Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index fabb8b2f29..22cdf71f1e 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -581,6 +581,12 @@
   # Point to the MdeModulePkg/Application/UiApp/UiApp.inf
   gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
 
+  # Simplify hibernation safety by putting relevant data into its own memory ranges
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIReclaimMemory|0x19000000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIMemoryNVS|0x19100000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesCode|0x19200000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesData|0x19300000
+
 ################################################################################
 #
 # Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
-- 
2.16.4




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879




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

* Re: [edk2-devel] [PATCH 1/2] MdeModulePkg/Core/Dxe: Allow to force runtime allocations at separate range
  2021-02-18 20:09 ` [PATCH 1/2] MdeModulePkg/Core/Dxe: Allow to force runtime allocations at separate range Alexander Graf
@ 2021-02-18 22:28   ` Michael D Kinney
  2021-02-19 14:10     ` Alexander Graf
  0 siblings, 1 reply; 7+ messages in thread
From: Michael D Kinney @ 2021-02-18 22:28 UTC (permalink / raw)
  To: devel@edk2.groups.io, graf@amazon.com, Kinney, Michael D
  Cc: Leif Lindholm, Laszlo Ersek, Ard Biesheuvel, Justen, Jordan L,
	Woodhouse, David, Hendrik Borghorst

Hi Alex,

This feature is already available from the DXE Core using the MemoryTypeInformation and was
specifically added to support hibernation use case.

There is an optional HOB that is passed into DXE Core that can provide bin sizes for any supported memory types.  Not just Runtime and ACPI.

This feature can use a fixed HOB or use a dynamic HOB from a UEFI Variable, so that changes in the memory usage of 
the critical memory types for hibernation can be tracked and stored in the UEFI Variables and be used to populate
the HOB.  It is a platform choice to use fixed or dynamic HOB.

https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Include/Guid/MemoryTypeInformation.h

https://github.com/tianocore/edk2/blob/978b9d511f5b9cb7bc5b09749f86c39bec51525d/MdeModulePkg/Core/Dxe/Gcd/Gcd.c#L2233

https://github.com/tianocore/edk2/blob/978b9d511f5b9cb7bc5b09749f86c39bec51525d/MdeModulePkg/Core/Dxe/Mem/Page.c#L45

The DXE Core use the HOB to pre-allocate bins for the memory types and do allocations from those bins.

The UEFI Memory Map provides an entry for the entire bin (no just the allocated space), so small
differences in allocations from boot to boot do not change the UEFI memory map.  This also
reduces the total number of memory map entries in the UEFI memory map.

If dynamic HOB is used, then the Boot Manager compares the actual memory usage to the HOB.
If the usage is larger or smaller by more than a threshold, then the UEFI Variable is
updated.  The platform has the choice to reboot or continue booting after this UEIF Variable
update based on a PCD.  The reboot can help make sure the first boot to the OS has the right
bin sizes to support future hibernate boot flows.


Mike

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Alexander Graf via groups.io
> Sent: Thursday, February 18, 2021 12:10 PM
> To: devel@edk2.groups.io
> Cc: Leif Lindholm <leif@nuviainc.com>; Laszlo Ersek <lersek@redhat.com>; Ard Biesheuvel <ardb+tianocore@kernel.org>;
> Justen, Jordan L <jordan.l.justen@intel.com>; Woodhouse, David <dwmw@amazon.co.uk>; Hendrik Borghorst <hborghor@amazon.de>
> Subject: [edk2-devel] [PATCH 1/2] MdeModulePkg/Core/Dxe: Allow to force runtime allocations at separate range
> 
> Operating Systems that get hibernated expect all non-boot-time allocations
> to be identical before and after hibernation.
> 
> In edk2, we create pools and allocate pages starting from the highest
> allowed address for the allocation, usually 0xFFFFFFFF. Typically, that
> means we allocate a few pages of boot time data, then a few pages of
> runtime data, then another few pages of boot time data and again runtime
> data. Every allocation has direct impact on the following allocations.
> 
> The problem with this scheme is that small code changes in boot time code
> already can have significant impact on runtime allocations, which then
> break hibernation.
> 
> This patch adds a mechanism to override the MaxAddress for runtime
> allocations with a target defined Pcd value. With this feature enabled,
> we can have different allocation ranges for runtime and boot time
> allocations.
> 
> This allows us to determine at boot time whether to load an old,
> hibernation compatible runtime allocation path or a new, hibernation
> unsafe runtime allocation. All within the same edk2 target binary.
> It also allows us to modify boot time behavior, such as modifying
> buffer allocation mechanisms without compromising on hibernation safety.
> 
> Signed-off-by: Alexander Graf <graf@amazon.com>
> ---
>  MdeModulePkg/Core/Dxe/DxeMain.inf |  4 +++
>  MdeModulePkg/Core/Dxe/Mem/Page.c  | 70 +++++++++++++++++++++++++++++++++++++++
>  MdeModulePkg/MdeModulePkg.dec     | 16 +++++++++
>  MdeModulePkg/MdeModulePkg.uni     | 12 +++++++
>  4 files changed, 102 insertions(+)
> 
> diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf
> index e4bca89577..0696246970 100644
> --- a/MdeModulePkg/Core/Dxe/DxeMain.inf
> +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf
> @@ -186,6 +186,10 @@
>    gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask                   ## CONSUMES
>    gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                           ## CONSUMES
>    gEfiMdeModulePkgTokenSpaceGuid.PcdFwVolDxeMaxEncapsulationDepth           ## CONSUMES
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIReclaimMemory             ## CONSUMES
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIMemoryNVS                 ## CONSUMES
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesCode        ## CONSUMES
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesData        ## CONSUMES
> 
>  # [Hob]
>  # RESOURCE_DESCRIPTOR   ## CONSUMES
> diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c
> index 731bf08bc9..91599adccb 100644
> --- a/MdeModulePkg/Core/Dxe/Mem/Page.c
> +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c
> @@ -1007,6 +1007,74 @@ CoreUpdateMemoryAttributes (
>    CoreReleaseMemoryLock ();
>  }
> 
> +UINT64
> +EnforceMaxAddress (
> +  IN UINT64           MaxAddress,
> +  IN EFI_MEMORY_TYPE  NewType,
> +  IN UINT64           NumberOfPages
> +  )
> +{
> +  UINT64     NumberOfBytes = LShiftU64 (NumberOfPages, EFI_PAGE_SHIFT);
> +  UINT64     LowestPossible = MaxAddress;
> +  UINT64     ForceMaxAddress;
> +  LIST_ENTRY *Link;
> +  MEMORY_MAP *Entry;
> +
> +  switch (NewType) {
> +  case EfiACPIReclaimMemory:
> +    ForceMaxAddress = PcdGet64(PcdEnforceMaxACPIReclaimMemory);
> +    break;
> +  case EfiACPIMemoryNVS:
> +    ForceMaxAddress = PcdGet64(PcdEnforceMaxACPIMemoryNVS);
> +    break;
> +  case EfiRuntimeServicesCode:
> +    ForceMaxAddress = PcdGet64(PcdEnforceMaxEfiRuntimeServicesCode);
> +    break;
> +  case EfiRuntimeServicesData:
> +    ForceMaxAddress = PcdGet64(PcdEnforceMaxEfiRuntimeServicesData);
> +    break;
> +  default:
> +    ForceMaxAddress = MaxAddress;
> +    break;
> +  }
> +
> +  //
> +  // The currently requested address already fits our forced max constraint?
> +  // Great, let's use that then.
> +  //
> +  if (ForceMaxAddress >= MaxAddress) {
> +    return MaxAddress;
> +  }
> +
> +  //
> +  // Check if the allocation would fit. If not, don't force it.
> +  //
> +  for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) {
> +    Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
> +
> +    //
> +    // If it's not a free entry, don't bother with it
> +    //
> +    if (Entry->Type != EfiConventionalMemory) {
> +      continue;
> +    }
> +
> +    if ((Entry->Start < LowestPossible) &&
> +        ((Entry->End - Entry->Start) >= NumberOfBytes)) {
> +      LowestPossible = Entry->End;
> +    }
> +  }
> +  DEBUG ((DEBUG_ERROR | DEBUG_PAGE, "Force=%lx Lowest=%lx Max=%lx\n", ForceMaxAddress, LowestPossible, MaxAddress));
> +
> +  //
> +  // We don't have free RAM available in the desired target area? Bail out!
> +  //
> +  if (ForceMaxAddress < LowestPossible) {
> +    return MaxAddress;
> +  }
> +
> +  return ForceMaxAddress;
> +}
> 
>  /**
>    Internal function. Finds a consecutive free page range below
> @@ -1041,6 +1109,8 @@ CoreFindFreePagesI (
>    LIST_ENTRY      *Link;
>    MEMORY_MAP      *Entry;
> 
> +  MaxAddress = EnforceMaxAddress(MaxAddress, NewType, NumberOfPages);
> +
>    if ((MaxAddress < EFI_PAGE_MASK) ||(NumberOfPages == 0)) {
>      return 0;
>    }
> diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
> index 1483955110..cbad48af5e 100644
> --- a/MdeModulePkg/MdeModulePkg.dec
> +++ b/MdeModulePkg/MdeModulePkg.dec
> @@ -1535,6 +1535,22 @@
>    # @Prompt Maximum permitted FwVol section nesting depth (exclusive).
>    gEfiMdeModulePkgTokenSpaceGuid.PcdFwVolDxeMaxEncapsulationDepth|0x10|UINT32|0x00000030
> 
> +  ## Maximum address that a dynamic EfiACPIReclaimMemory allocation can be requested at
> +  # @Prompt Maximum address for EfiACPIReclaimMemory allocations
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIReclaimMemory|0xFFFFFFFFFFFFFFFF|UINT64|0x30001016
> +
> +  ## Maximum address that a dynamic EfiACPIMemoryNVS allocation can be requested at
> +  # @Prompt Maximum address for EfiACPIMemoryNVS allocations
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIMemoryNVS|0xFFFFFFFFFFFFFFFF|UINT64|0x30001017
> +
> +  ## Maximum address that a dynamic EfiRuntimeServicesCode allocation can be requested at
> +  # @Prompt Maximum address for EfiRuntimeServicesCode allocations
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesCode|0xFFFFFFFFFFFFFFFF|UINT64|0x30001018
> +
> +  ## Maximum address that a dynamic EfiRuntimeServicesData allocation can be requested at
> +  # @Prompt Maximum address for EfiRuntimeServicesData allocations
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesData|0xFFFFFFFFFFFFFFFF|UINT64|0x30001019
> +
>  [PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
>    ## This PCD defines the Console output row. The default value is 25 according to UEFI spec.
>    #  This PCD could be set to 0 then console output would be at max column and max row.
> diff --git a/MdeModulePkg/MdeModulePkg.uni b/MdeModulePkg/MdeModulePkg.uni
> index ef9f4d97b9..0dc5c1960b 100644
> --- a/MdeModulePkg/MdeModulePkg.uni
> +++ b/MdeModulePkg/MdeModulePkg.uni
> @@ -1330,3 +1330,15 @@
>  #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdPcieResizableBarSupport_HELP #language en-US "Indicates if the PCIe
> Resizable BAR Capability Supported.<BR><BR>\n"
>                                                                                              "TRUE  - PCIe Resizable BAR
> Capability is supported.<BR>\n"
>                                                                                              "FALSE - PCIe Resizable BAR
> Capability is not supported.<BR>"
> +
> +#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIReclaimMemory_PROMPT #language en-US "Maximum address for
> EfiACPIReclaimMemory allocations"
> +#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIReclaimMemory_HELP #language en-US "Maximum address that a
> dynamic EfiACPIReclaimMemory allocation can be requested at"
> +
> +#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIMemoryNVS_PROMPT #language en-US "Maximum address for
> EfiACPIMemoryNVS allocations"
> +#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIMemoryNVS_HELP #language en-US "Maximum address that a
> dynamic EfiACPIMemoryNVS allocation can be requested at"
> +
> +#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesCode_PROMPT #language en-US "Maximum address
> for EfiRuntimeServicesCode allocations"
> +#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesCode_HELP #language en-US "Maximum address that
> a dynamic EfiRuntimeServicesCode allocation can be requested at"
> +
> +#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesData_PROMPT #language en-US "Maximum address
> for EfiRuntimeServicesData allocations"
> +#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesData_HELP #language en-US "Maximum address that
> a dynamic EfiRuntimeServicesData allocation can be requested at"
> --
> 2.16.4
> 
> 
> 
> 
> Amazon Development Center Germany GmbH
> Krausenstr. 38
> 10117 Berlin
> Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
> Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
> Sitz: Berlin
> Ust-ID: DE 289 237 879
> 
> 
> 
> 
> 
> 
> 


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

* Re: [edk2-devel] [PATCH 1/2] MdeModulePkg/Core/Dxe: Allow to force runtime allocations at separate range
  2021-02-18 22:28   ` [edk2-devel] " Michael D Kinney
@ 2021-02-19 14:10     ` Alexander Graf
  2021-02-19 16:47       ` Laszlo Ersek
  0 siblings, 1 reply; 7+ messages in thread
From: Alexander Graf @ 2021-02-19 14:10 UTC (permalink / raw)
  To: Kinney, Michael D, devel@edk2.groups.io
  Cc: Leif Lindholm, Laszlo Ersek, Ard Biesheuvel, Justen, Jordan L,
	Woodhouse, David, Hendrik Borghorst

Hi Mike,

Thanks a lot for the pointer! In my case, the defaults for the 
preallocated memory regions was just not big enough to prevent 
hibernation breakage. I increased them now as intended and everything 
works like a charm.

Please ignore this patch set, the existing mechanism is definitely 
superior :)


Thanks!

Alex


On 18.02.21 23:28, Kinney, Michael D wrote:
> 
> Hi Alex,
> 
> This feature is already available from the DXE Core using the MemoryTypeInformation and was
> specifically added to support hibernation use case.
> 
> There is an optional HOB that is passed into DXE Core that can provide bin sizes for any supported memory types.  Not just Runtime and ACPI.
> 
> This feature can use a fixed HOB or use a dynamic HOB from a UEFI Variable, so that changes in the memory usage of
> the critical memory types for hibernation can be tracked and stored in the UEFI Variables and be used to populate
> the HOB.  It is a platform choice to use fixed or dynamic HOB.
> 
> https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Include/Guid/MemoryTypeInformation.h
> 
> https://github.com/tianocore/edk2/blob/978b9d511f5b9cb7bc5b09749f86c39bec51525d/MdeModulePkg/Core/Dxe/Gcd/Gcd.c#L2233
> 
> https://github.com/tianocore/edk2/blob/978b9d511f5b9cb7bc5b09749f86c39bec51525d/MdeModulePkg/Core/Dxe/Mem/Page.c#L45
> 
> The DXE Core use the HOB to pre-allocate bins for the memory types and do allocations from those bins.
> 
> The UEFI Memory Map provides an entry for the entire bin (no just the allocated space), so small
> differences in allocations from boot to boot do not change the UEFI memory map.  This also
> reduces the total number of memory map entries in the UEFI memory map.
> 
> If dynamic HOB is used, then the Boot Manager compares the actual memory usage to the HOB.
> If the usage is larger or smaller by more than a threshold, then the UEFI Variable is
> updated.  The platform has the choice to reboot or continue booting after this UEIF Variable
> update based on a PCD.  The reboot can help make sure the first boot to the OS has the right
> bin sizes to support future hibernate boot flows.
> 
> 
> Mike
> 
>> -----Original Message-----
>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Alexander Graf via groups.io
>> Sent: Thursday, February 18, 2021 12:10 PM
>> To: devel@edk2.groups.io
>> Cc: Leif Lindholm <leif@nuviainc.com>; Laszlo Ersek <lersek@redhat.com>; Ard Biesheuvel <ardb+tianocore@kernel.org>;
>> Justen, Jordan L <jordan.l.justen@intel.com>; Woodhouse, David <dwmw@amazon.co.uk>; Hendrik Borghorst <hborghor@amazon.de>
>> Subject: [edk2-devel] [PATCH 1/2] MdeModulePkg/Core/Dxe: Allow to force runtime allocations at separate range
>>
>> Operating Systems that get hibernated expect all non-boot-time allocations
>> to be identical before and after hibernation.
>>
>> In edk2, we create pools and allocate pages starting from the highest
>> allowed address for the allocation, usually 0xFFFFFFFF. Typically, that
>> means we allocate a few pages of boot time data, then a few pages of
>> runtime data, then another few pages of boot time data and again runtime
>> data. Every allocation has direct impact on the following allocations.
>>
>> The problem with this scheme is that small code changes in boot time code
>> already can have significant impact on runtime allocations, which then
>> break hibernation.
>>
>> This patch adds a mechanism to override the MaxAddress for runtime
>> allocations with a target defined Pcd value. With this feature enabled,
>> we can have different allocation ranges for runtime and boot time
>> allocations.
>>
>> This allows us to determine at boot time whether to load an old,
>> hibernation compatible runtime allocation path or a new, hibernation
>> unsafe runtime allocation. All within the same edk2 target binary.
>> It also allows us to modify boot time behavior, such as modifying
>> buffer allocation mechanisms without compromising on hibernation safety.
>>
>> Signed-off-by: Alexander Graf <graf@amazon.com>
>> ---
>>   MdeModulePkg/Core/Dxe/DxeMain.inf |  4 +++
>>   MdeModulePkg/Core/Dxe/Mem/Page.c  | 70 +++++++++++++++++++++++++++++++++++++++
>>   MdeModulePkg/MdeModulePkg.dec     | 16 +++++++++
>>   MdeModulePkg/MdeModulePkg.uni     | 12 +++++++
>>   4 files changed, 102 insertions(+)
>>
>> diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf
>> index e4bca89577..0696246970 100644
>> --- a/MdeModulePkg/Core/Dxe/DxeMain.inf
>> +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf
>> @@ -186,6 +186,10 @@
>>     gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask                   ## CONSUMES
>>     gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                           ## CONSUMES
>>     gEfiMdeModulePkgTokenSpaceGuid.PcdFwVolDxeMaxEncapsulationDepth           ## CONSUMES
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIReclaimMemory             ## CONSUMES
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIMemoryNVS                 ## CONSUMES
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesCode        ## CONSUMES
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesData        ## CONSUMES
>>
>>   # [Hob]
>>   # RESOURCE_DESCRIPTOR   ## CONSUMES
>> diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c
>> index 731bf08bc9..91599adccb 100644
>> --- a/MdeModulePkg/Core/Dxe/Mem/Page.c
>> +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c
>> @@ -1007,6 +1007,74 @@ CoreUpdateMemoryAttributes (
>>     CoreReleaseMemoryLock ();
>>   }
>>
>> +UINT64
>> +EnforceMaxAddress (
>> +  IN UINT64           MaxAddress,
>> +  IN EFI_MEMORY_TYPE  NewType,
>> +  IN UINT64           NumberOfPages
>> +  )
>> +{
>> +  UINT64     NumberOfBytes = LShiftU64 (NumberOfPages, EFI_PAGE_SHIFT);
>> +  UINT64     LowestPossible = MaxAddress;
>> +  UINT64     ForceMaxAddress;
>> +  LIST_ENTRY *Link;
>> +  MEMORY_MAP *Entry;
>> +
>> +  switch (NewType) {
>> +  case EfiACPIReclaimMemory:
>> +    ForceMaxAddress = PcdGet64(PcdEnforceMaxACPIReclaimMemory);
>> +    break;
>> +  case EfiACPIMemoryNVS:
>> +    ForceMaxAddress = PcdGet64(PcdEnforceMaxACPIMemoryNVS);
>> +    break;
>> +  case EfiRuntimeServicesCode:
>> +    ForceMaxAddress = PcdGet64(PcdEnforceMaxEfiRuntimeServicesCode);
>> +    break;
>> +  case EfiRuntimeServicesData:
>> +    ForceMaxAddress = PcdGet64(PcdEnforceMaxEfiRuntimeServicesData);
>> +    break;
>> +  default:
>> +    ForceMaxAddress = MaxAddress;
>> +    break;
>> +  }
>> +
>> +  //
>> +  // The currently requested address already fits our forced max constraint?
>> +  // Great, let's use that then.
>> +  //
>> +  if (ForceMaxAddress >= MaxAddress) {
>> +    return MaxAddress;
>> +  }
>> +
>> +  //
>> +  // Check if the allocation would fit. If not, don't force it.
>> +  //
>> +  for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) {
>> +    Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
>> +
>> +    //
>> +    // If it's not a free entry, don't bother with it
>> +    //
>> +    if (Entry->Type != EfiConventionalMemory) {
>> +      continue;
>> +    }
>> +
>> +    if ((Entry->Start < LowestPossible) &&
>> +        ((Entry->End - Entry->Start) >= NumberOfBytes)) {
>> +      LowestPossible = Entry->End;
>> +    }
>> +  }
>> +  DEBUG ((DEBUG_ERROR | DEBUG_PAGE, "Force=%lx Lowest=%lx Max=%lx\n", ForceMaxAddress, LowestPossible, MaxAddress));
>> +
>> +  //
>> +  // We don't have free RAM available in the desired target area? Bail out!
>> +  //
>> +  if (ForceMaxAddress < LowestPossible) {
>> +    return MaxAddress;
>> +  }
>> +
>> +  return ForceMaxAddress;
>> +}
>>
>>   /**
>>     Internal function. Finds a consecutive free page range below
>> @@ -1041,6 +1109,8 @@ CoreFindFreePagesI (
>>     LIST_ENTRY      *Link;
>>     MEMORY_MAP      *Entry;
>>
>> +  MaxAddress = EnforceMaxAddress(MaxAddress, NewType, NumberOfPages);
>> +
>>     if ((MaxAddress < EFI_PAGE_MASK) ||(NumberOfPages == 0)) {
>>       return 0;
>>     }
>> diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
>> index 1483955110..cbad48af5e 100644
>> --- a/MdeModulePkg/MdeModulePkg.dec
>> +++ b/MdeModulePkg/MdeModulePkg.dec
>> @@ -1535,6 +1535,22 @@
>>     # @Prompt Maximum permitted FwVol section nesting depth (exclusive).
>>     gEfiMdeModulePkgTokenSpaceGuid.PcdFwVolDxeMaxEncapsulationDepth|0x10|UINT32|0x00000030
>>
>> +  ## Maximum address that a dynamic EfiACPIReclaimMemory allocation can be requested at
>> +  # @Prompt Maximum address for EfiACPIReclaimMemory allocations
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIReclaimMemory|0xFFFFFFFFFFFFFFFF|UINT64|0x30001016
>> +
>> +  ## Maximum address that a dynamic EfiACPIMemoryNVS allocation can be requested at
>> +  # @Prompt Maximum address for EfiACPIMemoryNVS allocations
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIMemoryNVS|0xFFFFFFFFFFFFFFFF|UINT64|0x30001017
>> +
>> +  ## Maximum address that a dynamic EfiRuntimeServicesCode allocation can be requested at
>> +  # @Prompt Maximum address for EfiRuntimeServicesCode allocations
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesCode|0xFFFFFFFFFFFFFFFF|UINT64|0x30001018
>> +
>> +  ## Maximum address that a dynamic EfiRuntimeServicesData allocation can be requested at
>> +  # @Prompt Maximum address for EfiRuntimeServicesData allocations
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesData|0xFFFFFFFFFFFFFFFF|UINT64|0x30001019
>> +
>>   [PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
>>     ## This PCD defines the Console output row. The default value is 25 according to UEFI spec.
>>     #  This PCD could be set to 0 then console output would be at max column and max row.
>> diff --git a/MdeModulePkg/MdeModulePkg.uni b/MdeModulePkg/MdeModulePkg.uni
>> index ef9f4d97b9..0dc5c1960b 100644
>> --- a/MdeModulePkg/MdeModulePkg.uni
>> +++ b/MdeModulePkg/MdeModulePkg.uni
>> @@ -1330,3 +1330,15 @@
>>   #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdPcieResizableBarSupport_HELP #language en-US "Indicates if the PCIe
>> Resizable BAR Capability Supported.<BR><BR>\n"
>>                                                                                               "TRUE  - PCIe Resizable BAR
>> Capability is supported.<BR>\n"
>>                                                                                               "FALSE - PCIe Resizable BAR
>> Capability is not supported.<BR>"
>> +
>> +#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIReclaimMemory_PROMPT #language en-US "Maximum address for
>> EfiACPIReclaimMemory allocations"
>> +#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIReclaimMemory_HELP #language en-US "Maximum address that a
>> dynamic EfiACPIReclaimMemory allocation can be requested at"
>> +
>> +#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIMemoryNVS_PROMPT #language en-US "Maximum address for
>> EfiACPIMemoryNVS allocations"
>> +#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxACPIMemoryNVS_HELP #language en-US "Maximum address that a
>> dynamic EfiACPIMemoryNVS allocation can be requested at"
>> +
>> +#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesCode_PROMPT #language en-US "Maximum address
>> for EfiRuntimeServicesCode allocations"
>> +#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesCode_HELP #language en-US "Maximum address that
>> a dynamic EfiRuntimeServicesCode allocation can be requested at"
>> +
>> +#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesData_PROMPT #language en-US "Maximum address
>> for EfiRuntimeServicesData allocations"
>> +#string STR_gEfiMdeModulePkgTokenSpaceGuid.PcdEnforceMaxEfiRuntimeServicesData_HELP #language en-US "Maximum address that
>> a dynamic EfiRuntimeServicesData allocation can be requested at"
>> --
>> 2.16.4
>>
>>
>>
>>
>> Amazon Development Center Germany GmbH
>> Krausenstr. 38
>> 10117 Berlin
>> Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
>> Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
>> Sitz: Berlin
>> Ust-ID: DE 289 237 879
>>
>>
>>
>>
>>
>> 
>>
> 



Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879



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

* Re: [edk2-devel] [PATCH 1/2] MdeModulePkg/Core/Dxe: Allow to force runtime allocations at separate range
  2021-02-19 14:10     ` Alexander Graf
@ 2021-02-19 16:47       ` Laszlo Ersek
  2021-02-19 17:31         ` Alexander Graf
  0 siblings, 1 reply; 7+ messages in thread
From: Laszlo Ersek @ 2021-02-19 16:47 UTC (permalink / raw)
  To: Alexander Graf, Kinney, Michael D, devel@edk2.groups.io
  Cc: Leif Lindholm, Ard Biesheuvel, Justen, Jordan L, Woodhouse, David,
	Hendrik Borghorst

Hello Alex,

On 02/19/21 15:10, Alexander Graf wrote:
> Hi Mike,
> 
> Thanks a lot for the pointer! In my case, the defaults for the
> preallocated memory regions was just not big enough to prevent
> hibernation breakage. I increased them now as intended and everything
> works like a charm.

The most recent related OVMF commits are, for reference (merged on 2020-May-08):

     1  2c06e76bba06 OvmfPkg/PlatformPei: don't track BS Code/Data in default MemTypeInfo HOB
     2  356b96b3a2dc OvmfPkg/PlatformPei: rewrite MemTypeInfo HOB production logic
     3  8db87f98357b OvmfPkg/PlatformPei: extract memory type info defaults to PCDs
     4  7b6327ff03bb OvmfPkg/PlatformPei: increase memory type info defaults

The commit messages hopefully explain how OVMF utilizes the pattern described by Mike, and what PCDs to tweak if you need larger bins.

If you think your PCD updates are upstreamable, please feel free to submit those as a patch!

Thanks!
Laszlo

> 
> Please ignore this patch set, the existing mechanism is definitely
> superior :)
> 
> 
> Thanks!
> 
> Alex
> 
> 
> On 18.02.21 23:28, Kinney, Michael D wrote:
>>
>> Hi Alex,
>>
>> This feature is already available from the DXE Core using the
>> MemoryTypeInformation and was
>> specifically added to support hibernation use case.
>>
>> There is an optional HOB that is passed into DXE Core that can provide
>> bin sizes for any supported memory types.  Not just Runtime and ACPI.
>>
>> This feature can use a fixed HOB or use a dynamic HOB from a UEFI
>> Variable, so that changes in the memory usage of
>> the critical memory types for hibernation can be tracked and stored in
>> the UEFI Variables and be used to populate
>> the HOB.  It is a platform choice to use fixed or dynamic HOB.
>>
>> https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Include/Guid/MemoryTypeInformation.h
>>
>>
>> https://github.com/tianocore/edk2/blob/978b9d511f5b9cb7bc5b09749f86c39bec51525d/MdeModulePkg/Core/Dxe/Gcd/Gcd.c#L2233
>>
>>
>> https://github.com/tianocore/edk2/blob/978b9d511f5b9cb7bc5b09749f86c39bec51525d/MdeModulePkg/Core/Dxe/Mem/Page.c#L45
>>
>>
>> The DXE Core use the HOB to pre-allocate bins for the memory types and
>> do allocations from those bins.
>>
>> The UEFI Memory Map provides an entry for the entire bin (no just the
>> allocated space), so small
>> differences in allocations from boot to boot do not change the UEFI
>> memory map.  This also
>> reduces the total number of memory map entries in the UEFI memory map.
>>
>> If dynamic HOB is used, then the Boot Manager compares the actual
>> memory usage to the HOB.
>> If the usage is larger or smaller by more than a threshold, then the
>> UEFI Variable is
>> updated.  The platform has the choice to reboot or continue booting
>> after this UEIF Variable
>> update based on a PCD.  The reboot can help make sure the first boot
>> to the OS has the right
>> bin sizes to support future hibernate boot flows.



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

* Re: [edk2-devel] [PATCH 1/2] MdeModulePkg/Core/Dxe: Allow to force runtime allocations at separate range
  2021-02-19 16:47       ` Laszlo Ersek
@ 2021-02-19 17:31         ` Alexander Graf
  0 siblings, 0 replies; 7+ messages in thread
From: Alexander Graf @ 2021-02-19 17:31 UTC (permalink / raw)
  To: devel, lersek, Kinney, Michael D
  Cc: Leif Lindholm, Ard Biesheuvel, Justen, Jordan L, Woodhouse, David,
	Hendrik Borghorst

Hey Laszlo,

On 19.02.21 17:47, Laszlo Ersek wrote:
> 
> Hello Alex,
> 
> On 02/19/21 15:10, Alexander Graf wrote:
>> Hi Mike,
>>
>> Thanks a lot for the pointer! In my case, the defaults for the
>> preallocated memory regions was just not big enough to prevent
>> hibernation breakage. I increased them now as intended and everything
>> works like a charm.
> 
> The most recent related OVMF commits are, for reference (merged on 2020-May-08):
> 
>       1  2c06e76bba06 OvmfPkg/PlatformPei: don't track BS Code/Data in default MemTypeInfo HOB
>       2  356b96b3a2dc OvmfPkg/PlatformPei: rewrite MemTypeInfo HOB production logic
>       3  8db87f98357b OvmfPkg/PlatformPei: extract memory type info defaults to PCDs
>       4  7b6327ff03bb OvmfPkg/PlatformPei: increase memory type info defaults
> 
> The commit messages hopefully explain how OVMF utilizes the pattern described by Mike, and what PCDs to tweak if you need larger bins.
> 
> If you think your PCD updates are upstreamable, please feel free to submit those as a patch!

In a nutshell, I was missing 7b6327ff03bb. So unfortunately nothing 
upstreamable this time around - you beat me to it and I was just 
suffering from running UDK2018 ;)


Alex




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879



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

end of thread, other threads:[~2021-02-19 17:31 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-02-18 20:09 [PATCH 0/2] Improve hibernation safety Alexander Graf
2021-02-18 20:09 ` [PATCH 1/2] MdeModulePkg/Core/Dxe: Allow to force runtime allocations at separate range Alexander Graf
2021-02-18 22:28   ` [edk2-devel] " Michael D Kinney
2021-02-19 14:10     ` Alexander Graf
2021-02-19 16:47       ` Laszlo Ersek
2021-02-19 17:31         ` Alexander Graf
2021-02-18 20:09 ` [PATCH 2/2] OvmfPkg: Make hibernation critical allocations at own ranges Alexander Graf

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