nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

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

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