|
|
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 */
|