From 0f7bccf584d93b2642c0a413a47fc821d1f5dbfd Mon Sep 17 00:00:00 2001 From: "Liu, Zhiguang" Date: Tue, 9 Aug 2022 09:25:35 +0800 Subject: UefiCpuPkg: Simplify InitializeSeparateExceptionStacks Hide the Exception implementation details in CpuExcetionHandlerLib and caller only need to provide buffer Cc: Eric Dong Reviewed-by: Ray Ni Cc: Rahul Kumar Cc: Leif Lindholm Cc: Dandan Bi Cc: Liming Gao Cc: Jian J Wang Cc: Ard Biesheuvel Reviewed-by: Sami Mujawar Signed-off-by: Zhiguang Liu --- UefiCpuPkg/CpuMpPei/CpuMpPei.c | 176 ++++++++--------------------------------- 1 file changed, 34 insertions(+), 142 deletions(-) (limited to 'UefiCpuPkg/CpuMpPei') diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.c b/UefiCpuPkg/CpuMpPei/CpuMpPei.c index d478697..c0be11d 100644 --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.c +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.c @@ -1,7 +1,7 @@ /** @file CPU PEI Module installs CPU Multiple Processor PPI. - Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.
+ Copyright (c) 2015 - 2022, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -411,23 +411,13 @@ PeiWhoAmI ( return MpInitLibWhoAmI (ProcessorNumber); } -/** - Get GDT register value. - - This function is mainly for AP purpose because AP may have different GDT - table than BSP. - - @param[in,out] Buffer The pointer to private data buffer. - -**/ -VOID -EFIAPI -GetGdtr ( - IN OUT VOID *Buffer - ) -{ - AsmReadGdtr ((IA32_DESCRIPTOR *)Buffer); -} +// +// Structure for InitializeSeparateExceptionStacks +// +typedef struct { + VOID *Buffer; + UINTN *BufferSize; +} EXCEPTION_STACK_SWITCH_CONTEXT; /** Initializes CPU exceptions handlers for the sake of stack switch requirement. @@ -444,27 +434,17 @@ InitializeExceptionStackSwitchHandlers ( IN OUT VOID *Buffer ) { - CPU_EXCEPTION_INIT_DATA *EssData; - IA32_DESCRIPTOR Idtr; - EFI_STATUS Status; + EXCEPTION_STACK_SWITCH_CONTEXT *SwitchStackData; - EssData = Buffer; - // - // We don't plan to replace IDT table with a new one, but we should not assume - // the AP's IDT is the same as BSP's IDT either. - // - AsmReadIdtr (&Idtr); - EssData->Ia32.IdtTable = (VOID *)Idtr.Base; - EssData->Ia32.IdtTableSize = Idtr.Limit + 1; - Status = InitializeSeparateExceptionStacks (EssData); - ASSERT_EFI_ERROR (Status); + SwitchStackData = (EXCEPTION_STACK_SWITCH_CONTEXT *)Buffer; + InitializeSeparateExceptionStacks (SwitchStackData->Buffer, SwitchStackData->BufferSize); } /** Initializes MP exceptions handlers for the sake of stack switch requirement. This function will allocate required resources required to setup stack switch - and pass them through CPU_EXCEPTION_INIT_DATA to each logic processor. + and pass them through SwitchStackData to each logic processor. **/ VOID @@ -472,148 +452,60 @@ InitializeMpExceptionStackSwitchHandlers ( VOID ) { - EFI_STATUS Status; - UINTN Index; - UINTN Bsp; - UINTN ExceptionNumber; - UINTN OldGdtSize; - UINTN NewGdtSize; - UINTN NewStackSize; - IA32_DESCRIPTOR Gdtr; - CPU_EXCEPTION_INIT_DATA EssData; - UINT8 *GdtBuffer; - UINT8 *StackTop; - UINTN NumberOfProcessors; + UINTN Index; + UINTN Bsp; + EXCEPTION_STACK_SWITCH_CONTEXT SwitchStackData; + UINTN BufferSize; + UINTN NumberOfProcessors; if (!PcdGetBool (PcdCpuStackGuard)) { return; } + SwitchStackData.BufferSize = &BufferSize; MpInitLibGetNumberOfProcessors (&NumberOfProcessors, NULL); MpInitLibWhoAmI (&Bsp); - ExceptionNumber = FixedPcdGetSize (PcdCpuStackSwitchExceptionList); - NewStackSize = FixedPcdGet32 (PcdCpuKnownGoodStackSize) * ExceptionNumber; - - StackTop = AllocatePages (EFI_SIZE_TO_PAGES (NewStackSize * NumberOfProcessors)); - ASSERT (StackTop != NULL); - if (StackTop == NULL) { - return; - } - - StackTop += NewStackSize * NumberOfProcessors; - - // - // The default exception handlers must have been initialized. Let's just skip - // it in this method. - // - EssData.Ia32.Revision = CPU_EXCEPTION_INIT_DATA_REV; - EssData.Ia32.InitDefaultHandlers = FALSE; - - EssData.Ia32.StackSwitchExceptions = FixedPcdGetPtr (PcdCpuStackSwitchExceptionList); - EssData.Ia32.StackSwitchExceptionNumber = ExceptionNumber; - EssData.Ia32.KnownGoodStackSize = FixedPcdGet32 (PcdCpuKnownGoodStackSize); - - // - // Initialize Gdtr to suppress incorrect compiler/analyzer warnings. - // - Gdtr.Base = 0; - Gdtr.Limit = 0; for (Index = 0; Index < NumberOfProcessors; ++Index) { - // - // To support stack switch, we need to re-construct GDT but not IDT. - // + SwitchStackData.Buffer = NULL; + BufferSize = 0; + if (Index == Bsp) { - GetGdtr (&Gdtr); + InitializeExceptionStackSwitchHandlers (&SwitchStackData); } else { // - // AP might have different size of GDT from BSP. + // AP might need different buffer size from BSP. // - MpInitLibStartupThisAP (GetGdtr, Index, NULL, 0, (VOID *)&Gdtr, NULL); + MpInitLibStartupThisAP (InitializeExceptionStackSwitchHandlers, Index, NULL, 0, (VOID *)&SwitchStackData, NULL); } - // - // X64 needs only one TSS of current task working for all exceptions - // because of its IST feature. IA32 needs one TSS for each exception - // in addition to current task. Since AP is not supposed to allocate - // memory, we have to do it in BSP. To simplify the code, we allocate - // memory for IA32 case to cover both IA32 and X64 exception stack - // switch. - // - // Layout of memory to allocate for each processor: - // -------------------------------- - // | Alignment | (just in case) - // -------------------------------- - // | | - // | Original GDT | - // | | - // -------------------------------- - // | Current task descriptor | - // -------------------------------- - // | | - // | Exception task descriptors | X ExceptionNumber - // | | - // -------------------------------- - // | Current task-state segment | - // -------------------------------- - // | | - // | Exception task-state segment | X ExceptionNumber - // | | - // -------------------------------- - // - OldGdtSize = Gdtr.Limit + 1; - EssData.Ia32.ExceptionTssDescSize = sizeof (IA32_TSS_DESCRIPTOR) * - (ExceptionNumber + 1); - EssData.Ia32.ExceptionTssSize = sizeof (IA32_TASK_STATE_SEGMENT) * - (ExceptionNumber + 1); - NewGdtSize = sizeof (IA32_TSS_DESCRIPTOR) + - OldGdtSize + - EssData.Ia32.ExceptionTssDescSize + - EssData.Ia32.ExceptionTssSize; - - Status = PeiServicesAllocatePool ( - NewGdtSize, - (VOID **)&GdtBuffer - ); - ASSERT (GdtBuffer != NULL); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return; + if (BufferSize == 0) { + continue; } - // - // Make sure GDT table alignment - // - EssData.Ia32.GdtTable = ALIGN_POINTER (GdtBuffer, sizeof (IA32_TSS_DESCRIPTOR)); - NewGdtSize -= ((UINT8 *)EssData.Ia32.GdtTable - GdtBuffer); - EssData.Ia32.GdtTableSize = NewGdtSize; - - EssData.Ia32.ExceptionTssDesc = ((UINT8 *)EssData.Ia32.GdtTable + OldGdtSize); - EssData.Ia32.ExceptionTss = ((UINT8 *)EssData.Ia32.GdtTable + OldGdtSize + - EssData.Ia32.ExceptionTssDescSize); - - EssData.Ia32.KnownGoodStackTop = (UINTN)StackTop; + SwitchStackData.Buffer = AllocatePages (EFI_SIZE_TO_PAGES (BufferSize)); + ASSERT (SwitchStackData.Buffer != NULL); + ZeroMem (SwitchStackData.Buffer, EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (BufferSize))); DEBUG (( DEBUG_INFO, - "Exception stack top[cpu%lu]: 0x%lX\n", + "Buffer[cpu%lu] for InitializeExceptionStackSwitchHandlers: 0x%lX with size 0x%x\n", (UINT64)(UINTN)Index, - (UINT64)(UINTN)StackTop + (UINT64)(UINTN)SwitchStackData.Buffer, + (UINT32)BufferSize )); if (Index == Bsp) { - InitializeExceptionStackSwitchHandlers (&EssData); + InitializeExceptionStackSwitchHandlers (&SwitchStackData); } else { MpInitLibStartupThisAP ( InitializeExceptionStackSwitchHandlers, Index, NULL, 0, - (VOID *)&EssData, + (VOID *)&SwitchStackData, NULL ); } - - StackTop -= NewStackSize; } } -- cgit v1.1