]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / X64 / SmmProfileArch.c
index 79e23ef6476ea0a9e3bcb9713e8d7d04a499d397..cb7a69174530e6bccc2d26707caea2c45034bac2 100644 (file)
@@ -1,14 +1,10 @@
 /** @file\r
 X64 processor specific functions to enable SMM profile.\r
 \r
-Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
+Copyright (c) 2012 - 2019, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
 \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -18,17 +14,17 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 //\r
 // Current page index.\r
 //\r
-UINTN                     mPFPageIndex;\r
+UINTN  mPFPageIndex;\r
 \r
 //\r
 // Pool for dynamically creating page table in page fault handler.\r
 //\r
-UINT64                    mPFPageBuffer;\r
+UINT64  mPFPageBuffer;\r
 \r
 //\r
 // Store the uplink information for each page being used.\r
 //\r
-UINT64                    *mPFPageUplink[MAX_PF_PAGE_COUNT];\r
+UINT64  *mPFPageUplink[MAX_PF_PAGE_COUNT];\r
 \r
 /**\r
   Create SMM page table for S3 path.\r
@@ -39,19 +35,20 @@ InitSmmS3Cr3 (
   VOID\r
   )\r
 {\r
-  EFI_PHYSICAL_ADDRESS              Pages;\r
-  UINT64                            *PTEntry;\r
+  EFI_PHYSICAL_ADDRESS  Pages;\r
+  UINT64                *PTEntry;\r
 \r
   //\r
   // Generate PAE page table for the first 4GB memory space\r
   //\r
-  Pages = Gen4GPageTable (1, FALSE);\r
+  Pages = Gen4GPageTable (FALSE);\r
 \r
   //\r
   // Fill Page-Table-Level4 (PML4) entry\r
   //\r
-  PTEntry = (UINT64*)(UINTN)(Pages - EFI_PAGES_TO_SIZE (1));\r
-  *PTEntry = Pages | PAGE_ATTRIBUTE_BITS;\r
+  PTEntry = (UINT64 *)AllocatePageTableMemory (1);\r
+  ASSERT (PTEntry != NULL);\r
+  *PTEntry = Pages | mAddressEncMask | PAGE_ATTRIBUTE_BITS;\r
   ZeroMem (PTEntry + 1, EFI_PAGE_SIZE - sizeof (*PTEntry));\r
 \r
   //\r
@@ -59,7 +56,7 @@ InitSmmS3Cr3 (
   //\r
   mSmmS3ResumeState->SmmS3Cr3 = (UINT32)(UINTN)PTEntry;\r
 \r
-  return ;\r
+  return;\r
 }\r
 \r
 /**\r
@@ -71,18 +68,18 @@ InitPagesForPFHandler (
   VOID\r
   )\r
 {\r
-  VOID          *Address;\r
+  VOID  *Address;\r
 \r
   //\r
   // Pre-Allocate memory for page fault handler\r
   //\r
   Address = NULL;\r
   Address = AllocatePages (MAX_PF_PAGE_COUNT);\r
-  ASSERT_EFI_ERROR (Address != NULL);\r
+  ASSERT (Address != NULL);\r
 \r
-  mPFPageBuffer =  (UINT64)(UINTN) Address;\r
-  mPFPageIndex = 0;\r
-  ZeroMem ((VOID *) (UINTN) mPFPageBuffer, EFI_PAGE_SIZE * MAX_PF_PAGE_COUNT);\r
+  mPFPageBuffer =  (UINT64)(UINTN)Address;\r
+  mPFPageIndex  = 0;\r
+  ZeroMem ((VOID *)(UINTN)mPFPageBuffer, EFI_PAGE_SIZE * MAX_PF_PAGE_COUNT);\r
   ZeroMem (mPFPageUplink, sizeof (mPFPageUplink));\r
 \r
   return;\r
@@ -96,28 +93,28 @@ InitPagesForPFHandler (
 **/\r
 VOID\r
 AcquirePage (\r
-  UINT64          *Uplink\r
+  UINT64  *Uplink\r
   )\r
 {\r
-  UINT64          Address;\r
+  UINT64  Address;\r
 \r
   //\r
   // Get the buffer\r
   //\r
   Address = mPFPageBuffer + EFI_PAGES_TO_SIZE (mPFPageIndex);\r
-  ZeroMem ((VOID *) (UINTN) Address, EFI_PAGE_SIZE);\r
+  ZeroMem ((VOID *)(UINTN)Address, EFI_PAGE_SIZE);\r
 \r
   //\r
   // Cut the previous uplink if it exists and wasn't overwritten\r
   //\r
-  if ((mPFPageUplink[mPFPageIndex] != NULL) && ((*mPFPageUplink[mPFPageIndex] & PHYSICAL_ADDRESS_MASK) == Address)) {\r
+  if ((mPFPageUplink[mPFPageIndex] != NULL) && ((*mPFPageUplink[mPFPageIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK) == Address)) {\r
     *mPFPageUplink[mPFPageIndex] = 0;\r
   }\r
 \r
   //\r
   // Link & Record the current uplink\r
   //\r
-  *Uplink = Address | PAGE_ATTRIBUTE_BITS;\r
+  *Uplink                     = Address | mAddressEncMask | PAGE_ATTRIBUTE_BITS;\r
   mPFPageUplink[mPFPageIndex] = Uplink;\r
 \r
   mPFPageIndex = (mPFPageIndex + 1) % MAX_PF_PAGE_COUNT;\r
@@ -137,22 +134,27 @@ AcquirePage (
 **/\r
 VOID\r
 RestorePageTableAbove4G (\r
-  UINT64        *PageTable,\r
-  UINT64        PFAddress,\r
-  UINTN         CpuIndex,\r
-  UINTN         ErrorCode,\r
-  BOOLEAN       *IsValidPFAddress\r
+  UINT64   *PageTable,\r
+  UINT64   PFAddress,\r
+  UINTN    CpuIndex,\r
+  UINTN    ErrorCode,\r
+  BOOLEAN  *IsValidPFAddress\r
   )\r
 {\r
-  UINTN         PTIndex;\r
-  UINT64        Address;\r
-  BOOLEAN       Nx;\r
-  BOOLEAN       Existed;\r
-  UINTN         Index;\r
-  UINTN         PFIndex;\r
+  UINTN     PTIndex;\r
+  UINT64    Address;\r
+  BOOLEAN   Nx;\r
+  BOOLEAN   Existed;\r
+  UINTN     Index;\r
+  UINTN     PFIndex;\r
+  IA32_CR4  Cr4;\r
+  BOOLEAN   Enable5LevelPaging;\r
 \r
   ASSERT ((PageTable != NULL) && (IsValidPFAddress != NULL));\r
 \r
+  Cr4.UintN          = AsmReadCr4 ();\r
+  Enable5LevelPaging = (BOOLEAN)(Cr4.Bits.LA57 == 1);\r
+\r
   //\r
   // If page fault address is 4GB above.\r
   //\r
@@ -162,40 +164,52 @@ RestorePageTableAbove4G (
   // If it exists in page table but page fault is generated,\r
   // there are 2 possible reasons: 1. present flag is set to 0; 2. instruction fetch in protected memory range.\r
   //\r
-  Existed = FALSE;\r
-  PageTable = (UINT64*)(AsmReadCr3 () & PHYSICAL_ADDRESS_MASK);\r
-  PTIndex = BitFieldRead64 (PFAddress, 39, 47);\r
-  if ((PageTable[PTIndex] & IA32_PG_P) != 0) {\r
-    // PML4E\r
-    PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);\r
-    PTIndex = BitFieldRead64 (PFAddress, 30, 38);\r
+  Existed   = FALSE;\r
+  PageTable = (UINT64 *)(AsmReadCr3 () & PHYSICAL_ADDRESS_MASK);\r
+  PTIndex   = 0;\r
+  if (Enable5LevelPaging) {\r
+    PTIndex = BitFieldRead64 (PFAddress, 48, 56);\r
+  }\r
+\r
+  if ((!Enable5LevelPaging) || ((PageTable[PTIndex] & IA32_PG_P) != 0)) {\r
+    // PML5E\r
+    if (Enable5LevelPaging) {\r
+      PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK);\r
+    }\r
+\r
+    PTIndex = BitFieldRead64 (PFAddress, 39, 47);\r
     if ((PageTable[PTIndex] & IA32_PG_P) != 0) {\r
-      // PDPTE\r
-      PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);\r
-      PTIndex = BitFieldRead64 (PFAddress, 21, 29);\r
-      // PD\r
-      if ((PageTable[PTIndex] & IA32_PG_PS) != 0) {\r
-        //\r
-        // 2MB page\r
-        //\r
-        Address = (UINT64)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);\r
-        if ((Address & PHYSICAL_ADDRESS_MASK & ~((1ull << 21) - 1)) == ((PFAddress & PHYSICAL_ADDRESS_MASK & ~((1ull << 21) - 1)))) {\r
-          Existed = TRUE;\r
-        }\r
-      } else {\r
-        //\r
-        // 4KB page\r
-        //\r
-        PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);\r
-        if (PageTable != 0) {\r
+      // PML4E\r
+      PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK);\r
+      PTIndex   = BitFieldRead64 (PFAddress, 30, 38);\r
+      if ((PageTable[PTIndex] & IA32_PG_P) != 0) {\r
+        // PDPTE\r
+        PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK);\r
+        PTIndex   = BitFieldRead64 (PFAddress, 21, 29);\r
+        // PD\r
+        if ((PageTable[PTIndex] & IA32_PG_PS) != 0) {\r
           //\r
-          // When there is a valid entry to map to 4KB page, need not create a new entry to map 2MB.\r
+          // 2MB page\r
           //\r
-          PTIndex = BitFieldRead64 (PFAddress, 12, 20);\r
-          Address = (UINT64)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);\r
-          if ((Address & PHYSICAL_ADDRESS_MASK & ~((1ull << 12) - 1)) == (PFAddress & PHYSICAL_ADDRESS_MASK & ~((1ull << 12) - 1))) {\r
+          Address = (UINT64)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK);\r
+          if ((Address & ~((1ull << 21) - 1)) == ((PFAddress & PHYSICAL_ADDRESS_MASK & ~((1ull << 21) - 1)))) {\r
             Existed = TRUE;\r
           }\r
+        } else {\r
+          //\r
+          // 4KB page\r
+          //\r
+          PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask& PHYSICAL_ADDRESS_MASK);\r
+          if (PageTable != 0) {\r
+            //\r
+            // When there is a valid entry to map to 4KB page, need not create a new entry to map 2MB.\r
+            //\r
+            PTIndex = BitFieldRead64 (PFAddress, 12, 20);\r
+            Address = (UINT64)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK);\r
+            if ((Address & ~((1ull << 12) - 1)) == (PFAddress & PHYSICAL_ADDRESS_MASK & ~((1ull << 12) - 1))) {\r
+              Existed = TRUE;\r
+            }\r
+          }\r
         }\r
       }\r
     }\r
@@ -205,7 +219,6 @@ RestorePageTableAbove4G (
   // If page entry does not existed in page table at all, create a new entry.\r
   //\r
   if (!Existed) {\r
-\r
     if (IsAddressValid (PFAddress, &Nx)) {\r
       //\r
       // If page fault address above 4GB is in protected range but it causes a page fault exception,\r
@@ -222,17 +235,23 @@ RestorePageTableAbove4G (
     //\r
     // Find the page table entry created just now.\r
     //\r
-    PageTable = (UINT64*)(AsmReadCr3 () & PHYSICAL_ADDRESS_MASK);\r
+    PageTable = (UINT64 *)(AsmReadCr3 () & PHYSICAL_ADDRESS_MASK);\r
     PFAddress = AsmReadCr2 ();\r
+    // PML5E\r
+    if (Enable5LevelPaging) {\r
+      PTIndex   = BitFieldRead64 (PFAddress, 48, 56);\r
+      PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK);\r
+    }\r
+\r
     // PML4E\r
-    PTIndex = BitFieldRead64 (PFAddress, 39, 47);\r
-    PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);\r
+    PTIndex   = BitFieldRead64 (PFAddress, 39, 47);\r
+    PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK);\r
     // PDPTE\r
-    PTIndex = BitFieldRead64 (PFAddress, 30, 38);\r
-    PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);\r
+    PTIndex   = BitFieldRead64 (PFAddress, 30, 38);\r
+    PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK);\r
     // PD\r
     PTIndex = BitFieldRead64 (PFAddress, 21, 29);\r
-    Address = PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK;\r
+    Address = PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK;\r
     //\r
     // Check if 2MB-page entry need be changed to 4KB-page entry.\r
     //\r
@@ -240,18 +259,21 @@ RestorePageTableAbove4G (
       AcquirePage (&PageTable[PTIndex]);\r
 \r
       // PTE\r
-      PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);\r
+      PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK);\r
       for (Index = 0; Index < 512; Index++) {\r
-        PageTable[Index] = Address | PAGE_ATTRIBUTE_BITS;\r
+        PageTable[Index] = Address | mAddressEncMask | PAGE_ATTRIBUTE_BITS;\r
         if (!IsAddressValid (Address, &Nx)) {\r
           PageTable[Index] = PageTable[Index] & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS);\r
         }\r
+\r
         if (Nx && mXdSupported) {\r
           PageTable[Index] = PageTable[Index] | IA32_PG_NX;\r
         }\r
+\r
         if (Address == (PFAddress & PHYSICAL_ADDRESS_MASK & ~((1ull << 12) - 1))) {\r
           PTIndex = Index;\r
         }\r
+\r
         Address += SIZE_4KB;\r
       } // end for PT\r
     } else {\r
@@ -264,6 +286,7 @@ RestorePageTableAbove4G (
         //\r
         PageTable[PTIndex] = PageTable[PTIndex] & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS);\r
       }\r
+\r
       //\r
       // Set XD bit to 1\r
       //\r
@@ -280,7 +303,7 @@ RestorePageTableAbove4G (
   //\r
   ASSERT (mPFEntryCount[CpuIndex] < MAX_PF_ENTRY_COUNT);\r
   if (mPFEntryCount[CpuIndex] < MAX_PF_ENTRY_COUNT) {\r
-    PFIndex = mPFEntryCount[CpuIndex];\r
+    PFIndex                                = mPFEntryCount[CpuIndex];\r
     mLastPFEntryValue[CpuIndex][PFIndex]   = PageTable[PTIndex];\r
     mLastPFEntryPointer[CpuIndex][PFIndex] = &PageTable[PTIndex];\r
     mPFEntryCount[CpuIndex]++;\r
@@ -309,7 +332,7 @@ RestorePageTableAbove4G (
 **/\r
 VOID\r
 ClearTrapFlag (\r
-  IN OUT EFI_SYSTEM_CONTEXT   SystemContext\r
+  IN OUT EFI_SYSTEM_CONTEXT  SystemContext\r
   )\r
 {\r
   SystemContext.SystemContextX64->Rflags &= (UINTN) ~BIT8;\r