From nobody Sun May 19 12:26:37 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+92783+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+92783+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1661396127; cv=none; d=zohomail.com; s=zohoarc; b=b7gNI8eqL/s2MZEImH5MLzxcqbgTEATb9jWMVD9GIVPIwyWzrEYuLy9QiVJzKl4RMkX+7wVGT+5ZaxseYEdUPj34648Gf8yoYc0Bp9Npvg+H70ohS+Fj9H6g7ZieGNtrZpcdIHna3CUR4Rbeno05iPY1c42Zzjmu2Rk6iaP+dcE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1661396127; 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=y2YC4DXUi0pay1Vc44bh9/JRi3yaLDyyu+uxer1Jdqo=; b=KdQFWTFp1cgqM0CQYMTkOI/2nSeHTbleyi6lUpw7AinfcCgD4K4iUYd3a46OC/W9awZ7AItmMpHu9BOBx59HvgA8tfziE/pbnD+LlJ9r/9xjtbHzbKfxVk3tYGDpO7ozPsZDhXn9OXRPai1S0d0F+IuvnQ6D7pnc/vgVeSVP2Hk= 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+92783+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 166139612725273.99306799237104; Wed, 24 Aug 2022 19:55:27 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id O1CRYY1788612x3kBwl1z3Nz; Wed, 24 Aug 2022 19:55:26 -0700 X-Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mx.groups.io with SMTP id smtpd.web11.19719.1661396118095781814 for ; Wed, 24 Aug 2022 19:55:26 -0700 X-IronPort-AV: E=McAfee;i="6500,9779,10449"; a="355855727" X-IronPort-AV: E=Sophos;i="5.93,262,1654585200"; d="scan'208";a="355855727" X-Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Aug 2022 19:55:25 -0700 X-IronPort-AV: E=Sophos;i="5.93,262,1654585200"; d="scan'208";a="670782667" X-Received: from shwdesfp01.ccr.corp.intel.com ([10.239.158.151]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Aug 2022 19:55:24 -0700 From: "Zhiguang Liu" To: devel@edk2.groups.io Cc: Zhiguang Liu , Eric Dong , Ray Ni , Rahul Kumar Subject: [edk2-devel] [PATCH] UefiCpuPkg: Simplify the implementation when separate exception stacks Date: Thu, 25 Aug 2022 10:55:06 +0800 Message-Id: <20220825025506.2323-4-zhiguang.liu@intel.com> In-Reply-To: <20220825025506.2323-1-zhiguang.liu@intel.com> References: <20220825025506.2323-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: 5ediUrcoBAhqdebx3uNGyjt3x1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1661396126; bh=QCsrism2kK1lMqE5GkfIlqUt2le/B91fiXU34qbm728=; h=Cc:Date:From:Reply-To:Subject:To; b=VM9ottAuVqC4AaMDjoZSlsjCPz+Ttfv1nNGiPakDjIm2JOHhPBYy28tpUU5zJdgyP/S JbJTm4B3cQLxxI0WCNnzWiS+PcuOlAcyj+gv0vTpkqZht70oscP1oO8MiVpa4cwzHe7da tfXsxqK1AJMMWsmJjvkR6ChkEkeQQMcXVaU= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1661396128117100009 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 --- .../CpuExceptionCommon.h | 73 ++------- .../CpuExceptionHandlerLib/DxeException.c | 94 ++--------- .../Ia32/ArchExceptionHandler.c | 148 ++++++++---------- .../CpuExceptionHandlerLib/PeiCpuException.c | 77 +-------- .../SecPeiCpuExceptionHandlerLib.inf | 7 +- .../SmmCpuExceptionHandlerLib.inf | 7 +- .../X64/ArchExceptionHandler.c | 147 ++++++++--------- .../Xcode5SecPeiCpuExceptionHandlerLib.inf | 7 +- 8 files changed, 177 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..076382a9b5 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,18 @@ 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); + VOID *LocalBuffer; + 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); + LocalBuffer =3D mBuffer; + LocalBufferSize =3D sizeof (mBuffer); + Status =3D ArchSetupExceptionStack (LocalBuffer, &LocalBuffer= Size); + 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..e6b2a83575 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,77 @@ 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 | + // | | + // -------------------------------- + // | Current task descriptor | + // -------------------------------- + // | | + // | 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 +225,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 +256,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 (#92783): https://edk2.groups.io/g/devel/message/92783 Mute This Topic: https://groups.io/mt/93241593/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-