UefiCpuPkg/PiSmmCpuDxeSmm: Add paging protection.
PiSmmCpuDxeSmm consumes SmmAttributesTable and setup page table: 1) Code region is marked as read-only and Data region is non-executable, if the PE image is 4K aligned. 2) Important data structure is set to RO, such as GDT/IDT. 3) SmmSaveState is set to non-executable, and SmmEntrypoint is set to read-only. 4) If static page is supported, page table is read-only. We use page table to protect other components, and itself. If we use dynamic paging, we can still provide *partial* protection. And hope page table is not modified by other components. The XD enabling code is moved to SmiEntry to let NX take effect. Cc: Jeff Fan <jeff.fan@intel.com> Cc: Feng Tian <feng.tian@intel.com> Cc: Star Zeng <star.zeng@intel.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao <jiewen.yao@intel.com> Tested-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Jeff Fan <jeff.fan@intel.com> Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
This commit is contained in:
@@ -18,6 +18,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#define ACC_MAX_BIT BIT3
|
||||
LIST_ENTRY mPagePool = INITIALIZE_LIST_HEAD_VARIABLE (mPagePool);
|
||||
BOOLEAN m1GPageTableSupport = FALSE;
|
||||
UINT8 mPhysicalAddressBits;
|
||||
BOOLEAN mCpuSmmStaticPageTable;
|
||||
|
||||
/**
|
||||
Check if 1-GByte pages is supported by processor or not.
|
||||
@@ -85,6 +87,146 @@ GetSubEntriesNum (
|
||||
return BitFieldRead64 (*Entry, 52, 60);
|
||||
}
|
||||
|
||||
/**
|
||||
Calculate the maximum support address.
|
||||
|
||||
@return the maximum support address.
|
||||
**/
|
||||
UINT8
|
||||
CalculateMaximumSupportAddress (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINT32 RegEax;
|
||||
UINT8 PhysicalAddressBits;
|
||||
VOID *Hob;
|
||||
|
||||
//
|
||||
// Get physical address bits supported.
|
||||
//
|
||||
Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
|
||||
if (Hob != NULL) {
|
||||
PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;
|
||||
} else {
|
||||
AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
|
||||
if (RegEax >= 0x80000008) {
|
||||
AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
|
||||
PhysicalAddressBits = (UINT8) RegEax;
|
||||
} else {
|
||||
PhysicalAddressBits = 36;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.
|
||||
//
|
||||
ASSERT (PhysicalAddressBits <= 52);
|
||||
if (PhysicalAddressBits > 48) {
|
||||
PhysicalAddressBits = 48;
|
||||
}
|
||||
return PhysicalAddressBits;
|
||||
}
|
||||
|
||||
/**
|
||||
Set static page table.
|
||||
|
||||
@param[in] PageTable Address of page table.
|
||||
**/
|
||||
VOID
|
||||
SetStaticPageTable (
|
||||
IN UINTN PageTable
|
||||
)
|
||||
{
|
||||
UINT64 PageAddress;
|
||||
UINTN NumberOfPml4EntriesNeeded;
|
||||
UINTN NumberOfPdpEntriesNeeded;
|
||||
UINTN IndexOfPml4Entries;
|
||||
UINTN IndexOfPdpEntries;
|
||||
UINTN IndexOfPageDirectoryEntries;
|
||||
UINT64 *PageMapLevel4Entry;
|
||||
UINT64 *PageMap;
|
||||
UINT64 *PageDirectoryPointerEntry;
|
||||
UINT64 *PageDirectory1GEntry;
|
||||
UINT64 *PageDirectoryEntry;
|
||||
|
||||
if (mPhysicalAddressBits <= 39 ) {
|
||||
NumberOfPml4EntriesNeeded = 1;
|
||||
NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (mPhysicalAddressBits - 30));
|
||||
} else {
|
||||
NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (mPhysicalAddressBits - 39));
|
||||
NumberOfPdpEntriesNeeded = 512;
|
||||
}
|
||||
|
||||
//
|
||||
// By architecture only one PageMapLevel4 exists - so lets allocate storage for it.
|
||||
//
|
||||
PageMap = (VOID *) PageTable;
|
||||
|
||||
PageMapLevel4Entry = PageMap;
|
||||
PageAddress = 0;
|
||||
for (IndexOfPml4Entries = 0; IndexOfPml4Entries < NumberOfPml4EntriesNeeded; IndexOfPml4Entries++, PageMapLevel4Entry++) {
|
||||
//
|
||||
// Each PML4 entry points to a page of Page Directory Pointer entries.
|
||||
//
|
||||
PageDirectoryPointerEntry = (UINT64 *) ((*PageMapLevel4Entry) & gPhyMask);
|
||||
if (PageDirectoryPointerEntry == NULL) {
|
||||
PageDirectoryPointerEntry = AllocatePageTableMemory (1);
|
||||
ASSERT(PageDirectoryPointerEntry != NULL);
|
||||
ZeroMem (PageDirectoryPointerEntry, EFI_PAGES_TO_SIZE(1));
|
||||
|
||||
*PageMapLevel4Entry = ((UINTN)PageDirectoryPointerEntry & gPhyMask) | PAGE_ATTRIBUTE_BITS;
|
||||
}
|
||||
|
||||
if (m1GPageTableSupport) {
|
||||
PageDirectory1GEntry = PageDirectoryPointerEntry;
|
||||
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) {
|
||||
if (IndexOfPml4Entries == 0 && IndexOfPageDirectoryEntries < 4) {
|
||||
//
|
||||
// Skip the < 4G entries
|
||||
//
|
||||
continue;
|
||||
}
|
||||
//
|
||||
// Fill in the Page Directory entries
|
||||
//
|
||||
*PageDirectory1GEntry = (PageAddress & gPhyMask) | IA32_PG_PS | PAGE_ATTRIBUTE_BITS;
|
||||
}
|
||||
} else {
|
||||
PageAddress = BASE_4GB;
|
||||
for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
|
||||
if (IndexOfPml4Entries == 0 && IndexOfPdpEntries < 4) {
|
||||
//
|
||||
// Skip the < 4G entries
|
||||
//
|
||||
continue;
|
||||
}
|
||||
//
|
||||
// Each Directory Pointer entries points to a page of Page Directory entires.
|
||||
// So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.
|
||||
//
|
||||
PageDirectoryEntry = (UINT64 *) ((*PageDirectoryPointerEntry) & gPhyMask);
|
||||
if (PageDirectoryEntry == NULL) {
|
||||
PageDirectoryEntry = AllocatePageTableMemory (1);
|
||||
ASSERT(PageDirectoryEntry != NULL);
|
||||
ZeroMem (PageDirectoryEntry, EFI_PAGES_TO_SIZE(1));
|
||||
|
||||
//
|
||||
// Fill in a Page Directory Pointer Entries
|
||||
//
|
||||
*PageDirectoryPointerEntry = (UINT64)(UINTN)PageDirectoryEntry | PAGE_ATTRIBUTE_BITS;
|
||||
}
|
||||
|
||||
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) {
|
||||
//
|
||||
// Fill in the Page Directory entries
|
||||
//
|
||||
*PageDirectoryEntry = (UINT64)PageAddress | IA32_PG_PS | PAGE_ATTRIBUTE_BITS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Create PageTable for SMM use.
|
||||
|
||||
@@ -108,11 +250,17 @@ SmmInitPageTable (
|
||||
//
|
||||
InitializeSpinLock (mPFLock);
|
||||
|
||||
mCpuSmmStaticPageTable = PcdGetBool (PcdCpuSmmStaticPageTable);
|
||||
m1GPageTableSupport = Is1GPageSupport ();
|
||||
DEBUG ((DEBUG_INFO, "1GPageTableSupport - 0x%x\n", m1GPageTableSupport));
|
||||
DEBUG ((DEBUG_INFO, "PcdCpuSmmStaticPageTable - 0x%x\n", mCpuSmmStaticPageTable));
|
||||
|
||||
mPhysicalAddressBits = CalculateMaximumSupportAddress ();
|
||||
DEBUG ((DEBUG_INFO, "PhysicalAddressBits - 0x%x\n", mPhysicalAddressBits));
|
||||
//
|
||||
// Generate PAE page table for the first 4GB memory space
|
||||
//
|
||||
Pages = Gen4GPageTable (PAGE_TABLE_PAGES + 1, FALSE);
|
||||
Pages = Gen4GPageTable (FALSE);
|
||||
|
||||
//
|
||||
// Set IA32_PG_PMNT bit to mask this entry
|
||||
@@ -125,21 +273,28 @@ SmmInitPageTable (
|
||||
//
|
||||
// Fill Page-Table-Level4 (PML4) entry
|
||||
//
|
||||
PTEntry = (UINT64*)(UINTN)(Pages - EFI_PAGES_TO_SIZE (PAGE_TABLE_PAGES + 1));
|
||||
*PTEntry = Pages + PAGE_ATTRIBUTE_BITS;
|
||||
PTEntry = (UINT64*)AllocatePageTableMemory (1);
|
||||
ASSERT (PTEntry != NULL);
|
||||
*PTEntry = Pages | PAGE_ATTRIBUTE_BITS;
|
||||
ZeroMem (PTEntry + 1, EFI_PAGE_SIZE - sizeof (*PTEntry));
|
||||
|
||||
//
|
||||
// Set sub-entries number
|
||||
//
|
||||
SetSubEntriesNum (PTEntry, 3);
|
||||
|
||||
//
|
||||
// Add remaining pages to page pool
|
||||
//
|
||||
FreePage = (LIST_ENTRY*)(PTEntry + EFI_PAGE_SIZE / sizeof (*PTEntry));
|
||||
while ((UINTN)FreePage < Pages) {
|
||||
InsertTailList (&mPagePool, FreePage);
|
||||
FreePage += EFI_PAGE_SIZE / sizeof (*FreePage);
|
||||
if (mCpuSmmStaticPageTable) {
|
||||
SetStaticPageTable ((UINTN)PTEntry);
|
||||
} else {
|
||||
//
|
||||
// Add pages to page pool
|
||||
//
|
||||
FreePage = (LIST_ENTRY*)AllocatePageTableMemory (PAGE_TABLE_PAGES);
|
||||
ASSERT (FreePage != NULL);
|
||||
for (Index = 0; Index < PAGE_TABLE_PAGES; Index++) {
|
||||
InsertTailList (&mPagePool, FreePage);
|
||||
FreePage += EFI_PAGE_SIZE / sizeof (*FreePage);
|
||||
}
|
||||
}
|
||||
|
||||
if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
|
||||
@@ -561,7 +716,7 @@ SmiDefaultPFHandler (
|
||||
break;
|
||||
case SmmPageSize1G:
|
||||
if (!m1GPageTableSupport) {
|
||||
DEBUG ((EFI_D_ERROR, "1-GByte pages is not supported!"));
|
||||
DEBUG ((DEBUG_ERROR, "1-GByte pages is not supported!"));
|
||||
ASSERT (FALSE);
|
||||
}
|
||||
//
|
||||
@@ -612,8 +767,8 @@ SmiDefaultPFHandler (
|
||||
// Check if the entry has already existed, this issue may occur when the different
|
||||
// size page entries created under the same entry
|
||||
//
|
||||
DEBUG ((EFI_D_ERROR, "PageTable = %lx, PTIndex = %x, PageTable[PTIndex] = %lx\n", PageTable, PTIndex, PageTable[PTIndex]));
|
||||
DEBUG ((EFI_D_ERROR, "New page table overlapped with old page table!\n"));
|
||||
DEBUG ((DEBUG_ERROR, "PageTable = %lx, PTIndex = %x, PageTable[PTIndex] = %lx\n", PageTable, PTIndex, PageTable[PTIndex]));
|
||||
DEBUG ((DEBUG_ERROR, "New page table overlapped with old page table!\n"));
|
||||
ASSERT (FALSE);
|
||||
}
|
||||
//
|
||||
@@ -654,13 +809,18 @@ SmiPFHandler (
|
||||
|
||||
PFAddress = AsmReadCr2 ();
|
||||
|
||||
if (mCpuSmmStaticPageTable && (PFAddress >= LShiftU64 (1, (mPhysicalAddressBits - 1)))) {
|
||||
DEBUG ((DEBUG_ERROR, "Do not support address 0x%lx by processor!\n", PFAddress));
|
||||
CpuDeadLoop ();
|
||||
}
|
||||
|
||||
//
|
||||
// If a page fault occurs in SMRAM range, it should be in a SMM stack guard page.
|
||||
//
|
||||
if ((FeaturePcdGet (PcdCpuSmmStackGuard)) &&
|
||||
(PFAddress >= mCpuHotPlugData.SmrrBase) &&
|
||||
(PFAddress < (mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize))) {
|
||||
DEBUG ((EFI_D_ERROR, "SMM stack overflow!\n"));
|
||||
DEBUG ((DEBUG_ERROR, "SMM stack overflow!\n"));
|
||||
CpuDeadLoop ();
|
||||
}
|
||||
|
||||
@@ -670,7 +830,7 @@ SmiPFHandler (
|
||||
if ((PFAddress < mCpuHotPlugData.SmrrBase) ||
|
||||
(PFAddress >= mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize)) {
|
||||
if ((SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_ID) != 0) {
|
||||
DEBUG ((EFI_D_ERROR, "Code executed on IP(0x%lx) out of SMM range after SMM is locked!\n", PFAddress));
|
||||
DEBUG ((DEBUG_ERROR, "Code executed on IP(0x%lx) out of SMM range after SMM is locked!\n", PFAddress));
|
||||
DEBUG_CODE (
|
||||
DumpModuleInfoByIp (*(UINTN *)(UINTN)SystemContext.SystemContextX64->Rsp);
|
||||
);
|
||||
@@ -689,3 +849,87 @@ SmiPFHandler (
|
||||
|
||||
ReleaseSpinLock (mPFLock);
|
||||
}
|
||||
|
||||
/**
|
||||
This function sets memory attribute for page table.
|
||||
**/
|
||||
VOID
|
||||
SetPageTableAttributes (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINTN Index2;
|
||||
UINTN Index3;
|
||||
UINTN Index4;
|
||||
UINT64 *L1PageTable;
|
||||
UINT64 *L2PageTable;
|
||||
UINT64 *L3PageTable;
|
||||
UINT64 *L4PageTable;
|
||||
BOOLEAN IsSplitted;
|
||||
BOOLEAN PageTableSplitted;
|
||||
|
||||
if (!mCpuSmmStaticPageTable) {
|
||||
return ;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "SetPageTableAttributes\n"));
|
||||
|
||||
//
|
||||
// Disable write protection, because we need mark page table to be write protected.
|
||||
// We need *write* page table memory, to mark itself to be *read only*.
|
||||
//
|
||||
AsmWriteCr0 (AsmReadCr0() & ~CR0_WP);
|
||||
|
||||
do {
|
||||
DEBUG ((DEBUG_INFO, "Start...\n"));
|
||||
PageTableSplitted = FALSE;
|
||||
|
||||
L4PageTable = (UINT64 *)GetPageTableBase ();
|
||||
SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L4PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);
|
||||
PageTableSplitted = (PageTableSplitted || IsSplitted);
|
||||
|
||||
for (Index4 = 0; Index4 < SIZE_4KB/sizeof(UINT64); Index4++) {
|
||||
L3PageTable = (UINT64 *)(UINTN)(L4PageTable[Index4] & PAGING_4K_ADDRESS_MASK_64);
|
||||
if (L3PageTable == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L3PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);
|
||||
PageTableSplitted = (PageTableSplitted || IsSplitted);
|
||||
|
||||
for (Index3 = 0; Index3 < SIZE_4KB/sizeof(UINT64); Index3++) {
|
||||
if ((L3PageTable[Index3] & IA32_PG_PS) != 0) {
|
||||
// 1G
|
||||
continue;
|
||||
}
|
||||
L2PageTable = (UINT64 *)(UINTN)(L3PageTable[Index3] & PAGING_4K_ADDRESS_MASK_64);
|
||||
if (L2PageTable == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L2PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);
|
||||
PageTableSplitted = (PageTableSplitted || IsSplitted);
|
||||
|
||||
for (Index2 = 0; Index2 < SIZE_4KB/sizeof(UINT64); Index2++) {
|
||||
if ((L2PageTable[Index2] & IA32_PG_PS) != 0) {
|
||||
// 2M
|
||||
continue;
|
||||
}
|
||||
L1PageTable = (UINT64 *)(UINTN)(L2PageTable[Index2] & PAGING_4K_ADDRESS_MASK_64);
|
||||
if (L1PageTable == NULL) {
|
||||
continue;
|
||||
}
|
||||
SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L1PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);
|
||||
PageTableSplitted = (PageTableSplitted || IsSplitted);
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (PageTableSplitted);
|
||||
|
||||
//
|
||||
// Enable write protection, after page table updated.
|
||||
//
|
||||
AsmWriteCr0 (AsmReadCr0() | CR0_WP);
|
||||
|
||||
return ;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2009 - 2016, 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
|
||||
@@ -24,8 +24,13 @@ ASM_GLOBAL ASM_PFX(gcSmiHandlerSize)
|
||||
ASM_GLOBAL ASM_PFX(gSmiCr3)
|
||||
ASM_GLOBAL ASM_PFX(gSmiStack)
|
||||
ASM_GLOBAL ASM_PFX(gSmbase)
|
||||
ASM_GLOBAL ASM_PFX(mXdSupported)
|
||||
ASM_GLOBAL ASM_PFX(gSmiHandlerIdtr)
|
||||
|
||||
.equ MSR_IA32_MISC_ENABLE, 0x1A0
|
||||
.equ MSR_EFER, 0xc0000080
|
||||
.equ MSR_EFER_XD, 0x800
|
||||
|
||||
#
|
||||
# Constants relating to PROCESSOR_SMM_DESCRIPTOR
|
||||
#
|
||||
@@ -132,6 +137,32 @@ ASM_PFX(gSmiCr3): .space 4
|
||||
movl $TSS_SEGMENT, %eax
|
||||
ltr %ax
|
||||
|
||||
# enable NXE if supported
|
||||
.byte 0xb0 # mov al, imm8
|
||||
ASM_PFX(mXdSupported): .byte 1
|
||||
cmpb $0, %al
|
||||
jz SkipNxe
|
||||
#
|
||||
# Check XD disable bit
|
||||
#
|
||||
movl $MSR_IA32_MISC_ENABLE, %ecx
|
||||
rdmsr
|
||||
subl $4, %esp
|
||||
pushq %rdx # save MSR_IA32_MISC_ENABLE[63-32]
|
||||
testl $BIT2, %edx # MSR_IA32_MISC_ENABLE[34]
|
||||
jz L13
|
||||
andw $0x0FFFB, %dx # clear XD Disable bit if it is set
|
||||
wrmsr
|
||||
L13:
|
||||
movl $MSR_EFER, %ecx
|
||||
rdmsr
|
||||
orw $MSR_EFER_XD,%ax # enable NXE
|
||||
wrmsr
|
||||
jmp @NxeDone
|
||||
SkipNxe:
|
||||
subl $8, %esp
|
||||
NxeDone:
|
||||
|
||||
#
|
||||
# Switch to LongMode
|
||||
#
|
||||
@@ -139,12 +170,13 @@ ASM_PFX(gSmiCr3): .space 4
|
||||
call Base # push return address for retf later
|
||||
Base:
|
||||
addl $(LongMode - Base), (%rsp) # offset for far retf, seg is the 1st arg
|
||||
movl $0xc0000080, %ecx
|
||||
|
||||
movl $MSR_EFER, %ecx
|
||||
rdmsr
|
||||
orb $1,%ah
|
||||
orb $1,%ah # enable LME
|
||||
wrmsr
|
||||
movq %cr0, %rbx
|
||||
orl $0x080010000, %ebx # enable paging + WP
|
||||
orl $0x080010023, %ebx # enable paging + WP + NE + MP + PE
|
||||
movq %rbx, %cr0
|
||||
retf
|
||||
LongMode: # long mode (64-bit code) starts here
|
||||
@@ -162,10 +194,10 @@ LongMode: # long mode (64-bit code) starts here
|
||||
# jmp _SmiHandler ; instruction is not needed
|
||||
|
||||
_SmiHandler:
|
||||
movq (%rsp), %rbx
|
||||
movq 8(%rsp), %rbx
|
||||
# Save FP registers
|
||||
|
||||
subq $0x208, %rsp
|
||||
subq $0x200, %rsp
|
||||
.byte 0x48 # FXSAVE64
|
||||
fxsave (%rsp)
|
||||
|
||||
@@ -191,6 +223,21 @@ _SmiHandler:
|
||||
.byte 0x48 # FXRSTOR64
|
||||
fxrstor (%rsp)
|
||||
|
||||
addq $0x200, %rsp
|
||||
|
||||
movabsq $ASM_PFX(mXdSupported), %rax
|
||||
movb (%rax), %al
|
||||
cmpb $0, %al
|
||||
jz L16
|
||||
popq %rdx # get saved MSR_IA32_MISC_ENABLE[63-32]
|
||||
testl $BIT2, %edx
|
||||
jz L16
|
||||
movl $MSR_IA32_MISC_ENABLE, %ecx
|
||||
rdmsr
|
||||
orw $BIT2, %dx # set XD Disable bit if it was set before entering into SMM
|
||||
wrmsr
|
||||
|
||||
L16:
|
||||
rsm
|
||||
|
||||
ASM_PFX(gcSmiHandlerSize): .word . - _SmiEntryPoint
|
||||
|
@@ -1,5 +1,5 @@
|
||||
;------------------------------------------------------------------------------ ;
|
||||
; Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||
; Copyright (c) 2009 - 2016, 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
|
||||
@@ -29,8 +29,12 @@ EXTERNDEF gcSmiHandlerSize:WORD
|
||||
EXTERNDEF gSmiCr3:DWORD
|
||||
EXTERNDEF gSmiStack:DWORD
|
||||
EXTERNDEF gSmbase:DWORD
|
||||
EXTERNDEF mXdSupported:BYTE
|
||||
EXTERNDEF gSmiHandlerIdtr:FWORD
|
||||
|
||||
MSR_IA32_MISC_ENABLE EQU 1A0h
|
||||
MSR_EFER EQU 0c0000080h
|
||||
MSR_EFER_XD EQU 0800h
|
||||
|
||||
;
|
||||
; Constants relating to PROCESSOR_SMM_DESCRIPTOR
|
||||
@@ -130,17 +134,44 @@ gSmiCr3 DD ?
|
||||
mov eax, TSS_SEGMENT
|
||||
ltr ax
|
||||
|
||||
; enable NXE if supported
|
||||
DB 0b0h ; mov al, imm8
|
||||
mXdSupported DB 1
|
||||
cmp al, 0
|
||||
jz @SkipXd
|
||||
;
|
||||
; Check XD disable bit
|
||||
;
|
||||
mov ecx, MSR_IA32_MISC_ENABLE
|
||||
rdmsr
|
||||
sub esp, 4
|
||||
push rdx ; save MSR_IA32_MISC_ENABLE[63-32]
|
||||
test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
|
||||
jz @f
|
||||
and dx, 0FFFBh ; clear XD Disable bit if it is set
|
||||
wrmsr
|
||||
@@:
|
||||
mov ecx, MSR_EFER
|
||||
rdmsr
|
||||
or ax, MSR_EFER_XD ; enable NXE
|
||||
wrmsr
|
||||
jmp @XdDone
|
||||
@SkipXd:
|
||||
sub esp, 8
|
||||
@XdDone:
|
||||
|
||||
; Switch into @LongMode
|
||||
push LONG_MODE_CS ; push cs hardcore here
|
||||
call Base ; push return address for retf later
|
||||
Base:
|
||||
add dword ptr [rsp], @LongMode - Base; offset for far retf, seg is the 1st arg
|
||||
mov ecx, 0c0000080h
|
||||
|
||||
mov ecx, MSR_EFER
|
||||
rdmsr
|
||||
or ah, 1
|
||||
or ah, 1 ; enable LME
|
||||
wrmsr
|
||||
mov rbx, cr0
|
||||
or ebx, 080010000h ; enable paging + WP
|
||||
or ebx, 080010023h ; enable paging + WP + NE + MP + PE
|
||||
mov cr0, rbx
|
||||
retf
|
||||
@LongMode: ; long mode (64-bit code) starts here
|
||||
@@ -163,7 +194,7 @@ _SmiHandler:
|
||||
;
|
||||
; Save FP registers
|
||||
;
|
||||
sub rsp, 208h
|
||||
sub rsp, 200h
|
||||
DB 48h ; FXSAVE64
|
||||
fxsave [rsp]
|
||||
|
||||
@@ -172,15 +203,15 @@ _SmiHandler:
|
||||
mov rcx, rbx
|
||||
mov rax, CpuSmmDebugEntry
|
||||
call rax
|
||||
|
||||
|
||||
mov rcx, rbx
|
||||
mov rax, SmiRendezvous ; rax <- absolute addr of SmiRedezvous
|
||||
call rax
|
||||
|
||||
|
||||
mov rcx, rbx
|
||||
mov rax, CpuSmmDebugExit
|
||||
call rax
|
||||
|
||||
|
||||
add rsp, 20h
|
||||
|
||||
;
|
||||
@@ -189,6 +220,21 @@ _SmiHandler:
|
||||
DB 48h ; FXRSTOR64
|
||||
fxrstor [rsp]
|
||||
|
||||
add rsp, 200h
|
||||
|
||||
mov rax, ASM_PFX(mXdSupported)
|
||||
mov al, [rax]
|
||||
cmp al, 0
|
||||
jz @f
|
||||
pop rdx ; get saved MSR_IA32_MISC_ENABLE[63-32]
|
||||
test edx, BIT2
|
||||
jz @f
|
||||
mov ecx, MSR_IA32_MISC_ENABLE
|
||||
rdmsr
|
||||
or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM
|
||||
wrmsr
|
||||
|
||||
@@:
|
||||
rsm
|
||||
|
||||
gcSmiHandlerSize DW $ - _SmiEntryPoint
|
||||
|
@@ -22,6 +22,10 @@
|
||||
; Variables referrenced by C code
|
||||
;
|
||||
|
||||
%define MSR_IA32_MISC_ENABLE 0x1A0
|
||||
%define MSR_EFER 0xc0000080
|
||||
%define MSR_EFER_XD 0x800
|
||||
|
||||
;
|
||||
; Constants relating to PROCESSOR_SMM_DESCRIPTOR
|
||||
;
|
||||
@@ -50,6 +54,7 @@ extern ASM_PFX(CpuSmmDebugEntry)
|
||||
extern ASM_PFX(CpuSmmDebugExit)
|
||||
|
||||
global ASM_PFX(gSmbase)
|
||||
global ASM_PFX(mXdSupported)
|
||||
global ASM_PFX(gSmiStack)
|
||||
global ASM_PFX(gSmiCr3)
|
||||
global ASM_PFX(gcSmiHandlerTemplate)
|
||||
@@ -69,7 +74,7 @@ _SmiEntryPoint:
|
||||
mov [cs:bx + 2], eax
|
||||
o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]
|
||||
mov ax, PROTECT_MODE_CS
|
||||
mov [cs:bx-0x2],ax
|
||||
mov [cs:bx-0x2],ax
|
||||
DB 0x66, 0xbf ; mov edi, SMBASE
|
||||
ASM_PFX(gSmbase): DD 0
|
||||
lea eax, [edi + (@ProtectedMode - _SmiEntryPoint) + 0x8000]
|
||||
@@ -79,7 +84,7 @@ ASM_PFX(gSmbase): DD 0
|
||||
or ebx, 0x23
|
||||
mov cr0, ebx
|
||||
jmp dword 0x0:0x0
|
||||
_GdtDesc:
|
||||
_GdtDesc:
|
||||
DW 0
|
||||
DD 0
|
||||
|
||||
@@ -112,17 +117,44 @@ ASM_PFX(gSmiCr3): DD 0
|
||||
mov eax, TSS_SEGMENT
|
||||
ltr ax
|
||||
|
||||
; enable NXE if supported
|
||||
DB 0xb0 ; mov al, imm8
|
||||
ASM_PFX(mXdSupported): DB 1
|
||||
cmp al, 0
|
||||
jz @SkipXd
|
||||
;
|
||||
; Check XD disable bit
|
||||
;
|
||||
mov ecx, MSR_IA32_MISC_ENABLE
|
||||
rdmsr
|
||||
sub esp, 4
|
||||
push rdx ; save MSR_IA32_MISC_ENABLE[63-32]
|
||||
test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
|
||||
jz .0
|
||||
and dx, 0xFFFB ; clear XD Disable bit if it is set
|
||||
wrmsr
|
||||
.0:
|
||||
mov ecx, MSR_EFER
|
||||
rdmsr
|
||||
or ax, MSR_EFER_XD ; enable NXE
|
||||
wrmsr
|
||||
jmp @XdDone
|
||||
@SkipXd:
|
||||
sub esp, 8
|
||||
@XdDone:
|
||||
|
||||
; Switch into @LongMode
|
||||
push LONG_MODE_CS ; push cs hardcore here
|
||||
call Base ; push reture address for retf later
|
||||
call Base ; push return address for retf later
|
||||
Base:
|
||||
add dword [rsp], @LongMode - Base; offset for far retf, seg is the 1st arg
|
||||
mov ecx, 0xc0000080
|
||||
|
||||
mov ecx, MSR_EFER
|
||||
rdmsr
|
||||
or ah, 1
|
||||
or ah, 1 ; enable LME
|
||||
wrmsr
|
||||
mov rbx, cr0
|
||||
or ebx, 080010000h ; enable paging + WP
|
||||
or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE
|
||||
mov cr0, rbx
|
||||
retf
|
||||
@LongMode: ; long mode (64-bit code) starts here
|
||||
@@ -140,12 +172,12 @@ Base:
|
||||
; jmp _SmiHandler ; instruction is not needed
|
||||
|
||||
_SmiHandler:
|
||||
mov rbx, [rsp] ; rbx <- CpuIndex
|
||||
mov rbx, [rsp + 0x8] ; rcx <- CpuIndex
|
||||
|
||||
;
|
||||
; Save FP registers
|
||||
;
|
||||
sub rsp, 0x208
|
||||
sub rsp, 0x200
|
||||
DB 0x48 ; FXSAVE64
|
||||
fxsave [rsp]
|
||||
|
||||
@@ -154,15 +186,15 @@ _SmiHandler:
|
||||
mov rcx, rbx
|
||||
mov rax, CpuSmmDebugEntry
|
||||
call rax
|
||||
|
||||
|
||||
mov rcx, rbx
|
||||
mov rax, SmiRendezvous ; rax <- absolute addr of SmiRedezvous
|
||||
call rax
|
||||
|
||||
|
||||
mov rcx, rbx
|
||||
mov rax, CpuSmmDebugExit
|
||||
call rax
|
||||
|
||||
|
||||
add rsp, 0x20
|
||||
|
||||
;
|
||||
@@ -171,6 +203,21 @@ _SmiHandler:
|
||||
DB 0x48 ; FXRSTOR64
|
||||
fxrstor [rsp]
|
||||
|
||||
add rsp, 0x200
|
||||
|
||||
mov rax, ASM_PFX(mXdSupported)
|
||||
mov al, [rax]
|
||||
cmp al, 0
|
||||
jz .1
|
||||
pop rdx ; get saved MSR_IA32_MISC_ENABLE[63-32]
|
||||
test edx, BIT2
|
||||
jz .1
|
||||
mov ecx, MSR_IA32_MISC_ENABLE
|
||||
rdmsr
|
||||
or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM
|
||||
wrmsr
|
||||
|
||||
.1:
|
||||
rsm
|
||||
|
||||
gcSmiHandlerSize DW $ - _SmiEntryPoint
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2009 - 2016, 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
|
||||
@@ -128,244 +128,8 @@ ASM_PFX(gcSmiGdtr):
|
||||
.quad NullSeg
|
||||
|
||||
ASM_PFX(gcSmiIdtr):
|
||||
.word IDT_SIZE - 1
|
||||
.quad _SmiIDT
|
||||
|
||||
|
||||
#
|
||||
# Here is the IDT. There are 32 (not 255) entries in it since only processor
|
||||
# generated exceptions will be handled.
|
||||
#
|
||||
_SmiIDT:
|
||||
# The following segment repeats 32 times:
|
||||
# No. 1
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 2
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 3
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 4
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 5
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 6
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 7
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 8
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 9
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 10
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 11
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 12
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 13
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 14
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 15
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 16
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 17
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 18
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 19
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 20
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 21
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 22
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 23
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 24
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 25
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 26
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 27
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 28
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 29
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 30
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 31
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
# No. 32
|
||||
.word 0 # Offset 0:15
|
||||
.word CODE_SEL
|
||||
.byte 0 # Unused
|
||||
.byte 0x8e # Interrupt Gate, Present
|
||||
.word 0 # Offset 16:31
|
||||
.quad 0 # Offset 32:63
|
||||
|
||||
_SmiIDTEnd:
|
||||
|
||||
.equ IDT_SIZE, (_SmiIDTEnd - _SmiIDT)
|
||||
.word 0
|
||||
.quad 0
|
||||
|
||||
.text
|
||||
|
||||
@@ -600,11 +364,3 @@ L5:
|
||||
addq $16, %rsp # skip INT# & ErrCode
|
||||
iretq
|
||||
|
||||
ASM_GLOBAL ASM_PFX(InitializeIDTSmmStackGuard)
|
||||
ASM_PFX(InitializeIDTSmmStackGuard):
|
||||
# If SMM Stack Guard feature is enabled, set the IST field of
|
||||
# the interrupt gate for Page Fault Exception to be 1
|
||||
#
|
||||
movabsq $_SmiIDT + 14 * 16, %rax
|
||||
movb $1, 4(%rax)
|
||||
ret
|
||||
|
@@ -1,5 +1,5 @@
|
||||
;------------------------------------------------------------------------------ ;
|
||||
; Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||
; Copyright (c) 2009 - 2016, 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
|
||||
@@ -144,27 +144,8 @@ gcSmiGdtr LABEL FWORD
|
||||
DQ offset NullSeg
|
||||
|
||||
gcSmiIdtr LABEL FWORD
|
||||
DW IDT_SIZE - 1
|
||||
DQ offset _SmiIDT
|
||||
|
||||
.data
|
||||
|
||||
;
|
||||
; Here is the IDT. There are 32 (not 255) entries in it since only processor
|
||||
; generated exceptions will be handled.
|
||||
;
|
||||
_SmiIDT:
|
||||
REPEAT 32
|
||||
DW 0 ; Offset 0:15
|
||||
DW CODE_SEL ; Segment selector
|
||||
DB 0 ; Unused
|
||||
DB 8eh ; Interrupt Gate, Present
|
||||
DW 0 ; Offset 16:31
|
||||
DQ 0 ; Offset 32:63
|
||||
ENDM
|
||||
_SmiIDTEnd:
|
||||
|
||||
IDT_SIZE = (offset _SmiIDTEnd - offset _SmiIDT)
|
||||
DW 0
|
||||
DQ 0
|
||||
|
||||
.code
|
||||
|
||||
@@ -400,14 +381,4 @@ PageFaultIdtHandlerSmmProfile PROC
|
||||
iretq
|
||||
PageFaultIdtHandlerSmmProfile ENDP
|
||||
|
||||
InitializeIDTSmmStackGuard PROC
|
||||
;
|
||||
; If SMM Stack Guard feature is enabled, set the IST field of
|
||||
; the interrupt gate for Page Fault Exception to be 1
|
||||
;
|
||||
lea rax, _SmiIDT + 14 * 16
|
||||
mov byte ptr [rax + 4], 1
|
||||
ret
|
||||
InitializeIDTSmmStackGuard ENDP
|
||||
|
||||
END
|
||||
|
@@ -145,25 +145,8 @@ ASM_PFX(gcSmiGdtr):
|
||||
DQ NullSeg
|
||||
|
||||
ASM_PFX(gcSmiIdtr):
|
||||
DW IDT_SIZE - 1
|
||||
DQ _SmiIDT
|
||||
|
||||
;
|
||||
; Here is the IDT. There are 32 (not 255) entries in it since only processor
|
||||
; generated exceptions will be handled.
|
||||
;
|
||||
_SmiIDT:
|
||||
%rep 32
|
||||
DW 0 ; 0:15
|
||||
DW CODE_SEL ; Segment selector
|
||||
DB 0 ; Unused
|
||||
DB 0x8e ; Interrupt Gate, Present
|
||||
DW 0 ; 16:31
|
||||
DQ 0 ; 32:63
|
||||
%endrep
|
||||
_SmiIDTEnd:
|
||||
|
||||
IDT_SIZE equ _SmiIDTEnd - _SmiIDT
|
||||
DW 0
|
||||
DQ 0
|
||||
|
||||
DEFAULT REL
|
||||
SECTION .text
|
||||
@@ -400,13 +383,3 @@ ASM_PFX(PageFaultIdtHandlerSmmProfile):
|
||||
add rsp, 16 ; skip INT# & ErrCode
|
||||
iretq
|
||||
|
||||
global ASM_PFX(InitializeIDTSmmStackGuard)
|
||||
ASM_PFX(InitializeIDTSmmStackGuard):
|
||||
;
|
||||
; If SMM Stack Guard feature is enabled, set the IST field of
|
||||
; the interrupt gate for Page Fault Exception to be 1
|
||||
;
|
||||
lea rax, [_SmiIDT + 14 * 16]
|
||||
mov byte [rax + 4], 1
|
||||
ret
|
||||
|
||||
|
@@ -14,6 +14,30 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
#include "PiSmmCpuDxeSmm.h"
|
||||
|
||||
EFI_PHYSICAL_ADDRESS mGdtBuffer;
|
||||
UINTN mGdtBufferSize;
|
||||
|
||||
/**
|
||||
Initialize IDT for SMM Stack Guard.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
InitializeIDTSmmStackGuard (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
IA32_IDT_GATE_DESCRIPTOR *IdtGate;
|
||||
|
||||
//
|
||||
// If SMM Stack Guard feature is enabled, set the IST field of
|
||||
// the interrupt gate for Page Fault Exception to be 1
|
||||
//
|
||||
IdtGate = (IA32_IDT_GATE_DESCRIPTOR *)gcSmiIdtr.Base;
|
||||
IdtGate += EXCEPT_IA32_PAGE_FAULT;
|
||||
IdtGate->Bits.Reserved_0 = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize Gdt for all processors.
|
||||
|
||||
@@ -41,8 +65,10 @@ InitGdt (
|
||||
// on each SMI entry.
|
||||
//
|
||||
GdtTssTableSize = (gcSmiGdtr.Limit + 1 + TSS_SIZE + 7) & ~7; // 8 bytes aligned
|
||||
GdtTssTables = (UINT8*)AllocatePages (EFI_SIZE_TO_PAGES (GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus));
|
||||
mGdtBufferSize = GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus;
|
||||
GdtTssTables = (UINT8*)AllocateCodePages (EFI_SIZE_TO_PAGES (mGdtBufferSize));
|
||||
ASSERT (GdtTssTables != NULL);
|
||||
mGdtBuffer = (UINTN)GdtTssTables;
|
||||
GdtTableStepSize = GdtTssTableSize;
|
||||
|
||||
for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) {
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
X64 processor specific functions to enable SMM profile.
|
||||
|
||||
Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2012 - 2016, 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
|
||||
@@ -45,12 +45,13 @@ InitSmmS3Cr3 (
|
||||
//
|
||||
// Generate PAE page table for the first 4GB memory space
|
||||
//
|
||||
Pages = Gen4GPageTable (1, FALSE);
|
||||
Pages = Gen4GPageTable (FALSE);
|
||||
|
||||
//
|
||||
// Fill Page-Table-Level4 (PML4) entry
|
||||
//
|
||||
PTEntry = (UINT64*)(UINTN)(Pages - EFI_PAGES_TO_SIZE (1));
|
||||
PTEntry = (UINT64*)AllocatePageTableMemory (1);
|
||||
ASSERT (PTEntry != NULL);
|
||||
*PTEntry = Pages | PAGE_ATTRIBUTE_BITS;
|
||||
ZeroMem (PTEntry + 1, EFI_PAGE_SIZE - sizeof (*PTEntry));
|
||||
|
||||
|
Reference in New Issue
Block a user