grub-devel
[Top][All Lists]
Advanced

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

[PATCH v7 07/10] loader/powerpc/ieee1275: Use new allocation function fo


From: Stefan Berger
Subject: [PATCH v7 07/10] loader/powerpc/ieee1275: Use new allocation function for kernel and initrd
Date: Mon, 27 Nov 2023 06:58:50 -0500

On PowerVM and KVM on Power use the new memory allocation function that
honors restrictions on which memory GRUB can actually use. In the request
structure indicate the request for a single memory block along with
address alignment restrictions. Request direct usage of the memory block
by setting init_region to false (prevent it from being added to GRUB's
heap). Initialize the found addr to '-1', so that '-1' will be returned
to the loader in case no memory could be allocated.

Report an out-of-memory error in case the initrd could not be loaded.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Cc: Hari Bathini <hbathini@linux.ibm.com>
Cc: Pavithra Prakash <pavrampu@in.ibm.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Carolyn Scherrer <cpscherr@us.ibm.com>
Cc: Mahesh Salgaonkar <mahesh@linux.ibm.com>
Cc: Sourabh Jain <sourabhjain@linux.ibm.com>
---
 grub-core/loader/powerpc/ieee1275/linux.c | 55 +++++++++++++++++++----
 1 file changed, 46 insertions(+), 9 deletions(-)

diff --git a/grub-core/loader/powerpc/ieee1275/linux.c 
b/grub-core/loader/powerpc/ieee1275/linux.c
index e6d071508..4864e5fb0 100644
--- a/grub-core/loader/powerpc/ieee1275/linux.c
+++ b/grub-core/loader/powerpc/ieee1275/linux.c
@@ -30,6 +30,7 @@
 #include <grub/lib/cmdline.h>
 #include <grub/cache.h>
 #include <grub/linux.h>
+#include <grub/ieee1275/alloc.h>
 
 GRUB_MOD_LICENSE ("GPLv3+");
 
@@ -116,6 +117,22 @@ grub_linux_claimmap_iterate (grub_addr_t target, 
grub_size_t size,
   return ctx.found_addr;
 }
 
+static grub_addr_t
+grub_linux_claimmap_iterate_restricted (grub_size_t size, grub_size_t align)
+{
+  struct regions_claim_request rcr = {
+    .flags = GRUB_MM_ADD_REGION_CONSECUTIVE,
+    .total = size,
+    .init_region = false,
+    .addr = (grub_uint64_t) -1,
+    .align = align,
+  };
+
+  grub_machine_mmap_iterate (grub_regions_claim, &rcr);
+
+  return rcr.addr;
+}
+
 static grub_err_t
 grub_linux_boot (void)
 {
@@ -227,10 +244,18 @@ grub_linux_load64 (grub_elf_t elf, const char *filename)
   offset = entry - base_addr;
   /* Linux's incorrectly contains a virtual address.  */
 
-  /* On some systems, firmware occupies the memory we're trying to use.
-   * Happily, Linux can be loaded anywhere (it relocates itself).  Iterate
-   * until we find an open area.  */
-  seg_addr = grub_linux_claimmap_iterate (base_addr & ~ELF64_LOADMASK, 
linux_size, align);
+  if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_POWER_VM) ||
+      grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_POWER_KVM))
+    {
+      seg_addr = grub_linux_claimmap_iterate_restricted (linux_size, align);
+    }
+  else
+    {
+      /* On some systems, firmware occupies the memory we're trying to use.
+       * Happily, Linux can be loaded anywhere (it relocates itself).  Iterate
+       * until we find an open area.  */
+      seg_addr = grub_linux_claimmap_iterate (base_addr & ~ELF64_LOADMASK, 
linux_size, align);
+    }
   if (seg_addr == (grub_addr_t) -1)
     return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't claim memory");
 
@@ -339,13 +364,25 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ 
((unused)),
 
   size = grub_get_initrd_size (&initrd_ctx);
 
-  first_addr = linux_addr + linux_size;
 
-  /* Attempt to claim at a series of addresses until successful in
-     the same way that grub_rescue_cmd_linux does.  */
-  addr = grub_linux_claimmap_iterate (first_addr, size, 0x100000);
+  if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_POWER_VM) ||
+      grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_POWER_KVM))
+    {
+      addr = grub_linux_claimmap_iterate_restricted (size, 0x100000);
+    }
+  else
+    {
+      /* Attempt to claim at a series of addresses until successful in
+         the same way that grub_rescue_cmd_linux does.  */
+      first_addr = linux_addr + linux_size;
+      addr = grub_linux_claimmap_iterate (first_addr, size, 0x100000);
+    }
+
   if (addr == (grub_addr_t) -1)
-     goto fail;
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
+      goto fail;
+    }
 
   grub_dprintf ("loader", "Loading initrd at 0x%x, size 0x%x\n", addr, size);
 
-- 
2.42.0




reply via email to

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