Blame SOURCES/0557-efi-split-allocation-policy-for-kernel-vs-initrd-mem.patch

235a57
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
235a57
From: Peter Jones <pjones@redhat.com>
235a57
Date: Mon, 1 Aug 2022 14:24:39 -0400
235a57
Subject: [PATCH] efi: split allocation policy for kernel vs initrd memories.
235a57
235a57
Currently in our kernel allocator, we use the same set of choices for
235a57
all of our various kernel and initramfs allocations, though they do not
235a57
have exactly the same constraints.
235a57
235a57
This patch adds the concept of an allocation purpose, which currently
235a57
can be KERNEL_MEM or INITRD_MEM, and updates kernel_alloc() calls
235a57
appropriately, but does not change any current policy decision.  It
235a57
also adds a few debug prints.
235a57
235a57
Signed-off-by: Peter Jones <pjones@redhat.com>
235a57
(cherry picked from commit 36307bed28cd838116fc4af26a30719660d62d4c)
235a57
(cherry picked from commit dc1196350b0cbe89582832f44df0fce67e0c9fb2)
235a57
---
235a57
 grub-core/loader/i386/efi/linux.c | 35 +++++++++++++++++++++++++++--------
235a57
 1 file changed, 27 insertions(+), 8 deletions(-)
235a57
235a57
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
235a57
index 23b27f6507..09e7596064 100644
235a57
--- a/grub-core/loader/i386/efi/linux.c
235a57
+++ b/grub-core/loader/i386/efi/linux.c
235a57
@@ -55,7 +55,14 @@ struct grub_linuxefi_context {
235a57
 
235a57
 #define BYTES_TO_PAGES(bytes)   (((bytes) + 0xfff) >> 12)
235a57
 
235a57
+typedef enum {
235a57
+    NO_MEM,
235a57
+    KERNEL_MEM,
235a57
+    INITRD_MEM,
235a57
+} kernel_alloc_purpose_t;
235a57
+
235a57
 struct allocation_choice {
235a57
+    kernel_alloc_purpose_t purpose;
235a57
     grub_efi_physical_address_t addr;
235a57
     grub_efi_allocate_type_t alloc_type;
235a57
 };
235a57
@@ -64,6 +71,7 @@ enum {
235a57
     KERNEL_PREF_ADDRESS,
235a57
     KERNEL_4G_LIMIT,
235a57
     KERNEL_NO_LIMIT,
235a57
+    INITRD_MAX_ADDRESS,
235a57
 };
235a57
 
235a57
 static struct allocation_choice max_addresses[] =
235a57
@@ -71,14 +79,17 @@ static struct allocation_choice max_addresses[] =
235a57
     /* the kernel overrides this one with pref_address and
235a57
      * GRUB_EFI_ALLOCATE_ADDRESS */
235a57
     [KERNEL_PREF_ADDRESS] =
235a57
-      { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
235a57
+      { KERNEL_MEM, GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
235a57
     /* If the flag in params is set, this one gets changed to be above 4GB. */
235a57
     [KERNEL_4G_LIMIT] =
235a57
-      { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
235a57
+      { KERNEL_MEM, GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
235a57
     /* this one is always below 4GB, which we still *prefer* even if the flag
235a57
      * is set. */
235a57
     [KERNEL_NO_LIMIT] =
235a57
-      { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
235a57
+      { KERNEL_MEM, GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
235a57
+    /* this is for the initrd */
235a57
+    [INITRD_MAX_ADDRESS] =
235a57
+      { INITRD_MEM, GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
235a57
     { NO_MEM, 0, 0 }
235a57
   };
235a57
 static struct allocation_choice saved_addresses[4];
235a57
@@ -95,7 +106,8 @@ kernel_free(void *addr, grub_efi_uintn_t size)
235a57
 }
235a57
 
235a57
 static void *
235a57
-kernel_alloc(grub_efi_uintn_t size,
235a57
+kernel_alloc(kernel_alloc_purpose_t purpose,
235a57
+	     grub_efi_uintn_t size,
235a57
 	     grub_efi_memory_type_t memtype,
235a57
 	     const char * const errmsg)
235a57
 {
235a57
@@ -108,6 +120,9 @@ kernel_alloc(grub_efi_uintn_t size,
235a57
       grub_uint64_t max = max_addresses[i].addr;
235a57
       grub_efi_uintn_t pages;
235a57
 
235a57
+      if (purpose != max_addresses[i].purpose)
235a57
+	continue;
235a57
+
235a57
       /*
235a57
        * When we're *not* loading the kernel, or >4GB allocations aren't
235a57
        * supported, these entries are basically all the same, so don't re-try
235a57
@@ -262,7 +277,8 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
235a57
 	}
235a57
     }
235a57
 
235a57
-  initrd_mem = kernel_alloc(size, GRUB_EFI_RUNTIME_SERVICES_DATA,
235a57
+  grub_dprintf ("linux", "Trying to allocate initrd mem\n");
235a57
+  initrd_mem = kernel_alloc(INITRD_MEM, size, GRUB_EFI_RUNTIME_SERVICES_DATA,
235a57
 			    N_("can't allocate initrd"));
235a57
   if (initrd_mem == NULL)
235a57
     goto fail;
235a57
@@ -440,7 +456,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
235a57
     }
235a57
 #endif
235a57
 
235a57
-  params = kernel_alloc (sizeof(*params), GRUB_EFI_RUNTIME_SERVICES_DATA,
235a57
+  params = kernel_alloc (KERNEL_MEM, sizeof(*params),
235a57
+			 GRUB_EFI_RUNTIME_SERVICES_DATA,
235a57
 			 "cannot allocate kernel parameters");
235a57
   if (!params)
235a57
     goto fail;
235a57
@@ -462,7 +479,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
235a57
   grub_dprintf ("linux", "new lh is at %p\n", lh);
235a57
 
235a57
   grub_dprintf ("linux", "setting up cmdline\n");
235a57
-  cmdline = kernel_alloc (lh->cmdline_size + 1,
235a57
+  cmdline = kernel_alloc (KERNEL_MEM, lh->cmdline_size + 1,
235a57
 			  GRUB_EFI_RUNTIME_SERVICES_DATA,
235a57
 			  N_("can't allocate cmdline"));
235a57
   if (!cmdline)
235a57
@@ -510,7 +527,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
235a57
   max_addresses[KERNEL_4G_LIMIT].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
235a57
   max_addresses[KERNEL_NO_LIMIT].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
235a57
   kernel_size = lh->init_size;
235a57
-  kernel_mem = kernel_alloc (kernel_size, GRUB_EFI_RUNTIME_SERVICES_CODE,
235a57
+  grub_dprintf ("linux", "Trying to allocate kernel mem\n");
235a57
+  kernel_mem = kernel_alloc (KERNEL_MEM, kernel_size,
235a57
+			     GRUB_EFI_RUNTIME_SERVICES_CODE,
235a57
 			     N_("can't allocate kernel"));
235a57
   restore_addresses();
235a57
   if (!kernel_mem)