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

Anthony PERARD posted 35 patches 5 years, 3 months ago
[edk2-devel] [PATCH v5 22/35] OvmfPkg/XenPlatformPei: no hvmloader: get the E820 table via hypercall
Posted by Anthony PERARD 5 years, 3 months ago
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.

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:
    v5:
    - fix commit message, the hypercall *can* be made several time, but we
      still cache the result.
    
    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 f26f0e56dd..72f6f37b46 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 (#45547): https://edk2.groups.io/g/devel/message/45547
Mute This Topic: https://groups.io/mt/32851694/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-

Re: [edk2-devel] [PATCH v5 22/35] OvmfPkg/XenPlatformPei: no hvmloader: get the E820 table via hypercall
Posted by Laszlo Ersek 5 years, 3 months ago
On 08/13/19 13:31, 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.  We keep the result cached to avoid
> making a second hypercall which would give the same result.
> 
> 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:
>     v5:
>     - fix commit message, the hypercall *can* be made several time, but we
>       still cache the result.

Addresses Roger's feedback in:

http://mid.mail-archive.com/20190808104558.vm6dfic5dntjsnt4@Air-de-Roger
https://edk2.groups.io/g/devel/message/45160

My ACK stands.

Thanks
Laszlo


>     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 f26f0e56dd..72f6f37b46 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;
>  }
>  
>  /**
> 


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

View/Reply Online (#45705): https://edk2.groups.io/g/devel/message/45705
Mute This Topic: https://groups.io/mt/32851694/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-