nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

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

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