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