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

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