From 8e496a7abcb78c36b0af47ed473096ef7f171606 Mon Sep 17 00:00:00 2001 From: "Yao, Jiewen" Date: Thu, 26 Nov 2015 07:01:08 +0000 Subject: Always set WP in CR0. Always set RW+P bit for page table by default. So that we can use write-protection for code later. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: "Yao, Jiewen" Reviewed-by: "Kinney, Michael D" git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18960 6f19259b-4bc3-4df7-8a09-765794883524 --- UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.S | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.asm | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c | 10 +++++----- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 4 ++++ UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 12 ++++++------ UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 6 +++--- UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.S | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.asm | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c | 12 ++++++------ 9 files changed, 28 insertions(+), 24 deletions(-) (limited to 'UefiCpuPkg') diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.S b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.S index fbaa0725f0..ec5b9a0b04 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.S +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.S @@ -123,7 +123,7 @@ L11: L12: # as cr4.PGE is not set here, refresh cr3 movl %eax, %cr4 # in PreModifyMtrrs() to flush TLB. movl %cr0, %ebx - orl $0x080000000, %ebx # enable paging + orl $0x080010000, %ebx # enable paging + WP movl %ebx, %cr0 leal DSC_OFFSET(%edi),%ebx movw DSC_DS(%ebx),%ax diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.asm b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.asm index 8a12927300..ac1a9b48dd 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.asm +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.asm @@ -129,7 +129,7 @@ gSmiCr3 DD ? @@: ; as cr4.PGE is not set here, refresh cr3 mov cr4, eax ; in PreModifyMtrrs() to flush TLB. mov ebx, cr0 - or ebx, 080000000h ; enable paging + or ebx, 080010000h ; enable paging + WP mov cr0, ebx lea ebx, [edi + DSC_OFFSET] mov ax, [ebx + DSC_DS] diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c index 06ffc6dd86..99d03c4b85 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c @@ -785,7 +785,7 @@ Gen4GPageTable ( // Set Page Directory Pointers // for (Index = 0; Index < 4; Index++) { - Pte[Index] = (UINTN)PageTable + EFI_PAGE_SIZE * (Index + 1) + IA32_PG_P; + Pte[Index] = (UINTN)PageTable + EFI_PAGE_SIZE * (Index + 1) + PAGE_ATTRIBUTE_BITS; } Pte += EFI_PAGE_SIZE / sizeof (*Pte); @@ -793,7 +793,7 @@ Gen4GPageTable ( // Fill in Page Directory Entries // for (Index = 0; Index < EFI_PAGE_SIZE * 4 / sizeof (*Pte); Index++) { - Pte[Index] = (Index << 21) + IA32_PG_PS + IA32_PG_RW + IA32_PG_P; + Pte[Index] = (Index << 21) | IA32_PG_PS | PAGE_ATTRIBUTE_BITS; } if (FeaturePcdGet (PcdCpuSmmStackGuard)) { @@ -802,7 +802,7 @@ Gen4GPageTable ( Pdpte = (UINT64*)PageTable; for (PageIndex = Low2MBoundary; PageIndex <= High2MBoundary; PageIndex += SIZE_2MB) { Pte = (UINT64*)(UINTN)(Pdpte[BitFieldRead32 ((UINT32)PageIndex, 30, 31)] & ~(EFI_PAGE_SIZE - 1)); - Pte[BitFieldRead32 ((UINT32)PageIndex, 21, 29)] = (UINT64)Pages + IA32_PG_RW + IA32_PG_P; + Pte[BitFieldRead32 ((UINT32)PageIndex, 21, 29)] = (UINT64)Pages | PAGE_ATTRIBUTE_BITS; // // Fill in Page Table Entries // @@ -819,7 +819,7 @@ Gen4GPageTable ( GuardPage = 0; } } else { - Pte[Index] = PageAddress + IA32_PG_RW + IA32_PG_P; + Pte[Index] = PageAddress | PAGE_ATTRIBUTE_BITS; } PageAddress+= EFI_PAGE_SIZE; } @@ -886,7 +886,7 @@ SetCacheability ( NewPageTable[Index] |= (UINT64)(Index << EFI_PAGE_SHIFT); } - PageTable[PTIndex] = ((UINTN)NewPageTableAddress & gPhyMask) | IA32_PG_P; + PageTable[PTIndex] = ((UINTN)NewPageTableAddress & gPhyMask) | PAGE_ATTRIBUTE_BITS; } ASSERT (PageTable[PTIndex] & IA32_PG_P); diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h index f2a91655a3..133165db13 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h @@ -71,15 +71,19 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. /// #define IA32_PG_P BIT0 #define IA32_PG_RW BIT1 +#define IA32_PG_U BIT2 #define IA32_PG_WT BIT3 #define IA32_PG_CD BIT4 #define IA32_PG_A BIT5 +#define IA32_PG_D BIT6 #define IA32_PG_PS BIT7 #define IA32_PG_PAT_2M BIT12 #define IA32_PG_PAT_4K IA32_PG_PS #define IA32_PG_PMNT BIT62 #define IA32_PG_NX BIT63 +#define PAGE_ATTRIBUTE_BITS (IA32_PG_RW | IA32_PG_P) + // // Size of Task-State Segment defined in IA32 Manual // diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index ff4e28ec58..ec4ec9b067 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -557,9 +557,9 @@ InitPaging ( // Split it for (Level4 = 0; Level4 < SIZE_4KB / sizeof(*Pt); Level4++) { - Pt[Level4] = Address + ((Level4 << 12) | IA32_PG_RW | IA32_PG_P); + Pt[Level4] = Address + ((Level4 << 12) | PAGE_ATTRIBUTE_BITS); } // end for PT - *Pte = (UINTN)Pt | IA32_PG_RW | IA32_PG_P; + *Pte = (UINTN)Pt | PAGE_ATTRIBUTE_BITS; } // end if IsAddressSplit } // end for PTE } // end for PDE @@ -608,7 +608,7 @@ InitPaging ( // // Patch to remove Present flag and RW flag // - *Pte = *Pte & (INTN)(INT32)(~(IA32_PG_RW | IA32_PG_P)); + *Pte = *Pte & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS); } if (Nx && mXdSupported) { *Pte = *Pte | IA32_PG_NX; @@ -621,7 +621,7 @@ InitPaging ( } for (Level4 = 0; Level4 < SIZE_4KB / sizeof(*Pt); Level4++, Pt++) { if (!IsAddressValid (Address, &Nx)) { - *Pt = *Pt & (INTN)(INT32)(~(IA32_PG_RW | IA32_PG_P)); + *Pt = *Pt & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS); } if (Nx && mXdSupported) { *Pt = *Pt | IA32_PG_NX; @@ -1244,7 +1244,7 @@ RestorePageTableBelow4G ( // PageTable[PTIndex] = (PFAddress & ~((1ull << 21) - 1)); PageTable[PTIndex] |= (UINT64)IA32_PG_PS; - PageTable[PTIndex] |= (UINT64)(IA32_PG_RW | IA32_PG_P); + PageTable[PTIndex] |= (UINT64)PAGE_ATTRIBUTE_BITS; if ((ErrorCode & IA32_PF_EC_ID) != 0) { PageTable[PTIndex] &= ~IA32_PG_NX; } @@ -1277,7 +1277,7 @@ RestorePageTableBelow4G ( // Set new entry // PageTable[PTIndex] = (PFAddress & ~((1ull << 12) - 1)); - PageTable[PTIndex] |= (UINT64)(IA32_PG_RW | IA32_PG_P); + PageTable[PTIndex] |= (UINT64)PAGE_ATTRIBUTE_BITS; if ((ErrorCode & IA32_PF_EC_ID) != 0) { PageTable[PTIndex] &= ~IA32_PG_NX; } diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c index a7d790fd8a..d242e06a5e 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c @@ -127,7 +127,7 @@ SmmInitPageTable ( // Fill Page-Table-Level4 (PML4) entry // PTEntry = (UINT64*)(UINTN)(Pages - EFI_PAGES_TO_SIZE (PAGE_TABLE_PAGES + 1)); - *PTEntry = Pages + IA32_PG_P; + *PTEntry = Pages + PAGE_ATTRIBUTE_BITS; ZeroMem (PTEntry + 1, EFI_PAGE_SIZE - sizeof (*PTEntry)); // // Set sub-entries number @@ -591,7 +591,7 @@ SmiDefaultPFHandler ( // // If the entry is not present, allocate one page from page pool for it // - PageTable[PTIndex] = AllocPage () | IA32_PG_RW | IA32_PG_P; + PageTable[PTIndex] = AllocPage () | PAGE_ATTRIBUTE_BITS; } else { // // Save the upper entry address @@ -621,7 +621,7 @@ SmiDefaultPFHandler ( // Fill the new entry // PageTable[PTIndex] = (PFAddress & gPhyMask & ~((1ull << EndBit) - 1)) | - PageAttribute | IA32_PG_A | IA32_PG_RW | IA32_PG_P; + PageAttribute | IA32_PG_A | PAGE_ATTRIBUTE_BITS; if (UpperEntry != NULL) { SetSubEntriesNum (UpperEntry, GetSubEntriesNum (UpperEntry) + 1); } diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.S b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.S index b488b74b70..7e9ac58cb2 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.S +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.S @@ -144,7 +144,7 @@ Base: orb $1,%ah wrmsr movq %cr0, %rbx - btsl $31, %ebx + orl $0x080010000, %ebx # enable paging + WP movq %rbx, %cr0 retf LongMode: # long mode (64-bit code) starts here diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.asm b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.asm index 4f5c03c5cf..094cf2c3da 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.asm +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.asm @@ -140,7 +140,7 @@ Base: or ah, 1 wrmsr mov rbx, cr0 - bts ebx, 31 + or ebx, 080010000h ; enable paging + WP mov cr0, rbx retf @LongMode: ; long mode (64-bit code) starts here diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c index c4ec12debb..b3cd629f55 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c @@ -51,7 +51,7 @@ InitSmmS3Cr3 ( // Fill Page-Table-Level4 (PML4) entry // PTEntry = (UINT64*)(UINTN)(Pages - EFI_PAGES_TO_SIZE (1)); - *PTEntry = Pages + IA32_PG_P; + *PTEntry = Pages | PAGE_ATTRIBUTE_BITS; ZeroMem (PTEntry + 1, EFI_PAGE_SIZE - sizeof (*PTEntry)); // @@ -117,7 +117,7 @@ AcquirePage ( // // Link & Record the current uplink // - *Uplink = Address | IA32_PG_P | IA32_PG_RW; + *Uplink = Address | PAGE_ATTRIBUTE_BITS; mPFPageUplink[mPFPageIndex] = Uplink; mPFPageIndex = (mPFPageIndex + 1) % MAX_PF_PAGE_COUNT; @@ -242,9 +242,9 @@ RestorePageTableAbove4G ( // PTE PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK); for (Index = 0; Index < 512; Index++) { - PageTable[Index] = Address | IA32_PG_RW | IA32_PG_P; + PageTable[Index] = Address | PAGE_ATTRIBUTE_BITS; if (!IsAddressValid (Address, &Nx)) { - PageTable[Index] = PageTable[Index] & (INTN)(INT32)(~(IA32_PG_RW | IA32_PG_P)); + PageTable[Index] = PageTable[Index] & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS); } if (Nx && mXdSupported) { PageTable[Index] = PageTable[Index] | IA32_PG_NX; @@ -262,7 +262,7 @@ RestorePageTableAbove4G ( // // Patch to remove present flag and rw flag. // - PageTable[PTIndex] = PageTable[PTIndex] & (INTN)(INT32)(~(IA32_PG_RW | IA32_PG_P)); + PageTable[PTIndex] = PageTable[PTIndex] & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS); } // // Set XD bit to 1 @@ -289,7 +289,7 @@ RestorePageTableAbove4G ( // // Add present flag or clear XD flag to make page fault handler succeed. // - PageTable[PTIndex] |= (UINT64)(IA32_PG_RW | IA32_PG_P); + PageTable[PTIndex] |= (UINT64)(PAGE_ATTRIBUTE_BITS); if ((ErrorCode & IA32_PF_EC_ID) != 0) { // // If page fault is caused by instruction fetch, clear XD bit in the entry. -- cgit v1.2.3