[edk2-devel] [PATCH v4 22/35] OvmfPkg/XenPlatformPei: no hvmloader: get the E820 table via hypercall

Anthony PERARD anthony.perard at citrix.com
Mon Jul 29 15:39:31 UTC 2019


When the Xen PVH entry point has been used, hvmloader hasn't run and
hasn't prepared an E820 table. The only way left to get an E820 table
is to ask Xen via an hypercall, the call can only be made once so keep
the result cached for later.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard at citrix.com>
Acked-by: Laszlo Ersek <lersek at redhat.com>
---

Notes:
    v3:
    - fix commit message
    - add 'm' prefix to the global variables
      and make them static

 OvmfPkg/XenPlatformPei/Xen.c | 46 +++++++++++++++++++++++++++++++++++-
 1 file changed, 45 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
index 71fe5de446..a21d657357 100644
--- a/OvmfPkg/XenPlatformPei/Xen.c
+++ b/OvmfPkg/XenPlatformPei/Xen.c
@@ -27,6 +27,7 @@
 #include <Library/MtrrLib.h>
 #include <IndustryStandard/Xen/arch-x86/hvm/start_info.h>
 #include <Library/XenHypercallLib.h>
+#include <IndustryStandard/Xen/memory.h>
 
 #include "Platform.h"
 #include "Xen.h"
@@ -40,6 +41,8 @@ EFI_XEN_INFO mXenInfo;
 // Only the E820 table is used by OVMF.
 //
 EFI_XEN_OVMF_INFO *mXenHvmloaderInfo;
+STATIC EFI_E820_ENTRY64 mE820Entries[128];
+STATIC UINT32 mE820EntriesCount;
 
 /**
   Returns E820 map provided by Xen
@@ -55,6 +58,12 @@ XenGetE820Map (
   UINT32 *Count
   )
 {
+  INTN ReturnCode;
+  xen_memory_map_t Parameters;
+  UINTN LoopIndex;
+  UINTN Index;
+  EFI_E820_ENTRY64 TmpEntry;
+
   //
   // Get E820 produced by hvmloader
   //
@@ -66,7 +75,42 @@ XenGetE820Map (
     return EFI_SUCCESS;
   }
 
-  return EFI_NOT_FOUND;
+  //
+  // Otherwise, get the E820 table from the Xen hypervisor
+  //
+
+  if (mE820EntriesCount > 0) {
+    *Entries = mE820Entries;
+    *Count = mE820EntriesCount;
+    return EFI_SUCCESS;
+  }
+
+  Parameters.nr_entries = 128;
+  set_xen_guest_handle (Parameters.buffer, mE820Entries);
+
+  // Returns a errno
+  ReturnCode = XenHypercallMemoryOp (XENMEM_memory_map, &Parameters);
+  ASSERT (ReturnCode == 0);
+
+  mE820EntriesCount = Parameters.nr_entries;
+
+  //
+  // Sort E820 entries
+  //
+  for (LoopIndex = 1; LoopIndex < mE820EntriesCount; LoopIndex++) {
+    for (Index = LoopIndex; Index < mE820EntriesCount; Index++) {
+      if (mE820Entries[Index - 1].BaseAddr > mE820Entries[Index].BaseAddr) {
+        TmpEntry = mE820Entries[Index];
+        mE820Entries[Index] = mE820Entries[Index - 1];
+        mE820Entries[Index - 1] = TmpEntry;
+      }
+    }
+  }
+
+  *Count = mE820EntriesCount;
+  *Entries = mE820Entries;
+
+  return EFI_SUCCESS;
 }
 
 /**
-- 
Anthony PERARD


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#44559): https://edk2.groups.io/g/devel/message/44559
Mute This Topic: https://groups.io/mt/32644087/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list