diff mbox series

[v4,22/35] OvmfPkg/XenPlatformPei: no hvmloader: get the E820 table via hypercall

Message ID 20190729153944.24239-23-anthony.perard@citrix.com (mailing list archive)
State Superseded
Headers show
Series Specific platform to run OVMF in Xen PVH and HVM guests | expand

Commit Message

Anthony PERARD July 29, 2019, 3:39 p.m. UTC
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@citrix.com>
Acked-by: Laszlo Ersek <lersek@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(-)

Comments

Roger Pau Monné Aug. 7, 2019, 3:14 p.m. UTC | #1
On Mon, Jul 29, 2019 at 04:39:31PM +0100, Anthony PERARD wrote:
> 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.

I think we agreed that the above is not true, and that the memory
map can be fetched as many times as desired using the hypercall
interface.

Thanks, Roger.
Anthony PERARD Aug. 8, 2019, 10:41 a.m. UTC | #2
On Wed, Aug 07, 2019 at 05:14:33PM +0200, Roger Pau Monné wrote:
> On Mon, Jul 29, 2019 at 04:39:31PM +0100, Anthony PERARD wrote:
> > 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.
> 
> I think we agreed that the above is not true, and that the memory
> map can be fetched as many times as desired using the hypercall
> interface.

Yes, I'll change the commit message. How about:

  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.  We keep the result cached to avoid
  making a second hypercall which would give the same result.

Thanks,
Roger Pau Monné Aug. 8, 2019, 10:45 a.m. UTC | #3
On Thu, Aug 08, 2019 at 11:41:18AM +0100, Anthony PERARD wrote:
> On Wed, Aug 07, 2019 at 05:14:33PM +0200, Roger Pau Monné wrote:
> > On Mon, Jul 29, 2019 at 04:39:31PM +0100, Anthony PERARD wrote:
> > > 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.
> > 
> > I think we agreed that the above is not true, and that the memory
> > map can be fetched as many times as desired using the hypercall
> > interface.
> 
> Yes, I'll change the commit message. How about:
> 
>   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.  We keep the result cached to avoid
>   making a second hypercall which would give the same result.

LGTM, thanks.
diff mbox series

Patch

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;
 }
 
 /**