summaryrefslogtreecommitdiffstats
path: root/OvmfPkg/XenPlatformPei
diff options
context:
space:
mode:
authorAnthony PERARD <anthony.perard@citrix.com>2021-04-12 14:30:01 +0100
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2021-04-13 11:54:58 +0000
commit51e0bd28bba9631fd3e3244668b6ab9c561817b2 (patch)
treec1c13ffc582782b8d11bf4979d0f0ebc8eabf891 /OvmfPkg/XenPlatformPei
parent9d6861494aaa987fb728828801c84eb89be283c8 (diff)
downloadedk2-51e0bd28bba9631fd3e3244668b6ab9c561817b2.tar.gz
edk2-51e0bd28bba9631fd3e3244668b6ab9c561817b2.tar.bz2
edk2-51e0bd28bba9631fd3e3244668b6ab9c561817b2.zip
OvmfPkg/XenPlatformPei: Map extra physical address
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>
Diffstat (limited to 'OvmfPkg/XenPlatformPei')
-rw-r--r--OvmfPkg/XenPlatformPei/Platform.h5
-rw-r--r--OvmfPkg/XenPlatformPei/Xen.c71
-rw-r--r--OvmfPkg/XenPlatformPei/XenPlatformPei.inf1
3 files changed, 77 insertions, 0 deletions
diff --git a/OvmfPkg/XenPlatformPei/Platform.h b/OvmfPkg/XenPlatformPei/Platform.h
index 7661f4a8de..e70ca58078 100644
--- a/OvmfPkg/XenPlatformPei/Platform.h
+++ b/OvmfPkg/XenPlatformPei/Platform.h
@@ -127,6 +127,11 @@ XenGetE820Map (
UINT32 *Count
);
+EFI_STATUS
+PhysicalAddressIdentityMapping (
+ IN EFI_PHYSICAL_ADDRESS AddressToMap
+ );
+
extern EFI_BOOT_MODE mBootMode;
extern UINT8 mPhysMemAddressWidth;
diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
index c41fecdc48..b2a7d1c21d 100644
--- a/OvmfPkg/XenPlatformPei/Xen.c
+++ b/OvmfPkg/XenPlatformPei/Xen.c
@@ -17,6 +17,8 @@
//
// The Library classes this module consumes
//
+#include <Library/BaseMemoryLib.h>
+#include <Library/CpuLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/MemoryAllocationLib.h>
@@ -25,6 +27,7 @@
#include <IndustryStandard/E820.h>
#include <Library/ResourcePublicationLib.h>
#include <Library/MtrrLib.h>
+#include <IndustryStandard/PageTable.h>
#include <IndustryStandard/Xen/arch-x86/hvm/start_info.h>
#include <Library/XenHypercallLib.h>
#include <IndustryStandard/Xen/memory.h>
@@ -386,3 +389,71 @@ InitializeXen (
return EFI_SUCCESS;
}
+
+EFI_STATUS
+PhysicalAddressIdentityMapping (
+ IN EFI_PHYSICAL_ADDRESS AddressToMap
+ )
+{
+ INTN Index;
+ PAGE_MAP_AND_DIRECTORY_POINTER *L4, *L3;
+ PAGE_TABLE_ENTRY *PageTable;
+
+ DEBUG ((DEBUG_INFO, "Mapping 1:1 of address 0x%lx\n", (UINT64)AddressToMap));
+
+ // L4 / Top level Page Directory Pointers
+
+ L4 = (VOID*)(UINTN)PcdGet32 (PcdOvmfSecPageTablesBase);
+ Index = PML4_OFFSET (AddressToMap);
+
+ if (!L4[Index].Bits.Present) {
+ L3 = AllocatePages (1);
+ if (L3 == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ZeroMem (L3, EFI_PAGE_SIZE);
+
+ L4[Index].Bits.ReadWrite = 1;
+ L4[Index].Bits.Accessed = 1;
+ L4[Index].Bits.PageTableBaseAddress = (EFI_PHYSICAL_ADDRESS)L3 >> 12;
+ L4[Index].Bits.Present = 1;
+ }
+
+ // L3 / Next level Page Directory Pointers
+
+ L3 = (VOID*)(EFI_PHYSICAL_ADDRESS)(L4[Index].Bits.PageTableBaseAddress << 12);
+ Index = PDP_OFFSET (AddressToMap);
+
+ if (!L3[Index].Bits.Present) {
+ PageTable = AllocatePages (1);
+ if (PageTable == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ZeroMem (PageTable, EFI_PAGE_SIZE);
+
+ L3[Index].Bits.ReadWrite = 1;
+ L3[Index].Bits.Accessed = 1;
+ L3[Index].Bits.PageTableBaseAddress = (EFI_PHYSICAL_ADDRESS)PageTable >> 12;
+ L3[Index].Bits.Present = 1;
+ }
+
+ // L2 / Page Table Entries
+
+ PageTable = (VOID*)(EFI_PHYSICAL_ADDRESS)(L3[Index].Bits.PageTableBaseAddress << 12);
+ Index = PDE_OFFSET (AddressToMap);
+
+ if (!PageTable[Index].Bits.Present) {
+ PageTable[Index].Bits.ReadWrite = 1;
+ PageTable[Index].Bits.Accessed = 1;
+ PageTable[Index].Bits.Dirty = 1;
+ PageTable[Index].Bits.MustBe1 = 1;
+ PageTable[Index].Bits.PageTableBaseAddress = AddressToMap >> 21;
+ PageTable[Index].Bits.Present = 1;
+ }
+
+ CpuFlushTlb ();
+
+ return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/XenPlatformPei/XenPlatformPei.inf b/OvmfPkg/XenPlatformPei/XenPlatformPei.inf
index 0ef77db92c..8790d907d3 100644
--- a/OvmfPkg/XenPlatformPei/XenPlatformPei.inf
+++ b/OvmfPkg/XenPlatformPei/XenPlatformPei.inf
@@ -66,6 +66,7 @@
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId