public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Jordan Justen <jordan.l.justen@intel.com>
To: edk2-devel@lists.01.org
Cc: Jordan Justen <jordan.l.justen@intel.com>,
	Jian J Wang <jian.j.wang@intel.com>, Hao Wu <hao.a.wu@intel.com>,
	Ray Ni <ray.ni@intel.com>, Star Zeng <star.zeng@intel.com>
Subject: [PATCH 07/10] MdeModePkg/Core/Pei: Add code path to allow assembly temp-ram migration
Date: Sun, 17 Feb 2019 20:11:38 -0800	[thread overview]
Message-ID: <20190218041141.21363-8-jordan.l.justen@intel.com> (raw)
In-Reply-To: <20190218041141.21363-1-jordan.l.justen@intel.com>

There is potential problem with PEI Core's usage of the
TemporaryRamMigration PPI. When the TemporaryRamMigration function is
called, it returns to C based code after changing the stack to the new
permanent memory copy of the stack. But, the C compiler may have
stored pointers to addresses on the old temporary RAM stack. Even
though the stack is copied to a new permanent memory location, it is
not possible to adjust all pointers that the C compiler may have added
within the stack data.

For this reason, it is only safe to return to assembly code after
calling TemporaryRamMigration. The assembly code can make sure the old
temporary RAM stack is not used before calling a new C function. When
the new function is called, it will use the new permanent memory
stack, so it is safe to use C code again.

This code adds new function named PeiTemporaryRamMigration which can
be implemented in assembly code as described above.
PeiTemporaryRamMigration must call the TemporaryRamMigration function,
and then calls a new C PeiTemporaryRamMigrated function. This
guanantees PeiTemporaryRamMigrated will only use the permanent memory
stack.

For now, this patch should have no effect, since it still uses C to
implement PeiTemporaryRamMigration. But, PeiTemporaryRamMigration can
then be changed into an assembly code function to fix the issue
described above.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
---
 MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c | 59 ++++++++++++-------
 .../Pei/Dispatcher/TemporaryRamMigration.c    | 52 ++++++++++++++++
 MdeModulePkg/Core/Pei/PeiMain.h               | 52 ++++++++++++++++
 MdeModulePkg/Core/Pei/PeiMain.inf             |  1 +
 4 files changed, 143 insertions(+), 21 deletions(-)
 create mode 100644 MdeModulePkg/Core/Pei/Dispatcher/TemporaryRamMigration.c

diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
index 68670f43e0..8e3fa161dd 100644
--- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
+++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
@@ -688,6 +688,7 @@ PeiCheckAndSwitchStack (
   EFI_PHYSICAL_ADDRESS                  TempBase2;
   UINTN                                 TempSize2;
   UINTN                                 Index;
+  PEI_CORE_TEMPORARY_RAM_TRANSITION     TempRamTransitionData;
 
   PeiServices = (CONST EFI_PEI_SERVICES **) &Private->Ps;
 
@@ -822,30 +823,20 @@ PeiCheckAndSwitchStack (
         Private = (PEI_CORE_INSTANCE *)((UINTN)(VOID *)Private - StackOffset);
       }
 
-      //
-      // Temporary Ram Support PPI is provided by platform, it will copy
-      // temporary memory to permanent memory and do stack switching.
-      // After invoking Temporary Ram Support PPI, the following code's
-      // stack is in permanent memory.
-      //
-      TemporaryRamSupportPpi->TemporaryRamMigration (
-                                PeiServices,
-                                TemporaryRamBase,
-                                (EFI_PHYSICAL_ADDRESS)(UINTN)(TopOfNewStack - TemporaryStackSize),
-                                TemporaryRamSize
-                                );
-
-      //
-      // Migrate memory pages allocated in pre-memory phase.
-      // It could not be called before calling TemporaryRamSupportPpi->TemporaryRamMigration()
-      // as the migrated memory pages may be overridden by TemporaryRamSupportPpi->TemporaryRamMigration().
-      //
-      MigrateMemoryPages (Private, TRUE);
+      TempRamTransitionData.TemporaryRamMigration =
+        TemporaryRamSupportPpi->TemporaryRamMigration;
+      TempRamTransitionData.PeiServices = PeiServices;
+      TempRamTransitionData.TemporaryMemoryBase = TemporaryRamBase;
+      TempRamTransitionData.PermanentMemoryBase =
+        (EFI_PHYSICAL_ADDRESS)(UINTN)(TopOfNewStack - TemporaryStackSize);
+      TempRamTransitionData.CopySize = TemporaryRamSize;
+      TempRamTransitionData.Private = Private;
+      TempRamTransitionData.SecCoreData = SecCoreData;
 
       //
-      // Entry PEI Phase 2
+      // Migrate Temporary RAM and enter PEI Phase 2
       //
-      PeiCore (SecCoreData, NULL, Private);
+      PeiTemporaryRamMigration(&TempRamTransitionData);
     } else {
       //
       // Migrate memory pages allocated in pre-memory phase.
@@ -958,6 +949,32 @@ PeiCheckAndSwitchStack (
   }
 }
 
+VOID
+EFIAPI
+PeiTemporaryRamMigrated (
+  IN  VOID  *CallbackContext
+  )
+{
+  PEI_CORE_TEMPORARY_RAM_TRANSITION *TempRamTransitionData =
+    (PEI_CORE_TEMPORARY_RAM_TRANSITION*)CallbackContext;
+
+  //
+  // Migrate memory pages allocated in pre-memory phase.
+  // It could not be called before calling TemporaryRamSupportPpi->TemporaryRamMigration()
+  // as the migrated memory pages may be overridden by TemporaryRamSupportPpi->TemporaryRamMigration().
+  //
+  MigrateMemoryPages (TempRamTransitionData->Private, TRUE);
+
+  //
+  // Entry PEI Phase 2
+  //
+  PeiCore (
+    TempRamTransitionData->SecCoreData,
+    NULL,
+    TempRamTransitionData->Private
+    );
+}
+
 /**
   Conduct PEIM dispatch.
 
diff --git a/MdeModulePkg/Core/Pei/Dispatcher/TemporaryRamMigration.c b/MdeModulePkg/Core/Pei/Dispatcher/TemporaryRamMigration.c
new file mode 100644
index 0000000000..9e9d0854ed
--- /dev/null
+++ b/MdeModulePkg/Core/Pei/Dispatcher/TemporaryRamMigration.c
@@ -0,0 +1,52 @@
+/** @file
+  EFI PEI Core temporary RAM migration
+
+Copyright (c) 2018, Intel Corporation. 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 "PeiMain.h"
+
+/**
+  To call the TemporaryRamMigration PPI, we might not be able to rely
+  on C code's handling of the stack. In these cases we use an assembly
+  function to make sure the old stack is not used after the
+  TemporaryRamMigration PPI is used.
+
+  After calling the TemporaryRamMigration PPI, this function calls
+  PeiTemporaryRamMigrated.
+
+  This C based function provides an implementation that may work for
+  some architectures.
+
+  @param TempRamTransitionData
+**/
+VOID
+EFIAPI
+PeiTemporaryRamMigration (
+  IN  PEI_CORE_TEMPORARY_RAM_TRANSITION  *TempRamTransitionData
+  )
+{
+  //
+  // Temporary Ram Support PPI is provided by platform, it will copy
+  // temporary memory to permanent memory and do stack switching.
+  // After invoking Temporary Ram Support PPI, the following code's
+  // stack is in permanent memory.
+  //
+  TempRamTransitionData->TemporaryRamMigration (
+                           TempRamTransitionData->PeiServices,
+                           TempRamTransitionData->TemporaryMemoryBase,
+                           TempRamTransitionData->PermanentMemoryBase,
+                           TempRamTransitionData->CopySize
+                           );
+
+  PeiTemporaryRamMigrated(TempRamTransitionData);
+}
diff --git a/MdeModulePkg/Core/Pei/PeiMain.h b/MdeModulePkg/Core/Pei/PeiMain.h
index a61da73fd8..2d48f8d5d1 100644
--- a/MdeModulePkg/Core/Pei/PeiMain.h
+++ b/MdeModulePkg/Core/Pei/PeiMain.h
@@ -1871,4 +1871,56 @@ PeiReinitializeFv (
   IN  PEI_CORE_INSTANCE           *PrivateData
   );
 
+#pragma pack(1)
+typedef struct {
+  /**
+    These fields are used by PeiTemporaryRamMigration to call the
+    TemporaryRamMigration PPI.
+  **/
+  TEMPORARY_RAM_MIGRATION       TemporaryRamMigration;
+  CONST EFI_PEI_SERVICES        **PeiServices;
+  EFI_PHYSICAL_ADDRESS          TemporaryMemoryBase;
+  EFI_PHYSICAL_ADDRESS          PermanentMemoryBase;
+  UINTN                         CopySize;
+
+  /**
+    These fields are used by PeiTemporaryRamMigrated.
+  **/
+  PEI_CORE_INSTANCE             *Private;
+  CONST EFI_SEC_PEI_HAND_OFF    *SecCoreData;
+} PEI_CORE_TEMPORARY_RAM_TRANSITION;
+#pragma pack()
+
+/**
+  To call the TemporaryRamMigration PPI, we might not be able to rely
+  on C code's handling of the stack. In these cases we use an assembly
+  function to make sure the old stack is not used after the
+  TemporaryRamMigration PPI is used.
+
+  After calling the TemporaryRamMigration PPI, this function calls
+  PeiTemporaryRamMigrated.
+
+  @param TempRamTransitionData
+**/
+VOID
+EFIAPI
+PeiTemporaryRamMigration (
+  IN  PEI_CORE_TEMPORARY_RAM_TRANSITION  *TempRamTransitionData
+  );
+
+/**
+  After PeiTemporaryRamMigration has called the TemporaryRamMigration
+  PPI, it will call this C based function to allow PEI to continue
+  after the migration using the new stack in the migrated RAM.
+
+  @param CallbackContext   Pointer to PEI_CORE_TEMPORARY_RAM_TRANSITION
+                           data.
+**/
+VOID
+EFIAPI
+PeiTemporaryRamMigrated (
+  IN  VOID  *CallbackContext
+  );
+
+
 #endif
diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf b/MdeModulePkg/Core/Pei/PeiMain.inf
index 5bab2aab8c..94b26b3572 100644
--- a/MdeModulePkg/Core/Pei/PeiMain.inf
+++ b/MdeModulePkg/Core/Pei/PeiMain.inf
@@ -45,6 +45,7 @@
   FwVol/FwVol.c
   FwVol/FwVol.h
   Dispatcher/Dispatcher.c
+  Dispatcher/TemporaryRamMigration.c
   Dependency/Dependency.c
   Dependency/Dependency.h
   BootMode/BootMode.c
-- 
2.20.0.rc1



  parent reply	other threads:[~2019-02-18  4:12 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-18  4:11 [PATCH 00/10] Fix PEI Core issue during TemporaryRamMigration Jordan Justen
2019-02-18  4:11 ` [PATCH 01/10] EmulatorPkg/build.sh: Fix missing usage of -b BUILDTARGET parameter Jordan Justen
2019-02-18  4:11 ` [PATCH 02/10] EmulatorPkg/Unix/Host: Use PcdInitValueInTempStack to init temp-ram Jordan Justen
2019-02-18  4:11 ` [PATCH 03/10] EmulatorPkg/Sec: Replace assembly temp-ram support with C code Jordan Justen
2019-02-18  4:11 ` [PATCH 04/10] EmulatorPkg/Sec: Disable optimizations for TemporaryRamMigration function Jordan Justen
2019-02-18  4:11 ` [PATCH 05/10] OvmfPkg/Sec: Swap TemporaryRam Stack and Heap locations Jordan Justen
2019-02-18 12:58   ` Laszlo Ersek
2019-02-18  4:11 ` [PATCH 06/10] OvmfPkg/Sec: Disable optimizations for TemporaryRamMigration Jordan Justen
2019-02-18  7:53   ` Ard Biesheuvel
2019-02-18  9:08     ` Jordan Justen
2019-02-18  9:32       ` Ard Biesheuvel
2019-02-18 13:01         ` Laszlo Ersek
2019-02-19 22:50         ` Brian J. Johnson
2019-02-19 23:58           ` Jordan Justen
2019-02-20  8:52         ` Jordan Justen
2019-02-20  8:59           ` Ard Biesheuvel
2019-02-18  4:11 ` Jordan Justen [this message]
2019-02-18  4:11 ` [PATCH 08/10] MdeModulePkg/Core/Pei: Use assembly for X64 TemporaryRamMigration Jordan Justen
2019-02-18  4:11 ` [PATCH 09/10] MdeModulePkg/Core/Pei: Use assembly for IA32 TemporaryRamMigration Jordan Justen
2019-02-18  4:11 ` [PATCH 10/10] OvmfPkg/Sec: Fill Temp Ram after TemporaryRamMigration Jordan Justen
2019-02-18 13:15   ` Laszlo Ersek
2019-02-19  2:46 ` [PATCH 00/10] Fix PEI Core issue during TemporaryRamMigration Ni, Ray
2019-02-19 13:25   ` Gao, Liming
2019-02-20 13:27     ` Ni, Ray
2019-02-20 17:43       ` Jordan Justen
2019-02-21  0:15         ` Ni, Ray
2019-02-21  1:03           ` Jordan Justen
2019-02-21  4:43             ` Ni, Ray
2019-02-19 19:27   ` Jordan Justen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190218041141.21363-8-jordan.l.justen@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox