Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:gary_lin:branches:Base:System
grub2
0005-x86-efi-Use-bounce-buffers-for-reading-to-...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0005-x86-efi-Use-bounce-buffers-for-reading-to-addresses-.patch of Package grub2
From a33acb675fe0d0464637175e4f06176e4c329025 Mon Sep 17 00:00:00 2001 From: Peter Jones <pjones@redhat.com> Date: Fri, 12 Jul 2019 09:53:32 +0200 Subject: [PATCH 05/11] x86-efi: Use bounce buffers for reading to addresses > 4GB Lots of machines apparently can't DMA correctly above 4GB during UEFI, so use bounce buffers for the initramfs read. Signed-off-by: Peter Jones <pjones@redhat.com> --- grub-core/loader/i386/efi/linux.c | 52 ++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c index f3abbd025..d6bed4fb4 100644 --- a/grub-core/loader/i386/efi/linux.c +++ b/grub-core/loader/i386/efi/linux.c @@ -35,11 +35,16 @@ static grub_dl_t my_mod; static int loaded; static void *kernel_mem; static grub_uint64_t kernel_size; -static grub_uint8_t *initrd_mem; +static void *initrd_mem; static grub_uint32_t handover_offset; struct linux_kernel_params *params; static char *linux_cmdline; +#define MIN(a, b) \ + ({ typeof (a) _a = (a); \ + typeof (b) _b = (b); \ + _a < _b ? _a : _b; }) + #define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) static grub_err_t @@ -68,6 +73,44 @@ grub_linuxefi_unload (void) return GRUB_ERR_NONE; } +#define BOUNCE_BUFFER_MAX 0x10000000ull + +static grub_ssize_t +read(grub_file_t file, grub_uint8_t *bufp, grub_size_t len) +{ + grub_ssize_t bufpos = 0; + static grub_size_t bbufsz = 0; + static char *bbuf = NULL; + + if (bbufsz == 0) + bbufsz = MIN(BOUNCE_BUFFER_MAX, len); + + while (!bbuf && bbufsz) + { + bbuf = grub_malloc(bbufsz); + if (!bbuf) + bbufsz >>= 1; + } + if (!bbuf) + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate bounce buffer")); + + while (bufpos < (long long)len) + { + grub_ssize_t sz; + + sz = grub_file_read (file, bbuf, MIN(bbufsz, len - bufpos)); + if (sz < 0) + return sz; + if (sz == 0) + break; + + grub_memcpy(bufp + bufpos, bbuf, sz); + bufpos += sz; + } + + return bufpos; +} + static grub_err_t grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) @@ -120,7 +163,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), for (i = 0; i < nfiles; i++) { grub_ssize_t cursize = grub_file_size (files[i]); - if (grub_file_read (files[i], ptr, cursize) != cursize) + if (read (files[i], ptr, cursize) != cursize) { if (!grub_errno) grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), @@ -145,11 +188,6 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), return grub_errno; } -#define MIN(a, b) \ - ({ typeof (a) _a = (a); \ - typeof (b) _b = (b); \ - _a < _b ? _a : _b; }) - static grub_err_t grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) -- 2.31.1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor