This series adds support for QEMU's -kernel option by porting
the efilinux project into OvmfPkg.

v2:
 * Many changes based on Laszlo Ersek's code review
 * Initrd max address of 1GB (efilinux 8947b2)
 * Merge E820 memory types (efilinux d0efc6)
 * Only set efi_*_hi for x86-64 (efilinux 0f35b5)
 * Use bzimage size rather than 8MB (efilinux f72063)
 * Note: v1 vs. v2 diff is at the bottom of this email

Jordan Justen (5):
  OvmfPkg: Add Linux bzimage include file
  OvmfPkg: Add LoadLinuxLib library interface
  OvmfPkg: Add LoadLinuxLib library implementation
  OvmfPkg: Add QemuKernelDxe application
  OvmfPkg: Run the QemuKernelDxe application during BDS

 OvmfPkg/Application/QemuKernelDxe/QemuKernelDxe.c  |  184 ++++++++
 .../Application/QemuKernelDxe/QemuKernelDxe.inf    |   47 ++
 OvmfPkg/Include/Guid/OvmfQemuKernelFile.h          |   25 +
 OvmfPkg/Include/IndustryStandard/LinuxBzimage.h    |  164 +++++++
 OvmfPkg/Include/Library/LoadLinuxLib.h             |  210 +++++++++
 OvmfPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.S   |   29 ++
 OvmfPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.asm |   35 ++
 OvmfPkg/Library/LoadLinuxLib/Linux.c               |  487 ++++++++++++++++++++
 OvmfPkg/Library/LoadLinuxLib/LinuxGdt.c            |  200 ++++++++
 OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.h        |   56 +++
 OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf      |   50 ++
 OvmfPkg/Library/LoadLinuxLib/X64/JumpToKernel.S    |   30 ++
 OvmfPkg/Library/LoadLinuxLib/X64/JumpToKernel.asm  |   34 ++
 OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c       |   70 +++
 OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h       |    1 +
 OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf  |    4 +
 OvmfPkg/OvmfPkg.dec                                |    6 +
 OvmfPkg/OvmfPkgIa32.dsc                            |    4 +
 OvmfPkg/OvmfPkgIa32.fdf                            |    2 +
 OvmfPkg/OvmfPkgIa32X64.dsc                         |    4 +
 OvmfPkg/OvmfPkgIa32X64.fdf                         |    2 +
 OvmfPkg/OvmfPkgX64.dsc                             |    4 +
 OvmfPkg/OvmfPkgX64.fdf                             |    2 +
 23 files changed, 1650 insertions(+)
 create mode 100644 OvmfPkg/Application/QemuKernelDxe/QemuKernelDxe.c
 create mode 100644 OvmfPkg/Application/QemuKernelDxe/QemuKernelDxe.inf
 create mode 100644 OvmfPkg/Include/Guid/OvmfQemuKernelFile.h
 create mode 100644 OvmfPkg/Include/IndustryStandard/LinuxBzimage.h
 create mode 100644 OvmfPkg/Include/Library/LoadLinuxLib.h
 create mode 100644 OvmfPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.S
 create mode 100644 OvmfPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.asm
 create mode 100644 OvmfPkg/Library/LoadLinuxLib/Linux.c
 create mode 100644 OvmfPkg/Library/LoadLinuxLib/LinuxGdt.c
 create mode 100644 OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.h
 create mode 100644 OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
 create mode 100644 OvmfPkg/Library/LoadLinuxLib/X64/JumpToKernel.S
 create mode 100644 OvmfPkg/Library/LoadLinuxLib/X64/JumpToKernel.asm

-- 
1.7.9.5

diff --git a/OvmfPkg/Application/QemuKernelDxe/QemuKernelDxe.c 
b/OvmfPkg/Application/QemuKernelDxe/QemuKernelDxe.c
index f9b7092..448abcf 100644
--- a/OvmfPkg/Application/QemuKernelDxe/QemuKernelDxe.c
+++ b/OvmfPkg/Application/QemuKernelDxe/QemuKernelDxe.c
@@ -43,7 +43,15 @@ QemuFwCfgLoadLinux (
   CHAR8                     *CommandLine;
   UINTN                     InitrdSize;
   VOID*                     InitrdData;
-  struct boot_params        *Bp;
+
+  SetupBuf = NULL;
+  SetupSize = 0;
+  KernelBuf = NULL;
+  KernelInitialSize = 0;
+  CommandLine = NULL;
+  CommandLineSize = 0;
+  InitrdData = NULL;
+  InitrdSize = 0;
 
   if (!QemuFwCfgIsAvailable ()) {
     return EFI_NOT_FOUND;
@@ -51,11 +59,9 @@ QemuFwCfgLoadLinux (
 
   QemuFwCfgSelectItem (QemuFwCfgItemKernelSize);
   KernelSize = (UINTN) QemuFwCfgRead64 ();
-  DEBUG ((EFI_D_INFO, "Kernel size: 0x%x\n", KernelSize));
 
   QemuFwCfgSelectItem (QemuFwCfgItemKernelSetupSize);
   SetupSize = (UINTN) QemuFwCfgRead64 ();
-  DEBUG ((EFI_D_INFO, "Setup size: 0x%x\n", SetupSize));
 
   if (KernelSize == 0 || SetupSize == 0) {
     DEBUG ((EFI_D_INFO, "qemu -kernel was not used.\n"));
@@ -68,6 +74,7 @@ QemuFwCfgLoadLinux (
     return EFI_OUT_OF_RESOURCES;
   }
 
+  DEBUG ((EFI_D_INFO, "Setup size: 0x%x\n", (UINT32) SetupSize));
   DEBUG ((EFI_D_INFO, "Reading kernel setup image ..."));
   QemuFwCfgSelectItem (QemuFwCfgItemKernelSetupData);
   QemuFwCfgReadBytes (SetupSize, SetupBuf);
@@ -75,24 +82,25 @@ QemuFwCfgLoadLinux (
 
   Status = LoadLinuxCheckKernelSetup (SetupBuf, SetupSize);
   if (EFI_ERROR (Status)) {
-    return Status;
+    goto FreeAndReturn;
   }
 
   KernelInitialSize = LoadLinuxGetKernelSize (SetupBuf, KernelSize);
   if (KernelInitialSize == 0) {
-    return EFI_UNSUPPORTED;
+    Status = EFI_UNSUPPORTED;
+    goto FreeAndReturn;
   }
 
-  Bp = (struct boot_params*) SetupBuf;
-
   KernelBuf = LoadLinuxAllocateKernelPages (
                 SetupBuf,
                 EFI_SIZE_TO_PAGES (KernelInitialSize));
   if (KernelBuf == NULL) {
     DEBUG ((EFI_D_ERROR, "Unable to allocate memory for kernel!\n"));
-    return EFI_OUT_OF_RESOURCES;
+    Status = EFI_OUT_OF_RESOURCES;
+    goto FreeAndReturn;
   }
 
+  DEBUG ((EFI_D_INFO, "Kernel size: 0x%x\n", (UINT32) KernelSize));
   DEBUG ((EFI_D_INFO, "Reading kernel image ..."));
   QemuFwCfgSelectItem (QemuFwCfgItemKernelData);
   QemuFwCfgReadBytes (KernelSize, KernelBuf);
@@ -100,7 +108,6 @@ QemuFwCfgLoadLinux (
 
   QemuFwCfgSelectItem (QemuFwCfgItemCommandLineSize);
   CommandLineSize = (UINTN) QemuFwCfgRead64 ();
-  DEBUG ((EFI_D_INFO, "Command line size: 0x%x\n", CommandLineSize));
 
   if (CommandLineSize > 0) {
     CommandLine = LoadLinuxAllocateCommandLinePages (
@@ -113,15 +120,15 @@ QemuFwCfgLoadLinux (
 
   Status = LoadLinuxSetCommandLine (SetupBuf, CommandLine);
   if (EFI_ERROR (Status)) {
-    return Status;
+    goto FreeAndReturn;
   }
 
   QemuFwCfgSelectItem (QemuFwCfgItemInitrdSize);
   InitrdSize = (UINTN) QemuFwCfgRead64 ();
-  DEBUG ((EFI_D_INFO, "Initrd size: 0x%x\n", InitrdSize));
 
   if (InitrdSize > 0) {
     InitrdData = LoadLinuxAllocateInitrdPages (EFI_SIZE_TO_PAGES (InitrdSize));
+    DEBUG ((EFI_D_INFO, "Initrd size: 0x%x\n", (UINT32) InitrdSize));
     DEBUG ((EFI_D_INFO, "Reading initrd image ..."));
     QemuFwCfgSelectItem (QemuFwCfgItemInitrdData);
     QemuFwCfgReadBytes (InitrdSize, InitrdData);
@@ -132,10 +139,26 @@ QemuFwCfgLoadLinux (
 
   Status = LoadLinuxSetInitrd (SetupBuf, InitrdData, InitrdSize);
   if (EFI_ERROR (Status)) {
-    return Status;
+    goto FreeAndReturn;
+  }
+
+  Status = LoadLinux (KernelBuf, SetupBuf);
+
+FreeAndReturn:
+  if (SetupBuf != NULL) {
+    FreePages (SetupBuf, EFI_SIZE_TO_PAGES (SetupSize));
+  }
+  if (KernelBuf != NULL) {
+    FreePages (KernelBuf, EFI_SIZE_TO_PAGES (KernelInitialSize));
+  }
+  if (CommandLine != NULL) {
+    FreePages (CommandLine, EFI_SIZE_TO_PAGES (CommandLineSize));
+  }
+  if (InitrdData != NULL) {
+    FreePages (InitrdData, EFI_SIZE_TO_PAGES (InitrdSize));
   }
 
-  return LoadLinux (KernelBuf, SetupBuf);
+  return Status;
 }
 
 
diff --git a/OvmfPkg/Include/Library/LoadLinuxLib.h 
b/OvmfPkg/Include/Library/LoadLinuxLib.h
index d73ee9f..9867924 100644
--- a/OvmfPkg/Include/Library/LoadLinuxLib.h
+++ b/OvmfPkg/Include/Library/LoadLinuxLib.h
@@ -25,6 +25,7 @@
   @param[in]     KernelSetupSize - The kernel setup size
 
   @retval    EFI_SUCCESS - The Linux kernel setup is valid and supported
+  @retval    EFI_INVALID_PARAMETER - KernelSetup was NULL
   @retval    EFI_UNSUPPORTED - The Linux kernel is not supported
 
 **/
@@ -41,7 +42,7 @@ LoadLinuxCheckKernelSetup (
   the kernel setup image.
 
   @param[in]     KernelSetup - The kernel setup image
-  @param[in,out] KernelSize - The kernel size on disk.
+  @param[in]     KernelSize - The kernel size on disk.
 
   @retval    0                An error occured
   @retval    !0               The initial size required by the kernel to
@@ -61,12 +62,11 @@ LoadLinuxGetKernelSize (
 
   Note: If successful, then this routine will not return
 
-  @param[in] Kernel - The main kernel image
-  @param[in] KernelSetup - The kernel setup image
-  @param[in] Initrd - The kernel initial root disk
-  @param[in] CommandLine - The kernel command line
+  @param[in]     Kernel - The main kernel image
+  @param[in,out] KernelSetup - The kernel setup image
 
   @retval    EFI_NOT_FOUND - The Linux kernel was not found
+  @retval    EFI_INVALID_PARAMETER - Kernel or KernelSetup was NULL
   @retval    EFI_UNSUPPORTED - The Linux kernel version is not supported
 
 **/
@@ -74,7 +74,7 @@ EFI_STATUS
 EFIAPI
 LoadLinux (
   IN VOID      *Kernel,
-  IN VOID      *KernelSetup
+  IN OUT VOID  *KernelSetup
   );
 
 
@@ -83,20 +83,18 @@ LoadLinux (
 
   Note: If successful, then this routine will not return
 
-  @param[in] BzImage - The main kernel image
-  @param[in] BzImageSize - The main kernel image size
-  @param[in] Initrd - The initial root disk image
-  @param[in] InitrdSize - The initial root disk image size
-  @param[in] CommandLine - The kernel command line
+  @param[in,out] BzImage - The main kernel image
+  @param[in]     BzImageSize - The main kernel image size
 
   @retval    EFI_NOT_FOUND - The Linux kernel was not found
+  @retval    EFI_INVALID_PARAMETER - BzImage was NULL
   @retval    EFI_UNSUPPORTED - The Linux kernel version is not supported
 
 **/
 EFI_STATUS
 EFIAPI
 LoadLinuxBzImage (
-  IN VOID      *BzImage,
+  IN OUT VOID  *BzImage,
   IN UINTN     BzImageSize
   );
 
@@ -120,6 +118,7 @@ LoadLinuxAllocateKernelSetupPages (
 /**
   Allocates pages for the kernel.
 
+  @param[in]     KernelSetup - The kernel setup image
   @param[in]     Pages - The number of pages. (It is recommended to use the
                          size returned from LoadLinuxGetKernelSize.)
 
@@ -170,17 +169,18 @@ LoadLinuxAllocateInitrdPages (
 /**
   Sets the kernel command line parameter within the setup image.
 
-  @param[in]     KernelSetup - The kernel setup image
+  @param[in,out] KernelSetup - The kernel setup image
   @param[in]     CommandLine - The kernel command line
 
   @retval    EFI_SUCCESS - The Linux kernel setup is valid and supported
+  @retval    EFI_INVALID_PARAMETER - KernelSetup was NULL
   @retval    EFI_UNSUPPORTED - The Linux kernel is not supported
 
 **/
 EFI_STATUS
 EFIAPI
 LoadLinuxSetCommandLine (
-  IN VOID        *KernelSetup,
+  IN OUT VOID    *KernelSetup,
   IN CHAR8       *CommandLine
   );
 
@@ -188,17 +188,19 @@ LoadLinuxSetCommandLine (
 /**
   Sets the kernel command line parameter within the setup image.
 
-  @param[in]     KernelSetup - The kernel setup image
+  @param[in,out] KernelSetup - The kernel setup image
   @param[in]     Initrd - The initial root disk image
+  @param[in]     InitrdSize - The initial root disk image size
 
   @retval    EFI_SUCCESS - The Linux kernel setup is valid and supported
+  @retval    EFI_INVALID_PARAMETER - KernelSetup was NULL
   @retval    EFI_UNSUPPORTED - The Linux kernel is not supported
 
 **/
 EFI_STATUS
 EFIAPI
 LoadLinuxSetInitrd (
-  IN VOID        *KernelSetup,
+  IN OUT VOID    *KernelSetup,
   IN VOID        *Initrd,
   IN UINTN       InitrdSize
   );
diff --git a/OvmfPkg/Library/LoadLinuxLib/Linux.c 
b/OvmfPkg/Library/LoadLinuxLib/Linux.c
index b9dd5e4..e88b4ca 100644
--- a/OvmfPkg/Library/LoadLinuxLib/Linux.c
+++ b/OvmfPkg/Library/LoadLinuxLib/Linux.c
@@ -15,6 +15,30 @@
 #include "LoadLinuxLib.h"
 
 
+/**
+  A simple check of the kernel setup image
+
+  An assumption is made that the size of the data is at least the
+  size of struct boot_params.
+
+  @param[in]    KernelSetup - The kernel setup image
+
+  @retval    EFI_SUCCESS - The kernel setup looks valid and supported
+  @retval    EFI_INVALID_PARAMETER - KernelSetup was NULL
+  @retval    EFI_UNSUPPORTED - The kernel setup is not valid or supported
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BasicKernelSetupCheck (
+  IN VOID        *KernelSetup
+  )
+{
+  return LoadLinuxCheckKernelSetup(KernelSetup, sizeof (struct boot_params));
+}
+
+
 EFI_STATUS
 EFIAPI
 LoadLinuxCheckKernelSetup (
@@ -34,14 +58,14 @@ LoadLinuxCheckKernelSetup (
 
   Bp = (struct boot_params*) KernelSetup;
 
-  if (Bp->hdr.version < 0x205) {
-    //
-    // We only support relocatable kernels
-    //
+  if ((Bp->hdr.signature != 0xAA55) || // Check boot sector signature
+      (Bp->hdr.header != SETUP_HDR) ||
+      (Bp->hdr.version < 0x205)        // We only support relocatable kernels
+     ) {
     return EFI_UNSUPPORTED;
+  } else {
+    return EFI_SUCCESS;
   }
-
-  return EFI_SUCCESS;
 }
 
 
@@ -54,19 +78,10 @@ LoadLinuxGetKernelSize (
 {
   struct boot_params        *Bp;
 
-  if (KernelSetup == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
+  RETURN_X_ON_ERROR (BasicKernelSetupCheck (KernelSetup), 0);
 
   Bp = (struct boot_params*) KernelSetup;
 
-  if (Bp->hdr.version < 0x205) {
-    //
-    // We only support relocatable kernels
-    //
-    return 0;
-  }
-
   if (Bp->hdr.version > 0x20a) {
     return Bp->hdr.init_size;
   } else {
@@ -114,6 +129,8 @@ LoadLinuxAllocateKernelPages (
   UINT32                    Loop;
   struct boot_params        *Bp;
 
+  RETURN_X_ON_ERROR (BasicKernelSetupCheck (KernelSetup), NULL);
+
   Bp = (struct boot_params*) KernelSetup;
 
   for (Loop = 1; Loop < 512; Loop++) {
@@ -169,7 +186,7 @@ LoadLinuxAllocateInitrdPages (
   EFI_STATUS                Status;
   EFI_PHYSICAL_ADDRESS      Address;
 
-  Address = BASE_4GB;
+  Address = BASE_1GB;
   Status = gBS->AllocatePages (
                   AllocateMaxAddress,
                   EfiLoaderData,
@@ -184,9 +201,10 @@ LoadLinuxAllocateInitrdPages (
 }
 
 
+STATIC
 VOID
 SetupLinuxMemmap (
-  struct boot_params        *Bp
+  IN OUT struct boot_params        *Bp
   )
 {
   EFI_STATUS                           Status;
@@ -199,8 +217,10 @@ SetupLinuxMemmap (
   EFI_MEMORY_DESCRIPTOR                *MemoryMapPtr;
   UINTN                                Index;
   struct efi_info                      *Efi;
-  struct e820_entry                    *E820Map;
+  struct e820_entry                    *LastE820;
+  struct e820_entry                    *E820;
   UINTN                                E820EntryCount;
+  EFI_PHYSICAL_ADDRESS                 LastEndAddr;
 
   //
   // Get System MemoryMapSize
@@ -233,12 +253,18 @@ SetupLinuxMemmap (
                   );
   ASSERT_EFI_ERROR (Status);
 
-  E820Map = &Bp->e820_map[0];
+  LastE820 = &Bp->e820_map[0];
+  E820 = &Bp->e820_map[0];
   E820EntryCount = 0;
+  LastEndAddr = 0;
   MemoryMapPtr = MemoryMap;
   for (Index = 0; Index < (MemoryMapSize / DescriptorSize); Index++) {
     UINTN E820Type = 0;
 
+    if (MemoryMap->NumberOfPages == 0) {
+      continue;
+    }
+
     switch(MemoryMap->Type) {
     case EfiReservedMemoryType:
     case EfiRuntimeServicesCode:
@@ -278,11 +304,22 @@ SetupLinuxMemmap (
       continue;
     }
 
-    E820Map->addr = MemoryMap->PhysicalStart;
-    E820Map->size = MemoryMap->NumberOfPages << EFI_PAGE_SHIFT;
-    E820Map->type = (UINT32) E820Type;
-    E820Map++;
-    E820EntryCount++;
+    if ((LastE820 != NULL) &&
+        (LastE820->type == (UINT32) E820Type) &&
+        (MemoryMap->PhysicalStart == LastEndAddr)) {
+      LastE820->size += EFI_PAGES_TO_SIZE (MemoryMap->NumberOfPages);
+    } else {
+      if (E820EntryCount >= (sizeof (Bp->e820_map) / sizeof 
(Bp->e820_map[0]))) {
+        break;
+      }
+      E820->type = (UINT32) E820Type;
+      E820->addr = MemoryMap->PhysicalStart;
+      E820->size = EFI_PAGES_TO_SIZE (MemoryMap->NumberOfPages);
+      LastE820 = E820;
+      LastEndAddr = E820->addr + E820->size;
+      E820++;
+      E820EntryCount++;
+    }
 
     //
     // Get next item
@@ -297,15 +334,14 @@ SetupLinuxMemmap (
   Efi->efi_memdesc_version = DescriptorVersion;
   Efi->efi_memmap = (UINT32)(UINTN) MemoryMapPtr;
   Efi->efi_memmap_size = (UINT32) MemoryMapSize;
-  Efi->efi_systab_hi = ((UINT64)(UINTN) gST) >> 32;
-  Efi->efi_memmap_hi = ((UINT64)(UINTN) MemoryMapPtr) >> 32;
 #ifdef MDE_CPU_IA32
   Efi->efi_loader_signature = SIGNATURE_32 ('E', 'L', '3', '2');
 #else
+  Efi->efi_systab_hi = ((UINT64)(UINTN) gST) >> 32;
+  Efi->efi_memmap_hi = ((UINT64)(UINTN) MemoryMapPtr) >> 32;
   Efi->efi_loader_signature = SIGNATURE_32 ('E', 'L', '6', '4');
 #endif
 
-  //gBS->RaiseTPL (TPL_HIGH_LEVEL);
   gBS->ExitBootServices (gImageHandle, MapKey);
 }
 
@@ -313,12 +349,14 @@ SetupLinuxMemmap (
 EFI_STATUS
 EFIAPI
 LoadLinuxSetCommandLine (
-  IN VOID        *KernelSetup,
+  IN OUT VOID    *KernelSetup,
   IN CHAR8       *CommandLine
   )
 {
   struct boot_params     *Bp;
 
+  RETURN_STATUS_ON_ERROR (BasicKernelSetupCheck (KernelSetup));
+
   Bp = (struct boot_params*) KernelSetup;
 
   Bp->hdr.cmd_line_ptr = (UINT32)(UINTN) CommandLine;
@@ -330,13 +368,15 @@ LoadLinuxSetCommandLine (
 EFI_STATUS
 EFIAPI
 LoadLinuxSetInitrd (
-  IN VOID        *KernelSetup,
+  IN OUT VOID    *KernelSetup,
   IN VOID        *Initrd,
   IN UINTN       InitrdSize
   )
 {
   struct boot_params     *Bp;
 
+  RETURN_STATUS_ON_ERROR (BasicKernelSetupCheck (KernelSetup));
+
   Bp = (struct boot_params*) KernelSetup;
 
   Bp->hdr.ramdisk_start = (UINT32)(UINTN) Initrd;
@@ -351,7 +391,7 @@ STATIC
 EFI_STATUS
 SetupLinuxBootParams (
   IN VOID                   *Kernel,
-  IN struct boot_params     *Bp
+  IN OUT struct boot_params *Bp
   )
 {
   Bp->alt_mem_k = SIZE_32KB;
@@ -366,22 +406,10 @@ SetupLinuxBootParams (
 }
 
 
-/**
-  Loads and boots UEFI Linux.
-
-  @param[in] BzImage - The main kernel image
-  @param[in] BzImageSize - The main kernel image size
-  @param[in] Initrd - The initial root disk image
-  @param[in] InitrdSize - The initial root disk image size
-  @param[in] CommandLine - The kernel command line
-
-  @retval    EFI_NOT_FOUND - The Linux kernel was not found
-
-**/
 EFI_STATUS
 EFIAPI
 LoadLinuxBzImage (
-  IN VOID      *BzImage,
+  IN OUT VOID  *BzImage,
   IN UINTN     BzImageSize
   )
 {
@@ -393,6 +421,8 @@ LoadLinuxBzImage (
 
   Bp = (struct boot_params *) BzImage;
 
+  RETURN_STATUS_ON_ERROR (LoadLinuxCheckKernelSetup (BzImage, BzImageSize));
+
   SetupSize = (Bp->hdr.setup_secs + 1) * 512;
 
   if (SetupSize > BzImageSize) {
@@ -412,7 +442,7 @@ LoadLinuxBzImage (
 
   Bp = (struct boot_params *) KernelSetup;
 
-  Kernel = LoadLinuxAllocateKernelPages (Bp, EFI_SIZE_TO_PAGES (SIZE_8MB));
+  Kernel = LoadLinuxAllocateKernelPages (Bp, EFI_SIZE_TO_PAGES (BzImageSize));
   if (Kernel == NULL) {
     FreePages (KernelSetup, EFI_SIZE_TO_PAGES (SetupSize));
     return EFI_OUT_OF_RESOURCES;
@@ -423,25 +453,17 @@ LoadLinuxBzImage (
 }
 
 
-/**
-  Loads and boots UEFI Linux.
-
-  @param[in] Kernel - The main kernel image
-  @param[in] KernelSetup - The kernel setup image
-  @param[in] CommandLine - The kernel command line
-
-  @retval    EFI_NOT_FOUND - The Linux kernel was not found
-
-**/
 EFI_STATUS
 EFIAPI
 LoadLinux (
   IN VOID      *Kernel,
-  IN VOID      *KernelSetup
+  IN OUT VOID  *KernelSetup
   )
 {
   struct boot_params  *Bp;
 
+  RETURN_STATUS_ON_ERROR (BasicKernelSetupCheck (KernelSetup));
+
   Bp = (struct boot_params *) KernelSetup;
 
   if (Bp->hdr.version < 0x205) {
diff --git a/OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.h 
b/OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.h
index 49abb8c..0c5f8e6 100644
--- a/OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.h
+++ b/OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.h
@@ -27,6 +27,14 @@
 
 #include <IndustryStandard/LinuxBzimage.h>
 
+#define RETURN_X_ON_ERROR(Status, X) \
+  do { if (RETURN_ERROR (Status)) { return (X); } } while(0)
+
+#define RETURN_STATUS_ON_ERROR(Status) \
+  do { RETURN_STATUS __MacroStatus = (Status); \
+       if (RETURN_ERROR (__MacroStatus)) { return __MacroStatus; } \
+  } while(0)
+
 VOID
 EFIAPI
 JumpToKernel (
diff --git a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c 
b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
index 64dcb75..ae96010 100644
--- a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
+++ b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
@@ -118,25 +118,35 @@ TryRunningQemuKernel (
   //
   // Check if we have on flash shell
   //
-  gBS->LocateHandleBuffer (
-        ByProtocol,
-        &gEfiFirmwareVolume2ProtocolGuid,
-        NULL,
-        &FvHandleCount,
-        &FvHandleBuffer
-        );
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiFirmwareVolume2ProtocolGuid,
+                  NULL,
+                  &FvHandleCount,
+                  &FvHandleBuffer
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
   for (Index = 0; Index < FvHandleCount; Index++) {
-    gBS->HandleProtocol (
-          FvHandleBuffer[Index],
-          &gEfiDevicePathProtocolGuid,
-          (VOID **) &DevicePath
-          );
+    Status = gBS->HandleProtocol (
+                    FvHandleBuffer[Index],
+                    &gEfiDevicePathProtocolGuid,
+                    (VOID **) &DevicePath
+                    );
+    if (EFI_ERROR (Status)) {
+      continue;
+    }
 
     //
     // Build device path for QEMU Kernel executable
     //
     EfiInitializeFwVolDevicepathNode (&ShellNode, &gOvmfQemuKernelFile);
     DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL 
*) &ShellNode);
+    if (DevicePath == NULL) {
+      continue;
+    }
     Status = gBS->LoadImage (
                     TRUE,
                     gImageHandle,
@@ -145,13 +155,15 @@ TryRunningQemuKernel (
                     0,
                     &ImageHandle
                     );
+    FreePool (DevicePath);
     if (!EFI_ERROR (Status)) {
       Status = gBS->StartImage (ImageHandle, NULL, NULL);
       break;
     }
   }
 
-  return EFI_SUCCESS;
+  FreePool (FvHandleBuffer);
+  return Status;
 }
 
 

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_sfd2d_oct
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to