From: "Wang, Jian J" <jian.j.wang@intel.com>
To: "Yao, Jiewen" <jiewen.yao@intel.com>,
"Kinney, Michael D" <michael.d.kinney@intel.com>,
Fan Jeff <vanjeff_919@hotmail.com>,
"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>
Cc: "Dong, Eric" <eric.dong@intel.com>, "Zeng, Star" <star.zeng@intel.com>
Subject: Re: [PATCH 3/3] UefiCpuPkg/CpuExceptionHandlerLib: Add stack switch support
Date: Fri, 3 Nov 2017 02:30:38 +0000 [thread overview]
Message-ID: <D827630B58408649ACB04F44C510003624CA7A45@SHSMSX103.ccr.corp.intel.com> (raw)
In-Reply-To: <74D8A39837DF1E4DA445A8C0B3885C503AA0DB7C@shsmsx102.ccr.corp.intel.com>
I see. Thanks for the explanation.
> -----Original Message-----
> From: Yao, Jiewen
> Sent: Friday, November 03, 2017 10:27 AM
> To: Wang, Jian J <jian.j.wang@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Fan Jeff <vanjeff_919@hotmail.com>; edk2-
> devel@lists.01.org
> Cc: Dong, Eric <eric.dong@intel.com>; Zeng, Star <star.zeng@intel.com>
> Subject: RE: [PATCH 3/3] UefiCpuPkg/CpuExceptionHandlerLib: Add stack switch
> support
>
> Jian
> That is for compatibility consideration.
>
> Once there is UDK release, we never change API. We can only add new one.
> Or you may break an old platform, that may use new UDK release.
>
> Thank you
> Yao Jiewen
>
> > -----Original Message-----
> > From: Wang, Jian J
> > Sent: Friday, November 3, 2017 10:10 AM
> > To: Yao, Jiewen <jiewen.yao@intel.com>; Kinney, Michael D
> > <michael.d.kinney@intel.com>; Fan Jeff <vanjeff_919@hotmail.com>;
> > edk2-devel@lists.01.org
> > Cc: Dong, Eric <eric.dong@intel.com>; Zeng, Star <star.zeng@intel.com>
> > Subject: RE: [PATCH 3/3] UefiCpuPkg/CpuExceptionHandlerLib: Add stack
> switch
> > support
> >
> > Hi Jiewen,
> >
> > > -----Original Message-----
> > > From: Yao, Jiewen
> > > Sent: Friday, November 03, 2017 9:25 AM
> > > To: Kinney, Michael D <michael.d.kinney@intel.com>; Fan Jeff
> > > <vanjeff_919@hotmail.com>; Wang, Jian J <jian.j.wang@intel.com>; edk2-
> > > devel@lists.01.org
> > > Cc: Dong, Eric <eric.dong@intel.com>; Zeng, Star <star.zeng@intel.com>
> > > Subject: RE: [PATCH 3/3] UefiCpuPkg/CpuExceptionHandlerLib: Add stack
> > switch
> > > support
> > >
> > > HI Jian
> > > There is another potential problem.
> > >
> > > This feature is enabled in InitializeCpuInterruptHandlers(). However, we
> expect
> > > this is enabled in InitializeCpuExceptionHandlers().
> > >
> > > In order to get the exception stack in InitializeCpuExceptionHandlers(). We
> can
> > > have 2 ways:
> > > A) Let InitializeCpuExceptionHandlers() allocate the exception stack.
> > > B) Let caller to pass the exception stack to InitializeCpuExceptionHandlers().
> > >
> > > For A), it is hard, because DxeCore calls InitializeCpuExceptionHandlers()
> earlier
> > > than CoreInitializeMemoryServices().
> > > For B), InitializeCpuExceptionHandlers() interface does not contain such
> > > information. We might need add a new API to add the exception stack
> > > information, such as InitializeCpuSwitchStackExceptionHandlers ().
> >
> > You're right. Enabling stack switch in InitializeCpuExceptionHandlers() is a bit
> > late for exception handling. But I don't see the difference between adding
> > parameters to existing API (InitializeCpuExceptionHandlers) and adding a new
> > API (InitializeCpuSwitchStackExceptionHandlers) in this case. If we have to
> > change library interface anyway, I'd suggest to add parameters to existing
> > API to carry information needed to setup new stack for exceptions.
> >
> > >
> > > Once this feature is done, can we clean up the SMM code to use the new API,
> > > instead of duplicate the SMM copy of exception handler ? The existing SMM
> > > copy has some assumption on CR4 and FXSAVE/RESTORE, and it broke Quark
> > > platform.
> >
> > I agree.
> >
> > >
> > > Thank you
> > > Yao Jiewen
> > >
> > >
> > >
> > > > -----Original Message-----
> > > > From: Kinney, Michael D
> > > > Sent: Wednesday, November 1, 2017 11:43 PM
> > > > To: Fan Jeff <vanjeff_919@hotmail.com>; Yao, Jiewen
> > > <jiewen.yao@intel.com>;
> > > > Wang, Jian J <jian.j.wang@intel.com>; edk2-devel@lists.01.org; Kinney,
> > > Michael
> > > > D <michael.d.kinney@intel.com>
> > > > Cc: Dong, Eric <eric.dong@intel.com>; Zeng, Star <star.zeng@intel.com>
> > > > Subject: RE: [PATCH 3/3] UefiCpuPkg/CpuExceptionHandlerLib: Add stack
> > > switch
> > > > support
> > > >
> > > > I agree that adding AsmWriteTr, IA32_TASK_STATE_SEGMENT,
> > > > IA32_TSS_DESCRIPTOR to MdePkg BaseLib is a good idea.
> > > >
> > > > Mike
> > > >
> > > > -----Original Message-----
> > > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Fan
> > > > Jeff
> > > > Sent: Tuesday, October 31, 2017 7:33 PM
> > > > To: Yao, Jiewen <jiewen.yao@intel.com>; Wang, Jian J
> > > <jian.j.wang@intel.com>;
> > > > edk2-devel@lists.01.org
> > > > Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Dong, Eric
> > > > <eric.dong@intel.com>; Zeng, Star <star.zeng@intel.com>
> > > > Subject: [edk2] 答复: [PATCH 3/3] UefiCpuPkg/CpuExceptionHandlerLib:
> Add
> > > > stack switch support
> > > >
> > > > Per https://bugzilla.tianocore.org/show_bug.cgi?id=109, TR should be
> setup
> > > > (Such as in DxeIplPeim) even though NULL Cpu Exception Handler instance
> is
> > > > chosen.
> > > >
> > > > For long term, I agree we need to move AsmWriteTr,
> > > > IA32_TASK_STATE_SEGMENT, IA32_TSS_DESCRIPTOR to MdePkg(Such as
> > > BaseLib)
> > > > For this patch, I have no strong opinion.
> > > >
> > > >
> > > > 发件人: Yao, Jiewen<mailto:jiewen.yao@intel.com>
> > > > 发送时间: 2017年11月1日 9:56
> > > > 收件人: Wang, Jian J<mailto:jian.j.wang@intel.com>;
> > > > edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> > > > 抄送: Kinney, Michael D<mailto:michael.d.kinney@intel.com>; Dong,
> > > > Eric<mailto:eric.dong@intel.com>; Zeng, Star<mailto:star.zeng@intel.com>
> > > > 主题: Re: [edk2] [PATCH 3/3] UefiCpuPkg/CpuExceptionHandlerLib: Add
> > stack
> > > > switch support
> > > >
> > > > Hi Jian
> > > > Thanks for the patch.
> > > >
> > > > Can we move all IA32 defined data structure or function to MdePkg?
> > > > Such as: AsmWriteTr, IA32_TASK_STATE_SEGMENT,
> IA32_TSS_DESCRIPTOR
> > > >
> > > > I am also curious why we use different policy for other boot mode.
> > > > Can we use consistent policy?
> > > > > + if (PcdGetBool (PcdCpuStackGuard)) {
> > > > > + //
> > > > > + // Stack Guard works with the support of page table established and
> > > > > + // memory management. So we have to exclude those boot modes
> > > > > without
> > > > > + // them.
> > > > > + //
> > > > > + switch (GetBootModeHob()) {
> > > > > + case BOOT_ON_FLASH_UPDATE:
> > > > > + case BOOT_IN_RECOVERY_MODE:
> > > > > + case BOOT_ON_S3_RESUME:
> > > > > + break;
> > > > > +
> > > > > + default:
> > > > > + ArchSetupExcpetionStack (IdtTable);
> > > > > + break;
> > > > > + }
> > > > > + }
> > > >
> > > >
> > > > Thank you
> > > > Yao Jiewen
> > > >
> > > >
> > > > > -----Original Message-----
> > > > > From: Wang, Jian J
> > > > > Sent: Tuesday, October 31, 2017 10:24 PM
> > > > > To: edk2-devel@lists.01.org
> > > > > Cc: Zeng, Star <star.zeng@intel.com>; Dong, Eric
> > > > > <eric.dong@intel.com>; Yao, Jiewen <jiewen.yao@intel.com>; Kinney,
> > > > > Michael D <michael.d.kinney@intel.com>
> > > > > Subject: [PATCH 3/3] UefiCpuPkg/CpuExceptionHandlerLib: Add stack
> > > > > switch support
> > > > >
> > > > > If Stack Guard is enabled and there's really a stack overflow happened
> > > > > during boot, a Page Fault exception will be triggered. Because the
> > > > > stack is out of usage, the exception handler, which shares the stack
> > > > > with normal UEFI driver, cannot be executed and cannot dump the
> > processor
> > > > information.
> > > > >
> > > > > Without those information, it's very difficult for the BIOS developers
> > > > > locate the root cause of stack overflow. And without a workable stack,
> > > > > the developer cannot event use single step to debug the UEFI driver with
> > > JTAG
> > > > debugger.
> > > > >
> > > > > In order to make sure the exception handler to execute normally after
> > > > > stack overflow. We need separate stacks for exception handlers in case
> > > > > of unusable stack.
> > > > >
> > > > > IA processor allows to switch to a new stack during handling interrupt
> > > > > and exception. But X64 and IA32 provides different ways to make it.
> > > > > X64 provides interrupt stack table (IST) to allow maximum 7 different
> > > > > exceptions to have new stack for its handler. IA32 doesn't have IST
> > > > > mechanism and can only use task gate to do it since task switch allows
> > > > > to load a new stack through its task-state segment (TSS).
> > > > >
> > > > > Note: Stack switch needs to allocate memory pages to be new stacks. So
> > this
> > > > > functionality works only in the boot phases capable of memory
> > > > > allocation (besides the paging, for the sake of Stack Guard). In
> > > > > other words, only DXE phase can supports Stack Guard with stack
> > > > switch.
> > > > >
> > > > > Cc: Star Zeng <star.zeng@intel.com>
> > > > > Cc: Eric Dong <eric.dong@intel.com>
> > > > > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > > > > Cc: Michael Kinney <michael.d.kinney@intel.com>
> > > > > Suggested-by: Ayellet Wolman <ayellet.wolman@intel.com>
> > > > > Contributed-under: TianoCore Contribution Agreement 1.1
> > > > > Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
> > > > > ---
> > > > > .../CpuExceptionHandlerLib/CpuExceptionCommon.h | 22 ++
> > > > > .../DxeCpuExceptionHandlerLib.inf | 5 +
> > > > > .../Library/CpuExceptionHandlerLib/DxeException.c | 19 +
> > > > > .../Ia32/ArchExceptionHandler.c | 135 +++++++
> > > > > .../Ia32/ArchInterruptDefs.h | 136 +++++++
> > > > > .../Ia32/ExceptionTssEntryAsm.nasm | 398
> > > > > +++++++++++++++++++++
> > > > > .../PeiCpuExceptionHandlerLib.inf | 1 +
> > > > > .../SecPeiCpuExceptionHandlerLib.inf | 3 +
> > > > > .../SmmCpuExceptionHandlerLib.inf | 1 +
> > > > > .../X64/ArchExceptionHandler.c | 108 ++++++
> > > > > .../CpuExceptionHandlerLib/X64/ArchInterruptDefs.h | 40 +++
> > > > > .../X64/ExceptionHandlerAsm.S | 12 +
> > > > > .../X64/ExceptionHandlerAsm.asm | 12 +
> > > > > .../X64/ExceptionHandlerAsm.nasm | 12 +
> > > > > 14 files changed, 904 insertions(+)
> > > > > create mode 100644
> > > > >
> > UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionTssEntryAsm.na
> > > > > sm
> > > > >
> > > > > diff --git
> > > > > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
> > > > > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
> > > > > index 740a58828b..fd4a26a458 100644
> > > > > ---
> > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
> > > > > +++
> > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
> > > > > @@ -25,6 +25,7 @@
> > > > > #include <Library/BaseMemoryLib.h>
> > > > > #include <Library/SynchronizationLib.h> #include
> > > > > <Library/CpuExceptionHandlerLib.h>
> > > > > +#include <Library/MemoryAllocationLib.h>
> > > > >
> > > > > #define CPU_EXCEPTION_NUM 32
> > > > > #define CPU_INTERRUPT_NUM 256
> > > > > @@ -288,5 +289,26 @@ CommonExceptionHandlerWorker (
> > > > > IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData
> > > > > );
> > > > >
> > > > > +/**
> > > > > + Load given selector into TR register
> > > > > +
> > > > > + @param Selector Task segment selector
> > > > > +**/
> > > > > +VOID
> > > > > +AsmWriteTr (
> > > > > + UINT16 Selector
> > > > > + );
> > > > > +
> > > > > +/**
> > > > > + Setup separate stack for specific exceptions.
> > > > > +
> > > > > + @param[in] IdtTable IDT table base.
> > > > > +**/
> > > > > +VOID
> > > > > +EFIAPI
> > > > > +ArchSetupExcpetionStack (
> > > > > + IN IA32_IDT_GATE_DESCRIPTOR *IdtTable
> > > > > + );
> > > > > +
> > > > > #endif
> > > > >
> > > > > diff --git
> > > > >
> > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.
> > > > > inf
> > > > >
> > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.
> > > > > inf
> > > > > index f4a8d01c80..b099ef4dad 100644
> > > > > ---
> > > > >
> > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.
> > > > > inf
> > > > > +++
> > > > >
> > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.
> > > > > inf
> > > > > @@ -30,6 +30,7 @@
> > > > > [Sources.Ia32]
> > > > > Ia32/ExceptionHandlerAsm.asm
> > > > > Ia32/ExceptionHandlerAsm.nasm
> > > > > + Ia32/ExceptionTssEntryAsm.nasm
> > > > > Ia32/ExceptionHandlerAsm.S
> > > > > Ia32/ArchExceptionHandler.c
> > > > > Ia32/ArchInterruptDefs.h
> > > > > @@ -47,6 +48,9 @@
> > > > > PeiDxeSmmCpuException.c
> > > > > DxeException.c
> > > > >
> > > > > +[Pcd]
> > > > > + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard
> > > > > +
> > > > > [Packages]
> > > > > MdePkg/MdePkg.dec
> > > > > MdeModulePkg/MdeModulePkg.dec
> > > > > @@ -61,3 +65,4 @@
> > > > > PeCoffGetEntryPointLib
> > > > > MemoryAllocationLib
> > > > > DebugLib
> > > > > + HobLib
> > > > > diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
> > > > > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
> > > > > index 31febec976..e9dcd00e02 100644
> > > > > --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
> > > > > +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
> > > > > @@ -16,6 +16,7 @@
> > > > > #include "CpuExceptionCommon.h"
> > > > > #include <Library/DebugLib.h>
> > > > > #include <Library/MemoryAllocationLib.h>
> > > > > +#include <Library/HobLib.h>
> > > > >
> > > > > CONST UINTN mDoFarReturnFlag = 0;
> > > > >
> > > > > @@ -155,6 +156,24 @@ InitializeCpuInterruptHandlers (
> > > > >
> > > > > UpdateIdtTable (IdtTable, &TemplateMap, &mExceptionHandlerData);
> > > > >
> > > > > + if (PcdGetBool (PcdCpuStackGuard)) {
> > > > > + //
> > > > > + // Stack Guard works with the support of page table established and
> > > > > + // memory management. So we have to exclude those boot modes
> > > > > without
> > > > > + // them.
> > > > > + //
> > > > > + switch (GetBootModeHob()) {
> > > > > + case BOOT_ON_FLASH_UPDATE:
> > > > > + case BOOT_IN_RECOVERY_MODE:
> > > > > + case BOOT_ON_S3_RESUME:
> > > > > + break;
> > > > > +
> > > > > + default:
> > > > > + ArchSetupExcpetionStack (IdtTable);
> > > > > + break;
> > > > > + }
> > > > > + }
> > > > > +
> > > > > //
> > > > > // Load Interrupt Descriptor Table
> > > > > //
> > > > > diff --git
> > > > >
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.
> > > > > c
> > > > >
> > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.
> > > > > c
> > > > > index f2c39eb193..3d41df75a5 100644
> > > > > ---
> > > > >
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.
> > > > > c
> > > > > +++
> > > > >
> > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.
> > > > > c
> > > > > @@ -14,6 +14,19 @@
> > > > >
> > > > > #include "CpuExceptionCommon.h"
> > > > >
> > > > > +//
> > > > > +// List of exceptions needing separate stack // STATIC
> > > > > +IA32_EXCEPTION_TS_ENTRY mExceptionsWithStack[] = {
> > > > > + {6, ExceptionTaskSwtichEntry6}, //#UD: Invalid Opcode Exception
> > > > > + {8, ExceptionTaskSwtichEntry8}, //#DF: Double Fault Exception
> > > > > + {12, ExceptionTaskSwtichEntry12}, //#SS: Stack Fault Exception
> > > > > + {13, ExceptionTaskSwtichEntry13}, //#GP: General Protection
> > > > > +Exception
> > > > > + {14, ExceptionTaskSwtichEntry14}, //#PF: Page-Fault Exception
> > > > > + {17, ExceptionTaskSwtichEntry17}, //#AC: Alignment Check Exception
> > > > > + {18, ExceptionTaskSwtichEntry18} //#MC: Machine-Check Exception };
> > > > > +
> > > > > /**
> > > > > Return address map of exception handler template so that C code can
> > > > > generate
> > > > > exception tables.
> > > > > @@ -107,6 +120,128 @@ ArchRestoreExceptionContext (
> > > > > SystemContext.SystemContextIa32->ExceptionData =
> > > > > ReservedVectors[ExceptionType].ExceptionData;
> > > > > }
> > > > >
> > > > > +/**
> > > > > + Setup separate stack for specific exceptions.
> > > > > +
> > > > > + @param[in] IdtTable IDT table base.
> > > > > +**/
> > > > > +VOID
> > > > > +EFIAPI
> > > > > +ArchSetupExcpetionStack (
> > > > > + IN IA32_IDT_GATE_DESCRIPTOR *IdtTable
> > > > > + )
> > > > > +{
> > > > > + VOID *NewGdt;
> > > > > + IA32_DESCRIPTOR GdtDesc;
> > > > > + UINTN OldGdtSize;
> > > > > + TSS_ENTRIES *TssEntry;
> > > > > + IA32_TSS_DESCRIPTOR *TssDesc;
> > > > > + IA32_TASK_STATE_SEGMENT *Tss;
> > > > > + UINTN StackBase;
> > > > > + UINTN StackTop;
> > > > > + UINTN StackSize;
> > > > > + UINTN Index;
> > > > > + UINTN Vector;
> > > > > + UINTN TssBase;
> > > > > +
> > > > > + //
> > > > > + // Allocate Runtime Data for the GDT // AsmReadGdtr(&GdtDesc);
> > > > > + OldGdtSize = GdtDesc.Limit + 1; NewGdt =
> > > > > + AllocateRuntimeZeroPool(OldGdtSize + sizeof(TSS_ENTRIES)
> > > > > + + IA32_GDT_ALIGNMENT); if
> > > > (NewGdt
> > > > > + == NULL) {
> > > > > + return;
> > > > > + }
> > > > > + NewGdt = ALIGN_POINTER (NewGdt, IA32_GDT_ALIGNMENT);
> > > > > +
> > > > > + //
> > > > > + // Initialize new GDT entries
> > > > > + //
> > > > > + CopyMem(NewGdt, (VOID *)GdtDesc.Base, OldGdtSize);
> > GdtDesc.Base =
> > > > > + (UINTN)(VOID*)NewGdt; GdtDesc.Limit = (UINT16)(OldGdtSize +
> > > > > + TSS_OFFSET - 1);
> > > > > +
> > > > > + //
> > > > > + // Reserve statck memory for given exceptions // StackSize =
> > > > > + ARRAY_SIZE (mExceptionsWithStack) * EXCEPTION_STACK_SIZE;
> > StackSize
> > > > > + = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (StackSize)); StackBase =
> > > > > + (UINT64)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES
> > > > > (StackSize));
> > > > > + if (StackBase == 0) {
> > > > > + FreePool (NewGdt);
> > > > > + return;
> > > > > + }
> > > > > +
> > > > > + //
> > > > > + // Fixup TSS descriptors and segments // TssEntry = (VOID
> > > > > + *)(GdtDesc.Base + OldGdtSize);
> > > > > +
> > > > > + TssBase = (UINTN)(VOID *)&TssEntry->Tss;
> > > > > + TssEntry->TssSeg.Limit15_0 =
> > > > > sizeof(IA32_TASK_STATE_SEGMENT) - 1;
> > > > > + TssEntry->TssSeg.Base15_0 = (UINT16)TssBase;
> > > > > + TssEntry->TssSeg.Base23_16 = (UINT8)(TssBase >> 16);
> > > > > + TssEntry->TssSeg.Type = IA32_GDT_TYPE_TSS;
> > > > > + TssEntry->TssSeg.Limit19_16_and_flags = 0;
> > > > > + TssEntry->TssSeg.Base31_24 = (UINT8)(TssBase >> 24);
> > > > > +
> > > > > + StackTop = StackBase + StackSize - CPU_STACK_ALIGNMENT;
> > StackTop
> > > > > + = (UINTN)ALIGN_POINTER (StackTop, CPU_STACK_ALIGNMENT); for
> > > (Index
> > > > > + = 0; Index < ARRAY_SIZE (mExceptionsWithStack); ++Index) {
> > > > > + //
> > > > > + // Fixup TSS descriptor
> > > > > + //
> > > > > + TssBase = (UINTN)(VOID *)&TssEntry->ExceptionTss[Index];
> > > > > + TssDesc = &TssEntry->ExceptionTssSeg[Index];
> > > > > +
> > > > > + TssDesc->Limit15_0 =
> > sizeof(IA32_TASK_STATE_SEGMENT) -
> > > > 1;
> > > > > + TssDesc->Base15_0 = (UINT16)TssBase;
> > > > > + TssDesc->Base23_16 = (UINT8)(TssBase >> 16);
> > > > > + TssDesc->Type = IA32_GDT_TYPE_TSS;
> > > > > + TssDesc->Limit19_16_and_flags = 0;
> > > > > + TssDesc->Base31_24 = (UINT8)(TssBase >> 24);
> > > > > +
> > > > > + //
> > > > > + // Fixup TSS
> > > > > + //
> > > > > + Tss = &TssEntry->ExceptionTss[Index];
> > > > > + Tss->CR3 = AsmReadCr3();
> > > > > + Tss->EIP = (UINT32)mExceptionsWithStack[Index].EntryPoint;
> > > > > + Tss->EFLAGS = 0x2;
> > > > > + Tss->ESP = StackTop;
> > > > > + Tss->ES = AsmReadEs();
> > > > > + Tss->CS = AsmReadCs();
> > > > > + Tss->SS = AsmReadSs();
> > > > > + Tss->DS = AsmReadDs();
> > > > > + Tss->FS = AsmReadFs();
> > > > > + Tss->GS = AsmReadGs();
> > > > > + StackTop -= EXCEPTION_STACK_SIZE;
> > > > > +
> > > > > + //
> > > > > + // Change specified exceptions in IDT to use TSS
> > > > > + //
> > > > > + Vector = mExceptionsWithStack[Index].Vector;
> > > > > +
> > > > > + IdtTable[Vector].Bits.OffsetLow = 0;
> > > > > + IdtTable[Vector].Bits.Selector = OldGdtSize +
> > > > > EXCEPTION_TSS_SEL(Index);
> > > > > + IdtTable[Vector].Bits.Reserved_0 = 0;
> > > > > + IdtTable[Vector].Bits.GateType = IA32_IDT_GATE_TYPE_TASK;
> > > > > + IdtTable[Vector].Bits.OffsetHigh = 0; }
> > > > > +
> > > > > + //
> > > > > + // Publish the changes
> > > > > + //
> > > > > + AsmWriteGdtr(&GdtDesc);
> > > > > +
> > > > > + //
> > > > > + // Load task register
> > > > > + //
> > > > > + AsmWriteTr ((UINT16)(OldGdtSize + TSS_SEL)); }
> > > > > +
> > > > > /**
> > > > > Display processor context.
> > > > >
> > > > > diff --git
> > > > > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h
> > > > > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h
> > > > > index a8d3556a80..77cc6f9919 100644
> > > > > ---
> > > > > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h
> > > > > +++
> > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs
> > > > > +++ .h
> > > > > @@ -41,4 +41,140 @@ typedef struct {
> > > > > UINT8 HookAfterStubHeaderCode[HOOKAFTER_STUB_SIZE];
> > > > > } RESERVED_VECTORS_DATA;
> > > > >
> > > > > +#pragma pack (1)
> > > > > +
> > > > > +#define EXCEPTION_LIST_MAX 7
> > > > > +#define EXCEPTION_STACK_SIZE EFI_PAGE_SIZE
> > > > > +#define IA32_GDT_TYPE_TSS 0x89
> > > > > +#define IA32_GDT_ALIGNMENT 8
> > > > > +
> > > > > +//
> > > > > +// IA32 TSS Definition
> > > > > +//
> > > > > +typedef struct {
> > > > > + UINT16 PreviousTaskLink; // 00
> > > > > + UINT16 Reserved_2;
> > > > > + UINT32 ESP0; // 04
> > > > > + UINT16 SS0; // 08
> > > > > + UINT16 Reserved_10;
> > > > > + UINT32 ESP1; // 0C
> > > > > + UINT16 SS1; // 10
> > > > > + UINT16 Reserved_18;
> > > > > + UINT32 ESP2; // 14
> > > > > + UINT16 SS2; // 18
> > > > > + UINT16 Reserved_26;
> > > > > + UINT32 CR3; // 1C
> > > > > + UINT32 EIP; // 20
> > > > > + UINT32 EFLAGS; // 24
> > > > > + UINT32 EAX; // 28
> > > > > + UINT32 ECX; // 2C
> > > > > + UINT32 EDX; // 30
> > > > > + UINT32 EBX; // 34
> > > > > + UINT32 ESP; // 38
> > > > > + UINT32 EBP;
> > > > > + UINT32 ESI;
> > > > > + UINT32 EDI;
> > > > > + UINT16 ES;
> > > > > + UINT16 Reserved_74;
> > > > > + UINT16 CS;
> > > > > + UINT16 Reserved_78;
> > > > > + UINT16 SS;
> > > > > + UINT16 Reserved_82;
> > > > > + UINT16 DS;
> > > > > + UINT16 Reserved_86;
> > > > > + UINT16 FS;
> > > > > + UINT16 Reserved_90;
> > > > > + UINT16 GS;
> > > > > + UINT16 Reserved_94;
> > > > > + UINT16 LDTSegmentSelector;
> > > > > + UINT16 Reserved_98;
> > > > > + UINT16 T;
> > > > > + UINT16 IOMapBaseAddress;
> > > > > +} IA32_TASK_STATE_SEGMENT;
> > > > > +
> > > > > +typedef struct {
> > > > > + UINT16 Limit15_0;
> > > > > + UINT16 Base15_0;
> > > > > + UINT8 Base23_16;
> > > > > + UINT8 Type;
> > > > > + UINT8 Limit19_16_and_flags;
> > > > > + UINT8 Base31_24;
> > > > > +} IA32_TSS_DESCRIPTOR;
> > > > > +
> > > > > +typedef struct {
> > > > > + IA32_TSS_DESCRIPTOR TssSeg;
> > > > > + IA32_TSS_DESCRIPTOR
> > > > ExceptionTssSeg[EXCEPTION_LIST_MAX];
> > > > > + IA32_TASK_STATE_SEGMENT Tss;
> > > > > + IA32_TASK_STATE_SEGMENT
> > ExceptionTss[EXCEPTION_LIST_MAX];
> > > > > +} TSS_ENTRIES;
> > > > > +
> > > > > +#pragma pack ()
> > > > > +
> > > > > +#define TSS_SEL OFFSET_OF (TSS_ENTRIES, TssSeg)
> > > > > +#define EXCEPTION_TSS_SEL(n) OFFSET_OF (TSS_ENTRIES,
> > > > > ExceptionTssSeg[n])
> > > > > +#define TSS_OFFSET OFFSET_OF (TSS_ENTRIES, Tss)
> > > > > +
> > > > > +typedef VOID (*EXCEPTION_ENTRY) (VOID);
> > > > > +
> > > > > +typedef struct {
> > > > > + UINTN Vector;
> > > > > + EXCEPTION_ENTRY EntryPoint;
> > > > > +} IA32_EXCEPTION_TS_ENTRY;
> > > > > +
> > > > > +/**
> > > > > + Exception handling entry through task gate for exception #UD.
> > > > > + **/
> > > > > +VOID
> > > > > +ExceptionTaskSwtichEntry6 (
> > > > > + VOID
> > > > > + );
> > > > > +
> > > > > +/**
> > > > > + Exception handling entry through task gate for exception #DF.
> > > > > + **/
> > > > > +VOID
> > > > > +ExceptionTaskSwtichEntry8 (
> > > > > + VOID
> > > > > + );
> > > > > +
> > > > > +/**
> > > > > + Exception handling entry through task gate for exception #SS.
> > > > > + **/
> > > > > +VOID
> > > > > +ExceptionTaskSwtichEntry12 (
> > > > > + VOID
> > > > > + );
> > > > > +
> > > > > +/**
> > > > > + Exception handling entry through task gate for exception #GP.
> > > > > + **/
> > > > > +VOID
> > > > > +ExceptionTaskSwtichEntry13 (
> > > > > + VOID
> > > > > + );
> > > > > +
> > > > > +/**
> > > > > + Exception handling entry through task gate for exception #PF.
> > > > > + **/
> > > > > +VOID
> > > > > +ExceptionTaskSwtichEntry14 (
> > > > > + VOID
> > > > > + );
> > > > > +
> > > > > +/**
> > > > > + Exception handling entry through task gate for exception #AC.
> > > > > + **/
> > > > > +VOID
> > > > > +ExceptionTaskSwtichEntry17 (
> > > > > + VOID
> > > > > + );
> > > > > +
> > > > > +/**
> > > > > + Exception handling entry through task gate for exception #MC.
> > > > > + **/
> > > > > +VOID
> > > > > +ExceptionTaskSwtichEntry18 (
> > > > > + VOID
> > > > > + );
> > > > > +
> > > > > #endif
> > > > > diff --git
> > > > >
> > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionTssEntryAsm.
> > > > > nas
> > > > > m
> > > > >
> > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionTssEntryAsm.
> > > > > nas
> > > > > m
> > > > > new file mode 100644
> > > > > index 0000000000..dbfbcfcf51
> > > > > --- /dev/null
> > > > > +++
> > > > >
> > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionTssEntryAsm.
> > > > > nas
> > > > > m
> > > > > @@ -0,0 +1,398 @@
> > > > > +;--------------------------------------------------------------------
> > > > > +---------- ; ; Copyright (c) 2017, Intel Corporation. All rights
> > > > > +reserved.<BR> ; This program and the accompanying materials ; are
> > > > > +licensed and made available under the terms and conditions of the BSD
> > > > > License
> > > > > +; which accompanies this distribution. The full text of the license
> > > > > +may be found
> > > > > at
> > > > > +; http://opensource.org/licenses/bsd-license.php.
> > > > > +;
> > > > > +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS
> IS"
> > > > > +BASIS, ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND,
> > > EITHER
> > > > > +EXPRESS
> > > > > OR IMPLIED.
> > > > > +;
> > > > > +; Module Name:
> > > > > +;
> > > > > +; ExceptionTssEntryAsm.Asm
> > > > > +;
> > > > > +; Abstract:
> > > > > +;
> > > > > +; IA32 CPU Exception Handler with Separate Stack
> > > > > +;
> > > > > +; Notes:
> > > > > +;
> > > > > +;--------------------------------------------------------------------
> > > > > +----------
> > > > > +
> > > > > +;
> > > > > +; IA32 TSS Memory Layout Description
> > > > > +;
> > > > > +struc IA32_TSS
> > > > > + resw 1
> > > > > + resw 1
> > > > > + .ESP0: resd 1
> > > > > + .SS0: resw 1
> > > > > + resw 1
> > > > > + .ESP1: resd 1
> > > > > + .SS1: resw 1
> > > > > + resw 1
> > > > > + .ESP2: resd 1
> > > > > + .SS2: resw 1
> > > > > + resw 1
> > > > > + ._CR3: resd 1
> > > > > + .EIP: resd 1
> > > > > + .EFLAGS: resd 1
> > > > > + ._EAX: resd 1
> > > > > + ._ECX: resd 1
> > > > > + ._EDX: resd 1
> > > > > + ._EBX: resd 1
> > > > > + ._ESP: resd 1
> > > > > + ._EBP: resd 1
> > > > > + ._ESI: resd 1
> > > > > + ._EDI: resd 1
> > > > > + ._ES: resw 1
> > > > > + resw 1
> > > > > + ._CS: resw 1
> > > > > + resw 1
> > > > > + ._SS: resw 1
> > > > > + resw 1
> > > > > + ._DS: resw 1
> > > > > + resw 1
> > > > > + ._FS: resw 1
> > > > > + resw 1
> > > > > + ._GS: resw 1
> > > > > + resw 1
> > > > > + .LDT: resw 1
> > > > > + resw 1
> > > > > + resw 1
> > > > > + resw 1
> > > > > +endstruc
> > > > > +
> > > > > +;
> > > > > +; CommonExceptionHandler()
> > > > > +;
> > > > > +extern ASM_PFX(CommonExceptionHandler)
> > > > > +
> > > > > +SECTION .data
> > > > > +
> > > > > +SECTION .text
> > > > > +
> > > > > +ALIGN 8
> > > > > +
> > > > > +;
> > > > > +; exception handler stub table
> > > > > +;
> > > > > +%macro DefExceptionTaskSwtichEntry 1
> > > > > +%%DoIret:
> > > > > + iretd
> > > > > +
> > > > > +global ASM_PFX(ExceptionTaskSwtichEntry%1)
> > > > > +ASM_PFX(ExceptionTaskSwtichEntry%1):
> > > > > + db 0x6a ; push #VectorNum
> > > > > + db %1 ; VectorNum
> > > > > + mov eax, ASM_PFX(CommonTaskSwtichEntryPoint)
> > > > > + call eax
> > > > > + mov esp, eax ; Restore stack top
> > > > > + jmp %%DoIret
> > > > > +%endmacro
> > > > > +
> > > > > +global ASM_PFX(CommonTaskSwtichEntryPoint)
> > > > > +ASM_PFX(CommonTaskSwtichEntryPoint):
> > > > > + ;
> > > > > + ; Stack:
> > > > > + ; +---------------------+ <-- EBP - 8
> > > > > + ; + TSS Base +
> > > > > + ; +---------------------+ <-- EBP - 4
> > > > > + ; + CPUID.EDX +
> > > > > + ; +---------------------+ <-- EBP
> > > > > + ; + EIP +
> > > > > + ; +---------------------+ <-- EBP + 4
> > > > > + ; + Vector Number +
> > > > > + ; +---------------------+ <-- EBP + 8
> > > > > + ; + Error Code +
> > > > > + ; +---------------------+
> > > > > + ;
> > > > > +;
> > > > > +; Get TSS of interrupted task
> > > > > +;
> > > > > + mov ebp, esp ; Stack frame
> > > > > +
> > > > > +; Use CPUID to determine if FXSAVE/FXRESTOR and DE are supported
> > > > > + mov eax, 1
> > > > > + cpuid
> > > > > + push edx
> > > > > +
> > > > > +; Get TSS base of interrupted task through PreviousTaskLink field in
> > > > > +; current TSS base
> > > > > + sub esp, 8
> > > > > + sgdt [esp + 2]
> > > > > + mov eax, [esp + 4] ; GDT base
> > > > > + add esp, 8
> > > > > +
> > > > > + xor ebx, ebx
> > > > > + str bx ; Current TR
> > > > > +
> > > > > + mov ecx, [eax + ebx + 2]
> > > > > + shl ecx, 8
> > > > > + mov cl, [eax + ebx + 7]
> > > > > + ror ecx, 8 ; ecx = Current TSS base
> > > > > + push ecx ; keep it in stack for later
> > use
> > > > > +
> > > > > + movzx ebx, word [ecx] ; Previous Task Link
> > > > > + mov ecx, [eax + ebx + 2]
> > > > > + shl ecx, 8
> > > > > + mov cl, [eax + ebx + 7]
> > > > > + ror ecx, 8 ; ecx = Previous TSS base
> > > > > +
> > > > > +;
> > > > > +; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of
> > > > > EFI_SYSTEM_CONTEXT_IA32
> > > > > +; is 16-byte aligned
> > > > > +;
> > > > > + and esp, 0xfffffff0
> > > > > + sub esp, 12
> > > > > +
> > > > > +;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
> > > > > + push dword [ecx + IA32_TSS._EAX]
> > > > > + push dword [ecx + IA32_TSS._ECX]
> > > > > + push dword [ecx + IA32_TSS._EDX]
> > > > > + push dword [ecx + IA32_TSS._EBX]
> > > > > + push dword [ecx + IA32_TSS._ESP]
> > > > > + push dword [ecx + IA32_TSS._EBP]
> > > > > + push dword [ecx + IA32_TSS._ESI]
> > > > > + push dword [ecx + IA32_TSS._EDI]
> > > > > +
> > > > > +;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
> > > > > + movzx eax, word [ecx + IA32_TSS._SS]
> > > > > + push eax
> > > > > + movzx eax, word [ecx + IA32_TSS._CS]
> > > > > + push eax
> > > > > + movzx eax, word [ecx + IA32_TSS._DS]
> > > > > + push eax
> > > > > + movzx eax, word [ecx + IA32_TSS._ES]
> > > > > + push eax
> > > > > + movzx eax, word [ecx + IA32_TSS._FS]
> > > > > + push eax
> > > > > + movzx eax, word [ecx + IA32_TSS._GS]
> > > > > + push eax
> > > > > +
> > > > > +;; UINT32 Eip;
> > > > > + push dword [ecx + IA32_TSS.EIP]
> > > > > +
> > > > > +;; UINT32 Gdtr[2], Idtr[2];
> > > > > + sub esp, 8
> > > > > + sidt [esp]
> > > > > + mov eax, [esp + 2]
> > > > > + xchg eax, [esp]
> > > > > + and eax, 0xFFFF
> > > > > + mov [esp+4], eax
> > > > > +
> > > > > + sub esp, 8
> > > > > + sgdt [esp]
> > > > > + mov eax, [esp + 2]
> > > > > + xchg eax, [esp]
> > > > > + and eax, 0xFFFF
> > > > > + mov [esp+4], eax
> > > > > +
> > > > > +;; UINT32 Ldtr, Tr;
> > > > > + mov eax, ebx ; ebx still keeps selector of interrupted task
> > > > > + push eax
> > > > > + movzx eax, word [ecx + IA32_TSS.LDT]
> > > > > + push eax
> > > > > +
> > > > > +;; UINT32 EFlags;
> > > > > + push dword [ecx + IA32_TSS.EFLAGS]
> > > > > +
> > > > > +;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
> > > > > + mov eax, cr4
> > > > > + push eax ; push cr4 firstly
> > > > > +
> > > > > + mov edx, [ebp - 4] ; cpuid.edx
> > > > > + test edx, BIT24 ; Test for FXSAVE/FXRESTOR support
> > > > > + jz .1
> > > > > + or eax, BIT9 ; Set CR4.OSFXSR
> > > > > +.1:
> > > > > + test edx, BIT2 ; Test for Debugging Extensions support
> > > > > + jz .2
> > > > > + or eax, BIT3 ; Set CR4.DE
> > > > > +.2:
> > > > > + mov cr4, eax
> > > > > +
> > > > > + mov eax, cr3
> > > > > + push eax
> > > > > + mov eax, cr2
> > > > > + push eax
> > > > > + xor eax, eax
> > > > > + push eax
> > > > > + mov eax, cr0
> > > > > + push eax
> > > > > +
> > > > > +;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
> > > > > + mov eax, dr7
> > > > > + push eax
> > > > > + mov eax, dr6
> > > > > + push eax
> > > > > + mov eax, dr3
> > > > > + push eax
> > > > > + mov eax, dr2
> > > > > + push eax
> > > > > + mov eax, dr1
> > > > > + push eax
> > > > > + mov eax, dr0
> > > > > + push eax
> > > > > +
> > > > > +;; FX_SAVE_STATE_IA32 FxSaveState;
> > > > > +;; Clear TS bit in CR0 to avoid Device Not Available Exception (#NM)
> > > > > +;; when executing fxsave/fxrstor instruction
> > > > > + test edx, BIT24 ; Test for FXSAVE/FXRESTOR support.
> > > > > + ; edx still contains result from CPUID above
> > > > > + jz .3
> > > > > + clts
> > > > > + sub esp, 512
> > > > > + mov edi, esp
> > > > > + db 0xf, 0xae, 0x7 ;fxsave [edi]
> > > > > +.3:
> > > > > +
> > > > > +;; UINT32 ExceptionData;
> > > > > + push dword [ebp + 8]
> > > > > +
> > > > > +;; UEFI calling convention for IA32 requires that Direction flag in EFLAGs
> is
> > > clear
> > > > > + cld
> > > > > +
> > > > > +;; call into exception handler
> > > > > + mov esi, ecx ; Keep TSS base to avoid overwrite
> > > > > + mov eax, ASM_PFX(CommonExceptionHandler)
> > > > > +
> > > > > +;; Prepare parameter and call
> > > > > + mov edx, esp
> > > > > + push edx ; EFI_SYSTEM_CONTEXT
> > > > > + push dword [ebp + 4] ; EFI_EXCEPTION_TYPE (vector
> > number)
> > > > > +
> > > > > + ;
> > > > > + ; Call External Exception Handler
> > > > > + ;
> > > > > + call eax
> > > > > + add esp, 8 ; Restore stack before calling
> > > > > + mov ecx, esi ; Restore TSS base
> > > > > +
> > > > > +;; UINT32 ExceptionData;
> > > > > + add esp, 4
> > > > > +
> > > > > +;; FX_SAVE_STATE_IA32 FxSaveState;
> > > > > + mov edx, [ebp - 4] ; cpuid.edx
> > > > > + test edx, BIT24 ; Test for FXSAVE/FXRESTOR support
> > > > > + jz .4
> > > > > + mov esi, esp
> > > > > + db 0xf, 0xae, 0xe ; fxrstor [esi]
> > > > > +.4:
> > > > > + add esp, 512
> > > > > +
> > > > > +;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; ;; Skip restoration of DRx
> > > > > +registers to support debuggers ;; that set breakpoints in
> > > > > +interrupt/exception context
> > > > > + add esp, 4 * 6
> > > > > +
> > > > > +;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
> > > > > + pop eax
> > > > > + mov cr0, eax
> > > > > + add esp, 4 ; not for Cr1
> > > > > + pop eax
> > > > > + mov cr2, eax
> > > > > + pop eax
> > > > > + mov dword [ecx + IA32_TSS._CR3], eax
> > > > > + pop eax
> > > > > + mov cr4, eax
> > > > > +
> > > > > +;; UINT32 EFlags;
> > > > > + pop dword [ecx + IA32_TSS.EFLAGS]
> > > > > + mov ebx, dword [ecx + IA32_TSS.EFLAGS]
> > > > > + btr ebx, 9 ; Do 'cli'
> > > > > + mov dword [ecx + IA32_TSS.EFLAGS], ebx
> > > > > +
> > > > > +;; UINT32 Ldtr, Tr;
> > > > > +;; UINT32 Gdtr[2], Idtr[2];
> > > > > +;; Best not let anyone mess with these particular registers...
> > > > > + add esp, 24
> > > > > +
> > > > > +;; UINT32 Eip;
> > > > > + pop dword [ecx + IA32_TSS.EIP]
> > > > > +
> > > > > +;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
> > > > > +;; NOTE - modified segment registers could hang the debugger... We
> > > > > +;; could attempt to insulate ourselves against this possibility,
> > > > > +;; but that poses risks as well.
> > > > > +;;
> > > > > + pop eax
> > > > > +o16 mov [ecx + IA32_TSS._GS], ax
> > > > > + pop eax
> > > > > +o16 mov [ecx + IA32_TSS._FS], ax
> > > > > + pop eax
> > > > > +o16 mov [ecx + IA32_TSS._ES], ax
> > > > > + pop eax
> > > > > +o16 mov [ecx + IA32_TSS._DS], ax
> > > > > + pop eax
> > > > > +o16 mov [ecx + IA32_TSS._CS], ax
> > > > > + pop eax
> > > > > +o16 mov [ecx + IA32_TSS._SS], ax
> > > > > +
> > > > > +;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
> > > > > + pop dword [ecx + IA32_TSS._EDI]
> > > > > + pop dword [ecx + IA32_TSS._ESI]
> > > > > + add esp, 4 ; not for ebp
> > > > > + add esp, 4 ; not for esp
> > > > > + pop dword [ecx + IA32_TSS._EBX]
> > > > > + pop dword [ecx + IA32_TSS._EDX]
> > > > > + pop dword [ecx + IA32_TSS._ECX]
> > > > > + pop dword [ecx + IA32_TSS._EAX]
> > > > > +
> > > > > +; Set single step DB# to allow debugger to able to go back to the EIP
> > > > > +; where the exception is triggered.
> > > > > +
> > > > > +;; Create return context for iretd in stub function
> > > > > + mov eax, dword [ecx + IA32_TSS._ESP] ; Get old stack
> > pointer
> > > > > + mov ebx, dword [ecx + IA32_TSS.EIP]
> > > > > + mov [eax - 0xc], ebx ; create EIP in old
> > stack
> > > > > + movzx ebx, word [ecx + IA32_TSS._CS]
> > > > > + mov [eax - 0x8], ebx ; create CS in old
> > stack
> > > > > + mov ebx, dword [ecx + IA32_TSS.EFLAGS]
> > > > > + bts ebx, 8
> > > > > + mov [eax - 0x4], ebx ; create eflags in old
> > > > stack
> > > > > + mov dword [ecx + IA32_TSS.EFLAGS], ebx ; update eflags in
> > old
> > > > TSS
> > > > > + mov eax, dword [ecx + IA32_TSS._ESP] ; Get old stack
> > pointer
> > > > > + sub eax, 0xc ; minus 12 byte
> > > > > + mov dword [ecx + IA32_TSS._ESP], eax ; Set new stack
> > pointer
> > > > > +
> > > > > +;; Replace the EIP of interrupted task with stub function
> > > > > + mov eax, ASM_PFX(SingleStepStubFunction)
> > > > > + mov dword [ecx + IA32_TSS.EIP], eax
> > > > > +
> > > > > + mov ecx, [ebp - 8] ; Get current TSS
> > base
> > > > > + mov eax, dword [ecx + IA32_TSS._ESP] ; Return current
> > stack
> > > > top
> > > > > + mov esp, ebp
> > > > > +
> > > > > + ret
> > > > > +
> > > > > +global ASM_PFX(SingleStepStubFunction)
> > > > > +ASM_PFX(SingleStepStubFunction):
> > > > > +;
> > > > > +; we need clean TS bit in CR0 to execute ; x87
> > > > > +FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 instructions.
> > > > > +;
> > > > > + clts
> > > > > + iretd
> > > > > +
> > > > > +;--------------------------------------------------------------------
> > > > > +----------
> > > > > +; VOID
> > > > > +; AsmWriteTr (
> > > > > +; UINT16 Selector
> > > > > +; );
> > > > > +;--------------------------------------------------------------------
> > > > > +----------
> > > > > +global ASM_PFX(AsmWriteTr)
> > > > > +ASM_PFX(AsmWriteTr):
> > > > > + mov eax, [esp+4]
> > > > > + ltr ax
> > > > > + ret
> > > > > +
> > > > > +DefExceptionTaskSwtichEntry 6
> > > > > +DefExceptionTaskSwtichEntry 8
> > > > > +DefExceptionTaskSwtichEntry 12
> > > > > +DefExceptionTaskSwtichEntry 13
> > > > > +DefExceptionTaskSwtichEntry 14
> > > > > +DefExceptionTaskSwtichEntry 17
> > > > > +DefExceptionTaskSwtichEntry 18
> > > > > +
> > > > > diff --git
> > > > >
> > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.
> > > > > inf
> > > > >
> > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.
> > > > > inf
> > > > > index 75443288a9..4c0d435136 100644
> > > > > ---
> > > > >
> > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.
> > > > > inf
> > > > > +++
> > > > >
> > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.
> > > > > inf
> > > > > @@ -30,6 +30,7 @@
> > > > > [Sources.Ia32]
> > > > > Ia32/ExceptionHandlerAsm.asm
> > > > > Ia32/ExceptionHandlerAsm.nasm
> > > > > + Ia32/ExceptionTssEntryAsm.nasm
> > > > > Ia32/ExceptionHandlerAsm.S
> > > > > Ia32/ArchExceptionHandler.c
> > > > > Ia32/ArchInterruptDefs.h
> > > > > diff --git
> > > > >
> > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerL
> > > > > ib.i
> > > > > nf
> > > > >
> > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerL
> > > > > ib.i
> > > > > nf
> > > > > index d70a99c100..adb415ba5a 100644
> > > > > ---
> > > > >
> > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerL
> > > > > ib.i
> > > > > nf
> > > > > +++
> > > > >
> > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerL
> > > > > ib.i
> > > > > nf
> > > > > @@ -30,6 +30,7 @@
> > > > > [Sources.Ia32]
> > > > > Ia32/ExceptionHandlerAsm.asm
> > > > > Ia32/ExceptionHandlerAsm.nasm
> > > > > + Ia32/ExceptionTssEntryAsm.nasm
> > > > > Ia32/ExceptionHandlerAsm.S
> > > > > Ia32/ArchExceptionHandler.c
> > > > > Ia32/ArchInterruptDefs.h
> > > > > @@ -57,3 +58,5 @@
> > > > > PrintLib
> > > > > LocalApicLib
> > > > > PeCoffGetEntryPointLib
> > > > > + MemoryAllocationLib
> > > > > +
> > > > > diff --git
> > > > >
> > >
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.
> > > > > inf
> > > > >
> > >
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.
> > > > > inf
> > > > > index 634ffcb21d..56b875b7c8 100644
> > > > > ---
> > > > >
> > >
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.
> > > > > inf
> > > > > +++
> > > > >
> > >
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.
> > > > > inf
> > > > > @@ -30,6 +30,7 @@
> > > > > [Sources.Ia32]
> > > > > Ia32/ExceptionHandlerAsm.asm
> > > > > Ia32/ExceptionHandlerAsm.nasm
> > > > > + Ia32/ExceptionTssEntryAsm.nasm
> > > > > Ia32/ExceptionHandlerAsm.S
> > > > > Ia32/ArchExceptionHandler.c
> > > > > Ia32/ArchInterruptDefs.h
> > > > > diff --git
> > > > >
> > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
> > > > >
> > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
> > > > > index 65f0cff680..24f2a8486a 100644
> > > > > ---
> > > > >
> > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
> > > > > +++
> > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandl
> > > > > +++ er.c
> > > > > @@ -14,6 +14,19 @@
> > > > >
> > > > > #include "CpuExceptionCommon.h"
> > > > >
> > > > > +//
> > > > > +// List of exceptions needing separate stack // STATIC UINTN
> > > > > +mExceptionsWithStack[] = {
> > > > > + 6, //#UD: Invalid Opcode Exception
> > > > > + 8, //#DF: Double Fault Exception
> > > > > + 12, //#SS: Stack Fault Exception
> > > > > + 13, //#GP: General Protection Exception
> > > > > + 14, //#PF: Page-Fault Exception
> > > > > + 17, //#AC: Alignment Check Exception
> > > > > + 18 //#MC: Machine-Check Exception
> > > > > + };
> > > > > +
> > > > > /**
> > > > > Return address map of exception handler template so that C code can
> > > > > generate
> > > > > exception tables.
> > > > > @@ -112,6 +125,101 @@ ArchRestoreExceptionContext (
> > > > > SystemContext.SystemContextX64->ExceptionData =
> > > > > ReservedVectors[ExceptionType].ExceptionData;
> > > > > }
> > > > >
> > > > > +/**
> > > > > + Setup separate stack for specific exceptions.
> > > > > +
> > > > > + @param[in] IdtTable IDT table base.
> > > > > +**/
> > > > > +VOID
> > > > > +EFIAPI
> > > > > +ArchSetupExcpetionStack (
> > > > > + IN IA32_IDT_GATE_DESCRIPTOR *IdtTable
> > > > > + )
> > > > > +{
> > > > > + VOID *NewGdt;
> > > > > + IA32_DESCRIPTOR GdtDesc;
> > > > > + UINTN OldGdtSize;
> > > > > + TSS_ENTRIES *TssEntry;
> > > > > + UINTN StackBase;
> > > > > + UINTN StackTop;
> > > > > + UINTN StackSize;
> > > > > + UINTN TssBase;
> > > > > + UINTN Index;
> > > > > +
> > > > > + //
> > > > > + // Allocate Runtime Data for the GDT // AsmReadGdtr(&GdtDesc);
> > > > > + OldGdtSize = GdtDesc.Limit + 1; NewGdt =
> > > > > + AllocateRuntimeZeroPool(OldGdtSize + sizeof(TSS_ENTRIES)
> > > > > + + IA32_GDT_ALIGNMENT); if
> > (NewGdt
> > > > ==
> > > > > + NULL) {
> > > > > + return;
> > > > > + }
> > > > > + NewGdt = ALIGN_POINTER (NewGdt, IA32_GDT_ALIGNMENT);
> > > > > +
> > > > > + //
> > > > > + // Initialize new GDT entries
> > > > > + //
> > > > > + CopyMem(NewGdt, (VOID *)GdtDesc.Base, OldGdtSize);
> > GdtDesc.Base =
> > > > > + (UINTN)(VOID*)NewGdt; GdtDesc.Limit = (UINT16)(OldGdtSize +
> > > > > + TSS_OFFSET - 1);
> > > > > +
> > > > > + //
> > > > > + // Reserve statck memory for supported exceptions // StackSize =
> > > > > + ARRAY_SIZE (mExceptionsWithStack) * EXCEPTION_STACK_SIZE;
> > StackSize
> > > > > + = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (StackSize)); StackBase =
> > > > > + (UINT64)AllocatePages (EFI_SIZE_TO_PAGES (StackSize)); if
> > > > > + (StackBase == 0) {
> > > > > + FreePool (NewGdt);
> > > > > + return;
> > > > > + }
> > > > > +
> > > > > + //
> > > > > + // Fixup TSS descriptors
> > > > > + //
> > > > > + TssEntry = (VOID *)(GdtDesc.Base + OldGdtSize); TssBase =
> > > > > + (UINTN)(VOID *)&TssEntry->Tss;
> > > > > +
> > > > > + TssEntry->TssSeg.Limit15_0 =
> > > > > sizeof(IA32_TASK_STATE_SEGMENT) - 1;
> > > > > + TssEntry->TssSeg.Base15_0 = (UINT16)TssBase;
> > > > > + TssEntry->TssSeg.Base23_16 = (UINT8)(TssBase >> 16);
> > > > > + TssEntry->TssSeg.Type = IA32_GDT_TYPE_TSS;
> > > > > + TssEntry->TssSeg.Limit19_16_and_flags = 0;
> > > > > + TssEntry->TssSeg.Base31_24 = (UINT8)(TssBase >> 24);
> > > > > + TssEntry->TssSeg.Base63_32 = (UINT32)(TssBase >> 32);
> > > > > + TssEntry->TssSeg.Reserved = 0;
> > > > > +
> > > > > + //
> > > > > + // Enable Interrupt Stack Table (IST) for each required exception
> > > > > + // StackTop = StackBase + StackSize - CPU_STACK_ALIGNMENT;
> > > > > + StackTop = (UINTN)ALIGN_POINTER (StackTop,
> > CPU_STACK_ALIGNMENT);
> > > > > + for (Index = 0; Index < ARRAY_SIZE (mExceptionsWithStack); ++Index) {
> > > > > + //
> > > > > + // Fixup TSS
> > > > > + //
> > > > > + TssEntry->Tss.IST[Index] = StackTop;
> > > > > + StackTop -= EXCEPTION_STACK_SIZE;
> > > > > +
> > > > > + //
> > > > > + // Set the IST field to 1 to enable corresponding IST
> > > > > + //
> > > > > + IdtTable[mExceptionsWithStack[Index]].Bits.Reserved_0 =
> > > > > + (UINT8)(Index +
> > > > > 1);
> > > > > + }
> > > > > +
> > > > > + //
> > > > > + // Publish the changes
> > > > > + //
> > > > > + AsmWriteGdtr(&GdtDesc);
> > > > > +
> > > > > + //
> > > > > + // Load task register
> > > > > + //
> > > > > + AsmWriteTr ((UINT16)(OldGdtSize + TSS_SEL)); }
> > > > > +
> > > > > /**
> > > > > Display CPU information.
> > > > >
> > > > > diff --git
> > > > > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h
> > > > > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h
> > > > > index 906480134a..5a913bae7b 100644
> > > > > ---
> > > > > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h
> > > > > +++
> > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.
> > > > > +++ h
> > > > > @@ -43,4 +43,44 @@ typedef struct {
> > > > > UINT8 HookAfterStubHeaderCode[HOOKAFTER_STUB_SIZE];
> > > > > } RESERVED_VECTORS_DATA;
> > > > >
> > > > > +#pragma pack (1)
> > > > > +
> > > > > +#define EXCEPTION_LIST_MAX 7
> > > > > +#define EXCEPTION_STACK_SIZE EFI_PAGE_SIZE
> > > > > +#define IA32_GDT_TYPE_TSS 0x89
> > > > > +#define IA32_GDT_ALIGNMENT 8
> > > > > +
> > > > > +typedef struct {
> > > > > + UINT32 Reserved_0;
> > > > > + UINT64 RSP0;
> > > > > + UINT64 RSP1;
> > > > > + UINT64 RSP2;
> > > > > + UINT64 Reserved_28;
> > > > > + UINT64 IST[7];
> > > > > + UINT64 Reserved_92;
> > > > > + UINT16 Reserved_100;
> > > > > + UINT16 IOMapBaseAddress;
> > > > > +} IA32_TASK_STATE_SEGMENT;
> > > > > +
> > > > > +typedef struct {
> > > > > + UINT16 Limit15_0;
> > > > > + UINT16 Base15_0;
> > > > > + UINT8 Base23_16;
> > > > > + UINT8 Type;
> > > > > + UINT8 Limit19_16_and_flags;
> > > > > + UINT8 Base31_24;
> > > > > + UINT32 Base63_32;
> > > > > + UINT32 Reserved;
> > > > > +} IA32_TSS_DESCRIPTOR;
> > > > > +
> > > > > +typedef struct {
> > > > > + IA32_TSS_DESCRIPTOR TssSeg;
> > > > > + IA32_TASK_STATE_SEGMENT Tss;
> > > > > +} TSS_ENTRIES;
> > > > > +
> > > > > +#pragma pack ()
> > > > > +
> > > > > +#define TSS_SEL OFFSET_OF (TSS_ENTRIES, TssSeg)
> > > > > +#define TSS_OFFSET OFFSET_OF (TSS_ENTRIES, Tss)
> > > > > +
> > > > > #endif
> > > > > diff --git
> > > > >
> > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
> > > > >
> > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
> > > > > index edd363cdaa..bdaf132cf5 100644
> > > > > ---
> > > > >
> > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
> > > > > +++
> > > > >
> > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
> > > > > @@ -429,6 +429,18 @@ ASM_PFX(AsmVectorNumFixup):
> > > > > popq %rbp
> > > > > ret
> > > > >
> > > > > +#--------------------------------------------------------------------
> > > > > +----------
> > > > > +# VOID
> > > > > +# AsmWriteTr (
> > > > > +# UINT16 Selector
> > > > > +# );
> > > > > +#--------------------------------------------------------------------
> > > > > +----------
> > > > > +ASM_GLOBAL ASM_PFX(AsmWriteTr)
> > > > > +ASM_PFX(AsmWriteTr):
> > > > > + movl %ecx, %eax
> > > > > + ltrw %ax
> > > > > + ret
> > > > > +
> > > > > #END
> > > > >
> > > > >
> > > > > diff --git
> > > > >
> > >
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.as
> > > > > m
> > > > >
> > >
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.as
> > > > > m
> > > > > index 726c64a140..aec56ef4bf 100644
> > > > > ---
> > > > >
> > >
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.as
> > > > > m
> > > > > +++
> > > > >
> > > >
> > >
> >
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm
> > > > > @@ -386,4 +386,16 @@ AsmVectorNumFixup PROC
> > > > > ret
> > > > > AsmVectorNumFixup ENDP
> > > > >
> > > > > +;--------------------------------------------------------------------
> > > > > +----------
> > > > > +; VOID
> > > > > +; AsmWriteTr (
> > > > > +; UINT16 Selector
> > > > > +; );
> > > > > +;--------------------------------------------------------------------
> > > > > +----------
> > > > > +AsmWriteTr PROC PUBLIC
> > > > > + mov eax, ecx
> > > > > + ltr ax
> > > > > + ret
> > > > > +AsmWriteTr ENDP
> > > > > +
> > > > > END
> > > > > diff --git
> > > > >
> > >
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.na
> > > > > sm
> > > > >
> > >
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.na
> > > > > sm
> > > > > index ba8993d84b..1e2ac411b0 100644
> > > > > ---
> > > > >
> > >
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.na
> > > > > sm
> > > > > +++
> > > > >
> > >
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.na
> > > > > sm @@ -385,3 +385,15 @@ ASM_PFX(AsmVectorNumFixup):
> > > > > mov [rcx + (@VectorNum - HookAfterStubHeaderBegin)], al
> > > > > ret
> > > > >
> > > > > +;--------------------------------------------------------------------
> > > > > +----------
> > > > > +; VOID
> > > > > +; AsmWriteTr (
> > > > > +; UINT16 Selector
> > > > > +; );
> > > > > +;--------------------------------------------------------------------
> > > > > +----------
> > > > > +global ASM_PFX(AsmWriteTr)
> > > > > +ASM_PFX(AsmWriteTr):
> > > > > + mov eax, ecx
> > > > > + ltr ax
> > > > > + ret
> > > > > +
> > > > > --
> > > > > 2.14.1.windows.1
> > > >
> > > > _______________________________________________
> > > > edk2-devel mailing list
> > > > edk2-devel@lists.01.org
> > > > https://lists.01.org/mailman/listinfo/edk2-devel
> > > >
> > > > _______________________________________________
> > > > edk2-devel mailing list
> > > > edk2-devel@lists.01.org
> > > > https://lists.01.org/mailman/listinfo/edk2-devel
next prev parent reply other threads:[~2017-11-03 2:26 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-31 14:24 [PATCH 0/3] Implement stack guard feature Jian J Wang
2017-10-31 14:24 ` [PATCH 1/3] MdeModulePkg/metafile: Add PCD PcdCpuStackGuard Jian J Wang
2017-10-31 14:24 ` [PATCH 2/3] MdeModulePkg/DxeIpl: Enable paging for stack guard Jian J Wang
2017-10-31 14:24 ` [PATCH 3/3] UefiCpuPkg/CpuExceptionHandlerLib: Add stack switch support Jian J Wang
2017-11-01 1:56 ` Yao, Jiewen
2017-11-01 2:33 ` 答复: " Fan Jeff
2017-11-01 2:48 ` Wang, Jian J
2017-11-01 2:59 ` 答复: " Fan Jeff
2017-11-01 3:08 ` Wang, Jian J
2017-11-01 3:12 ` Wang, Jian J
2017-11-01 3:45 ` 答复: " Fan Jeff
2017-11-01 3:12 ` Fan Jeff
2017-11-01 15:42 ` Kinney, Michael D
2017-11-03 1:24 ` Yao, Jiewen
2017-11-03 2:10 ` Wang, Jian J
2017-11-03 2:27 ` Yao, Jiewen
2017-11-03 2:30 ` Wang, Jian J [this message]
2017-11-03 8:21 ` 答复: " Fan Jeff
2017-11-03 8:58 ` Fan Jeff
2017-11-06 0:30 ` Wang, Jian J
2017-11-06 1:54 ` Yao, Jiewen
2017-11-06 2:27 ` Wang, Jian J
2017-11-06 3:47 ` Yao, Jiewen
2017-11-06 3:10 ` 答复: " Fan Jeff
2017-11-06 2:00 ` Fan Jeff
2017-11-01 2:36 ` Wang, Jian J
2017-11-01 2:37 ` 答复: " Fan Jeff
2017-11-01 2:45 ` Wang, Jian J
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=D827630B58408649ACB04F44C510003624CA7A45@SHSMSX103.ccr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox