|
|
23a3f0 |
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
23a3f0 |
From: Peter Jones <pjones@redhat.com>
|
|
|
23a3f0 |
Date: Fri, 12 Jul 2019 09:53:32 +0200
|
|
|
23a3f0 |
Subject: [PATCH] x86-efi: Use bounce buffers for reading to addresses > 4GB
|
|
|
23a3f0 |
|
|
|
23a3f0 |
Lots of machines apparently can't DMA correctly above 4GB during UEFI,
|
|
|
23a3f0 |
so use bounce buffers for the initramfs read.
|
|
|
23a3f0 |
|
|
|
23a3f0 |
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
|
23a3f0 |
(cherry picked from commit 7765a790dee00f2e0d414cf3a3d016c493cf0d9b)
|
|
|
23a3f0 |
|
|
|
23a3f0 |
Conflicts:
|
|
|
23a3f0 |
grub-core/loader/i386/efi/linux.c
|
|
|
23a3f0 |
git cherry-pick thought delete of prior def of MIN was a
|
|
|
23a3f0 |
conflict.
|
|
|
23a3f0 |
|
|
|
23a3f0 |
Signed-off-by: Lenny Szubowicz <lszubowi@redhat.com>
|
|
|
030dc3 |
(cherry picked from commit 382fc90ade7297b93b2e42df6972f18337ef2ee8)
|
|
|
030dc3 |
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
|
|
23a3f0 |
---
|
|
|
23a3f0 |
grub-core/loader/i386/efi/linux.c | 52 +++++++++++++++++++++++++++++++++------
|
|
|
23a3f0 |
1 file changed, 45 insertions(+), 7 deletions(-)
|
|
|
23a3f0 |
|
|
|
23a3f0 |
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
|
|
23a3f0 |
index c5fdf522b..73cd838e9 100644
|
|
|
23a3f0 |
--- a/grub-core/loader/i386/efi/linux.c
|
|
|
23a3f0 |
+++ b/grub-core/loader/i386/efi/linux.c
|
|
|
23a3f0 |
@@ -37,11 +37,16 @@ static grub_dl_t my_mod;
|
|
|
23a3f0 |
static int loaded;
|
|
|
23a3f0 |
static void *kernel_mem;
|
|
|
23a3f0 |
static grub_uint64_t kernel_size;
|
|
|
23a3f0 |
-static grub_uint8_t *initrd_mem;
|
|
|
23a3f0 |
+static void *initrd_mem;
|
|
|
23a3f0 |
static grub_uint32_t handover_offset;
|
|
|
23a3f0 |
struct linux_kernel_params *params;
|
|
|
23a3f0 |
static char *linux_cmdline;
|
|
|
23a3f0 |
|
|
|
23a3f0 |
+#define MIN(a, b) \
|
|
|
23a3f0 |
+ ({ typeof (a) _a = (a); \
|
|
|
23a3f0 |
+ typeof (b) _b = (b); \
|
|
|
23a3f0 |
+ _a < _b ? _a : _b; })
|
|
|
23a3f0 |
+
|
|
|
23a3f0 |
#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12)
|
|
|
23a3f0 |
|
|
|
23a3f0 |
static grub_err_t
|
|
|
23a3f0 |
@@ -75,6 +80,44 @@ grub_linuxefi_unload (void)
|
|
|
23a3f0 |
return GRUB_ERR_NONE;
|
|
|
23a3f0 |
}
|
|
|
23a3f0 |
|
|
|
23a3f0 |
+#define BOUNCE_BUFFER_MAX 0x10000000ull
|
|
|
23a3f0 |
+
|
|
|
23a3f0 |
+static grub_ssize_t
|
|
|
23a3f0 |
+read(grub_file_t file, grub_uint8_t *bufp, grub_size_t len)
|
|
|
23a3f0 |
+{
|
|
|
23a3f0 |
+ grub_ssize_t bufpos = 0;
|
|
|
23a3f0 |
+ static grub_size_t bbufsz = 0;
|
|
|
23a3f0 |
+ static char *bbuf = NULL;
|
|
|
23a3f0 |
+
|
|
|
23a3f0 |
+ if (bbufsz == 0)
|
|
|
23a3f0 |
+ bbufsz = MIN(BOUNCE_BUFFER_MAX, len);
|
|
|
23a3f0 |
+
|
|
|
23a3f0 |
+ while (!bbuf && bbufsz)
|
|
|
23a3f0 |
+ {
|
|
|
23a3f0 |
+ bbuf = grub_malloc(bbufsz);
|
|
|
23a3f0 |
+ if (!bbuf)
|
|
|
23a3f0 |
+ bbufsz >>= 1;
|
|
|
23a3f0 |
+ }
|
|
|
23a3f0 |
+ if (!bbuf)
|
|
|
23a3f0 |
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate bounce buffer"));
|
|
|
23a3f0 |
+
|
|
|
23a3f0 |
+ while (bufpos < (long long)len)
|
|
|
23a3f0 |
+ {
|
|
|
23a3f0 |
+ grub_ssize_t sz;
|
|
|
23a3f0 |
+
|
|
|
23a3f0 |
+ sz = grub_file_read (file, bbuf, MIN(bbufsz, len - bufpos));
|
|
|
23a3f0 |
+ if (sz < 0)
|
|
|
23a3f0 |
+ return sz;
|
|
|
23a3f0 |
+ if (sz == 0)
|
|
|
23a3f0 |
+ break;
|
|
|
23a3f0 |
+
|
|
|
23a3f0 |
+ grub_memcpy(bufp + bufpos, bbuf, sz);
|
|
|
23a3f0 |
+ bufpos += sz;
|
|
|
23a3f0 |
+ }
|
|
|
23a3f0 |
+
|
|
|
23a3f0 |
+ return bufpos;
|
|
|
23a3f0 |
+}
|
|
|
23a3f0 |
+
|
|
|
23a3f0 |
static grub_err_t
|
|
|
23a3f0 |
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|
|
23a3f0 |
int argc, char *argv[])
|
|
|
23a3f0 |
@@ -133,7 +176,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|
|
23a3f0 |
for (i = 0; i < nfiles; i++)
|
|
|
23a3f0 |
{
|
|
|
23a3f0 |
grub_ssize_t cursize = grub_file_size (files[i]);
|
|
|
23a3f0 |
- if (grub_file_read (files[i], ptr, cursize) != cursize)
|
|
|
23a3f0 |
+ if (read (files[i], ptr, cursize) != cursize)
|
|
|
23a3f0 |
{
|
|
|
23a3f0 |
if (!grub_errno)
|
|
|
23a3f0 |
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
|
|
23a3f0 |
@@ -161,11 +204,6 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|
|
23a3f0 |
return grub_errno;
|
|
|
23a3f0 |
}
|
|
|
23a3f0 |
|
|
|
23a3f0 |
-#define MIN(a, b) \
|
|
|
23a3f0 |
- ({ typeof (a) _a = (a); \
|
|
|
23a3f0 |
- typeof (b) _b = (b); \
|
|
|
23a3f0 |
- _a < _b ? _a : _b; })
|
|
|
23a3f0 |
-
|
|
|
23a3f0 |
static grub_err_t
|
|
|
23a3f0 |
grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|
|
23a3f0 |
int argc, char *argv[])
|