]> git.proxmox.com Git - mirror_edk2.git/commitdiff
CpuException: Add InitializeSeparateExceptionStacks
authorRay Ni <ray.ni@intel.com>
Fri, 20 May 2022 11:12:35 +0000 (19:12 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Fri, 10 Jun 2022 07:54:48 +0000 (07:54 +0000)
Today InitializeCpuExceptionHandlersEx is called from three modules:
1. DxeCore (links to DxeCpuExceptionHandlerLib)
    DxeCore expects it initializes the IDT entries as well as
    assigning separate stacks for #DF and #PF.
2. CpuMpPei (links to PeiCpuExceptionHandlerLib)
   and CpuDxe (links to DxeCpuExceptionHandlerLib)
    It's called for each thread for only assigning separate stacks for
    #DF and #PF. The IDT entries initialization is skipped because
    caller sets InitData->X64.InitDefaultHandlers to FALSE.

Additionally, SecPeiCpuExceptionHandlerLib, SmmCpuExceptionHandlerLib
also implement such API and the behavior of the API is simply to initialize
IDT entries only.

Because it mixes the IDT entries initialization and separate stacks
assignment for certain exception handlers together, in order to know
whether the function call only initializes IDT entries, or assigns stacks,
we need to check:
1. value of InitData->X64.InitDefaultHandlers
2. library instance

This patch cleans up the code to separate the stack assignment to a new API:
InitializeSeparateExceptionStacks().

Only when caller calls the new API, the separate stacks are assigned.
With this change, the SecPei and Smm instance can return unsupported which
gives caller a very clear status.

The old API InitializeCpuExceptionHandlersEx() is removed in this patch.
Because no platform module is consuming the old API, the impact is none.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h
MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.c
UefiCpuPkg/CpuDxe/CpuMp.c
UefiCpuPkg/CpuMpPei/CpuMpPei.c
UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c
UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c

index 2c27fc0695bc217e804636814b7888b5f99bab18..83f49d7c0071b34b90722db2abff04b9b686823c 100644 (file)
@@ -253,7 +253,7 @@ DxeMain (
     VectorInfoList = (EFI_VECTOR_HANDOFF_INFO *)(GET_GUID_HOB_DATA (GuidHob));\r
   }\r
 \r
-  Status = InitializeCpuExceptionHandlersEx (VectorInfoList, NULL);\r
+  Status = InitializeCpuExceptionHandlers (VectorInfoList);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   //\r
index d4649bebe1ba4a066f0774610cf206bfd0c54c49..9a495081f7ed9221f09ac7caf5d482cc31cf794b 100644 (file)
@@ -103,32 +103,20 @@ InitializeCpuExceptionHandlers (
   );\r
 \r
 /**\r
-  Initializes all CPU exceptions entries with optional extra initializations.\r
+  Setup separate stacks for certain exception handlers.\r
 \r
-  By default, this method should include all functionalities implemented by\r
-  InitializeCpuExceptionHandlers(), plus extra initialization works, if any.\r
-  This could be done by calling InitializeCpuExceptionHandlers() directly\r
-  in this method besides the extra works.\r
+  InitData is optional and processor arch dependent.\r
 \r
-  InitData is optional and its use and content are processor arch dependent.\r
-  The typical usage of it is to convey resources which have to be reserved\r
-  elsewhere and are necessary for the extra initializations of exception.\r
+  @param[in]  InitData      Pointer to data optional for information about how\r
+                            to assign stacks for certain exception handlers.\r
 \r
-  @param[in]  VectorInfo    Pointer to reserved vector list.\r
-  @param[in]  InitData      Pointer to data optional for extra initializations\r
-                            of exception.\r
-\r
-  @retval EFI_SUCCESS             The exceptions have been successfully\r
-                                  initialized.\r
-  @retval EFI_INVALID_PARAMETER   VectorInfo or InitData contains invalid\r
-                                  content.\r
+  @retval EFI_SUCCESS             The stacks are assigned successfully.\r
   @retval EFI_UNSUPPORTED         This function is not supported.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-InitializeCpuExceptionHandlersEx (\r
-  IN EFI_VECTOR_HANDOFF_INFO  *VectorInfo OPTIONAL,\r
+InitializeSeparateExceptionStacks (\r
   IN CPU_EXCEPTION_INIT_DATA  *InitData OPTIONAL\r
   );\r
 \r
index 54f38788fe990cd64ef91994d4031dd62c3143b8..8aeedcb4d1378b88c4589c6f5e68624717814834 100644 (file)
@@ -82,34 +82,22 @@ DumpCpuContext (
 }\r
 \r
 /**\r
-  Initializes all CPU exceptions entries with optional extra initializations.\r
+  Setup separate stacks for certain exception handlers.\r
 \r
-  By default, this method should include all functionalities implemented by\r
-  InitializeCpuExceptionHandlers(), plus extra initialization works, if any.\r
-  This could be done by calling InitializeCpuExceptionHandlers() directly\r
-  in this method besides the extra works.\r
+  InitData is optional and processor arch dependent.\r
 \r
-  InitData is optional and its use and content are processor arch dependent.\r
-  The typical usage of it is to convey resources which have to be reserved\r
-  elsewhere and are necessary for the extra initializations of exception.\r
+  @param[in]  InitData      Pointer to data optional for information about how\r
+                            to assign stacks for certain exception handlers.\r
 \r
-  @param[in]  VectorInfo    Pointer to reserved vector list.\r
-  @param[in]  InitData      Pointer to data optional for extra initializations\r
-                            of exception.\r
-\r
-  @retval EFI_SUCCESS             The exceptions have been successfully\r
-                                  initialized.\r
-  @retval EFI_INVALID_PARAMETER   VectorInfo or InitData contains invalid\r
-                                  content.\r
+  @retval EFI_SUCCESS             The stacks are assigned successfully.\r
   @retval EFI_UNSUPPORTED         This function is not supported.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-InitializeCpuExceptionHandlersEx (\r
-  IN EFI_VECTOR_HANDOFF_INFO  *VectorInfo OPTIONAL,\r
+InitializeSeparateExceptionStacks (\r
   IN CPU_EXCEPTION_INIT_DATA  *InitData OPTIONAL\r
   )\r
 {\r
-  return InitializeCpuExceptionHandlers (VectorInfo);\r
+  return EFI_UNSUPPORTED;\r
 }\r
index 1f218367b3a155cd2a86db495c3938a42e8b26f9..e385f585c7f15f455086a19aa0f29a2f82f72e5e 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   CPU DXE Module to produce CPU MP Protocol.\r
 \r
-  Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2008 - 2022, Intel Corporation. All rights reserved.<BR>\r
   SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
@@ -617,7 +617,7 @@ GetGdtr (
 /**\r
   Initializes CPU exceptions handlers for the sake of stack switch requirement.\r
 \r
-  This function is a wrapper of InitializeCpuExceptionHandlersEx. It's mainly\r
+  This function is a wrapper of InitializeSeparateExceptionStacks. It's mainly\r
   for the sake of AP's init because of EFI_AP_PROCEDURE API requirement.\r
 \r
   @param[in,out] Buffer  The pointer to private data buffer.\r
@@ -641,7 +641,7 @@ InitializeExceptionStackSwitchHandlers (
   AsmReadIdtr (&Idtr);\r
   EssData->Ia32.IdtTable     = (VOID *)Idtr.Base;\r
   EssData->Ia32.IdtTableSize = Idtr.Limit + 1;\r
-  Status                     = InitializeCpuExceptionHandlersEx (NULL, EssData);\r
+  Status                     = InitializeSeparateExceptionStacks (EssData);\r
   ASSERT_EFI_ERROR (Status);\r
 }\r
 \r
index 1e68c91d95f31c579d5d5e86d58259cf70077599..d4786979fa1b15a53affdebb516aa53971b9ecac 100644 (file)
@@ -432,7 +432,7 @@ GetGdtr (
 /**\r
   Initializes CPU exceptions handlers for the sake of stack switch requirement.\r
 \r
-  This function is a wrapper of InitializeCpuExceptionHandlersEx. It's mainly\r
+  This function is a wrapper of InitializeSeparateExceptionStacks. It's mainly\r
   for the sake of AP's init because of EFI_AP_PROCEDURE API requirement.\r
 \r
   @param[in,out] Buffer  The pointer to private data buffer.\r
@@ -456,7 +456,7 @@ InitializeExceptionStackSwitchHandlers (
   AsmReadIdtr (&Idtr);\r
   EssData->Ia32.IdtTable     = (VOID *)Idtr.Base;\r
   EssData->Ia32.IdtTableSize = Idtr.Limit + 1;\r
-  Status                     = InitializeCpuExceptionHandlersEx (NULL, EssData);\r
+  Status                     = InitializeSeparateExceptionStacks (EssData);\r
   ASSERT_EFI_ERROR (Status);\r
 }\r
 \r
index c7c1fe31d2e7955bfc4f709aff8fad9f44d8cf28..e62bb5e6c07c1b2767277918cabc0e6751d5d1e3 100644 (file)
@@ -103,82 +103,49 @@ RegisterCpuInterruptHandler (
 }\r
 \r
 /**\r
-  Initializes CPU exceptions entries and setup stack switch for given exceptions.\r
+  Setup separate stacks for certain exception handlers.\r
 \r
-  This method will call InitializeCpuExceptionHandlers() to setup default\r
-  exception handlers unless indicated not to do it explicitly.\r
+  InitData is optional and processor arch dependent.\r
 \r
-  If InitData is passed with NULL, this method will use the resource reserved\r
-  by global variables to initialize it; Otherwise it will use data in InitData\r
-  to setup stack switch. This is for the different use cases in DxeCore and\r
-  Cpu MP exception initialization.\r
+  @param[in]  InitData      Pointer to data optional for information about how\r
+                            to assign stacks for certain exception handlers.\r
 \r
-  @param[in]  VectorInfo    Pointer to reserved vector list.\r
-  @param[in]  InitData      Pointer to data required to setup stack switch for\r
-                            given exceptions.\r
-\r
-  @retval EFI_SUCCESS             The exceptions have been successfully\r
-                                  initialized.\r
-  @retval EFI_INVALID_PARAMETER   VectorInfo or InitData contains invalid\r
-                                  content.\r
+  @retval EFI_SUCCESS             The stacks are assigned successfully.\r
+  @retval EFI_UNSUPPORTED         This function is not supported.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-InitializeCpuExceptionHandlersEx (\r
-  IN EFI_VECTOR_HANDOFF_INFO  *VectorInfo OPTIONAL,\r
+InitializeSeparateExceptionStacks (\r
   IN CPU_EXCEPTION_INIT_DATA  *InitData OPTIONAL\r
   )\r
 {\r
-  EFI_STATUS               Status;\r
   CPU_EXCEPTION_INIT_DATA  EssData;\r
   IA32_DESCRIPTOR          Idtr;\r
   IA32_DESCRIPTOR          Gdtr;\r
 \r
-  //\r
-  // To avoid repeat initialization of default handlers, the caller should pass\r
-  // an extended init data with InitDefaultHandlers set to FALSE. There's no\r
-  // need to call this method to just initialize default handlers. Call non-ex\r
-  // version instead; or this method must be implemented as a simple wrapper of\r
-  // non-ex version of it, if this version has to be called.\r
-  //\r
-  if ((InitData == NULL) || InitData->X64.InitDefaultHandlers) {\r
-    Status = InitializeCpuExceptionHandlers (VectorInfo);\r
-  } else {\r
-    Status = EFI_SUCCESS;\r
-  }\r
-\r
-  if (!EFI_ERROR (Status)) {\r
-    //\r
-    // Initializing stack switch is only necessary for Stack Guard functionality.\r
-    //\r
-    if (PcdGetBool (PcdCpuStackGuard)) {\r
-      if (InitData == NULL) {\r
-        SetMem (mNewGdt, sizeof (mNewGdt), 0);\r
-\r
-        AsmReadIdtr (&Idtr);\r
-        AsmReadGdtr (&Gdtr);\r
-\r
-        EssData.X64.Revision                   = CPU_EXCEPTION_INIT_DATA_REV;\r
-        EssData.X64.KnownGoodStackTop          = (UINTN)mNewStack + sizeof (mNewStack);\r
-        EssData.X64.KnownGoodStackSize         = CPU_KNOWN_GOOD_STACK_SIZE;\r
-        EssData.X64.StackSwitchExceptions      = CPU_STACK_SWITCH_EXCEPTION_LIST;\r
-        EssData.X64.StackSwitchExceptionNumber = CPU_STACK_SWITCH_EXCEPTION_NUMBER;\r
-        EssData.X64.IdtTable                   = (VOID *)Idtr.Base;\r
-        EssData.X64.IdtTableSize               = Idtr.Limit + 1;\r
-        EssData.X64.GdtTable                   = mNewGdt;\r
-        EssData.X64.GdtTableSize               = sizeof (mNewGdt);\r
-        EssData.X64.ExceptionTssDesc           = mNewGdt + Gdtr.Limit + 1;\r
-        EssData.X64.ExceptionTssDescSize       = CPU_TSS_DESC_SIZE;\r
-        EssData.X64.ExceptionTss               = mNewGdt + Gdtr.Limit + 1 + CPU_TSS_DESC_SIZE;\r
-        EssData.X64.ExceptionTssSize           = CPU_TSS_SIZE;\r
-\r
-        InitData = &EssData;\r
-      }\r
-\r
-      Status = ArchSetupExceptionStack (InitData);\r
-    }\r
+  if (InitData == NULL) {\r
+    SetMem (mNewGdt, sizeof (mNewGdt), 0);\r
+\r
+    AsmReadIdtr (&Idtr);\r
+    AsmReadGdtr (&Gdtr);\r
+\r
+    EssData.X64.Revision                   = CPU_EXCEPTION_INIT_DATA_REV;\r
+    EssData.X64.KnownGoodStackTop          = (UINTN)mNewStack + sizeof (mNewStack);\r
+    EssData.X64.KnownGoodStackSize         = CPU_KNOWN_GOOD_STACK_SIZE;\r
+    EssData.X64.StackSwitchExceptions      = CPU_STACK_SWITCH_EXCEPTION_LIST;\r
+    EssData.X64.StackSwitchExceptionNumber = CPU_STACK_SWITCH_EXCEPTION_NUMBER;\r
+    EssData.X64.IdtTable                   = (VOID *)Idtr.Base;\r
+    EssData.X64.IdtTableSize               = Idtr.Limit + 1;\r
+    EssData.X64.GdtTable                   = mNewGdt;\r
+    EssData.X64.GdtTableSize               = sizeof (mNewGdt);\r
+    EssData.X64.ExceptionTssDesc           = mNewGdt + Gdtr.Limit + 1;\r
+    EssData.X64.ExceptionTssDescSize       = CPU_TSS_DESC_SIZE;\r
+    EssData.X64.ExceptionTss               = mNewGdt + Gdtr.Limit + 1 + CPU_TSS_DESC_SIZE;\r
+    EssData.X64.ExceptionTssSize           = CPU_TSS_SIZE;\r
+\r
+    InitData = &EssData;\r
   }\r
 \r
-  return Status;\r
+  return ArchSetupExceptionStack (InitData);\r
 }\r
index 1ae611c75e69fd71202a613217922c114cd83a99..494c2ab4332a85e796d6a7d773cd797415c7f0e6 100644 (file)
@@ -150,57 +150,26 @@ InitializeCpuExceptionHandlers (
 }\r
 \r
 /**\r
-  Initializes all CPU exceptions entries with optional extra initializations.\r
+  Setup separate stacks for certain exception handlers.\r
 \r
-  By default, this method should include all functionalities implemented by\r
-  InitializeCpuExceptionHandlers(), plus extra initialization works, if any.\r
-  This could be done by calling InitializeCpuExceptionHandlers() directly\r
-  in this method besides the extra works.\r
+  InitData is optional and processor arch dependent.\r
 \r
-  InitData is optional and its use and content are processor arch dependent.\r
-  The typical usage of it is to convey resources which have to be reserved\r
-  elsewhere and are necessary for the extra initializations of exception.\r
+  @param[in]  InitData      Pointer to data optional for information about how\r
+                            to assign stacks for certain exception handlers.\r
 \r
-  @param[in]  VectorInfo    Pointer to reserved vector list.\r
-  @param[in]  InitData      Pointer to data optional for extra initializations\r
-                            of exception.\r
-\r
-  @retval EFI_SUCCESS             The exceptions have been successfully\r
-                                  initialized.\r
-  @retval EFI_INVALID_PARAMETER   VectorInfo or InitData contains invalid\r
-                                  content.\r
+  @retval EFI_SUCCESS             The stacks are assigned successfully.\r
+  @retval EFI_UNSUPPORTED         This function is not supported.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-InitializeCpuExceptionHandlersEx (\r
-  IN EFI_VECTOR_HANDOFF_INFO  *VectorInfo OPTIONAL,\r
+InitializeSeparateExceptionStacks (\r
   IN CPU_EXCEPTION_INIT_DATA  *InitData OPTIONAL\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
-\r
-  //\r
-  // To avoid repeat initialization of default handlers, the caller should pass\r
-  // an extended init data with InitDefaultHandlers set to FALSE. There's no\r
-  // need to call this method to just initialize default handlers. Call non-ex\r
-  // version instead; or this method must be implemented as a simple wrapper of\r
-  // non-ex version of it, if this version has to be called.\r
-  //\r
-  if ((InitData == NULL) || InitData->Ia32.InitDefaultHandlers) {\r
-    Status = InitializeCpuExceptionHandlers (VectorInfo);\r
-  } else {\r
-    Status = EFI_SUCCESS;\r
-  }\r
-\r
-  if (!EFI_ERROR (Status)) {\r
-    //\r
-    // Initializing stack switch is only necessary for Stack Guard functionality.\r
-    //\r
-    if (PcdGetBool (PcdCpuStackGuard) && (InitData != NULL)) {\r
-      Status = ArchSetupExceptionStack (InitData);\r
-    }\r
+  if (InitData == NULL) {\r
+    return EFI_UNSUPPORTED;\r
   }\r
 \r
-  return Status;\r
+  return ArchSetupExceptionStack (InitData);\r
 }\r
index e894ead612d28a651b6df4d23a9057918c6a482f..4313cc5582e3cd7d066478ea43c7bdc5b16035fb 100644 (file)
@@ -200,33 +200,22 @@ RegisterCpuInterruptHandler (
 }\r
 \r
 /**\r
-  Initializes all CPU exceptions entries with optional extra initializations.\r
+  Setup separate stacks for certain exception handlers.\r
 \r
-  By default, this method should include all functionalities implemented by\r
-  InitializeCpuExceptionHandlers(), plus extra initialization works, if any.\r
-  This could be done by calling InitializeCpuExceptionHandlers() directly\r
-  in this method besides the extra works.\r
+  InitData is optional and processor arch dependent.\r
 \r
-  InitData is optional and its use and content are processor arch dependent.\r
-  The typical usage of it is to convey resources which have to be reserved\r
-  elsewhere and are necessary for the extra initializations of exception.\r
+  @param[in]  InitData      Pointer to data optional for information about how\r
+                            to assign stacks for certain exception handlers.\r
 \r
-  @param[in]  VectorInfo    Pointer to reserved vector list.\r
-  @param[in]  InitData      Pointer to data optional for extra initializations\r
-                            of exception.\r
-\r
-  @retval EFI_SUCCESS             The exceptions have been successfully\r
-                                  initialized.\r
-  @retval EFI_INVALID_PARAMETER   VectorInfo or InitData contains invalid\r
-                                  content.\r
+  @retval EFI_SUCCESS             The stacks are assigned successfully.\r
+  @retval EFI_UNSUPPORTED         This function is not supported.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-InitializeCpuExceptionHandlersEx (\r
-  IN EFI_VECTOR_HANDOFF_INFO  *VectorInfo OPTIONAL,\r
+InitializeSeparateExceptionStacks (\r
   IN CPU_EXCEPTION_INIT_DATA  *InitData OPTIONAL\r
   )\r
 {\r
-  return InitializeCpuExceptionHandlers (VectorInfo);\r
+  return EFI_UNSUPPORTED;\r
 }\r
index ec643556c7c720bfad351f89fd77c35e29c36a08..1c97dab926971a3fa1b089eb139b27205e5184bc 100644 (file)
@@ -96,33 +96,22 @@ RegisterCpuInterruptHandler (
 }\r
 \r
 /**\r
-  Initializes all CPU exceptions entries with optional extra initializations.\r
+  Setup separate stacks for certain exception handlers.\r
 \r
-  By default, this method should include all functionalities implemented by\r
-  InitializeCpuExceptionHandlers(), plus extra initialization works, if any.\r
-  This could be done by calling InitializeCpuExceptionHandlers() directly\r
-  in this method besides the extra works.\r
+  InitData is optional and processor arch dependent.\r
 \r
-  InitData is optional and its use and content are processor arch dependent.\r
-  The typical usage of it is to convey resources which have to be reserved\r
-  elsewhere and are necessary for the extra initializations of exception.\r
+  @param[in]  InitData      Pointer to data optional for information about how\r
+                            to assign stacks for certain exception handlers.\r
 \r
-  @param[in]  VectorInfo    Pointer to reserved vector list.\r
-  @param[in]  InitData      Pointer to data optional for extra initializations\r
-                            of exception.\r
-\r
-  @retval EFI_SUCCESS             The exceptions have been successfully\r
-                                  initialized.\r
-  @retval EFI_INVALID_PARAMETER   VectorInfo or InitData contains invalid\r
-                                  content.\r
+  @retval EFI_SUCCESS             The stacks are assigned successfully.\r
+  @retval EFI_UNSUPPORTED         This function is not supported.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-InitializeCpuExceptionHandlersEx (\r
-  IN EFI_VECTOR_HANDOFF_INFO  *VectorInfo OPTIONAL,\r
+InitializeSeparateExceptionStacks (\r
   IN CPU_EXCEPTION_INIT_DATA  *InitData OPTIONAL\r
   )\r
 {\r
-  return InitializeCpuExceptionHandlers (VectorInfo);\r
+  return EFI_UNSUPPORTED;\r
 }\r