grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Reset grub_mm_add_region_fn after exiting EFI services


From: Ruihan Li
Subject: Re: [PATCH] Reset grub_mm_add_region_fn after exiting EFI services
Date: Tue, 17 Dec 2024 09:20:22 +0800

On Mon, Dec 16, 2024 at 05:10:04PM +0100, Daniel Kiper wrote:
> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>

Thanks for your review!

> However, should not we go further and extend the heap with additional
> memory before EBS? 1 MiB?

Yeah, I think it's a good idea. I'm not sure how much memory we should
reserve, so I'll use your 1MiB suggestion below.

I can send a v2 patch with the following changes. Since this involves a
larger amount of code changes (compared to my original patch), maybe you
could take a look to see if I implemented your suggestions correctly
first (so I can keep the Reviewed-by tag)? Thanks!

diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
index bc97ecd47..6ffddf3c9 100644
--- a/grub-core/kern/efi/mm.c
+++ b/grub-core/kern/efi/mm.c
@@ -41,6 +41,9 @@
 /* The default heap size for GRUB itself in bytes.  */
 #define DEFAULT_HEAP_SIZE      0x2000000
 
+/* The heap size reserved when exiting EFI services in bytes. */
+#define EBS_HEAP_SIZE          0x100000
+
 static void *finish_mmap_buf = 0;
 static grub_efi_uintn_t finish_mmap_size = 0;
 static grub_efi_uintn_t finish_key = 0;
@@ -231,6 +234,9 @@ stop_broadcom (void)
 
 #endif
 
+static grub_err_t
+grub_efi_mm_add_regions (grub_size_t required_bytes, unsigned int flags);
+
 grub_err_t
 grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf,
                               grub_efi_uintn_t *map_key,
@@ -248,24 +254,41 @@ grub_efi_finish_boot_services (grub_efi_uintn_t 
*outbuf_size, void *outbuf,
                           apple, sizeof (apple)) == 0);
 #endif
 
+  /*
+   * We can no longer request new memory from EFI Services.
+   * So we reserve some memory in advance.
+   */
+  grub_efi_mm_add_regions (EBS_HEAP_SIZE, GRUB_MM_ADD_REGION_NONE);
+  grub_mm_add_region_fn = NULL;
+
   while (1)
     {
       if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, 
&finish_key,
                                   &finish_desc_size, &finish_desc_version) < 0)
-       return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
+       {
+         grub_mm_add_region_fn = grub_efi_mm_add_regions;
+         return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
+       }
 
       if (outbuf && *outbuf_size < finish_mmap_size)
-       return grub_error (GRUB_ERR_IO, "memory map buffer is too small");
+       {
+         grub_mm_add_region_fn = grub_efi_mm_add_regions;
+         return grub_error (GRUB_ERR_IO, "memory map buffer is too small");
+       }
 
       finish_mmap_buf = grub_malloc (finish_mmap_size);
       if (!finish_mmap_buf)
-       return grub_errno;
+       {
+         grub_mm_add_region_fn = grub_efi_mm_add_regions;
+         return grub_errno;
+       }
 
       if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, 
&finish_key,
                                   &finish_desc_size, &finish_desc_version) <= 
0)
        {
          grub_free (finish_mmap_buf);
          finish_mmap_buf = NULL;
+         grub_mm_add_region_fn = grub_efi_mm_add_regions;
          return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
        }
 
@@ -278,6 +301,7 @@ grub_efi_finish_boot_services (grub_efi_uintn_t 
*outbuf_size, void *outbuf,
        {
          grub_free (finish_mmap_buf);
          finish_mmap_buf = NULL;
+         grub_mm_add_region_fn = grub_efi_mm_add_regions;
          return grub_error (GRUB_ERR_IO, "couldn't terminate EFI services");
        }
 
Thanks,
Ruihan Li




reply via email to

[Prev in Thread] Current Thread [Next in Thread]