Reviewed-by: Jian J Wang <jian.j.w...@intel.com>
Regards, Jian > -----Original Message----- > From: Ni, Ray <ray...@intel.com> > Sent: Friday, May 20, 2022 10:16 PM > To: devel@edk2.groups.io > Cc: Dong, Eric <eric.d...@intel.com>; Wang, Jian J <jian.j.w...@intel.com> > Subject: [PATCH 5/5] CpuException: Add InitializeSeparateExceptionStacks > > 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...@intel.com> > Cc: Eric Dong <eric.d...@intel.com> > Cc: Jian J Wang <jian.j.w...@intel.com> > --- > MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 2 +- > .../Include/Library/CpuExceptionHandlerLib.h | 24 ++--- > .../CpuExceptionHandlerLibNull.c | 26 ++---- > UefiCpuPkg/CpuDxe/CpuMp.c | 6 +- > UefiCpuPkg/CpuMpPei/CpuMpPei.c | 4 +- > .../CpuExceptionHandlerLib/DxeException.c | 91 ++++++------------- > .../CpuExceptionHandlerLib/PeiCpuException.c | 51 ++--------- > .../SecPeiCpuException.c | 27 ++---- > .../CpuExceptionHandlerLib/SmmException.c | 27 ++---- > 9 files changed, 74 insertions(+), 184 deletions(-) > > diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c > b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c > index 2c27fc0695..83f49d7c00 100644 > --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c > +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c > @@ -253,7 +253,7 @@ DxeMain ( > VectorInfoList = (EFI_VECTOR_HANDOFF_INFO *)(GET_GUID_HOB_DATA > (GuidHob)); > > } > > > > - Status = InitializeCpuExceptionHandlersEx (VectorInfoList, NULL); > > + Status = InitializeCpuExceptionHandlers (VectorInfoList); > > ASSERT_EFI_ERROR (Status); > > > > // > > diff --git a/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h > b/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h > index d4649bebe1..9a495081f7 100644 > --- a/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h > +++ b/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h > @@ -103,32 +103,20 @@ InitializeCpuExceptionHandlers ( > ); > > > > /** > > - Initializes all CPU exceptions entries with optional extra initializations. > > + Setup separate stacks for certain exception handlers. > > > > - By default, this method should include all functionalities implemented by > > - InitializeCpuExceptionHandlers(), plus extra initialization works, if any. > > - This could be done by calling InitializeCpuExceptionHandlers() directly > > - in this method besides the extra works. > > + InitData is optional and processor arch dependent. > > > > - InitData is optional and its use and content are processor arch dependent. > > - The typical usage of it is to convey resources which have to be reserved > > - elsewhere and are necessary for the extra initializations of exception. > > + @param[in] InitData Pointer to data optional for information about > how > > + to assign stacks for certain exception handlers. > > > > - @param[in] VectorInfo Pointer to reserved vector list. > > - @param[in] InitData Pointer to data optional for extra > initializations > > - of exception. > > - > > - @retval EFI_SUCCESS The exceptions have been successfully > > - initialized. > > - @retval EFI_INVALID_PARAMETER VectorInfo or InitData contains invalid > > - content. > > + @retval EFI_SUCCESS The stacks are assigned successfully. > > @retval EFI_UNSUPPORTED This function is not supported. > > > > **/ > > EFI_STATUS > > EFIAPI > > -InitializeCpuExceptionHandlersEx ( > > - IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL, > > +InitializeSeparateExceptionStacks ( > > IN CPU_EXCEPTION_INIT_DATA *InitData OPTIONAL > > ); > > > > diff --git > a/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLib > Null.c > b/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLib > Null.c > index 54f38788fe..8aeedcb4d1 100644 > --- > a/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLib > Null.c > +++ > b/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLib > Null.c > @@ -82,34 +82,22 @@ DumpCpuContext ( > } > > > > /** > > - Initializes all CPU exceptions entries with optional extra initializations. > > + Setup separate stacks for certain exception handlers. > > > > - By default, this method should include all functionalities implemented by > > - InitializeCpuExceptionHandlers(), plus extra initialization works, if any. > > - This could be done by calling InitializeCpuExceptionHandlers() directly > > - in this method besides the extra works. > > + InitData is optional and processor arch dependent. > > > > - InitData is optional and its use and content are processor arch dependent. > > - The typical usage of it is to convey resources which have to be reserved > > - elsewhere and are necessary for the extra initializations of exception. > > + @param[in] InitData Pointer to data optional for information about > how > > + to assign stacks for certain exception handlers. > > > > - @param[in] VectorInfo Pointer to reserved vector list. > > - @param[in] InitData Pointer to data optional for extra > initializations > > - of exception. > > - > > - @retval EFI_SUCCESS The exceptions have been successfully > > - initialized. > > - @retval EFI_INVALID_PARAMETER VectorInfo or InitData contains invalid > > - content. > > + @retval EFI_SUCCESS The stacks are assigned successfully. > > @retval EFI_UNSUPPORTED This function is not supported. > > > > **/ > > EFI_STATUS > > EFIAPI > > -InitializeCpuExceptionHandlersEx ( > > - IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL, > > +InitializeSeparateExceptionStacks ( > > IN CPU_EXCEPTION_INIT_DATA *InitData OPTIONAL > > ) > > { > > - return InitializeCpuExceptionHandlers (VectorInfo); > > + return EFI_UNSUPPORTED; > > } > > diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c > index 1f218367b3..e385f585c7 100644 > --- a/UefiCpuPkg/CpuDxe/CpuMp.c > +++ b/UefiCpuPkg/CpuDxe/CpuMp.c > @@ -1,7 +1,7 @@ > /** @file > > CPU DXE Module to produce CPU MP Protocol. > > > > - Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.<BR> > > + Copyright (c) 2008 - 2022, Intel Corporation. All rights reserved.<BR> > > SPDX-License-Identifier: BSD-2-Clause-Patent > > > > **/ > > @@ -617,7 +617,7 @@ GetGdtr ( > /** > > Initializes CPU exceptions handlers for the sake of stack switch > requirement. > > > > - This function is a wrapper of InitializeCpuExceptionHandlersEx. It's mainly > > + This function is a wrapper of InitializeSeparateExceptionStacks. It's > mainly > > for the sake of AP's init because of EFI_AP_PROCEDURE API requirement. > > > > @param[in,out] Buffer The pointer to private data buffer. > > @@ -641,7 +641,7 @@ InitializeExceptionStackSwitchHandlers ( > AsmReadIdtr (&Idtr); > > EssData->Ia32.IdtTable = (VOID *)Idtr.Base; > > EssData->Ia32.IdtTableSize = Idtr.Limit + 1; > > - Status = InitializeCpuExceptionHandlersEx (NULL, > EssData); > > + Status = InitializeSeparateExceptionStacks (EssData); > > ASSERT_EFI_ERROR (Status); > > } > > > > diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.c > b/UefiCpuPkg/CpuMpPei/CpuMpPei.c > index 1e68c91d95..d4786979fa 100644 > --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.c > +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.c > @@ -432,7 +432,7 @@ GetGdtr ( > /** > > Initializes CPU exceptions handlers for the sake of stack switch > requirement. > > > > - This function is a wrapper of InitializeCpuExceptionHandlersEx. It's mainly > > + This function is a wrapper of InitializeSeparateExceptionStacks. It's > mainly > > for the sake of AP's init because of EFI_AP_PROCEDURE API requirement. > > > > @param[in,out] Buffer The pointer to private data buffer. > > @@ -456,7 +456,7 @@ InitializeExceptionStackSwitchHandlers ( > AsmReadIdtr (&Idtr); > > EssData->Ia32.IdtTable = (VOID *)Idtr.Base; > > EssData->Ia32.IdtTableSize = Idtr.Limit + 1; > > - Status = InitializeCpuExceptionHandlersEx (NULL, > EssData); > > + Status = InitializeSeparateExceptionStacks (EssData); > > ASSERT_EFI_ERROR (Status); > > } > > > > diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c > index c7c1fe31d2..e62bb5e6c0 100644 > --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c > +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c > @@ -103,82 +103,49 @@ RegisterCpuInterruptHandler ( > } > > > > /** > > - Initializes CPU exceptions entries and setup stack switch for given > exceptions. > > + Setup separate stacks for certain exception handlers. > > > > - This method will call InitializeCpuExceptionHandlers() to setup default > > - exception handlers unless indicated not to do it explicitly. > > + InitData is optional and processor arch dependent. > > > > - If InitData is passed with NULL, this method will use the resource reserved > > - by global variables to initialize it; Otherwise it will use data in > InitData > > - to setup stack switch. This is for the different use cases in DxeCore and > > - Cpu MP exception initialization. > > + @param[in] InitData Pointer to data optional for information about > how > > + to assign stacks for certain exception handlers. > > > > - @param[in] VectorInfo Pointer to reserved vector list. > > - @param[in] InitData Pointer to data required to setup stack switch > for > > - given exceptions. > > - > > - @retval EFI_SUCCESS The exceptions have been successfully > > - initialized. > > - @retval EFI_INVALID_PARAMETER VectorInfo or InitData contains invalid > > - content. > > + @retval EFI_SUCCESS The stacks are assigned successfully. > > + @retval EFI_UNSUPPORTED This function is not supported. > > > > **/ > > EFI_STATUS > > EFIAPI > > -InitializeCpuExceptionHandlersEx ( > > - IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL, > > +InitializeSeparateExceptionStacks ( > > IN CPU_EXCEPTION_INIT_DATA *InitData OPTIONAL > > ) > > { > > - EFI_STATUS Status; > > CPU_EXCEPTION_INIT_DATA EssData; > > IA32_DESCRIPTOR Idtr; > > IA32_DESCRIPTOR Gdtr; > > > > - // > > - // To avoid repeat initialization of default handlers, the caller should > pass > > - // an extended init data with InitDefaultHandlers set to FALSE. There's no > > - // need to call this method to just initialize default handlers. Call > non-ex > > - // version instead; or this method must be implemented as a simple wrapper > of > > - // non-ex version of it, if this version has to be called. > > - // > > - if ((InitData == NULL) || InitData->X64.InitDefaultHandlers) { > > - Status = InitializeCpuExceptionHandlers (VectorInfo); > > - } else { > > - Status = EFI_SUCCESS; > > - } > > - > > - if (!EFI_ERROR (Status)) { > > - // > > - // Initializing stack switch is only necessary for Stack Guard > functionality. > > - // > > - if (PcdGetBool (PcdCpuStackGuard)) { > > - if (InitData == NULL) { > > - SetMem (mNewGdt, sizeof (mNewGdt), 0); > > - > > - AsmReadIdtr (&Idtr); > > - AsmReadGdtr (&Gdtr); > > - > > - EssData.X64.Revision = CPU_EXCEPTION_INIT_DATA_REV; > > - EssData.X64.KnownGoodStackTop = (UINTN)mNewStack + sizeof > (mNewStack); > > - EssData.X64.KnownGoodStackSize = > CPU_KNOWN_GOOD_STACK_SIZE; > > - EssData.X64.StackSwitchExceptions = > CPU_STACK_SWITCH_EXCEPTION_LIST; > > - EssData.X64.StackSwitchExceptionNumber = > CPU_STACK_SWITCH_EXCEPTION_NUMBER; > > - EssData.X64.IdtTable = (VOID *)Idtr.Base; > > - EssData.X64.IdtTableSize = Idtr.Limit + 1; > > - EssData.X64.GdtTable = mNewGdt; > > - EssData.X64.GdtTableSize = sizeof (mNewGdt); > > - EssData.X64.ExceptionTssDesc = mNewGdt + Gdtr.Limit + 1; > > - EssData.X64.ExceptionTssDescSize = CPU_TSS_DESC_SIZE; > > - EssData.X64.ExceptionTss = mNewGdt + Gdtr.Limit + 1 + > CPU_TSS_DESC_SIZE; > > - EssData.X64.ExceptionTssSize = CPU_TSS_SIZE; > > - > > - InitData = &EssData; > > - } > > - > > - Status = ArchSetupExceptionStack (InitData); > > - } > > + if (InitData == NULL) { > > + SetMem (mNewGdt, sizeof (mNewGdt), 0); > > + > > + AsmReadIdtr (&Idtr); > > + AsmReadGdtr (&Gdtr); > > + > > + EssData.X64.Revision = CPU_EXCEPTION_INIT_DATA_REV; > > + EssData.X64.KnownGoodStackTop = (UINTN)mNewStack + sizeof > (mNewStack); > > + EssData.X64.KnownGoodStackSize = CPU_KNOWN_GOOD_STACK_SIZE; > > + EssData.X64.StackSwitchExceptions = > CPU_STACK_SWITCH_EXCEPTION_LIST; > > + EssData.X64.StackSwitchExceptionNumber = > CPU_STACK_SWITCH_EXCEPTION_NUMBER; > > + EssData.X64.IdtTable = (VOID *)Idtr.Base; > > + EssData.X64.IdtTableSize = Idtr.Limit + 1; > > + EssData.X64.GdtTable = mNewGdt; > > + EssData.X64.GdtTableSize = sizeof (mNewGdt); > > + EssData.X64.ExceptionTssDesc = mNewGdt + Gdtr.Limit + 1; > > + EssData.X64.ExceptionTssDescSize = CPU_TSS_DESC_SIZE; > > + EssData.X64.ExceptionTss = mNewGdt + Gdtr.Limit + 1 + > CPU_TSS_DESC_SIZE; > > + EssData.X64.ExceptionTssSize = CPU_TSS_SIZE; > > + > > + InitData = &EssData; > > } > > > > - return Status; > > + return ArchSetupExceptionStack (InitData); > > } > > diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c > index 1ae611c75e..494c2ab433 100644 > --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c > +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c > @@ -150,57 +150,26 @@ InitializeCpuExceptionHandlers ( > } > > > > /** > > - Initializes all CPU exceptions entries with optional extra initializations. > > + Setup separate stacks for certain exception handlers. > > > > - By default, this method should include all functionalities implemented by > > - InitializeCpuExceptionHandlers(), plus extra initialization works, if any. > > - This could be done by calling InitializeCpuExceptionHandlers() directly > > - in this method besides the extra works. > > + InitData is optional and processor arch dependent. > > > > - InitData is optional and its use and content are processor arch dependent. > > - The typical usage of it is to convey resources which have to be reserved > > - elsewhere and are necessary for the extra initializations of exception. > > + @param[in] InitData Pointer to data optional for information about > how > > + to assign stacks for certain exception handlers. > > > > - @param[in] VectorInfo Pointer to reserved vector list. > > - @param[in] InitData Pointer to data optional for extra > initializations > > - of exception. > > - > > - @retval EFI_SUCCESS The exceptions have been successfully > > - initialized. > > - @retval EFI_INVALID_PARAMETER VectorInfo or InitData contains invalid > > - content. > > + @retval EFI_SUCCESS The stacks are assigned successfully. > > + @retval EFI_UNSUPPORTED This function is not supported. > > > > **/ > > EFI_STATUS > > EFIAPI > > -InitializeCpuExceptionHandlersEx ( > > - IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL, > > +InitializeSeparateExceptionStacks ( > > IN CPU_EXCEPTION_INIT_DATA *InitData OPTIONAL > > ) > > { > > - EFI_STATUS Status; > > - > > - // > > - // To avoid repeat initialization of default handlers, the caller should > pass > > - // an extended init data with InitDefaultHandlers set to FALSE. There's no > > - // need to call this method to just initialize default handlers. Call > non-ex > > - // version instead; or this method must be implemented as a simple wrapper > of > > - // non-ex version of it, if this version has to be called. > > - // > > - if ((InitData == NULL) || InitData->Ia32.InitDefaultHandlers) { > > - Status = InitializeCpuExceptionHandlers (VectorInfo); > > - } else { > > - Status = EFI_SUCCESS; > > - } > > - > > - if (!EFI_ERROR (Status)) { > > - // > > - // Initializing stack switch is only necessary for Stack Guard > functionality. > > - // > > - if (PcdGetBool (PcdCpuStackGuard) && (InitData != NULL)) { > > - Status = ArchSetupExceptionStack (InitData); > > - } > > + if (InitData == NULL) { > > + return EFI_UNSUPPORTED; > > } > > > > - return Status; > > + return ArchSetupExceptionStack (InitData); > > } > > diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c > index e894ead612..4313cc5582 100644 > --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c > +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c > @@ -200,33 +200,22 @@ RegisterCpuInterruptHandler ( > } > > > > /** > > - Initializes all CPU exceptions entries with optional extra initializations. > > + Setup separate stacks for certain exception handlers. > > > > - By default, this method should include all functionalities implemented by > > - InitializeCpuExceptionHandlers(), plus extra initialization works, if any. > > - This could be done by calling InitializeCpuExceptionHandlers() directly > > - in this method besides the extra works. > > + InitData is optional and processor arch dependent. > > > > - InitData is optional and its use and content are processor arch dependent. > > - The typical usage of it is to convey resources which have to be reserved > > - elsewhere and are necessary for the extra initializations of exception. > > + @param[in] InitData Pointer to data optional for information about > how > > + to assign stacks for certain exception handlers. > > > > - @param[in] VectorInfo Pointer to reserved vector list. > > - @param[in] InitData Pointer to data optional for extra > initializations > > - of exception. > > - > > - @retval EFI_SUCCESS The exceptions have been successfully > > - initialized. > > - @retval EFI_INVALID_PARAMETER VectorInfo or InitData contains invalid > > - content. > > + @retval EFI_SUCCESS The stacks are assigned successfully. > > + @retval EFI_UNSUPPORTED This function is not supported. > > > > **/ > > EFI_STATUS > > EFIAPI > > -InitializeCpuExceptionHandlersEx ( > > - IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL, > > +InitializeSeparateExceptionStacks ( > > IN CPU_EXCEPTION_INIT_DATA *InitData OPTIONAL > > ) > > { > > - return InitializeCpuExceptionHandlers (VectorInfo); > > + return EFI_UNSUPPORTED; > > } > > diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c > index ec643556c7..1c97dab926 100644 > --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c > +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c > @@ -96,33 +96,22 @@ RegisterCpuInterruptHandler ( > } > > > > /** > > - Initializes all CPU exceptions entries with optional extra initializations. > > + Setup separate stacks for certain exception handlers. > > > > - By default, this method should include all functionalities implemented by > > - InitializeCpuExceptionHandlers(), plus extra initialization works, if any. > > - This could be done by calling InitializeCpuExceptionHandlers() directly > > - in this method besides the extra works. > > + InitData is optional and processor arch dependent. > > > > - InitData is optional and its use and content are processor arch dependent. > > - The typical usage of it is to convey resources which have to be reserved > > - elsewhere and are necessary for the extra initializations of exception. > > + @param[in] InitData Pointer to data optional for information about > how > > + to assign stacks for certain exception handlers. > > > > - @param[in] VectorInfo Pointer to reserved vector list. > > - @param[in] InitData Pointer to data optional for extra > initializations > > - of exception. > > - > > - @retval EFI_SUCCESS The exceptions have been successfully > > - initialized. > > - @retval EFI_INVALID_PARAMETER VectorInfo or InitData contains invalid > > - content. > > + @retval EFI_SUCCESS The stacks are assigned successfully. > > + @retval EFI_UNSUPPORTED This function is not supported. > > > > **/ > > EFI_STATUS > > EFIAPI > > -InitializeCpuExceptionHandlersEx ( > > - IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL, > > +InitializeSeparateExceptionStacks ( > > IN CPU_EXCEPTION_INIT_DATA *InitData OPTIONAL > > ) > > { > > - return InitializeCpuExceptionHandlers (VectorInfo); > > + return EFI_UNSUPPORTED; > > } > > -- > 2.35.1.windows.2 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#89938): https://edk2.groups.io/g/devel/message/89938 Mute This Topic: https://groups.io/mt/91231771/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-