nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

Blame SOURCES/0115-Try-to-pick-better-locations-for-kernel-and-initrd.patch

5593c8
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
5593c8
From: Peter Jones <pjones@redhat.com>
5593c8
Date: Thu, 11 Jul 2019 17:17:02 +0200
5593c8
Subject: [PATCH] Try to pick better locations for kernel and initrd
5593c8
5593c8
- Don't limit allocations on 64-bit platforms to < 0x[37f]fffffff if
5593c8
  we're using the "large" code model ; use __UINTPTR_MAX__.
5593c8
- Get the comparison right to check the address we've allocated.
5593c8
- Fix the allocation for the command line as well.
5593c8
5593c8
*But*, when we did this some systems started failing badly; coudln't
5593c8
parse partition tables, etc.  What's going on here is the disk controller
5593c8
is silently failing DMAs to addresses above 4GB, so we're trying to parse
5593c8
uninitialized (or HW zeroed) ram when looking for the partition table,
5593c8
etc.
5593c8
5593c8
So to limit this, we make grub_malloc() pick addresses below 4GB on
5593c8
x86_64, but the direct EFI page allocation functions can get addresses
5593c8
above that.
5593c8
5593c8
Additionally, we now try to locate kernel+initrd+cmdline+etc below
5593c8
0x7fffffff, and if they're too big to fit any memory window there, then
5593c8
we try a higher address.
5593c8
5593c8
Signed-off-by: Peter Jones <pjones@redhat.com>
5593c8
---
5593c8
 grub-core/kern/efi/mm.c           |  8 ++++----
5593c8
 grub-core/loader/i386/efi/linux.c | 24 +++++++++++++++++-------
5593c8
 include/grub/arm/efi/memory.h     |  1 +
5593c8
 include/grub/arm64/efi/memory.h   |  1 +
5593c8
 include/grub/i386/efi/memory.h    |  1 +
5593c8
 include/grub/ia64/efi/memory.h    |  1 +
5593c8
 include/grub/x86_64/efi/memory.h  |  4 +++-
5593c8
 7 files changed, 28 insertions(+), 12 deletions(-)
5593c8
5593c8
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
1c6ba0
index 85ad4b4494..e84961d078 100644
5593c8
--- a/grub-core/kern/efi/mm.c
5593c8
+++ b/grub-core/kern/efi/mm.c
5593c8
@@ -122,7 +122,7 @@ grub_efi_allocate_pages_max (grub_efi_physical_address_t max,
5593c8
   grub_efi_boot_services_t *b;
5593c8
   grub_efi_physical_address_t address = max;
5593c8
 
5593c8
-  if (max > 0xffffffff)
5593c8
+  if (max > GRUB_EFI_MAX_USABLE_ADDRESS)
5593c8
     return 0;
5593c8
 
5593c8
   b = grub_efi_system_table->boot_services;
5593c8
@@ -480,7 +480,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
5593c8
     {
5593c8
       if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
5593c8
 #if 1
5593c8
-	  && desc->physical_start <= GRUB_EFI_MAX_USABLE_ADDRESS
5593c8
+	  && desc->physical_start <= GRUB_EFI_MAX_ALLOCATION_ADDRESS
5593c8
 #endif
5593c8
 	  && desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000
5593c8
 	  && desc->num_pages != 0)
5593c8
@@ -498,9 +498,9 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
5593c8
 #if 1
5593c8
 	  if (BYTES_TO_PAGES (filtered_desc->physical_start)
5593c8
 	      + filtered_desc->num_pages
5593c8
-	      > BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS))
5593c8
+	      > BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_ALLOCATION_ADDRESS))
5593c8
 	    filtered_desc->num_pages
5593c8
-	      = (BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS)
5593c8
+	      = (BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_ALLOCATION_ADDRESS)
5593c8
 		 - BYTES_TO_PAGES (filtered_desc->physical_start));
5593c8
 #endif
5593c8
 
5593c8
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
1c6ba0
index 3017d0f3e5..33e981e76e 100644
5593c8
--- a/grub-core/loader/i386/efi/linux.c
5593c8
+++ b/grub-core/loader/i386/efi/linux.c
5593c8
@@ -27,6 +27,7 @@
5593c8
 #include <grub/lib/cmdline.h>
5593c8
 #include <grub/efi/efi.h>
5593c8
 #include <grub/efi/linux.h>
5593c8
+#include <grub/cpu/efi/memory.h>
5593c8
 
5593c8
 GRUB_MOD_LICENSE ("GPLv3+");
5593c8
 
5593c8
@@ -106,7 +107,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
5593c8
       size += ALIGN_UP (grub_file_size (files[i]), 4);
5593c8
     }
5593c8
 
5593c8
-  initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size));
5593c8
+  initrd_mem = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS, BYTES_TO_PAGES(size));
5593c8
+  if (!initrd_mem)
5593c8
+    initrd_mem = grub_efi_allocate_pages_max (GRUB_EFI_MAX_USABLE_ADDRESS, BYTES_TO_PAGES(size));
5593c8
   if (!initrd_mem)
5593c8
     {
5593c8
       grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd"));
5593c8
@@ -202,8 +205,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
5593c8
       goto fail;
5593c8
     }
5593c8
 
5593c8
-  params = grub_efi_allocate_pages_max (0x3fffffff,
5593c8
+  params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS,
5593c8
 					BYTES_TO_PAGES(sizeof(*params)));
5593c8
+  if (!params)
5593c8
+    params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_USABLE_ADDRESS,
5593c8
+					  BYTES_TO_PAGES(sizeof(*params)));
5593c8
   if (! params)
5593c8
     {
5593c8
       grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters");
5593c8
@@ -273,8 +279,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
5593c8
 #endif
5593c8
 
5593c8
   grub_dprintf ("linux", "setting up cmdline\n");
5593c8
-  linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff,
5593c8
-					 BYTES_TO_PAGES(lh->cmdline_size + 1));
5593c8
+  linux_cmdline = grub_efi_allocate_pages_max(GRUB_EFI_MAX_ALLOCATION_ADDRESS,
5593c8
+					      BYTES_TO_PAGES(lh->cmdline_size + 1));
5593c8
+  if (!linux_cmdline)
5593c8
+    linux_cmdline = grub_efi_allocate_pages_max(GRUB_EFI_MAX_USABLE_ADDRESS,
5593c8
+						BYTES_TO_PAGES(lh->cmdline_size + 1));
5593c8
   if (!linux_cmdline)
5593c8
     {
5593c8
       grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline"));
5593c8
@@ -301,11 +310,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
5593c8
 
5593c8
   kernel_mem = grub_efi_allocate_pages_max(lh->pref_address,
5593c8
 					   BYTES_TO_PAGES(lh->init_size));
5593c8
-
5593c8
   if (!kernel_mem)
5593c8
-    kernel_mem = grub_efi_allocate_pages_max(0x3fffffff,
5593c8
+    kernel_mem = grub_efi_allocate_pages_max(GRUB_EFI_MAX_ALLOCATION_ADDRESS,
5593c8
+					     BYTES_TO_PAGES(lh->init_size));
5593c8
+  if (!kernel_mem)
5593c8
+    kernel_mem = grub_efi_allocate_pages_max(GRUB_EFI_MAX_USABLE_ADDRESS,
5593c8
 					     BYTES_TO_PAGES(lh->init_size));
5593c8
-
5593c8
   if (!kernel_mem)
5593c8
     {
5593c8
       grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel"));
5593c8
diff --git a/include/grub/arm/efi/memory.h b/include/grub/arm/efi/memory.h
1c6ba0
index 2c64918e3f..a4c2ec8350 100644
5593c8
--- a/include/grub/arm/efi/memory.h
5593c8
+++ b/include/grub/arm/efi/memory.h
5593c8
@@ -2,5 +2,6 @@
5593c8
 #include <grub/efi/memory.h>
5593c8
 
5593c8
 #define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff
5593c8
+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS
5593c8
 
5593c8
 #endif /* ! GRUB_MEMORY_CPU_HEADER */
5593c8
diff --git a/include/grub/arm64/efi/memory.h b/include/grub/arm64/efi/memory.h
1c6ba0
index c6cb324171..acb61dca44 100644
5593c8
--- a/include/grub/arm64/efi/memory.h
5593c8
+++ b/include/grub/arm64/efi/memory.h
5593c8
@@ -2,5 +2,6 @@
5593c8
 #include <grub/efi/memory.h>
5593c8
 
5593c8
 #define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffffffULL
5593c8
+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS
5593c8
 
5593c8
 #endif /* ! GRUB_MEMORY_CPU_HEADER */
5593c8
diff --git a/include/grub/i386/efi/memory.h b/include/grub/i386/efi/memory.h
1c6ba0
index 2c64918e3f..a4c2ec8350 100644
5593c8
--- a/include/grub/i386/efi/memory.h
5593c8
+++ b/include/grub/i386/efi/memory.h
5593c8
@@ -2,5 +2,6 @@
5593c8
 #include <grub/efi/memory.h>
5593c8
 
5593c8
 #define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff
5593c8
+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS
5593c8
 
5593c8
 #endif /* ! GRUB_MEMORY_CPU_HEADER */
5593c8
diff --git a/include/grub/ia64/efi/memory.h b/include/grub/ia64/efi/memory.h
1c6ba0
index 2c64918e3f..a4c2ec8350 100644
5593c8
--- a/include/grub/ia64/efi/memory.h
5593c8
+++ b/include/grub/ia64/efi/memory.h
5593c8
@@ -2,5 +2,6 @@
5593c8
 #include <grub/efi/memory.h>
5593c8
 
5593c8
 #define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff
5593c8
+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS
5593c8
 
5593c8
 #endif /* ! GRUB_MEMORY_CPU_HEADER */
5593c8
diff --git a/include/grub/x86_64/efi/memory.h b/include/grub/x86_64/efi/memory.h
1c6ba0
index 46e9145a30..e81cfb3221 100644
5593c8
--- a/include/grub/x86_64/efi/memory.h
5593c8
+++ b/include/grub/x86_64/efi/memory.h
5593c8
@@ -2,9 +2,11 @@
5593c8
 #include <grub/efi/memory.h>
5593c8
 
5593c8
 #if defined (__code_model_large__)
5593c8
-#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff
5593c8
+#define GRUB_EFI_MAX_USABLE_ADDRESS __UINTPTR_MAX__
5593c8
+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS 0x7fffffff
5593c8
 #else
5593c8
 #define GRUB_EFI_MAX_USABLE_ADDRESS 0x7fffffff
5593c8
+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS
5593c8
 #endif
5593c8
 
5593c8
 #endif /* ! GRUB_MEMORY_CPU_HEADER */