nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

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

23a3f0
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
23a3f0
From: Peter Jones <pjones@redhat.com>
23a3f0
Date: Thu, 11 Jul 2019 17:17:02 +0200
23a3f0
Subject: [PATCH] Try to pick better locations for kernel and initrd
23a3f0
23a3f0
- Don't limit allocations on 64-bit platforms to < 0x[37f]fffffff if
23a3f0
  we're using the "large" code model ; use __UINTPTR_MAX__.
23a3f0
- Get the comparison right to check the address we've allocated.
23a3f0
- Fix the allocation for the command line as well.
23a3f0
23a3f0
*But*, when we did this some systems started failing badly; coudln't
23a3f0
parse partition tables, etc.  What's going on here is the disk controller
23a3f0
is silently failing DMAs to addresses above 4GB, so we're trying to parse
23a3f0
uninitialized (or HW zeroed) ram when looking for the partition table,
23a3f0
etc.
23a3f0
23a3f0
So to limit this, we make grub_malloc() pick addresses below 4GB on
23a3f0
x86_64, but the direct EFI page allocation functions can get addresses
23a3f0
above that.
23a3f0
23a3f0
Additionally, we now try to locate kernel+initrd+cmdline+etc below
23a3f0
0x7fffffff, and if they're too big to fit any memory window there, then
23a3f0
we try a higher address.
23a3f0
23a3f0
Signed-off-by: Peter Jones <pjones@redhat.com>
23a3f0
(cherry picked from commit 9035d4f9ea2f26a9d4412a0918d597ceb5365442)
23a3f0
23a3f0
Conflicts:
23a3f0
	grub-core/loader/i386/efi/linux.c
23a3f0
        Context diffs in includes.
23a3f0
23a3f0
Signed-off-by: Lenny Szubowicz <lszubowi@redhat.com>
23a3f0
---
23a3f0
 grub-core/kern/efi/mm.c           |  8 ++++----
23a3f0
 grub-core/loader/i386/efi/linux.c | 24 +++++++++++++++++-------
23a3f0
 include/grub/arm/efi/memory.h     |  1 +
23a3f0
 include/grub/arm64/efi/memory.h   |  1 +
23a3f0
 include/grub/i386/efi/memory.h    |  1 +
23a3f0
 include/grub/ia64/efi/memory.h    |  1 +
23a3f0
 include/grub/x86_64/efi/memory.h  |  4 +++-
23a3f0
 7 files changed, 28 insertions(+), 12 deletions(-)
23a3f0
23a3f0
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
23a3f0
index 2d9c9032b..9e76f23e5 100644
23a3f0
--- a/grub-core/kern/efi/mm.c
23a3f0
+++ b/grub-core/kern/efi/mm.c
23a3f0
@@ -122,7 +122,7 @@ grub_efi_allocate_pages_max (grub_efi_physical_address_t max,
23a3f0
   grub_efi_boot_services_t *b;
23a3f0
   grub_efi_physical_address_t address = max;
23a3f0
 
23a3f0
-  if (max > 0xffffffff)
23a3f0
+  if (max > GRUB_EFI_MAX_USABLE_ADDRESS)
23a3f0
     return 0;
23a3f0
 
23a3f0
   b = grub_efi_system_table->boot_services;
23a3f0
@@ -472,7 +472,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
23a3f0
     {
23a3f0
       if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
23a3f0
 #if 1
23a3f0
-	  && desc->physical_start <= GRUB_EFI_MAX_USABLE_ADDRESS
23a3f0
+	  && desc->physical_start <= GRUB_EFI_MAX_ALLOCATION_ADDRESS
23a3f0
 #endif
23a3f0
 	  && desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000
23a3f0
 	  && desc->num_pages != 0)
23a3f0
@@ -490,9 +490,9 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
23a3f0
 #if 1
23a3f0
 	  if (BYTES_TO_PAGES (filtered_desc->physical_start)
23a3f0
 	      + filtered_desc->num_pages
23a3f0
-	      > BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS))
23a3f0
+	      > BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_ALLOCATION_ADDRESS))
23a3f0
 	    filtered_desc->num_pages
23a3f0
-	      = (BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS)
23a3f0
+	      = (BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_ALLOCATION_ADDRESS)
23a3f0
 		 - BYTES_TO_PAGES (filtered_desc->physical_start));
23a3f0
 #endif
23a3f0
 
23a3f0
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
23a3f0
index 576f8c07e..c5fdf522b 100644
23a3f0
--- a/grub-core/loader/i386/efi/linux.c
23a3f0
+++ b/grub-core/loader/i386/efi/linux.c
23a3f0
@@ -27,6 +27,7 @@
23a3f0
 #include <grub/lib/cmdline.h>
23a3f0
 #include <grub/efi/efi.h>
23a3f0
 #include <grub/efi/linux.h>
23a3f0
+#include <grub/cpu/efi/memory.h>
23a3f0
 #include <grub/tpm.h>
23a3f0
 #include <grub/safemath.h>
23a3f0
 
23a3f0
@@ -113,7 +114,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
23a3f0
 	}
23a3f0
     }
23a3f0
 
23a3f0
-  initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size));
23a3f0
+  initrd_mem = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS, BYTES_TO_PAGES(size));
23a3f0
+  if (!initrd_mem)
23a3f0
+    initrd_mem = grub_efi_allocate_pages_max (GRUB_EFI_MAX_USABLE_ADDRESS, BYTES_TO_PAGES(size));
23a3f0
   if (!initrd_mem)
23a3f0
     {
23a3f0
       grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd"));
23a3f0
@@ -217,8 +220,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
23a3f0
 	}
23a3f0
     }
23a3f0
 
23a3f0
-  params = grub_efi_allocate_pages_max (0x3fffffff,
23a3f0
+  params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS,
23a3f0
 					BYTES_TO_PAGES(sizeof(*params)));
23a3f0
+  if (!params)
23a3f0
+    params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_USABLE_ADDRESS,
23a3f0
+					  BYTES_TO_PAGES(sizeof(*params)));
23a3f0
   if (! params)
23a3f0
     {
23a3f0
       grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters");
23a3f0
@@ -288,8 +294,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
23a3f0
 #endif
23a3f0
 
23a3f0
   grub_dprintf ("linux", "setting up cmdline\n");
23a3f0
-  linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff,
23a3f0
-					 BYTES_TO_PAGES(lh->cmdline_size + 1));
23a3f0
+  linux_cmdline = grub_efi_allocate_pages_max(GRUB_EFI_MAX_ALLOCATION_ADDRESS,
23a3f0
+					      BYTES_TO_PAGES(lh->cmdline_size + 1));
23a3f0
+  if (!linux_cmdline)
23a3f0
+    linux_cmdline = grub_efi_allocate_pages_max(GRUB_EFI_MAX_USABLE_ADDRESS,
23a3f0
+						BYTES_TO_PAGES(lh->cmdline_size + 1));
23a3f0
   if (!linux_cmdline)
23a3f0
     {
23a3f0
       grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline"));
23a3f0
@@ -316,11 +325,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
23a3f0
 
23a3f0
   kernel_mem = grub_efi_allocate_pages_max(lh->pref_address,
23a3f0
 					   BYTES_TO_PAGES(lh->init_size));
23a3f0
-
23a3f0
   if (!kernel_mem)
23a3f0
-    kernel_mem = grub_efi_allocate_pages_max(0x3fffffff,
23a3f0
+    kernel_mem = grub_efi_allocate_pages_max(GRUB_EFI_MAX_ALLOCATION_ADDRESS,
23a3f0
+					     BYTES_TO_PAGES(lh->init_size));
23a3f0
+  if (!kernel_mem)
23a3f0
+    kernel_mem = grub_efi_allocate_pages_max(GRUB_EFI_MAX_USABLE_ADDRESS,
23a3f0
 					     BYTES_TO_PAGES(lh->init_size));
23a3f0
-
23a3f0
   if (!kernel_mem)
23a3f0
     {
23a3f0
       grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel"));
23a3f0
diff --git a/include/grub/arm/efi/memory.h b/include/grub/arm/efi/memory.h
23a3f0
index 2c64918e3..a4c2ec835 100644
23a3f0
--- a/include/grub/arm/efi/memory.h
23a3f0
+++ b/include/grub/arm/efi/memory.h
23a3f0
@@ -2,5 +2,6 @@
23a3f0
 #include <grub/efi/memory.h>
23a3f0
 
23a3f0
 #define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff
23a3f0
+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS
23a3f0
 
23a3f0
 #endif /* ! GRUB_MEMORY_CPU_HEADER */
23a3f0
diff --git a/include/grub/arm64/efi/memory.h b/include/grub/arm64/efi/memory.h
23a3f0
index c6cb32417..acb61dca4 100644
23a3f0
--- a/include/grub/arm64/efi/memory.h
23a3f0
+++ b/include/grub/arm64/efi/memory.h
23a3f0
@@ -2,5 +2,6 @@
23a3f0
 #include <grub/efi/memory.h>
23a3f0
 
23a3f0
 #define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffffffULL
23a3f0
+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS
23a3f0
 
23a3f0
 #endif /* ! GRUB_MEMORY_CPU_HEADER */
23a3f0
diff --git a/include/grub/i386/efi/memory.h b/include/grub/i386/efi/memory.h
23a3f0
index 2c64918e3..a4c2ec835 100644
23a3f0
--- a/include/grub/i386/efi/memory.h
23a3f0
+++ b/include/grub/i386/efi/memory.h
23a3f0
@@ -2,5 +2,6 @@
23a3f0
 #include <grub/efi/memory.h>
23a3f0
 
23a3f0
 #define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff
23a3f0
+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS
23a3f0
 
23a3f0
 #endif /* ! GRUB_MEMORY_CPU_HEADER */
23a3f0
diff --git a/include/grub/ia64/efi/memory.h b/include/grub/ia64/efi/memory.h
23a3f0
index 2c64918e3..a4c2ec835 100644
23a3f0
--- a/include/grub/ia64/efi/memory.h
23a3f0
+++ b/include/grub/ia64/efi/memory.h
23a3f0
@@ -2,5 +2,6 @@
23a3f0
 #include <grub/efi/memory.h>
23a3f0
 
23a3f0
 #define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff
23a3f0
+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS
23a3f0
 
23a3f0
 #endif /* ! GRUB_MEMORY_CPU_HEADER */
23a3f0
diff --git a/include/grub/x86_64/efi/memory.h b/include/grub/x86_64/efi/memory.h
23a3f0
index 46e9145a3..e81cfb322 100644
23a3f0
--- a/include/grub/x86_64/efi/memory.h
23a3f0
+++ b/include/grub/x86_64/efi/memory.h
23a3f0
@@ -2,9 +2,11 @@
23a3f0
 #include <grub/efi/memory.h>
23a3f0
 
23a3f0
 #if defined (__code_model_large__)
23a3f0
-#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff
23a3f0
+#define GRUB_EFI_MAX_USABLE_ADDRESS __UINTPTR_MAX__
23a3f0
+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS 0x7fffffff
23a3f0
 #else
23a3f0
 #define GRUB_EFI_MAX_USABLE_ADDRESS 0x7fffffff
23a3f0
+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS
23a3f0
 #endif
23a3f0
 
23a3f0
 #endif /* ! GRUB_MEMORY_CPU_HEADER */