From nobody Sun May 19 16:27:49 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+92849+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+92849+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1661497503; cv=none; d=zohomail.com; s=zohoarc; b=Y1iyanr3fVRqQ28T7nCPHS9Gi6OCjYwNMkR0AKSZf/+13ZnKVhpf85fQg7aJSYEh/jYTarCd5wLUv+4c/TtsQ+2IbqHlmJ0ZusARN89+nGUUYZOqJOyhEgZVg5WYTBvLvoR7sgBoiX+TdVJtmMVH/DHD/hHrfhRk9BpCmEmOj3I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1661497503; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=8O5Rb0T4vWKOutbWgOcalg6qVOvfWVqOk4Rzf+sw6I4=; b=lTfK4T1bnROiJBUmEOeYbIiWlDD/sTiGm+jKTItioweIFpxcd/R+Jw92/FBjKEvUxa1LiEUfgu3KFJVH0pTq8GFwu65zoOUWO2kWnhdxH0GkqgxvxOsuZRrDZi68hoVb05Qw4Wg/yB/pUDSGClVtLAmrg3D/aSHX/nJH1kV+R5g= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+92849+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1661497503046885.5065119431666; Fri, 26 Aug 2022 00:05:03 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id iaTaYY1788612x8pkKLGN6H2; Fri, 26 Aug 2022 00:05:02 -0700 X-Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by mx.groups.io with SMTP id smtpd.web08.34470.1661497501700181625 for ; Fri, 26 Aug 2022 00:05:01 -0700 X-IronPort-AV: E=McAfee;i="6500,9779,10450"; a="274193845" X-IronPort-AV: E=Sophos;i="5.93,264,1654585200"; d="scan'208";a="274193845" X-Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Aug 2022 00:05:01 -0700 X-IronPort-AV: E=Sophos;i="5.93,264,1654585200"; d="scan'208";a="938651868" X-Received: from shwdesfp01.ccr.corp.intel.com ([10.239.158.151]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Aug 2022 00:04:59 -0700 From: "Zhiguang Liu" To: devel@edk2.groups.io Cc: Zhiguang Liu , Eric Dong , Ray Ni , Rahul Kumar Subject: [edk2-devel] [PATCH v2] UefiCpuPkg: Simplify the implementation when separate exception stacks Date: Fri, 26 Aug 2022 15:04:47 +0800 Message-Id: <20220826070447.2508-3-zhiguang.liu@intel.com> In-Reply-To: <20220826070447.2508-1-zhiguang.liu@intel.com> References: <20220826070447.2508-1-zhiguang.liu@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,zhiguang.liu@intel.com X-Gm-Message-State: Y0So02seQ5UDhWUM3V2woGmjx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1661497502; bh=/jfNteXtysrSglcIwJX5BVcRDxzbg9nZK7gacThsM9M=; h=Cc:Date:From:Reply-To:Subject:To; b=INcUaPKN2QwwDxDZAt3Y0++WiW3ktPZHQTgmnnKDrLpnraQQ7Pa7e+uzsbyxHDLTDiZ 0Oobdi42P4/HYi9eGn69CrRlI8Rg09mEICAWbuWtFlv3PifFoLdhU3DBuDGIXX+OWwgsB IG1sosxoSQeIG+l3JaMKCPkMuR+KVM7fZGQ= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1661497505205100007 Content-Type: text/plain; charset="utf-8" The API of InitializeSeparateExceptionStacks is just changed before, and makes the struct CPU_EXCEPTION_INIT_DATA an internal definition. Furthermore, we can even remove the struct to make core simpler. Cc: Eric Dong Cc: Ray Ni Cc: Rahul Kumar Signed-off-by: Zhiguang Liu Reviewed-by: Ray Ni --- .../CpuExceptionCommon.h | 73 ++------- .../CpuExceptionHandlerLib/DxeException.c | 92 ++--------- .../Ia32/ArchExceptionHandler.c | 148 ++++++++---------- .../CpuExceptionHandlerLib/PeiCpuException.c | 77 +-------- .../SecPeiCpuExceptionHandlerLib.inf | 7 +- .../SmmCpuExceptionHandlerLib.inf | 7 +- .../X64/ArchExceptionHandler.c | 145 ++++++++--------- .../Xcode5SecPeiCpuExceptionHandlerLib.inf | 7 +- 8 files changed, 173 insertions(+), 383 deletions(-) diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h= b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h index 11a5624f51..4593c204a6 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h @@ -49,61 +49,6 @@ =20 #define CPU_TSS_GDT_SIZE (SIZE_2KB + CPU_TSS_DESC_SIZE + CPU_TSS_SIZE) =20 -typedef struct { - // - // The address of top of known good stack reserved for *ALL* exceptions - // listed in field StackSwitchExceptions. - // - UINTN KnownGoodStackTop; - // - // The size of known good stack for *ONE* exception only. - // - UINTN KnownGoodStackSize; - // - // Buffer of exception vector list for stack switch. - // - UINT8 *StackSwitchExceptions; - // - // Number of exception vectors in StackSwitchExceptions. - // - UINTN StackSwitchExceptionNumber; - // - // Buffer of IDT table. It must be type of IA32_IDT_GATE_DESCRIPTOR. - // Normally there's no need to change IDT table size. - // - VOID *IdtTable; - // - // Size of buffer for IdtTable. - // - UINTN IdtTableSize; - // - // Buffer of GDT table. It must be type of IA32_SEGMENT_DESCRIPTOR. - // - VOID *GdtTable; - // - // Size of buffer for GdtTable. - // - UINTN GdtTableSize; - // - // Pointer to start address of descriptor of exception task gate in the - // GDT table. It must be type of IA32_TSS_DESCRIPTOR. - // - VOID *ExceptionTssDesc; - // - // Size of buffer for ExceptionTssDesc. - // - UINTN ExceptionTssDescSize; - // - // Buffer of task-state segment for exceptions. It must be type of - // IA32_TASK_STATE_SEGMENT. - // - VOID *ExceptionTss; - // - // Size of buffer for ExceptionTss. - // - UINTN ExceptionTssSize; -} CPU_EXCEPTION_INIT_DATA; - // // Record exception handler information // @@ -345,18 +290,22 @@ CommonExceptionHandlerWorker ( ); =20 /** - Setup separate stack for specific exceptions. + Setup separate stacks for certain exception handlers. =20 - @param[in] StackSwitchData Pointer to data required for setuping up - stack switch. + @param[in] Buffer Point to buffer used to separate exceptio= n stack. + @param[in, out] BufferSize On input, it indicates the byte size of B= uffer. + If the size is not enough, the return sta= tus will + be EFI_BUFFER_TOO_SMALL, and output Buffe= rSize + will be the size it needs. =20 - @retval EFI_SUCCESS The exceptions have been successfully - initialized with new stack. - @retval EFI_INVALID_PARAMETER StackSwitchData contains invalid content. + @retval EFI_SUCCESS The stacks are assigned successfully. + @retval EFI_BUFFER_TOO_SMALL This BufferSize is too small. + @retval EFI_UNSUPPORTED This function is not supported. **/ EFI_STATUS ArchSetupExceptionStack ( - IN CPU_EXCEPTION_INIT_DATA *StackSwitchData + IN VOID *Buffer, + IN OUT UINTN *BufferSize ); =20 /** diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c b/Uef= iCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c index d90c607bd7..ee989bf079 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c @@ -23,9 +23,8 @@ EXCEPTION_HANDLER_DATA mExceptionHandlerData =3D { mExternalInterruptHandlerTable }; =20 -UINT8 mNewStack[CPU_STACK_SWITCH_EXCEPTION_NUMBER * - CPU_KNOWN_GOOD_STACK_SIZE]; -UINT8 mNewGdt[CPU_TSS_GDT_SIZE]; +UINT8 mBuffer[CPU_STACK_SWITCH_EXCEPTION_NUMBER * CPU_KNOWN_GOOD_STACK_SI= ZE + + CPU_TSS_GDT_SIZE]; =20 /** Common exception handler. @@ -123,85 +122,16 @@ InitializeSeparateExceptionStacks ( IN OUT UINTN *BufferSize ) { - CPU_EXCEPTION_INIT_DATA EssData; - IA32_DESCRIPTOR Idtr; - IA32_DESCRIPTOR Gdtr; - UINTN NeedBufferSize; - UINTN StackTop; - UINT8 *NewGdtTable; - - // - // 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. To simplify the code, we report the - // needed memory for IA32 case to cover both IA32 and X64 exception - // stack switch. - // - // Layout of memory needed 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 - // | | - // -------------------------------- - // - AsmReadGdtr (&Gdtr); + UINTN LocalBufferSize; + EFI_STATUS Status; + if ((Buffer =3D=3D NULL) && (BufferSize =3D=3D NULL)) { - SetMem (mNewGdt, sizeof (mNewGdt), 0); - StackTop =3D (UINTN)mNewStack + sizeof (mNewStack); - NewGdtTable =3D mNewGdt; + SetMem (mBuffer, sizeof (mBuffer), 0); + LocalBufferSize =3D sizeof (mBuffer); + Status =3D ArchSetupExceptionStack (mBuffer, &LocalBufferSize= ); + ASSERT_EFI_ERROR (Status); + return Status; } else { - if (BufferSize =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Total needed size includes stack size, new GDT table size, TSS size. - // Add another DESCRIPTOR size for alignment requiremet. - // - NeedBufferSize =3D CPU_STACK_SWITCH_EXCEPTION_NUMBER * CPU_KNOWN_GOOD_= STACK_SIZE + - CPU_TSS_DESC_SIZE + Gdtr.Limit + 1 + - CPU_TSS_SIZE + - sizeof (IA32_TSS_DESCRIPTOR); - if (*BufferSize < NeedBufferSize) { - *BufferSize =3D NeedBufferSize; - return EFI_BUFFER_TOO_SMALL; - } - - if (Buffer =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - StackTop =3D (UINTN)Buffer + CPU_STACK_SWITCH_EXCEPTION_NUMBER * CP= U_KNOWN_GOOD_STACK_SIZE; - NewGdtTable =3D ALIGN_POINTER (StackTop, sizeof (IA32_TSS_DESCRIPTOR)); + return ArchSetupExceptionStack (Buffer, BufferSize); } - - AsmReadIdtr (&Idtr); - EssData.KnownGoodStackTop =3D StackTop; - EssData.KnownGoodStackSize =3D CPU_KNOWN_GOOD_STACK_SIZE; - EssData.StackSwitchExceptions =3D CPU_STACK_SWITCH_EXCEPTION_LIST; - EssData.StackSwitchExceptionNumber =3D CPU_STACK_SWITCH_EXCEPTION_NUMBER; - EssData.IdtTable =3D (VOID *)Idtr.Base; - EssData.IdtTableSize =3D Idtr.Limit + 1; - EssData.GdtTable =3D NewGdtTable; - EssData.GdtTableSize =3D CPU_TSS_DESC_SIZE + Gdtr.Limit + = 1; - EssData.ExceptionTssDesc =3D NewGdtTable + Gdtr.Limit + 1; - EssData.ExceptionTssDescSize =3D CPU_TSS_DESC_SIZE; - EssData.ExceptionTss =3D NewGdtTable + Gdtr.Limit + 1 + CP= U_TSS_DESC_SIZE; - EssData.ExceptionTssSize =3D CPU_TSS_SIZE; - - return ArchSetupExceptionStack (&EssData); } diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHa= ndler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandl= er.c index 194d3a499b..8c398ebc5b 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c @@ -104,108 +104,97 @@ ArchRestoreExceptionContext ( } =20 /** - Setup separate stack for given exceptions. + Setup separate stacks for certain exception handlers. =20 - @param[in] StackSwitchData Pointer to data required for setuping up - stack switch. - - @retval EFI_SUCCESS The exceptions have been successfully - initialized with new stack. - @retval EFI_INVALID_PARAMETER StackSwitchData contains invalid content. + @param[in] Buffer Point to buffer used to separate exceptio= n stack. + @param[in, out] BufferSize On input, it indicates the byte size of B= uffer. + If the size is not enough, the return sta= tus will + be EFI_BUFFER_TOO_SMALL, and output Buffe= rSize + will be the size it needs. =20 + @retval EFI_SUCCESS The stacks are assigned successfully. + @retval EFI_BUFFER_TOO_SMALL This BufferSize is too small. **/ EFI_STATUS ArchSetupExceptionStack ( - IN CPU_EXCEPTION_INIT_DATA *StackSwitchData + IN VOID *Buffer, + IN OUT UINTN *BufferSize ) { IA32_DESCRIPTOR Gdtr; IA32_DESCRIPTOR Idtr; IA32_IDT_GATE_DESCRIPTOR *IdtTable; IA32_TSS_DESCRIPTOR *TssDesc; + IA32_TSS_DESCRIPTOR *TssDescBase; IA32_TASK_STATE_SEGMENT *Tss; + VOID *NewGdtTable; UINTN StackTop; UINTN Index; UINTN Vector; UINTN TssBase; - UINTN GdtSize; + UINT8 *StackSwitchExceptions; + UINTN NeedBufferSize; EXCEPTION_HANDLER_TEMPLATE_MAP TemplateMap; =20 - if ((StackSwitchData =3D=3D NULL) || - (StackSwitchData->KnownGoodStackTop =3D=3D 0) || - (StackSwitchData->KnownGoodStackSize =3D=3D 0) || - (StackSwitchData->StackSwitchExceptions =3D=3D NULL) || - (StackSwitchData->StackSwitchExceptionNumber =3D=3D 0) || - (StackSwitchData->StackSwitchExceptionNumber > CPU_EXCEPTION_NUM) || - (StackSwitchData->GdtTable =3D=3D NULL) || - (StackSwitchData->IdtTable =3D=3D NULL) || - (StackSwitchData->ExceptionTssDesc =3D=3D NULL) || - (StackSwitchData->ExceptionTss =3D=3D NULL)) - { + if (BufferSize =3D=3D NULL) { return EFI_INVALID_PARAMETER; } =20 // - // The caller is responsible for that the GDT table, no matter the exist= ing - // one or newly allocated, has enough space to hold descriptors for exce= ption - // task-state segments. + // Total needed size includes stack size, new GDT table size, TSS size. + // Add another DESCRIPTOR size for alignment requiremet. // - if (((UINTN)StackSwitchData->GdtTable & (IA32_GDT_ALIGNMENT - 1)) !=3D 0= ) { - return EFI_INVALID_PARAMETER; - } - - if ((UINTN)StackSwitchData->ExceptionTssDesc < (UINTN)(StackSwitchData->= GdtTable)) { - return EFI_INVALID_PARAMETER; - } - - if ((UINTN)StackSwitchData->ExceptionTssDesc + StackSwitchData->Exceptio= nTssDescSize > - ((UINTN)(StackSwitchData->GdtTable) + StackSwitchData->GdtTableSize)) - { - return EFI_INVALID_PARAMETER; - } - + // Layout of memory needed for each processor: + // -------------------------------- + // | | + // | Stack Size | X ExceptionNumber + // | | + // -------------------------------- + // | Alignment | (just in case) + // -------------------------------- + // | | + // | Original GDT | + // | | + // -------------------------------- + // | Current task descriptor | + // -------------------------------- + // | | + // | Exception task descriptors | X ExceptionNumber + // | | + // -------------------------------- + // | Current task-state segment | + // -------------------------------- + // | | + // | Exception task-state segment | X ExceptionNumber + // | | + // -------------------------------- // - // We need one descriptor and one TSS for current task and every excepti= on - // specified. - // - if (StackSwitchData->ExceptionTssDescSize < - sizeof (IA32_TSS_DESCRIPTOR) * (StackSwitchData->StackSwitchExceptio= nNumber + 1)) - { - return EFI_INVALID_PARAMETER; + AsmReadGdtr (&Gdtr); + NeedBufferSize =3D CPU_STACK_SWITCH_EXCEPTION_NUMBER * CPU_KNOWN_GOOD_ST= ACK_SIZE + + sizeof (IA32_TSS_DESCRIPTOR) + + Gdtr.Limit + 1 + CPU_TSS_DESC_SIZE + + CPU_TSS_SIZE; + + if (*BufferSize < NeedBufferSize) { + *BufferSize =3D NeedBufferSize; + return EFI_BUFFER_TOO_SMALL; } =20 - if (StackSwitchData->ExceptionTssSize < - sizeof (IA32_TASK_STATE_SEGMENT) * (StackSwitchData->StackSwitchExce= ptionNumber + 1)) - { + if (Buffer =3D=3D NULL) { return EFI_INVALID_PARAMETER; } =20 - TssDesc =3D StackSwitchData->ExceptionTssDesc; - Tss =3D StackSwitchData->ExceptionTss; - - // - // Initialize new GDT table and/or IDT table, if any - // AsmReadIdtr (&Idtr); - AsmReadGdtr (&Gdtr); - - GdtSize =3D (UINTN)TssDesc + - sizeof (IA32_TSS_DESCRIPTOR) * - (StackSwitchData->StackSwitchExceptionNumber + 1) - - (UINTN)(StackSwitchData->GdtTable); - if ((UINTN)StackSwitchData->GdtTable !=3D Gdtr.Base) { - CopyMem (StackSwitchData->GdtTable, (VOID *)Gdtr.Base, Gdtr.Limit + 1); - Gdtr.Base =3D (UINTN)StackSwitchData->GdtTable; - Gdtr.Limit =3D (UINT16)GdtSize - 1; - } - - if ((UINTN)StackSwitchData->IdtTable !=3D Idtr.Base) { - Idtr.Base =3D (UINTN)StackSwitchData->IdtTable; - } + StackSwitchExceptions =3D CPU_STACK_SWITCH_EXCEPTION_LIST; + StackTop =3D (UINTN)Buffer + CPU_STACK_SWITCH_EXCEPTION_NUM= BER * CPU_KNOWN_GOOD_STACK_SIZE; + NewGdtTable =3D ALIGN_POINTER (StackTop, sizeof (IA32_TSS_DESC= RIPTOR)); + TssDesc =3D (IA32_TSS_DESCRIPTOR *)((UINTN)NewGdtTable + G= dtr.Limit + 1); + Tss =3D (IA32_TASK_STATE_SEGMENT *)((UINTN)TssDesc + C= PU_TSS_DESC_SIZE); + TssDescBase =3D TssDesc; =20 - if (StackSwitchData->IdtTableSize > 0) { - Idtr.Limit =3D (UINT16)(StackSwitchData->IdtTableSize - 1); - } + CopyMem (NewGdtTable, (VOID *)Gdtr.Base, Gdtr.Limit + 1); + Gdtr.Base =3D (UINTN)NewGdtTable; + Gdtr.Limit =3D (UINT16)(Gdtr.Limit + CPU_TSS_DESC_SIZE); =20 // // Fixup current task descriptor. Task-state segment for current task wi= ll @@ -226,10 +215,10 @@ ArchSetupExceptionStack ( // Fixup exception task descriptor and task-state segment // AsmGetTssTemplateMap (&TemplateMap); - StackTop =3D StackSwitchData->KnownGoodStackTop - CPU_STACK_ALIGNMENT; + StackTop =3D StackTop - CPU_STACK_ALIGNMENT; StackTop =3D (UINTN)ALIGN_POINTER (StackTop, CPU_STACK_ALIGNMENT); - IdtTable =3D StackSwitchData->IdtTable; - for (Index =3D 0; Index < StackSwitchData->StackSwitchExceptionNumber; += +Index) { + IdtTable =3D (IA32_IDT_GATE_DESCRIPTOR *)Idtr.Base; + for (Index =3D 0; Index < CPU_STACK_SWITCH_EXCEPTION_NUMBER; ++Index) { TssDesc +=3D 1; Tss +=3D 1; =20 @@ -250,7 +239,7 @@ ArchSetupExceptionStack ( // // Fixup TSS // - Vector =3D StackSwitchData->StackSwitchExceptions[Index]; + Vector =3D StackSwitchExceptions[Index]; if ((Vector >=3D CPU_EXCEPTION_NUM) || (Vector >=3D (Idtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR))) { @@ -270,7 +259,7 @@ ArchSetupExceptionStack ( Tss->FS =3D AsmReadFs (); Tss->GS =3D AsmReadGs (); =20 - StackTop -=3D StackSwitchData->KnownGoodStackSize; + StackTop -=3D CPU_KNOWN_GOOD_STACK_SIZE; =20 // // Update IDT to use Task Gate for given exception @@ -290,12 +279,7 @@ ArchSetupExceptionStack ( // // Load current task // - AsmWriteTr ((UINT16)((UINTN)StackSwitchData->ExceptionTssDesc - Gdtr.Bas= e)); - - // - // Publish IDT - // - AsmWriteIdtr (&Idtr); + AsmWriteTr ((UINT16)((UINTN)TssDescBase - Gdtr.Base)); =20 return EFI_SUCCESS; } diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c b/= UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c index 5952295126..940d83a92f 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c @@ -170,84 +170,9 @@ InitializeSeparateExceptionStacks ( IN OUT UINTN *BufferSize ) { - CPU_EXCEPTION_INIT_DATA EssData; - IA32_DESCRIPTOR Idtr; - IA32_DESCRIPTOR Gdtr; - UINTN NeedBufferSize; - UINTN StackTop; - UINT8 *NewGdtTable; - - // - // 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. To simplify the code, we report the - // needed memory for IA32 case to cover both IA32 and X64 exception - // stack switch. - // - // Layout of memory needed 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 - // | | - // -------------------------------- - // - if ((Buffer =3D=3D NULL) && (BufferSize =3D=3D NULL)) { return EFI_UNSUPPORTED; } =20 - if (BufferSize =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - AsmReadGdtr (&Gdtr); - // - // Total needed size includes stack size, new GDT table size, TSS size. - // Add another DESCRIPTOR size for alignment requiremet. - // - NeedBufferSize =3D CPU_STACK_SWITCH_EXCEPTION_NUMBER * CPU_KNOWN_GOOD_ST= ACK_SIZE + - CPU_TSS_DESC_SIZE + Gdtr.Limit + 1 + - CPU_TSS_SIZE + - sizeof (IA32_TSS_DESCRIPTOR); - if (*BufferSize < NeedBufferSize) { - *BufferSize =3D NeedBufferSize; - return EFI_BUFFER_TOO_SMALL; - } - - if (Buffer =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - StackTop =3D (UINTN)Buffer + CPU_STACK_SWITCH_EXCEPTION_NUMBER * CPU_= KNOWN_GOOD_STACK_SIZE; - NewGdtTable =3D ALIGN_POINTER (StackTop, sizeof (IA32_TSS_DESCRIPTOR)); - - AsmReadIdtr (&Idtr); - EssData.KnownGoodStackTop =3D StackTop; - EssData.KnownGoodStackSize =3D CPU_KNOWN_GOOD_STACK_SIZE; - EssData.StackSwitchExceptions =3D CPU_STACK_SWITCH_EXCEPTION_LIST; - EssData.StackSwitchExceptionNumber =3D CPU_STACK_SWITCH_EXCEPTION_NUMBER; - EssData.IdtTable =3D (VOID *)Idtr.Base; - EssData.IdtTableSize =3D Idtr.Limit + 1; - EssData.GdtTable =3D NewGdtTable; - EssData.GdtTableSize =3D CPU_TSS_DESC_SIZE + Gdtr.Limit + = 1; - EssData.ExceptionTssDesc =3D NewGdtTable + Gdtr.Limit + 1; - EssData.ExceptionTssDescSize =3D CPU_TSS_DESC_SIZE; - EssData.ExceptionTss =3D NewGdtTable + Gdtr.Limit + 1 + CP= U_TSS_DESC_SIZE; - EssData.ExceptionTssSize =3D CPU_TSS_SIZE; - - return ArchSetupExceptionStack (&EssData); + return ArchSetupExceptionStack (Buffer, BufferSize); } diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHa= ndlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException= HandlerLib.inf index 8ae4feae62..6a170286c8 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLi= b.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLi= b.inf @@ -1,7 +1,7 @@ ## @file # CPU Exception Handler library instance for SEC/PEI modules. # -# Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.
+# Copyright (c) 2012 - 2022, Intel Corporation. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -50,6 +50,11 @@ PeCoffGetEntryPointLib VmgExitLib =20 +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard + gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList + gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize + [FeaturePcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard ## CONS= UMES =20 diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandl= erLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandle= rLib.inf index c9f20da058..9dde07612a 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.i= nf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.i= nf @@ -1,7 +1,7 @@ ## @file # CPU Exception Handler library instance for SMM modules. # -# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+# Copyright (c) 2013 - 2022, Intel Corporation. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -53,6 +53,11 @@ DebugLib VmgExitLib =20 +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard + gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList + gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize + [FeaturePcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard ## CONS= UMES =20 diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHan= dler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler= .c index c14ac66c43..80e9f08e5b 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c @@ -109,19 +109,22 @@ ArchRestoreExceptionContext ( } =20 /** - Setup separate stack for given exceptions. + Setup separate stacks for certain exception handlers. =20 - @param[in] StackSwitchData Pointer to data required for setuping up - stack switch. - - @retval EFI_SUCCESS The exceptions have been successfully - initialized with new stack. - @retval EFI_INVALID_PARAMETER StackSwitchData contains invalid content. + @param[in] Buffer Point to buffer used to separate exceptio= n stack. + @param[in, out] BufferSize On input, it indicates the byte size of B= uffer. + If the size is not enough, the return sta= tus will + be EFI_BUFFER_TOO_SMALL, and output Buffe= rSize + will be the size it needs. =20 + @retval EFI_SUCCESS The stacks are assigned successfully. + @retval EFI_BUFFER_TOO_SMALL This BufferSize is too small. + @retval EFI_UNSUPPORTED This function is not supported. **/ EFI_STATUS ArchSetupExceptionStack ( - IN CPU_EXCEPTION_INIT_DATA *StackSwitchData + IN VOID *Buffer, + IN OUT UINTN *BufferSize ) { IA32_DESCRIPTOR Gdtr; @@ -129,86 +132,75 @@ ArchSetupExceptionStack ( IA32_IDT_GATE_DESCRIPTOR *IdtTable; IA32_TSS_DESCRIPTOR *TssDesc; IA32_TASK_STATE_SEGMENT *Tss; + VOID *NewGdtTable; UINTN StackTop; UINTN Index; UINTN Vector; UINTN TssBase; - UINTN GdtSize; - - if ((StackSwitchData =3D=3D NULL) || - (StackSwitchData->KnownGoodStackTop =3D=3D 0) || - (StackSwitchData->KnownGoodStackSize =3D=3D 0) || - (StackSwitchData->StackSwitchExceptions =3D=3D NULL) || - (StackSwitchData->StackSwitchExceptionNumber =3D=3D 0) || - (StackSwitchData->StackSwitchExceptionNumber > CPU_EXCEPTION_NUM) || - (StackSwitchData->GdtTable =3D=3D NULL) || - (StackSwitchData->IdtTable =3D=3D NULL) || - (StackSwitchData->ExceptionTssDesc =3D=3D NULL) || - (StackSwitchData->ExceptionTss =3D=3D NULL)) - { - return EFI_INVALID_PARAMETER; - } - - // - // The caller is responsible for that the GDT table, no matter the exist= ing - // one or newly allocated, has enough space to hold descriptors for exce= ption - // task-state segments. - // - if (((UINTN)StackSwitchData->GdtTable & (IA32_GDT_ALIGNMENT - 1)) !=3D 0= ) { - return EFI_INVALID_PARAMETER; - } - - if ((UINTN)StackSwitchData->ExceptionTssDesc < (UINTN)(StackSwitchData->= GdtTable)) { - return EFI_INVALID_PARAMETER; - } - - if (((UINTN)StackSwitchData->ExceptionTssDesc + StackSwitchData->Excepti= onTssDescSize) > - ((UINTN)(StackSwitchData->GdtTable) + StackSwitchData->GdtTableSize)) - { - return EFI_INVALID_PARAMETER; - } + UINT8 *StackSwitchExceptions; + UINTN NeedBufferSize; =20 - // - // One task gate descriptor and one task-state segment are needed. - // - if (StackSwitchData->ExceptionTssDescSize < sizeof (IA32_TSS_DESCRIPTOR)= ) { - return EFI_INVALID_PARAMETER; - } - - if (StackSwitchData->ExceptionTssSize < sizeof (IA32_TASK_STATE_SEGMENT)= ) { + if (BufferSize =3D=3D NULL) { return EFI_INVALID_PARAMETER; } =20 // // Interrupt stack table supports only 7 vectors. // - TssDesc =3D StackSwitchData->ExceptionTssDesc; - Tss =3D StackSwitchData->ExceptionTss; - if (StackSwitchData->StackSwitchExceptionNumber > ARRAY_SIZE (Tss->IST))= { - return EFI_INVALID_PARAMETER; + if (CPU_STACK_SWITCH_EXCEPTION_NUMBER > ARRAY_SIZE (Tss->IST)) { + return EFI_UNSUPPORTED; } =20 // - // Initialize new GDT table and/or IDT table, if any + // Total needed size includes stack size, new GDT table size, TSS size. + // Add another DESCRIPTOR size for alignment requiremet. + // + // Layout of memory needed for each processor: + // -------------------------------- + // | | + // | Stack Size | X ExceptionNumber + // | | + // -------------------------------- + // | Alignment | (just in case) + // -------------------------------- + // | | + // | Original GDT | + // | | + // -------------------------------- + // | | + // | Exception task descriptors | X 1 + // | | + // -------------------------------- + // | | + // | Exception task-state segment | X 1 + // | | + // -------------------------------- // - AsmReadIdtr (&Idtr); AsmReadGdtr (&Gdtr); - - GdtSize =3D (UINTN)TssDesc + sizeof (IA32_TSS_DESCRIPTOR) - - (UINTN)(StackSwitchData->GdtTable); - if ((UINTN)StackSwitchData->GdtTable !=3D Gdtr.Base) { - CopyMem (StackSwitchData->GdtTable, (VOID *)Gdtr.Base, Gdtr.Limit + 1); - Gdtr.Base =3D (UINTN)StackSwitchData->GdtTable; - Gdtr.Limit =3D (UINT16)GdtSize - 1; + NeedBufferSize =3D CPU_STACK_SWITCH_EXCEPTION_NUMBER * CPU_KNOWN_GOOD_ST= ACK_SIZE + + sizeof (IA32_TSS_DESCRIPTOR) + + Gdtr.Limit + 1 + CPU_TSS_DESC_SIZE + + CPU_TSS_SIZE; + + if (*BufferSize < NeedBufferSize) { + *BufferSize =3D NeedBufferSize; + return EFI_BUFFER_TOO_SMALL; } =20 - if ((UINTN)StackSwitchData->IdtTable !=3D Idtr.Base) { - Idtr.Base =3D (UINTN)StackSwitchData->IdtTable; + if (Buffer =3D=3D NULL) { + return EFI_INVALID_PARAMETER; } =20 - if (StackSwitchData->IdtTableSize > 0) { - Idtr.Limit =3D (UINT16)(StackSwitchData->IdtTableSize - 1); - } + AsmReadIdtr (&Idtr); + StackSwitchExceptions =3D CPU_STACK_SWITCH_EXCEPTION_LIST; + StackTop =3D (UINTN)Buffer + CPU_STACK_SWITCH_EXCEPTION_NUM= BER * CPU_KNOWN_GOOD_STACK_SIZE; + NewGdtTable =3D ALIGN_POINTER (StackTop, sizeof (IA32_TSS_DESC= RIPTOR)); + TssDesc =3D (IA32_TSS_DESCRIPTOR *)((UINTN)NewGdtTable + G= dtr.Limit + 1); + Tss =3D (IA32_TASK_STATE_SEGMENT *)((UINTN)TssDesc + C= PU_TSS_DESC_SIZE); + + CopyMem (NewGdtTable, (VOID *)Gdtr.Base, Gdtr.Limit + 1); + Gdtr.Base =3D (UINTN)NewGdtTable; + Gdtr.Limit =3D (UINT16)(Gdtr.Limit + CPU_TSS_DESC_SIZE); =20 // // Fixup current task descriptor. Task-state segment for current task wi= ll @@ -231,20 +223,20 @@ ArchSetupExceptionStack ( // Fixup exception task descriptor and task-state segment // ZeroMem (Tss, sizeof (*Tss)); - StackTop =3D StackSwitchData->KnownGoodStackTop - CPU_STACK_ALIGNMENT; + StackTop =3D StackTop - CPU_STACK_ALIGNMENT; StackTop =3D (UINTN)ALIGN_POINTER (StackTop, CPU_STACK_ALIGNMENT); - IdtTable =3D StackSwitchData->IdtTable; - for (Index =3D 0; Index < StackSwitchData->StackSwitchExceptionNumber; += +Index) { + IdtTable =3D (IA32_IDT_GATE_DESCRIPTOR *)Idtr.Base; + for (Index =3D 0; Index < CPU_STACK_SWITCH_EXCEPTION_NUMBER; ++Index) { // // Fixup IST // Tss->IST[Index] =3D StackTop; - StackTop -=3D StackSwitchData->KnownGoodStackSize; + StackTop -=3D CPU_KNOWN_GOOD_STACK_SIZE; =20 // // Set the IST field to enable corresponding IST // - Vector =3D StackSwitchData->StackSwitchExceptions[Index]; + Vector =3D StackSwitchExceptions[Index]; if ((Vector >=3D CPU_EXCEPTION_NUM) || (Vector >=3D (Idtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR))) { @@ -262,12 +254,7 @@ ArchSetupExceptionStack ( // // Load current task // - AsmWriteTr ((UINT16)((UINTN)StackSwitchData->ExceptionTssDesc - Gdtr.Bas= e)); - - // - // Publish IDT - // - AsmWriteIdtr (&Idtr); + AsmWriteTr ((UINT16)((UINTN)TssDesc - Gdtr.Base)); =20 return EFI_SUCCESS; } diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuExcep= tionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPei= CpuExceptionHandlerLib.inf index a15f125d5b..6d2f66504a 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuExceptionHan= dlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuExceptionHan= dlerLib.inf @@ -2,7 +2,7 @@ # CPU Exception Handler library instance for SEC/PEI modules. # # Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved. -# Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.
+# Copyright (c) 2012 - 2022, Intel Corporation. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent # # This is the XCODE5 variant of the SEC/PEI CpuExceptionHandlerLib. This @@ -55,6 +55,11 @@ PeCoffGetEntryPointLib VmgExitLib =20 +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard + gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList + gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize + [FeaturePcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard ## CONS= UMES =20 --=20 2.31.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#92849): https://edk2.groups.io/g/devel/message/92849 Mute This Topic: https://groups.io/mt/93265209/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-