]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/XenPlatformPei: Map extra physical address
authorAnthony PERARD <anthony.perard@citrix.com>
Mon, 12 Apr 2021 13:30:01 +0000 (14:30 +0100)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Tue, 13 Apr 2021 11:54:58 +0000 (11:54 +0000)
Some information available in a Xen guest can be mapped anywhere in
the physical address space and they don't need to be backed by RAM.
For example, the shared info page.

While it's easier to put those pages anywhere, it is better to avoid
mapping it where the RAM is. It might split a nice 1G guest page table
into 4k pages and thus reducing performance of the guest when it
accesses its memory. Also mapping a page like the shared info page and
then unmapping it or mapping it somewhere else would leave a hole in
the RAM that the guest would propably not be able to use anymore.

So the patch introduces a new function which can be used to 1:1
mapping of guest physical memory above 4G during the PEI phase so we
can map the Xen shared pages outside of memory that can be used by
guest, and as high as possible.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20210412133003.146438-6-anthony.perard@citrix.com>

OvmfPkg/XenPlatformPei/Platform.h
OvmfPkg/XenPlatformPei/Xen.c
OvmfPkg/XenPlatformPei/XenPlatformPei.inf

index 7661f4a8de0a4b76487d2472c226f5c6d7694d00..e70ca58078ebe82344fe79d31263c709f90f9845 100644 (file)
@@ -127,6 +127,11 @@ XenGetE820Map (
   UINT32 *Count\r
   );\r
 \r
+EFI_STATUS\r
+PhysicalAddressIdentityMapping (\r
+  IN EFI_PHYSICAL_ADDRESS AddressToMap\r
+  );\r
+\r
 extern EFI_BOOT_MODE mBootMode;\r
 \r
 extern UINT8 mPhysMemAddressWidth;\r
index c41fecdc486e7f816e59ca475f462726406997e0..b2a7d1c21dacc305a036808515acbd1d79849e6f 100644 (file)
@@ -17,6 +17,8 @@
 //\r
 // The Library classes this module consumes\r
 //\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/CpuLib.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/HobLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
@@ -25,6 +27,7 @@
 #include <IndustryStandard/E820.h>\r
 #include <Library/ResourcePublicationLib.h>\r
 #include <Library/MtrrLib.h>\r
+#include <IndustryStandard/PageTable.h>\r
 #include <IndustryStandard/Xen/arch-x86/hvm/start_info.h>\r
 #include <Library/XenHypercallLib.h>\r
 #include <IndustryStandard/Xen/memory.h>\r
@@ -386,3 +389,71 @@ InitializeXen (
 \r
   return EFI_SUCCESS;\r
 }\r
+\r
+EFI_STATUS\r
+PhysicalAddressIdentityMapping (\r
+  IN EFI_PHYSICAL_ADDRESS   AddressToMap\r
+  )\r
+{\r
+  INTN                            Index;\r
+  PAGE_MAP_AND_DIRECTORY_POINTER  *L4, *L3;\r
+  PAGE_TABLE_ENTRY                *PageTable;\r
+\r
+  DEBUG ((DEBUG_INFO, "Mapping 1:1 of address 0x%lx\n", (UINT64)AddressToMap));\r
+\r
+  // L4 / Top level Page Directory Pointers\r
+\r
+  L4 = (VOID*)(UINTN)PcdGet32 (PcdOvmfSecPageTablesBase);\r
+  Index = PML4_OFFSET (AddressToMap);\r
+\r
+  if (!L4[Index].Bits.Present) {\r
+    L3 = AllocatePages (1);\r
+    if (L3 == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    ZeroMem (L3, EFI_PAGE_SIZE);\r
+\r
+    L4[Index].Bits.ReadWrite = 1;\r
+    L4[Index].Bits.Accessed = 1;\r
+    L4[Index].Bits.PageTableBaseAddress = (EFI_PHYSICAL_ADDRESS)L3 >> 12;\r
+    L4[Index].Bits.Present = 1;\r
+  }\r
+\r
+  // L3 / Next level Page Directory Pointers\r
+\r
+  L3 = (VOID*)(EFI_PHYSICAL_ADDRESS)(L4[Index].Bits.PageTableBaseAddress << 12);\r
+  Index = PDP_OFFSET (AddressToMap);\r
+\r
+  if (!L3[Index].Bits.Present) {\r
+    PageTable = AllocatePages (1);\r
+    if (PageTable == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    ZeroMem (PageTable, EFI_PAGE_SIZE);\r
+\r
+    L3[Index].Bits.ReadWrite = 1;\r
+    L3[Index].Bits.Accessed = 1;\r
+    L3[Index].Bits.PageTableBaseAddress = (EFI_PHYSICAL_ADDRESS)PageTable >> 12;\r
+    L3[Index].Bits.Present = 1;\r
+  }\r
+\r
+  // L2 / Page Table Entries\r
+\r
+  PageTable = (VOID*)(EFI_PHYSICAL_ADDRESS)(L3[Index].Bits.PageTableBaseAddress << 12);\r
+  Index = PDE_OFFSET (AddressToMap);\r
+\r
+  if (!PageTable[Index].Bits.Present) {\r
+    PageTable[Index].Bits.ReadWrite = 1;\r
+    PageTable[Index].Bits.Accessed = 1;\r
+    PageTable[Index].Bits.Dirty = 1;\r
+    PageTable[Index].Bits.MustBe1 = 1;\r
+    PageTable[Index].Bits.PageTableBaseAddress = AddressToMap >> 21;\r
+    PageTable[Index].Bits.Present = 1;\r
+  }\r
+\r
+  CpuFlushTlb ();\r
+\r
+  return EFI_SUCCESS;\r
+}\r
index 0ef77db92c03027592769d1abe7a436a07057998..8790d907d3ec6640227c39b854bc334503d15834 100644 (file)
@@ -66,6 +66,7 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize\r
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase\r
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase\r
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase\r
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize\r
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId\r