Revision: 19067
          http://sourceforge.net/p/edk2/code/19067
Author:   lersek
Date:     2015-11-30 19:57:40 +0000 (Mon, 30 Nov 2015)
Log Message:
-----------
UefiCpuPkg/PiSmmCpu: Always set RW+P bit for page table by default

So that we can use write-protection for code later.

This is REPOST.
It includes the bug fix from "Paolo Bonzini" <[email protected]>:

  Title: fix generation of 32-bit PAE page tables

  "Bits 1 and 2 are reserved in 32-bit PAE Page Directory Pointer Table
  Entries (PDPTEs); see Table 4-8 in the SDM.  With VMX extended page
  tables, the processor notices and fails the VM entry as soon as CR0.PG
  is set to 1."

And thanks "Laszlo Ersek" <[email protected]> to validate the fix.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: "Yao, Jiewen" <[email protected]>
Signed-off-by: "Paolo Bonzini" <[email protected]>
Reviewed-by: Michael Kinney <[email protected]>
Tested-by: Laszlo Ersek <[email protected]>
Cc: "Fan, Jeff" <[email protected]>
Cc: "Kinney, Michael D" <[email protected]>
Cc: "Laszlo Ersek" <[email protected]>
Cc: "Paolo Bonzini" <[email protected]>

Modified Paths:
--------------
    trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
    trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c
    trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
    trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
    trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
    trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
    trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c

Modified: trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
===================================================================
--- trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c 2015-11-30 18:49:07 UTC 
(rev 19066)
+++ trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c 2015-11-30 19:57:40 UTC 
(rev 19067)
@@ -60,7 +60,7 @@
   if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
     InitializeIDTSmmStackGuard ();
   }
-  return Gen4GPageTable (0);
+  return Gen4GPageTable (0, TRUE);
 }
 
 /**

Modified: trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c
===================================================================
--- trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c  2015-11-30 
18:49:07 UTC (rev 19066)
+++ trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c  2015-11-30 
19:57:40 UTC (rev 19067)
@@ -24,7 +24,7 @@
   VOID
   )
 {
-  mSmmS3ResumeState->SmmS3Cr3 = Gen4GPageTable (0);
+  mSmmS3ResumeState->SmmS3Cr3 = Gen4GPageTable (0, TRUE);
 
   return ;
 }

Modified: trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
===================================================================
--- trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c    2015-11-30 18:49:07 UTC 
(rev 19066)
+++ trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c    2015-11-30 19:57:40 UTC 
(rev 19067)
@@ -732,12 +732,14 @@
   Create 4G PageTable in SMRAM.
 
   @param          ExtraPages       Additional page numbers besides for 4G 
memory
+  @param          Is32BitPageTable Whether the page table is 32-bit PAE
   @return         PageTable Address
 
 **/
 UINT32
 Gen4GPageTable (
-  IN      UINTN                     ExtraPages
+  IN      UINTN                     ExtraPages,
+  IN      BOOLEAN                   Is32BitPageTable
   )
 {
   VOID    *PageTable;
@@ -785,7 +787,7 @@
   // 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) + 
(Is32BitPageTable ? IA32_PAE_PDPTE_ATTRIBUTE_BITS : PAGE_ATTRIBUTE_BITS);
   }
   Pte += EFI_PAGE_SIZE / sizeof (*Pte);
 
@@ -793,7 +795,7 @@
   // 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 +804,7 @@
     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 +821,7 @@
             GuardPage = 0;
           }
         } else {
-          Pte[Index] = PageAddress + IA32_PG_RW + IA32_PG_P;
+          Pte[Index] = PageAddress | PAGE_ATTRIBUTE_BITS;
         }
         PageAddress+= EFI_PAGE_SIZE;
       }
@@ -886,7 +888,7 @@
       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);

Modified: trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
===================================================================
--- trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h       2015-11-30 
18:49:07 UTC (rev 19066)
+++ trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h       2015-11-30 
19:57:40 UTC (rev 19067)
@@ -71,16 +71,25 @@
 ///
 #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)
 //
+// Bits 1, 2, 5, 6 are reserved in the IA32 PAE PDPTE
+// X64 PAE PDPTE does not have such restriction
+//
+#define IA32_PAE_PDPTE_ATTRIBUTE_BITS    (IA32_PG_P)
+
+//
 // Size of Task-State Segment defined in IA32 Manual
 //
 #define TSS_SIZE              104
@@ -364,12 +373,14 @@
   Create 4G PageTable in SMRAM.
 
   @param          ExtraPages       Additional page numbers besides for 4G 
memory
+  @param          Is32BitPageTable Whether the page table is 32-bit PAE
   @return         PageTable Address
 
 **/
 UINT32
 Gen4GPageTable (
-  IN      UINTN                     ExtraPages
+  IN      UINTN                     ExtraPages,
+  IN      BOOLEAN                   Is32BitPageTable
   );
 
 

Modified: trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
===================================================================
--- trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c   2015-11-30 18:49:07 UTC 
(rev 19066)
+++ trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c   2015-11-30 19:57:40 UTC 
(rev 19067)
@@ -557,9 +557,9 @@
 
           // 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 @@
             //
             // 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 @@
           }
           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 @@
     //
     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 @@
     // 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;
     }

Modified: trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
===================================================================
--- trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c  2015-11-30 18:49:07 UTC 
(rev 19066)
+++ trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c  2015-11-30 19:57:40 UTC 
(rev 19067)
@@ -113,7 +113,7 @@
   //
   // Generate PAE page table for the first 4GB memory space
   //
-  Pages = Gen4GPageTable (PAGE_TABLE_PAGES + 1);
+  Pages = Gen4GPageTable (PAGE_TABLE_PAGES + 1, FALSE);
 
   //
   // Set IA32_PG_PMNT bit to mask this entry
@@ -127,7 +127,7 @@
   // 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 @@
         //
         // 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 @@
     // 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);
     }

Modified: trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c
===================================================================
--- trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c   2015-11-30 
18:49:07 UTC (rev 19066)
+++ trunk/edk2/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c   2015-11-30 
19:57:40 UTC (rev 19067)
@@ -45,13 +45,13 @@
   //
   // Generate PAE page table for the first 4GB memory space
   //
-  Pages = Gen4GPageTable (1);
+  Pages = Gen4GPageTable (1, FALSE);
 
   //
   // 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 @@
   //
   // 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 @@
       // 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 @@
         //
         // 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 @@
   //
   // 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.


------------------------------------------------------------------------------
Go from Idea to Many App Stores Faster with Intel(R) XDK
Give your users amazing mobile app experiences with Intel(R) XDK.
Use one codebase in this all-in-one HTML5 development environment.
Design, debug & build mobile apps & 2D/3D high-impact games for multiple OSs.
http://pubads.g.doubleclick.net/gampad/clk?id=254741911&iu=/4140
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to