]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/CapsulePei/X64/X64Entry.c
MdeModulePkg/Universal/CapsulePei: Add support for PCD PcdPteMemoryEncryptionAddressO...
[mirror_edk2.git] / MdeModulePkg / Universal / CapsulePei / X64 / X64Entry.c
index 5ad95d215176bbe0acc027bd80bab165ebe0cc78..e1871c3c2ad585f89924f0471fccefcf0fec7d37 100644 (file)
@@ -2,6 +2,8 @@
   The X64 entrypoint is used to process capsule in long mode.\r
 \r
 Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
+\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
@@ -29,6 +31,7 @@ typedef struct _PAGE_FAULT_CONTEXT {
   UINT64                        PhyMask;\r
   UINTN                         PageFaultBuffer;\r
   UINTN                         PageFaultIndex;\r
+  UINT64                        AddressEncMask;\r
   //\r
   // Store the uplink information for each page being used.\r
   //\r
@@ -114,21 +117,25 @@ AcquirePage (
   )\r
 {\r
   UINTN             Address;\r
+  UINT64            AddressEncMask;\r
 \r
   Address = PageFaultContext->PageFaultBuffer + EFI_PAGES_TO_SIZE (PageFaultContext->PageFaultIndex);\r
   ZeroMem ((VOID *) Address, EFI_PAGES_TO_SIZE (1));\r
 \r
+  AddressEncMask = PageFaultContext->AddressEncMask;\r
+\r
   //\r
   // Cut the previous uplink if it exists and wasn't overwritten.\r
   //\r
-  if ((PageFaultContext->PageFaultUplink[PageFaultContext->PageFaultIndex] != NULL) && ((*PageFaultContext->PageFaultUplink[PageFaultContext->PageFaultIndex] & PageFaultContext->PhyMask) == Address)) {\r
+  if ((PageFaultContext->PageFaultUplink[PageFaultContext->PageFaultIndex] != NULL) &&\r
+     ((*PageFaultContext->PageFaultUplink[PageFaultContext->PageFaultIndex] & ~AddressEncMask & PageFaultContext->PhyMask) == Address)) {\r
     *PageFaultContext->PageFaultUplink[PageFaultContext->PageFaultIndex] = 0;\r
   }\r
 \r
   //\r
   // Link & Record the current uplink.\r
   //\r
-  *Uplink = Address | IA32_PG_P | IA32_PG_RW;\r
+  *Uplink = Address | AddressEncMask | IA32_PG_P | IA32_PG_RW;\r
   PageFaultContext->PageFaultUplink[PageFaultContext->PageFaultIndex] = Uplink;\r
 \r
   PageFaultContext->PageFaultIndex = (PageFaultContext->PageFaultIndex + 1) % EXTRA_PAGE_TABLE_PAGES;\r
@@ -153,6 +160,7 @@ PageFaultHandler (
   UINT64                    *PageTable;\r
   UINT64                    PFAddress;\r
   UINTN                     PTIndex;\r
+  UINT64                    AddressEncMask;\r
 \r
   //\r
   // Get the IDT Descriptor.\r
@@ -163,6 +171,7 @@ PageFaultHandler (
   //\r
   PageFaultContext = (PAGE_FAULT_CONTEXT *) (UINTN) (Idtr.Base - sizeof (PAGE_FAULT_CONTEXT));\r
   PhyMask = PageFaultContext->PhyMask;\r
+  AddressEncMask = PageFaultContext->AddressEncMask;\r
 \r
   PFAddress = AsmReadCr2 ();\r
   DEBUG ((EFI_D_ERROR, "CapsuleX64 - PageFaultHandler: Cr2 - %lx\n", PFAddress));\r
@@ -179,19 +188,19 @@ PageFaultHandler (
   if ((PageTable[PTIndex] & IA32_PG_P) == 0) {\r
     AcquirePage (PageFaultContext, &PageTable[PTIndex]);\r
   }\r
-  PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PhyMask);\r
+  PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & ~AddressEncMask & PhyMask);\r
   PTIndex = BitFieldRead64 (PFAddress, 30, 38);\r
   // PDPTE\r
   if (PageFaultContext->Page1GSupport) {\r
-    PageTable[PTIndex] = (PFAddress & ~((1ull << 30) - 1)) | IA32_PG_P | IA32_PG_RW | IA32_PG_PS;\r
+    PageTable[PTIndex] = ((PFAddress | AddressEncMask) & ~((1ull << 30) - 1)) | IA32_PG_P | IA32_PG_RW | IA32_PG_PS;\r
   } else {\r
     if ((PageTable[PTIndex] & IA32_PG_P) == 0) {\r
       AcquirePage (PageFaultContext, &PageTable[PTIndex]);\r
     }\r
-    PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PhyMask);\r
+    PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & ~AddressEncMask & PhyMask);\r
     PTIndex = BitFieldRead64 (PFAddress, 21, 29);\r
     // PD\r
-    PageTable[PTIndex] = (PFAddress & ~((1ull << 21) - 1)) | IA32_PG_P | IA32_PG_RW | IA32_PG_PS;\r
+    PageTable[PTIndex] = ((PFAddress | AddressEncMask) & ~((1ull << 21) - 1)) | IA32_PG_P | IA32_PG_RW | IA32_PG_PS;\r
   }\r
 \r
   return NULL;\r
@@ -244,6 +253,7 @@ _ModuleEntryPoint (
   // Hook page fault handler to handle >4G request.\r
   //\r
   PageFaultIdtTable.PageFaultContext.Page1GSupport = EntrypointContext->Page1GSupport;\r
+  PageFaultIdtTable.PageFaultContext.AddressEncMask = EntrypointContext->AddressEncMask;\r
   IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) (X64Idtr.Base + (14 * sizeof (IA32_IDT_GATE_DESCRIPTOR)));\r
   HookPageFaultHandler (IdtEntry, &(PageFaultIdtTable.PageFaultContext));\r
 \r
@@ -298,4 +308,4 @@ _ModuleEntryPoint (
   //\r
   ASSERT (FALSE);\r
   return EFI_SUCCESS;\r
-}
\ No newline at end of file
+}\r