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

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