Jeff, Sorry for the misunderstanding. I think stack switch cannot work with NULL exception handler. But without exception handler, what do we need stack switch for?
Thanks, Jian > -----Original Message----- > From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of Wang, > Jian J > Sent: Wednesday, November 01, 2017 11:09 AM > To: Fan Jeff <vanjeff_...@hotmail.com>; Yao, Jiewen <jiewen....@intel.com>; > edk2-devel@lists.01.org > Cc: Kinney, Michael D <michael.d.kin...@intel.com>; Dong, Eric > <eric.d...@intel.com>; Zeng, Star <star.z...@intel.com> > Subject: Re: [edk2] [PATCH 3/3] UefiCpuPkg/CpuExceptionHandlerLib: Add stack > switch support > > Jeff, > > Stack guard will still work. But the developer cannot know what’s going on > without exception dumping message when stack overflow occurs. > > Thanks, > Jian > > From: Fan Jeff [mailto:vanjeff_...@hotmail.com] > Sent: Wednesday, November 01, 2017 10:59 AM > To: Wang, Jian J <jian.j.w...@intel.com>; Yao, Jiewen <jiewen....@intel.com>; > edk2-devel@lists.01.org > Cc: Kinney, Michael D <michael.d.kin...@intel.com>; Dong, Eric > <eric.d...@intel.com>; Zeng, Star <star.z...@intel.com> > Subject: 答复: [PATCH 3/3] UefiCpuPkg/CpuExceptionHandlerLib: Add stack > switch support > > Jian, > > No. I suggest to fix #109 in another separate patch. > > But to fix #109, we have to makes sure AsmWriteTr() and some definitions are > in > MdePkg. > But I have no strong opinion to add them into MdePkg in this patch. > > I have another question: If NULL CPU exception handler instance is chosen, > could Stack Switch work if PCD PcdCpuStackGuard is set to TRUE. > > Thanks! > Jeff > > 发件人: Wang, Jian J<mailto:jian.j.w...@intel.com> > 发送时间: 2017年11月1日 10:48 > 收件人: Fan Jeff<mailto:vanjeff_...@hotmail.com>; Yao, > Jiewen<mailto:jiewen....@intel.com>; edk2-devel@lists.01.org<mailto:edk2- > de...@lists.01.org> > 抄送: Kinney, Michael D<mailto:michael.d.kin...@intel.com>; Dong, > Eric<mailto:eric.d...@intel.com>; Zeng, Star<mailto:star.z...@intel.com> > 主题: RE: [PATCH 3/3] UefiCpuPkg/CpuExceptionHandlerLib: Add stack switch > support > > Hi Jeff, > > Thanks for the feedback. Are you suggesting to fix Bugzilla 109 in this patch? > > Thanks, > Jian > > From: Fan Jeff [mailto:vanjeff_...@hotmail.com] > Sent: Wednesday, November 01, 2017 10:33 AM > To: Yao, Jiewen <jiewen....@intel.com<mailto:jiewen....@intel.com>>; > Wang, Jian J <jian.j.w...@intel.com<mailto:jian.j.w...@intel.com>>; edk2- > de...@lists.01.org<mailto:edk2-devel@lists.01.org> > Cc: Kinney, Michael D > <michael.d.kin...@intel.com<mailto:michael.d.kin...@intel.com>>; Dong, Eric > <eric.d...@intel.com<mailto:eric.d...@intel.com>>; Zeng, Star > <star.z...@intel.com<mailto:star.z...@intel.com>> > Subject: 答复: [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....@intel.com> > 发送时间: 2017年11月1日 9:56 > 收件人: Wang, Jian J<mailto:jian.j.w...@intel.com>; edk2- > de...@lists.01.org<mailto:edk2-devel@lists.01.org> > 抄送: Kinney, Michael D<mailto:michael.d.kin...@intel.com>; Dong, > Eric<mailto:eric.d...@intel.com>; Zeng, Star<mailto:star.z...@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<mailto:edk2-devel@lists.01.org> > > Cc: Zeng, Star <star.z...@intel.com<mailto:star.z...@intel.com>>; Dong, > Eric <eric.d...@intel.com<mailto:eric.d...@intel.com>>; Yao, > > Jiewen <jiewen....@intel.com<mailto:jiewen....@intel.com>>; Kinney, > Michael D > > <michael.d.kin...@intel.com<mailto:michael.d.kin...@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.z...@intel.com<mailto:star.z...@intel.com>> > > Cc: Eric Dong <eric.d...@intel.com<mailto:eric.d...@intel.com>> > > Cc: Jiewen Yao <jiewen....@intel.com<mailto:jiewen....@intel.com>> > > Cc: Michael Kinney > <michael.d.kin...@intel.com<mailto:michael.d.kin...@intel.com>> > > Suggested-by: Ayellet Wolman > <ayellet.wol...@intel.com<mailto:ayellet.wol...@intel.com>> > > Contributed-under: TianoCore Contribution Agreement 1.1 > > Signed-off-by: Jian J Wang > <jian.j.w...@intel.com<mailto:jian.j.w...@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.nasm > > > > 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/SecPeiCpuExceptionHandlerLib.i > > nf > > > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.i > > nf > > index d70a99c100..adb415ba5a 100644 > > --- > > > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.i > > nf > > +++ > > > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.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/ArchExceptionHandler.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.asm > > > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm > > index 726c64a140..aec56ef4bf 100644 > > --- > > > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm > > +++ > > > 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.nasm > > > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm > > index ba8993d84b..1e2ac411b0 100644 > > --- > > > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm > > +++ > > > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm > > @@ -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<mailto: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 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel