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