nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

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

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