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