public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
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

  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