Update some more stuff again and whatnot.

Fix AArch64 machines with no RAM latched lower than 1GB
  Resolves: rhbz#1615969
Set http_path and http_url when HTTP booting
Hopefully slightly better error reporting in some cases
Better allocation of kernel+initramfs on x86_64 and aarch64
  Resolves: rhbz#1572126

Signed-off-by: Peter Jones <pjones@redhat.com>
This commit is contained in:
Peter Jones 2018-08-30 11:15:43 -04:00
parent c87b938e5d
commit c2f7a5e9af
10 changed files with 715 additions and 137 deletions

View File

@ -0,0 +1,138 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Stephen Benjamin <stephen@redhat.com>
Date: Thu, 16 Aug 2018 16:58:51 -0400
Subject: [PATCH] Prepend prefix when HTTP path is relative
This sets a couple of variables. With the url http://www.example.com/foo/bar :
http_path: /foo/bar
http_url: http://www.example.com/foo/bar
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/kern/main.c | 2 +-
grub-core/net/efi/http.c | 82 ++++++++++++++++++++++++++++++++++++------------
2 files changed, 63 insertions(+), 21 deletions(-)
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
index da47b18b50e..fc8d8c6c9d4 100644
--- a/grub-core/kern/main.c
+++ b/grub-core/kern/main.c
@@ -131,7 +131,7 @@ grub_set_prefix_and_root (void)
{
char *fw_path;
- fw_path = grub_xasprintf ("(%s)/%s", fwdevice, fwpath);
+ fw_path = grub_xasprintf ("(%s)%s%s", fwdevice, fwpath[0] == '/' ? "" : "/", fwpath);
if (fw_path)
{
grub_env_set ("fw_path", fw_path);
diff --git a/grub-core/net/efi/http.c b/grub-core/net/efi/http.c
index 243acbaa35b..2a9624dacc4 100644
--- a/grub-core/net/efi/http.c
+++ b/grub-core/net/efi/http.c
@@ -9,10 +9,52 @@
static void
http_configure (struct grub_efi_net_device *dev, int prefer_ip6)
{
+ grub_efi_ipv6_address_t address;
grub_efi_http_config_data_t http_config;
grub_efi_httpv4_access_point_t httpv4_node;
grub_efi_httpv6_access_point_t httpv6_node;
grub_efi_status_t status;
+ int https;
+ char *http_url;
+ const char *rest, *http_server, *http_path = NULL;
+
+ http_server = grub_env_get ("root");
+ https = grub_strncmp (http_server, "https", 5) ? 1 : 0;
+
+ /* extract http server + port */
+ if (http_server)
+ {
+ http_server = grub_strchr (http_server, ',');
+ if (http_server)
+ http_server++;
+ }
+
+ /* fw_path is like (http,192.168.1.1:8000)/httpboot, extract path part */
+ http_path = grub_env_get ("fw_path");
+ if (http_path)
+ {
+ http_path = grub_strchr (http_path, ')');
+ if (http_path)
+ {
+ http_path++;
+ grub_env_unset ("http_path");
+ grub_env_set ("http_path", http_path);
+ }
+ }
+
+ if (http_server && http_path)
+ {
+ if (grub_efi_string_to_ip6_address (http_server, &address, &rest) && *rest == 0)
+ http_url = grub_xasprintf ("%s://[%s]%s", https ? "https" : "http", http_server, http_path);
+ else
+ http_url = grub_xasprintf ("%s://%s%s", https ? "https" : "http", http_server, http_path);
+ if (http_url)
+ {
+ grub_env_unset ("http_url");
+ grub_env_set ("http_url", http_url);
+ grub_free (http_url);
+ }
+ }
grub_efi_http_t *http = dev->http;
@@ -352,32 +394,32 @@ grub_efihttp_open (struct grub_efi_net_device *dev,
grub_err_t err;
grub_off_t size;
char *buf;
- char *root_url;
- grub_efi_ipv6_address_t address;
- const char *rest;
+ char *file_name;
+ const char *http_path;
- if (grub_efi_string_to_ip6_address (file->device->net->server, &address, &rest) && *rest == 0)
- root_url = grub_xasprintf ("%s://[%s]", type ? "https" : "http", file->device->net->server);
+ /* If path is relative, prepend http_path */
+ http_path = grub_env_get ("http_path");
+ if (http_path && file->device->net->name[0] != '/')
+ file_name = grub_xasprintf ("%s/%s", http_path, file->device->net->name);
else
- root_url = grub_xasprintf ("%s://%s", type ? "https" : "http", file->device->net->server);
- if (root_url)
- {
- grub_env_unset ("root_url");
- grub_env_set ("root_url", root_url);
- grub_free (root_url);
- }
- else
- {
- return grub_errno;
- }
+ file_name = grub_strdup (file->device->net->name);
- err = efihttp_request (dev->http, file->device->net->server, file->device->net->name, type, 1, 0);
+ if (!file_name)
+ return grub_errno;
+
+ err = efihttp_request (dev->http, file->device->net->server, file_name, type, 1, 0);
if (err != GRUB_ERR_NONE)
- return err;
+ {
+ grub_free (file_name);
+ return err;
+ }
- err = efihttp_request (dev->http, file->device->net->server, file->device->net->name, type, 0, &size);
+ err = efihttp_request (dev->http, file->device->net->server, file_name, type, 0, &size);
+ grub_free (file_name);
if (err != GRUB_ERR_NONE)
- return err;
+ {
+ return err;
+ }
buf = grub_malloc (size);
efihttp_read (dev, buf, size);

View File

@ -1,129 +0,0 @@
From 8dd7777e4d49ab02a57f4d029afda4944b4773e0 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Tue, 14 Aug 2018 14:07:44 -0400
Subject: [PATCH] arm/arm64 loader: better error messages.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/loader/arm64/linux.c | 54 ++++++++++++++++++++++++++--------
1 file changed, 41 insertions(+), 13 deletions(-)
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
index 93b5cd306eb..3d73861421d 100644
--- a/grub-core/loader/arm64/linux.c
+++ b/grub-core/loader/arm64/linux.c
@@ -70,13 +70,15 @@ finalize_params_linux (void)
{
grub_efi_loaded_image_t *loaded_image = NULL;
int node, retval, len;
-
+ grub_err_t err = GRUB_ERR_NONE;
void *fdt;
fdt = grub_fdt_load (0x400);
-
if (!fdt)
- goto failure;
+ {
+ err = grub_error(GRUB_ERR_BAD_OS, "failed to load FDT");
+ goto failure;
+ }
node = grub_fdt_find_subnode (fdt, 0, "chosen");
if (node < 0)
@@ -87,17 +89,26 @@ finalize_params_linux (void)
*/
retval = grub_fdt_set_prop32(fdt, 0, "#address-cells", 2);
if (retval)
- goto failure;
+ {
+ err = grub_error(retval, "Could not find #address-cells");
+ goto failure;
+ }
retval = grub_fdt_set_prop32(fdt, 0, "#size-cells", 2);
if (retval)
- goto failure;
+ {
+ err = grub_error(retval, "Could not find #size-cells");
+ goto failure;
+ }
node = grub_fdt_add_subnode (fdt, 0, "chosen");
}
if (node < 1)
- goto failure;
+ {
+ err = grub_error(grub_errno, "failed to load chosen fdt node.");
+ goto failure;
+ }
/* Set initrd info */
if (initrd_start && initrd_end > initrd_start)
@@ -108,15 +119,26 @@ finalize_params_linux (void)
retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start",
initrd_start);
if (retval)
- goto failure;
+ {
+ err = grub_error(retval, "Failed to set linux,initrd-start property");
+ goto failure;
+ }
+
retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end",
initrd_end);
if (retval)
- goto failure;
+ {
+ err = grub_error(retval, "Failed to set linux,initrd-end property");
+ goto failure;
+ }
}
- if (grub_fdt_install() != GRUB_ERR_NONE)
- goto failure;
+ retval = grub_fdt_install();
+ if (retval != GRUB_ERR_NONE)
+ {
+ err = grub_error(retval, "Failed to install fdt");
+ goto failure;
+ }
grub_dprintf ("linux", "Installed/updated FDT configuration table @ %p\n",
fdt);
@@ -124,14 +146,20 @@ finalize_params_linux (void)
/* Convert command line to UCS-2 */
loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
if (!loaded_image)
- goto failure;
+ {
+ err = grub_error(grub_errno, "Failed to install fdt");
+ goto failure;
+ }
loaded_image->load_options_size = len =
(grub_strlen (linux_args) + 1) * sizeof (grub_efi_char16_t);
loaded_image->load_options =
grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
if (!loaded_image->load_options)
- return grub_error(GRUB_ERR_BAD_OS, "failed to create kernel parameters");
+ {
+ err = grub_error(GRUB_ERR_BAD_OS, "failed to create kernel parameters");
+ goto failure;
+ }
loaded_image->load_options_size =
2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
@@ -141,7 +169,7 @@ finalize_params_linux (void)
failure:
grub_fdt_unload();
- return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
+ return err;
}
static void
--
2.17.1

View File

@ -1,4 +1,4 @@
From 2d9fe8142b8d470ffe63a23f7788e1c2530401d2 Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Thu, 16 Aug 2018 11:08:11 -0400
Subject: [PATCH] Make linux_arm_kernel_header.hdr_offset be at the right place
@ -37,10 +37,9 @@ can find the PE header correcrtly at 0x40 by reading the value at 0x3c.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/kern/dl.c | 5 +++++
grub-core/loader/efi/linux.c | 3 +++
include/grub/arm/linux.h | 2 +-
3 files changed, 9 insertions(+), 1 deletion(-)
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
index 0622dfa48d4..b56ea0bc041 100644
@ -70,6 +69,3 @@ index 5900fc8a40c..bed308f22cb 100644
grub_uint32_t hdr_offset;
};
--
2.17.1

View File

@ -0,0 +1,32 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 27 Aug 2018 13:10:08 -0400
Subject: [PATCH] Mark some unused stuff unused
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/commands/blscfg.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
index bdb1c5a95aa..abd6f00d0de 100644
--- a/grub-core/commands/blscfg.c
+++ b/grub-core/commands/blscfg.c
@@ -434,7 +434,7 @@ finish:
static grub_envblk_t saved_env = NULL;
-static int
+static int UNUSED
save_var (const char *name, const char *value, void *whitelist UNUSED)
{
const char *val = grub_env_get (name);
@@ -446,7 +446,7 @@ save_var (const char *name, const char *value, void *whitelist UNUSED)
return 0;
}
-static int
+static int UNUSED
unset_var (const char *name, const char *value UNUSED, void *whitelist)
{
grub_dprintf("blscfg", "restoring \"%s\"\n", name);

View File

@ -0,0 +1,98 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 27 Aug 2018 13:14:06 -0400
Subject: [PATCH] Make grub_error() more verbose
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/kern/efi/mm.c | 17 ++++++++++++++---
grub-core/kern/err.c | 13 +++++++++++--
include/grub/err.h | 5 ++++-
3 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
index 5cdf6c943f2..7692e63ba24 100644
--- a/grub-core/kern/efi/mm.c
+++ b/grub-core/kern/efi/mm.c
@@ -157,12 +157,20 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address,
/* Limit the memory access to less than 4GB for 32-bit platforms. */
if (address > GRUB_EFI_MAX_USABLE_ADDRESS)
- return 0;
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("invalid memory address (0x%llx > 0x%llx)"),
+ address, GRUB_EFI_MAX_USABLE_ADDRESS);
+ return NULL;
+ }
b = grub_efi_system_table->boot_services;
status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
if (status != GRUB_EFI_SUCCESS)
- return 0;
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+ return NULL;
+ }
if (address == 0)
{
@@ -172,7 +180,10 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address,
status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
grub_efi_free_pages (0, pages);
if (status != GRUB_EFI_SUCCESS)
- return 0;
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+ return NULL;
+ }
}
grub_efi_store_alloc (address, pages);
diff --git a/grub-core/kern/err.c b/grub-core/kern/err.c
index 53c734de70e..aebfe0cf839 100644
--- a/grub-core/kern/err.c
+++ b/grub-core/kern/err.c
@@ -33,15 +33,24 @@ static struct grub_error_saved grub_error_stack_items[GRUB_ERROR_STACK_SIZE];
static int grub_error_stack_pos;
static int grub_error_stack_assert;
+#ifdef grub_error
+#undef grub_error
+#endif
+
grub_err_t
-grub_error (grub_err_t n, const char *fmt, ...)
+grub_error (grub_err_t n, const char *file, const int line, const char *fmt, ...)
{
va_list ap;
+ int m;
grub_errno = n;
+ m = grub_snprintf (grub_errmsg, sizeof (grub_errmsg), "%s:%d:", file, line);
+ if (m < 0)
+ m = 0;
+
va_start (ap, fmt);
- grub_vsnprintf (grub_errmsg, sizeof (grub_errmsg), _(fmt), ap);
+ grub_vsnprintf (grub_errmsg + m, sizeof (grub_errmsg) - m, _(fmt), ap);
va_end (ap);
return n;
diff --git a/include/grub/err.h b/include/grub/err.h
index 1590c688e1d..9b830757d35 100644
--- a/include/grub/err.h
+++ b/include/grub/err.h
@@ -84,7 +84,10 @@ struct grub_error_saved
extern grub_err_t EXPORT_VAR(grub_errno);
extern char EXPORT_VAR(grub_errmsg)[GRUB_MAX_ERRMSG];
-grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *fmt, ...);
+grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *file, const int line, const char *fmt, ...);
+
+#define grub_error(n, fmt, ...) grub_error (n, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
+
void EXPORT_FUNC(grub_fatal) (const char *fmt, ...) __attribute__ ((noreturn));
void EXPORT_FUNC(grub_error_push) (void);
int EXPORT_FUNC(grub_error_pop) (void);

View File

@ -0,0 +1,307 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Tue, 14 Aug 2018 14:07:44 -0400
Subject: [PATCH] arm/arm64 loader: Better memory allocation and error
messages.
On mustang, our memory map looks like:
Type Physical start - end #Pages Size Attributes
reserved 0000004000000000-00000040001fffff 00000200 2MiB UC WC WT WB
conv-mem 0000004000200000-0000004393ffffff 00393e00 14654MiB UC WC WT WB
ldr-code 0000004394000000-00000043f7ffffff 00064000 1600MiB UC WC WT WB
BS-data 00000043f8000000-00000043f801ffff 00000020 128KiB UC WC WT WB
conv-mem 00000043f8020000-00000043fa15bfff 0000213c 34032KiB UC WC WT WB
ldr-code 00000043fa15c000-00000043fa2a1fff 00000146 1304KiB UC WC WT WB
ldr-data 00000043fa2a2000-00000043fa3e8fff 00000147 1308KiB UC WC WT WB
conv-mem 00000043fa3e9000-00000043fa3e9fff 00000001 4KiB UC WC WT WB
ldr-data 00000043fa3ea000-00000043fa3eafff 00000001 4KiB UC WC WT WB
ldr-code 00000043fa3eb000-00000043fa4affff 000000c5 788KiB UC WC WT WB
BS-code 00000043fa4b0000-00000043fa59ffff 000000f0 960KiB UC WC WT WB
RT-code 00000043fa5a0000-00000043fa5affff 00000010 64KiB RT UC WC WT WB
RT-data 00000043fa5b0000-00000043fa5bffff 00000010 64KiB RT UC WC WT WB
RT-code 00000043fa5c0000-00000043fa5cffff 00000010 64KiB RT UC WC WT WB
ldr-data 00000043fa5d0000-00000043fa5d0fff 00000001 4KiB UC WC WT WB
BS-code 00000043fa5d1000-00000043fa5ddfff 0000000d 52KiB UC WC WT WB
reserved 00000043fa5de000-00000043fa60ffff 00000032 200KiB UC WC WT WB
ACPI-rec 00000043fa610000-00000043fa6affff 000000a0 640KiB UC WC WT WB
ACPI-nvs 00000043fa6b0000-00000043fa6bffff 00000010 64KiB UC WC WT WB
ACPI-rec 00000043fa6c0000-00000043fa70ffff 00000050 320KiB UC WC WT WB
RT-code 00000043fa710000-00000043fa72ffff 00000020 128KiB RT UC WC WT WB
RT-data 00000043fa730000-00000043fa78ffff 00000060 384KiB RT UC WC WT WB
RT-code 00000043fa790000-00000043fa79ffff 00000010 64KiB RT UC WC WT WB
RT-data 00000043fa7a0000-00000043fa99ffff 00000200 2MiB RT UC WC WT WB
RT-code 00000043fa9a0000-00000043fa9affff 00000010 64KiB RT UC WC WT WB
RT-data 00000043fa9b0000-00000043fa9cffff 00000020 128KiB RT UC WC WT WB
BS-code 00000043fa9d0000-00000043fa9d9fff 0000000a 40KiB UC WC WT WB
reserved 00000043fa9da000-00000043fa9dbfff 00000002 8KiB UC WC WT WB
conv-mem 00000043fa9dc000-00000043fc29dfff 000018c2 25352KiB UC WC WT WB
BS-data 00000043fc29e000-00000043fc78afff 000004ed 5044KiB UC WC WT WB
conv-mem 00000043fc78b000-00000043fca01fff 00000277 2524KiB UC WC WT WB
BS-data 00000043fca02000-00000043fcea3fff 000004a2 4744KiB UC WC WT WB
conv-mem 00000043fcea4000-00000043fcea4fff 00000001 4KiB UC WC WT WB
BS-data 00000043fcea5000-00000043fd192fff 000002ee 3000KiB UC WC WT WB
conv-mem 00000043fd193000-00000043fd2b0fff 0000011e 1144KiB UC WC WT WB
BS-data 00000043fd2b1000-00000043ff80ffff 0000255f 38268KiB UC WC WT WB
BS-code 00000043ff810000-00000043ff99ffff 00000190 1600KiB UC WC WT WB
RT-code 00000043ff9a0000-00000043ff9affff 00000010 64KiB RT UC WC WT WB
conv-mem 00000043ff9b0000-00000043ff9bffff 00000010 64KiB UC WC WT WB
RT-data 00000043ff9c0000-00000043ff9effff 00000030 192KiB RT UC WC WT WB
conv-mem 00000043ff9f0000-00000043ffa05fff 00000016 88KiB UC WC WT WB
BS-data 00000043ffa06000-00000043ffffffff 000005fa 6120KiB UC WC WT WB
MMIO 0000000010510000-0000000010510fff 00000001 4KiB RT
MMIO 0000000010548000-0000000010549fff 00000002 8KiB RT
MMIO 0000000017000000-0000000017001fff 00000002 8KiB RT
MMIO 000000001c025000-000000001c025fff 00000001 4KiB RT
When we're trying to find the base of ram, if we start with GRUB_UINT_MAX
(0xffffffff on all platforms) and always use min(), that means we eventually
decide that the base of ram is GRUB_UINT_MAX, which is lower than our first
memory address, and thus our allocation of the initramfs, which specifies this
value as the maximum possible address it can be at, fails.
This patch changes it to start at GRUB_EFI_MAX_USABLE_ADDRESS, which is always
at least 0xffffffff on 32-bit platforms and at least 0x7ffffffffffffff on
64-bit platforms. Additionally, this adds a requirement that the memory we
choose is actually /allocatable/ conventional memory, not merely
write-combining. On this machine that means we wind up with an allocation
around 0x4392XXXXXX, which is a reasonable address.
This also changes grub_efi_allocate_pages_real() so that if 0 is allocated, it
tries to allocate again starting with the same max address it did the first
time, rather than interposing GRUB_EFI_MAX_USABLE_ADDRESS there, so that any
per-platform constraints on its given address are maintained.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/kern/efi/mm.c | 32 ++++++++++++-----
grub-core/loader/arm64/linux.c | 78 ++++++++++++++++++++++++++++++++----------
2 files changed, 82 insertions(+), 28 deletions(-)
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
index 7692e63ba24..306924f73a4 100644
--- a/grub-core/kern/efi/mm.c
+++ b/grub-core/kern/efi/mm.c
@@ -154,6 +154,7 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address,
{
grub_efi_status_t status;
grub_efi_boot_services_t *b;
+ grub_efi_physical_address_t ret = address;
/* Limit the memory access to less than 4GB for 32-bit platforms. */
if (address > GRUB_EFI_MAX_USABLE_ADDRESS)
@@ -165,19 +166,19 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address,
}
b = grub_efi_system_table->boot_services;
- status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
+ status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &ret);
if (status != GRUB_EFI_SUCCESS)
{
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
return NULL;
}
- if (address == 0)
+ if (ret == 0)
{
/* Uggh, the address 0 was allocated... This is too annoying,
so reallocate another one. */
- address = GRUB_EFI_MAX_USABLE_ADDRESS;
- status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
+ ret = address;
+ status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &ret);
grub_efi_free_pages (0, pages);
if (status != GRUB_EFI_SUCCESS)
{
@@ -186,9 +187,9 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address,
}
}
- grub_efi_store_alloc (address, pages);
+ grub_efi_store_alloc (ret, pages);
- return (void *) ((grub_addr_t) address);
+ return (void *) ((grub_addr_t) ret);
}
void *
@@ -696,11 +697,24 @@ grub_efi_get_ram_base(grub_addr_t *base_addr)
if (ret < 1)
return GRUB_ERR_BUG;
- for (desc = memory_map, *base_addr = GRUB_UINT_MAX;
+ for (desc = memory_map, *base_addr = GRUB_EFI_MAX_USABLE_ADDRESS;
(grub_addr_t) desc < ((grub_addr_t) memory_map + memory_map_size);
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
- if (desc->attribute & GRUB_EFI_MEMORY_WB)
- *base_addr = grub_min (*base_addr, desc->physical_start);
+ {
+ if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY &&
+ (desc->attribute & GRUB_EFI_MEMORY_WB))
+ {
+ *base_addr = grub_min (*base_addr, desc->physical_start);
+ grub_dprintf ("efi", "setting base_addr=0x%016lx\n", *base_addr);
+ }
+ else
+ {
+ grub_dprintf ("efi", "ignoring address 0x%016lx\n", desc->physical_start);
+ }
+ }
+
+ if (*base_addr == GRUB_EFI_MAX_USABLE_ADDRESS)
+ grub_dprintf ("efi", "base_addr 0x%016lx is probably wrong.\n", *base_addr);
grub_free(memory_map);
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
index 93b5cd306eb..e1110749eb9 100644
--- a/grub-core/loader/arm64/linux.c
+++ b/grub-core/loader/arm64/linux.c
@@ -70,13 +70,15 @@ finalize_params_linux (void)
{
grub_efi_loaded_image_t *loaded_image = NULL;
int node, retval, len;
-
+ grub_err_t err = GRUB_ERR_NONE;
void *fdt;
fdt = grub_fdt_load (0x400);
-
if (!fdt)
- goto failure;
+ {
+ err = grub_error(GRUB_ERR_BAD_OS, "failed to load FDT");
+ goto failure;
+ }
node = grub_fdt_find_subnode (fdt, 0, "chosen");
if (node < 0)
@@ -87,17 +89,26 @@ finalize_params_linux (void)
*/
retval = grub_fdt_set_prop32(fdt, 0, "#address-cells", 2);
if (retval)
- goto failure;
+ {
+ err = grub_error(retval, "Could not find #address-cells");
+ goto failure;
+ }
retval = grub_fdt_set_prop32(fdt, 0, "#size-cells", 2);
if (retval)
- goto failure;
+ {
+ err = grub_error(retval, "Could not find #size-cells");
+ goto failure;
+ }
node = grub_fdt_add_subnode (fdt, 0, "chosen");
}
if (node < 1)
- goto failure;
+ {
+ err = grub_error(grub_errno, "failed to load chosen fdt node.");
+ goto failure;
+ }
/* Set initrd info */
if (initrd_start && initrd_end > initrd_start)
@@ -108,15 +119,26 @@ finalize_params_linux (void)
retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start",
initrd_start);
if (retval)
- goto failure;
+ {
+ err = grub_error(retval, "Failed to set linux,initrd-start property");
+ goto failure;
+ }
+
retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end",
initrd_end);
if (retval)
- goto failure;
+ {
+ err = grub_error(retval, "Failed to set linux,initrd-end property");
+ goto failure;
+ }
}
- if (grub_fdt_install() != GRUB_ERR_NONE)
- goto failure;
+ retval = grub_fdt_install();
+ if (retval != GRUB_ERR_NONE)
+ {
+ err = grub_error(retval, "Failed to install fdt");
+ goto failure;
+ }
grub_dprintf ("linux", "Installed/updated FDT configuration table @ %p\n",
fdt);
@@ -124,14 +146,20 @@ finalize_params_linux (void)
/* Convert command line to UCS-2 */
loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
if (!loaded_image)
- goto failure;
+ {
+ err = grub_error(grub_errno, "Failed to install fdt");
+ goto failure;
+ }
loaded_image->load_options_size = len =
(grub_strlen (linux_args) + 1) * sizeof (grub_efi_char16_t);
loaded_image->load_options =
grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
if (!loaded_image->load_options)
- return grub_error(GRUB_ERR_BAD_OS, "failed to create kernel parameters");
+ {
+ err = grub_error(GRUB_ERR_BAD_OS, "failed to create kernel parameters");
+ goto failure;
+ }
loaded_image->load_options_size =
2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
@@ -141,7 +169,7 @@ finalize_params_linux (void)
failure:
grub_fdt_unload();
- return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
+ return err;
}
static void
@@ -225,16 +253,28 @@ grub_linux_unload (void)
static void *
allocate_initrd_mem (int initrd_pages)
{
- grub_addr_t max_addr;
+ grub_addr_t max_addr = 0;
+ grub_err_t err;
+ void *ret;
- if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE)
- return NULL;
+ err = grub_efi_get_ram_base (&max_addr);
+ if (err != GRUB_ERR_NONE)
+ {
+ grub_error (err, "grub_efi_get_ram_base() failed");
+ return NULL;
+ }
+
+ grub_dprintf ("linux", "max_addr: 0x%016lx, INITRD_MAX_ADDRESS_OFFSET: 0x%016llx\n",
+ max_addr, INITRD_MAX_ADDRESS_OFFSET);
max_addr += INITRD_MAX_ADDRESS_OFFSET - 1;
+ grub_dprintf ("linux", "calling grub_efi_allocate_pages_real (0x%016lx, 0x%08x, EFI_ALLOCATE_MAX_ADDRESS, EFI_LOADER_DATA)", max_addr, initrd_pages);
- return grub_efi_allocate_pages_real (max_addr, initrd_pages,
- GRUB_EFI_ALLOCATE_MAX_ADDRESS,
- GRUB_EFI_LOADER_DATA);
+ ret = grub_efi_allocate_pages_real (max_addr, initrd_pages,
+ GRUB_EFI_ALLOCATE_MAX_ADDRESS,
+ GRUB_EFI_LOADER_DATA);
+ grub_dprintf ("linux", "got 0x%016llx\n", (unsigned long long)ret);
+ return ret;
}
static grub_err_t

View File

@ -0,0 +1,27 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 27 Aug 2018 14:31:37 -0400
Subject: [PATCH] Fix GRUB_EFI_MAX_USABLE_ADDRESS to be 64-bit on x86_64 EFI
machines.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
include/grub/x86_64/efi/memory.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/grub/x86_64/efi/memory.h b/include/grub/x86_64/efi/memory.h
index 46e9145a308..fb7437f7b5f 100644
--- a/include/grub/x86_64/efi/memory.h
+++ b/include/grub/x86_64/efi/memory.h
@@ -2,9 +2,9 @@
#include <grub/efi/memory.h>
#if defined (__code_model_large__)
-#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff
+#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffffffffffULL
#else
-#define GRUB_EFI_MAX_USABLE_ADDRESS 0x7fffffff
+#define GRUB_EFI_MAX_USABLE_ADDRESS 0x7fffffffffffffffULL
#endif
#endif /* ! GRUB_MEMORY_CPU_HEADER */

View File

@ -0,0 +1,96 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Thu, 30 Aug 2018 11:10:18 -0400
Subject: [PATCH] Try to pick better locations for kernel and initrd
Don't limit allocations on 64-bit platforms to < 0x3fffffff; use
__UINTPTR_MAX__ or __INTPTR_MAX__.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/kern/efi/mm.c | 2 +-
grub-core/loader/i386/efi/linux.c | 7 ++++---
include/grub/arm64/efi/memory.h | 2 +-
include/grub/x86_64/efi/memory.h | 4 ++--
4 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
index 306924f73a4..4c00f4cc9d3 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;
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
index ea9f5134e67..fddf54762a7 100644
--- a/grub-core/loader/i386/efi/linux.c
+++ b/grub-core/loader/i386/efi/linux.c
@@ -28,6 +28,7 @@
#include <grub/efi/efi.h>
#include <grub/efi/linux.h>
#include <grub/tpm.h>
+#include <grub/cpu/efi/memory.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -108,7 +109,7 @@ 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_USABLE_ADDRESS, BYTES_TO_PAGES(size));
if (!initrd_mem)
{
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd"));
@@ -209,7 +210,7 @@ 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_USABLE_ADDRESS,
BYTES_TO_PAGES(sizeof(*params)));
if (! params)
{
@@ -309,7 +310,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
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_USABLE_ADDRESS,
BYTES_TO_PAGES(lh->init_size));
if (!kernel_mem)
diff --git a/include/grub/arm64/efi/memory.h b/include/grub/arm64/efi/memory.h
index c6cb3241714..af62f56cf7e 100644
--- a/include/grub/arm64/efi/memory.h
+++ b/include/grub/arm64/efi/memory.h
@@ -1,6 +1,6 @@
#ifndef GRUB_MEMORY_CPU_HEADER
#include <grub/efi/memory.h>
-#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffffffULL
+#define GRUB_EFI_MAX_USABLE_ADDRESS __UINTPTR_MAX__
#endif /* ! GRUB_MEMORY_CPU_HEADER */
diff --git a/include/grub/x86_64/efi/memory.h b/include/grub/x86_64/efi/memory.h
index fb7437f7b5f..70bce170850 100644
--- a/include/grub/x86_64/efi/memory.h
+++ b/include/grub/x86_64/efi/memory.h
@@ -2,9 +2,9 @@
#include <grub/efi/memory.h>
#if defined (__code_model_large__)
-#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffffffffffULL
+#define GRUB_EFI_MAX_USABLE_ADDRESS __UINTPTR_MAX__
#else
-#define GRUB_EFI_MAX_USABLE_ADDRESS 0x7fffffffffffffffULL
+#define GRUB_EFI_MAX_USABLE_ADDRESS __INTPTR_MAX__
#endif
#endif /* ! GRUB_MEMORY_CPU_HEADER */

View File

@ -227,5 +227,10 @@ Patch0226: 0226-Make-efi_netfs-not-duplicate-symbols-from-efinet.patch
Patch0227: 0227-Rework-how-the-fdt-command-builds.patch
Patch0228: 0228-Disable-non-wordsize-allocations-on-arm.patch
Patch0229: 0229-strip-R-.note.gnu.property-at-more-places.patch
Patch0230: 0230-arm-arm64-loader-better-error-messages.patch
Patch0230: 0230-Prepend-prefix-when-HTTP-path-is-relative.patch
Patch0231: 0231-Make-linux_arm_kernel_header.hdr_offset-be-at-the-ri.patch
Patch0232: 0232-Mark-some-unused-stuff-unused.patch
Patch0233: 0233-Make-grub_error-more-verbose.patch
Patch0234: 0234-arm-arm64-loader-Better-memory-allocation-and-error-.patch
Patch0235: 0235-Fix-GRUB_EFI_MAX_USABLE_ADDRESS-to-be-64-bit-on-x86_.patch
Patch0236: 0236-Try-to-pick-better-locations-for-kernel-and-initrd.patch

View File

@ -7,7 +7,7 @@
Name: grub2
Epoch: 1
Version: 2.02
Release: 51%{?dist}
Release: 52%{?dist}
Summary: Bootloader with support for Linux, Multiboot and more
Group: System Environment/Base
License: GPLv3+
@ -498,6 +498,14 @@ fi
%endif
%changelog
* Thu Aug 30 2018 Peter Jones <pjones@redhat.com> - 2.02-52
- Fix AArch64 machines with no RAM latched lower than 1GB
Resolves: rhbz#1615969
- Set http_path and http_url when HTTP booting
- Hopefully slightly better error reporting in some cases
- Better allocation of kernel+initramfs on x86_64 and aarch64
Resolves: rhbz#1572126
* Sun Aug 19 2018 Peter Jones <pjones@redhat.com> - 2.02-51
- Make it quieter.