[Top][All Lists]

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

[RFC PATCH 1/3] mm: allow dynamically requesting additional memory regio

From: Patrick Steinhardt
Subject: [RFC PATCH 1/3] mm: allow dynamically requesting additional memory regions
Date: Mon, 1 Jun 2020 21:34:38 +0200

Currently, all platforms will set up their heap on initialization of the
platform code. While this works mostly fine, it poses some limitations
on memory management on us. Most notably, allocating big chunks of
memory in the gigabyte range would require us to pre-request this many
bytes from the firmware and add it to the heap from the beginning on
some platforms like EFI. As this isn't needed for most configurations,
it is inefficient and may even negatively impact some usecases when
chainloading. Nonetheless, allocating big chunks of memory is required
sometimes, where one example is the upcoming support for the Argon2 key
derival function in LUKS2.

In order to avoid pre-allocating big chunks of memory, this commit
implements a runtime mechanism to add more pages to the system. When
a given allocation cannot be currently be satisfied, we'll call a given
callback set up by the platform's own memory management subsystem,
asking it to add a memory area with at least `n` bytes. If this
succeeds, we retry searching for a valid memory region, which should now

Signed-off-by: Patrick Steinhardt <>
 grub-core/kern/mm.c | 11 ++++++++++-
 include/grub/mm.h   | 13 +++++++++++++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c
index ee88ff611..e4badd104 100644
--- a/grub-core/kern/mm.c
+++ b/grub-core/kern/mm.c
@@ -79,6 +79,7 @@
 grub_mm_region_t grub_mm_base;
+grub_mm_region_func_t grub_mm_region_fn;
 /* Get a header from the pointer PTR, and set *P and *R to a pointer
    to the header and a pointer to its region, respectively. PTR must
@@ -358,8 +359,16 @@ grub_memalign (grub_size_t align, grub_size_t size)
       goto again;
-#if 0
     case 1:
+      /* Request additional pages.  */
+      count++;
+      if (grub_mm_region_fn && grub_mm_region_fn (size, 
+       goto again;
+      /* fallthrough */
+#if 0
+    case 2:
       /* Unload unneeded modules.  */
       grub_dl_unload_unneeded ();
diff --git a/include/grub/mm.h b/include/grub/mm.h
index 28e2e53eb..227e8b54c 100644
--- a/include/grub/mm.h
+++ b/include/grub/mm.h
@@ -20,6 +20,7 @@
 #ifndef GRUB_MM_H
 #define GRUB_MM_H      1
+#include <grub/err.h>
 #include <grub/types.h>
 #include <grub/symbol.h>
 #include <config.h>
@@ -28,6 +29,18 @@
 # define NULL  ((void *) 0)
+enum {
+/* Function used to request memory regions of `grub_size_t` bytes. The second
+ * parameter is a bitfield of `GRUB_MM_REGION` flags.  */
+typedef grub_err_t (*grub_mm_region_func_t) (grub_size_t, unsigned);
+/* Set this function pointer to enable adding memory-regions at runtime in case
+ * a memory allocation cannot be satisfied with existing regions.  */
+extern grub_mm_region_func_t EXPORT_VAR(grub_mm_region_fn);
 void grub_mm_init_region (void *addr, grub_size_t size);
 void *EXPORT_FUNC(grub_malloc) (grub_size_t size);
 void *EXPORT_FUNC(grub_zalloc) (grub_size_t size);

Attachment: signature.asc
Description: PGP signature

reply via email to

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