nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

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

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