Hi,

On 1/27/26 9:39 AM, Ahmad Fatoum wrote:
> So far we expected that a load operation will not overflow, but there
> was actually no way for the callee to check this.
> 
> As the architecture-specific bootm handlers are tasked with allocating
> memory for boot artifacts have them pass along not only the start of the
> load region, but also its end, so the callee can check that it didn't
> overflow.
> 
> Signed-off-by: Ahmad Fatoum <[email protected]>

Please dismiss this one patch. I got at least one end offset wrong and I
will just redo it separate from this series.

Thanks,
Ahmad

> ---
>  arch/arm/lib32/bootm.c              | 24 +++++---
>  arch/arm/lib64/armlinux.c           |  7 ++-
>  arch/arm/mach-at91/bootm-barebox.c  |  7 ++-
>  arch/arm/mach-imx/imx-v3-image.c    |  7 ++-
>  arch/arm/mach-layerscape/pblimage.c |  7 ++-
>  arch/arm/mach-rockchip/bootm.c      | 13 ++--
>  arch/arm/mach-zynq/bootm-zynqimg.c  |  7 ++-
>  arch/kvx/lib/bootm.c                | 17 ++++--
>  arch/powerpc/lib/ppclinux.c         | 13 +++-
>  common/booti.c                      | 30 +++++----
>  common/bootm-mock.c                 |  0
>  common/bootm.c                      | 95 ++++++++++++++++++-----------
>  efi/loader/bootm.c                  |  9 ++-
>  include/bootm.h                     | 13 ++--
>  14 files changed, 158 insertions(+), 91 deletions(-)
>  create mode 100644 common/bootm-mock.c
> 
> diff --git a/arch/arm/lib32/bootm.c b/arch/arm/lib32/bootm.c
> index e659d3c1a554..3641dbbdbe61 100644
> --- a/arch/arm/lib32/bootm.c
> +++ b/arch/arm/lib32/bootm.c
> @@ -236,12 +236,17 @@ static int __do_bootm_linux(struct image_data *data, 
> unsigned long free_mem,
>  {
>       unsigned long kernel;
>       unsigned long initrd_start = 0, initrd_size = 0, initrd_end = 0;
> -     const struct resource *initrd_res;
> +     const struct resource *initrd_res, *sdram;
> +     struct resource gap;
>       void *tee;
>       enum arm_security_state state = bootm_arm_security_state();
>       void *fdt_load_address = NULL;
>       int ret;
>  
> +     sdram = memory_bank_lookup_region(free_mem, &gap);
> +     if (sdram != &gap)
> +             return sdram ? -EBUSY : -EINVAL;
> +
>       kernel = data->os_res->start + data->os_entry;
>  
>       initrd_start = data->initrd_address;
> @@ -255,7 +260,7 @@ static int __do_bootm_linux(struct image_data *data, 
> unsigned long free_mem,
>               }
>       }
>  
> -     initrd_res = bootm_load_initrd(data, initrd_start);
> +     initrd_res = bootm_load_initrd(data, initrd_start, gap.end);
>       if (IS_ERR(initrd_res)) {
>               return PTR_ERR(initrd_res);
>       } else if (initrd_res) {
> @@ -277,13 +282,15 @@ static int __do_bootm_linux(struct image_data *data, 
> unsigned long free_mem,
>       }
>  
>       if (fdt) {
> +             const struct resource *fdt_res;
> +
>               fdt_load_address = (void *)free_mem;
> -             ret = bootm_load_devicetree(data, fdt, free_mem);
> +             fdt_res = bootm_load_devicetree(data, fdt, free_mem, gap.end);
>  
>               free(fdt);
>  
> -             if (ret)
> -                     return ret;
> +             if (IS_ERR(fdt_res))
> +                     return PTR_ERR(fdt_res);
>       }
>  
>       if (IS_ENABLED(CONFIG_BOOTM_OPTEE)) {
> @@ -339,6 +346,7 @@ static int __do_bootm_linux(struct image_data *data, 
> unsigned long free_mem,
>  
>  static int do_bootm_linux(struct image_data *data)
>  {
> +     const struct resource *os_res;
>       unsigned long load_address, mem_free;
>       int ret;
>  
> @@ -349,9 +357,9 @@ static int do_bootm_linux(struct image_data *data)
>       if (ret)
>               return ret;
>  
> -     ret = bootm_load_os(data, load_address);
> -     if (ret)
> -             return ret;
> +     os_res = bootm_load_os(data, load_address, mem_free - 1);
> +     if (IS_ERR(os_res))
> +             return PTR_ERR(os_res);
>  
>       return __do_bootm_linux(data, mem_free, 0, NULL);
>  }
> diff --git a/arch/arm/lib64/armlinux.c b/arch/arm/lib64/armlinux.c
> index e40b61a26b07..febffb6c858b 100644
> --- a/arch/arm/lib64/armlinux.c
> +++ b/arch/arm/lib64/armlinux.c
> @@ -43,6 +43,7 @@ static int do_bootm_barebox(struct image_data *data)
>  {
>       void (*fn)(unsigned long x0, unsigned long x1, unsigned long x2,
>                      unsigned long x3);
> +     const struct resource *os_res;
>       resource_size_t start, end;
>       unsigned long barebox;
>       int ret;
> @@ -53,9 +54,9 @@ static int do_bootm_barebox(struct image_data *data)
>  
>       barebox = PAGE_ALIGN(start);
>  
> -     ret = bootm_load_os(data, barebox);
> -     if (ret)
> -             goto out;
> +     os_res = bootm_load_os(data, barebox, end);
> +     if (IS_ERR(os_res))
> +             return PTR_ERR(os_res);
>  
>       printf("Loaded barebox image to 0x%08lx\n", barebox);
>  
> diff --git a/arch/arm/mach-at91/bootm-barebox.c 
> b/arch/arm/mach-at91/bootm-barebox.c
> index 5540b8fad35e..f4894f247d11 100644
> --- a/arch/arm/mach-at91/bootm-barebox.c
> +++ b/arch/arm/mach-at91/bootm-barebox.c
> @@ -13,6 +13,7 @@ EXPORT_SYMBOL(at91_bootsource);
>  
>  static int do_bootm_at91_barebox_image(struct image_data *data)
>  {
> +     const struct resource *os_res;
>       resource_size_t start, end;
>       int ret;
>  
> @@ -20,9 +21,9 @@ static int do_bootm_at91_barebox_image(struct image_data 
> *data)
>       if (ret)
>               return ret;
>  
> -     ret = bootm_load_os(data, start);
> -     if (ret)
> -             return ret;
> +     os_res = bootm_load_os(data, start, end);
> +     if (IS_ERR(os_res))
> +             return PTR_ERR(os_res);
>  
>       if (data->verbose)
>               printf("Loaded barebox image to 0x%08zx\n", start);
> diff --git a/arch/arm/mach-imx/imx-v3-image.c 
> b/arch/arm/mach-imx/imx-v3-image.c
> index e5df5fdb81d9..5cce846f867f 100644
> --- a/arch/arm/mach-imx/imx-v3-image.c
> +++ b/arch/arm/mach-imx/imx-v3-image.c
> @@ -8,6 +8,7 @@
>  
>  static int do_bootm_imx_image_v3(struct image_data *data)
>  {
> +     const struct resource *os_res;
>       void (*bb)(void);
>       resource_size_t start, end;
>       struct flash_header_v3 *hdr;
> @@ -18,9 +19,9 @@ static int do_bootm_imx_image_v3(struct image_data *data)
>       if (ret)
>               return ret;
>  
> -     ret = bootm_load_os(data, start);
> -     if (ret)
> -             return ret;
> +     os_res = bootm_load_os(data, start, end);
> +     if (IS_ERR(os_res))
> +             return PTR_ERR(os_res);
>  
>       hdr = (void *)start;
>       offset = hdr->img[0].offset;
> diff --git a/arch/arm/mach-layerscape/pblimage.c 
> b/arch/arm/mach-layerscape/pblimage.c
> index 5a525f0933d5..31783f18c74d 100644
> --- a/arch/arm/mach-layerscape/pblimage.c
> +++ b/arch/arm/mach-layerscape/pblimage.c
> @@ -15,6 +15,7 @@ static int do_bootm_layerscape_pblimage(struct image_data 
> *data)
>  {
>       void (*barebox)(unsigned long x0, unsigned long x1, unsigned long x2,
>                      unsigned long x3);
> +     const struct resource *os_res;
>       resource_size_t start, end;
>       int ret;
>  
> @@ -22,9 +23,9 @@ static int do_bootm_layerscape_pblimage(struct image_data 
> *data)
>       if (ret)
>               return ret;
>  
> -     ret = bootm_load_os(data, start);
> -     if (ret)
> -             return ret;
> +     os_res = bootm_load_os(data, start, end);
> +     if (IS_ERR(os_res))
> +             return PTR_ERR(os_res);
>  
>       barebox = (void*)start + BAREBOX_STAGE2_OFFSET;
>  
> diff --git a/arch/arm/mach-rockchip/bootm.c b/arch/arm/mach-rockchip/bootm.c
> index ff3d9a2db3a0..2e068b05cefd 100644
> --- a/arch/arm/mach-rockchip/bootm.c
> +++ b/arch/arm/mach-rockchip/bootm.c
> @@ -40,6 +40,7 @@ static int do_bootm_rkns_barebox_image(struct image_data 
> *data)
>  {
>       void (*barebox)(unsigned long x0, unsigned long x1, unsigned long x2,
>                       unsigned long x3);
> +     const struct resource *os_res;
>       resource_size_t start, end;
>       struct newidb *idb;
>       int ret, i, n_files;
> @@ -50,14 +51,14 @@ static int do_bootm_rkns_barebox_image(struct image_data 
> *data)
>       if (ret)
>               return ret;
>  
> -     ret = bootm_load_os(data, start);
> -     if (ret)
> -             return ret;
> +     os_res = bootm_load_os(data, start, end);
> +     if (IS_ERR(os_res))
> +             return PTR_ERR(os_res);
>  
> -     idb = (void *)data->os_res->start;
> -     buf = (void *)data->os_res->start;
> +     idb = (void *)os_res->start;
> +     buf = (void *)os_res->start;
>  
> -     image_size = resource_size(data->os_res);
> +     image_size = resource_size(os_res);
>  
>       if (image_size < SECTOR_SIZE)
>               return -EINVAL;
> diff --git a/arch/arm/mach-zynq/bootm-zynqimg.c 
> b/arch/arm/mach-zynq/bootm-zynqimg.c
> index 77ed6880e4b6..ebd2d621520b 100644
> --- a/arch/arm/mach-zynq/bootm-zynqimg.c
> +++ b/arch/arm/mach-zynq/bootm-zynqimg.c
> @@ -8,6 +8,7 @@
>  static int do_bootm_zynqimage(struct image_data *data)
>  {
>       resource_size_t start, end;
> +     const struct resource *os_res;
>       void (*barebox)(void);
>       u32 *header;
>       int ret;
> @@ -16,9 +17,9 @@ static int do_bootm_zynqimage(struct image_data *data)
>       if (ret)
>               return ret;
>  
> -     ret = bootm_load_os(data, start);
> -     if (ret)
> -             return ret;
> +     os_res = bootm_load_os(data, start, end);
> +     if (IS_ERR(os_res))
> +             return PTR_ERR(os_res);
>  
>       header = (u32*)start;
>       barebox = (void*)start + header[12];
> diff --git a/arch/kvx/lib/bootm.c b/arch/kvx/lib/bootm.c
> index 6eba4054e500..c464b5006fa2 100644
> --- a/arch/kvx/lib/bootm.c
> +++ b/arch/kvx/lib/bootm.c
> @@ -13,6 +13,7 @@
>  #include <bootm.h>
>  #include <binfmt.h>
>  #include <common.h>
> +#include <memory.h>
>  #include <libfile.h>
>  #include <linux/kernel.h>
>  
> @@ -54,7 +55,8 @@ static int do_boot_entry(struct image_data *data, 
> boot_func_entry entry,
>  
>  static int do_boot_elf(struct image_data *data, struct elf_image *elf)
>  {
> -     const struct resource *initrd_res;
> +     const struct resource *sdram, *initrd_res, *fdt_res;
> +     struct resource gap;
>       int ret;
>       void *fdt;
>       boot_func_entry entry;
> @@ -71,7 +73,11 @@ static int do_boot_elf(struct image_data *data, struct 
> elf_image *elf)
>       else
>               initrd_address = load_addr;
>  
> -     initrd_res = bootm_load_initrd(data, initrd_address);
> +     sdram = memory_bank_lookup_region(initrd_address, &gap);
> +     if (sdram != &gap)
> +             return sdram ? -EBUSY : -EINVAL;
> +
> +     initrd_res = bootm_load_initrd(data, initrd_address, gap.end);
>       if (IS_ERR(initrd_res)) {
>               printf("Failed to load initrd\n");
>               return PTR_ERR(initrd_res);
> @@ -93,9 +99,10 @@ static int do_boot_elf(struct image_data *data, struct 
> elf_image *elf)
>  
>       printf("Loading device tree at %lx\n", load_addr);
>       /* load device tree after the initrd if any */
> -     ret = bootm_load_devicetree(data, fdt, load_addr);
> -     if (ret) {
> -             printf("Failed to load device tree: %d\n", ret);
> +     fdt_res = bootm_load_devicetree(data, fdt, load_addr, gap.end);
> +     if (IS_ERR(fdt_res)) {
> +             printf("Failed to load device tree: %pe\n", fdt_res);
> +             ret = PTR_ERR(fdt_res);
>               goto err_free_fdt;
>       }
>  
> diff --git a/arch/powerpc/lib/ppclinux.c b/arch/powerpc/lib/ppclinux.c
> index 564086482e5f..eda2539e6125 100644
> --- a/arch/powerpc/lib/ppclinux.c
> +++ b/arch/powerpc/lib/ppclinux.c
> @@ -7,6 +7,7 @@
>  #include <image.h>
>  #include <init.h>
>  #include <malloc.h>
> +#include <memory.h>
>  #include <environment.h>
>  #include <asm/bitops.h>
>  #include <asm/processor.h>
> @@ -53,12 +54,18 @@ static int do_bootm_linux(struct image_data *data)
>  {
>       void    (*kernel)(void *, void *, unsigned long,
>                       unsigned long, unsigned long);
> +     const struct resource *os_res, *sdram;
> +     struct resource gap;
>       int ret;
>       struct fdt_header *fdt;
>  
> -     ret = bootm_load_os(data, data->os_address);
> -     if (ret)
> -             return ret;
> +     sdram = memory_bank_lookup_region(data->os_address, &gap);
> +     if (sdram != &gap)
> +             return sdram ? -EBUSY : -EINVAL;
> +
> +     os_res = bootm_load_os(data, data->os_address, gap.end);
> +     if (IS_ERR(os_res))
> +             return PTR_ERR(os_res);
>  
>       fdt = of_get_fixed_tree_for_boot(data->of_root_node);
>       if (!fdt) {
> diff --git a/common/booti.c b/common/booti.c
> index 6a87b84c0308..67f31b793517 100644
> --- a/common/booti.c
> +++ b/common/booti.c
> @@ -10,13 +10,14 @@
>  #include <linux/sizes.h>
>  
>  static unsigned long get_kernel_address(unsigned long os_address,
> -                                     unsigned long text_offset)
> +                                     unsigned long text_offset,
> +                                     resource_size_t *end)
>  {
> -     resource_size_t start, end;
> +     resource_size_t start;
>       int ret;
>  
>       if (!UIMAGE_IS_ADDRESS_VALID(os_address)) {
> -             ret = memory_bank_first_find_space(&start, &end);
> +             ret = memory_bank_first_find_space(&start, end);
>               if (ret)
>                       return UIMAGE_INVALID_ADDRESS;
>  
> @@ -33,9 +34,10 @@ void *booti_load_image(struct image_data *data, 
> phys_addr_t *oftree)
>  {
>       const void *kernel_header =
>                       data->os_fit ? data->fit_kernel : data->os_header;
> +     const struct resource *os_res;
>       unsigned long text_offset, image_size, kernel;
>       unsigned long image_end;
> -     int ret;
> +     resource_size_t end;
>       void *fdt;
>  
>       print_hex_dump_bytes("header ", DUMP_PREFIX_OFFSET, kernel_header, 80);
> @@ -49,24 +51,26 @@ void *booti_load_image(struct image_data *data, 
> phys_addr_t *oftree)
>       text_offset = le64_to_cpup(kernel_header + 8);
>       image_size = le64_to_cpup(kernel_header + 16);
>  
> -     kernel = get_kernel_address(data->os_address, text_offset);
> +     kernel = get_kernel_address(data->os_address, text_offset, &end);
>  
>       pr_debug("Kernel to be loaded to %lx+%lx\n", kernel, image_size);
>  
>       if (kernel == UIMAGE_INVALID_ADDRESS)
>               return ERR_PTR(-ENOENT);
> +     if (kernel + image_size - 1 > end)
> +             return ERR_PTR(-ENOSPC);
>  
> -     ret = bootm_load_os(data, kernel);
> -     if (ret)
> -             return ERR_PTR(ret);
> +     os_res = bootm_load_os(data, kernel, end);
> +     if (IS_ERR(os_res))
> +             return ERR_CAST(os_res);
>  
>       image_end = PAGE_ALIGN(kernel + image_size);
>  
>       if (oftree) {
>               unsigned long devicetree;
> -             const struct resource *initrd_res;
> +             const struct resource *initrd_res, *dt_res;
>  
> -             initrd_res = bootm_load_initrd(data, image_end);
> +             initrd_res = bootm_load_initrd(data, image_end, end);
>               if (IS_ERR(initrd_res)) {
>                       return ERR_CAST(initrd_res);
>               } else if (initrd_res) {
> @@ -85,11 +89,11 @@ void *booti_load_image(struct image_data *data, 
> phys_addr_t *oftree)
>                       goto out;
>               }
>  
> -             ret = bootm_load_devicetree(data, fdt, devicetree);
> +             dt_res = bootm_load_devicetree(data, fdt, devicetree, end);
>               free(fdt);
>  
> -             if (ret)
> -                     return ERR_PTR(ret);
> +             if (IS_ERR(dt_res))
> +                     return ERR_CAST(dt_res);
>  
>               *oftree = devicetree;
>       }
> diff --git a/common/bootm-mock.c b/common/bootm-mock.c
> new file mode 100644
> index 000000000000..e69de29bb2d1
> diff --git a/common/bootm.c b/common/bootm.c
> index 35305f25375a..fcf7868a5d75 100644
> --- a/common/bootm.c
> +++ b/common/bootm.c
> @@ -228,57 +228,69 @@ static bool bootm_get_override(char **oldpath, const 
> char *newpath)
>       return true;
>  }
>  
> -/*
> +/**
>   * bootm_load_os() - load OS to RAM
> - *
>   * @data:            image data context
>   * @load_address:    The address where the OS should be loaded to
> + * @end_address:     The end address of the load buffer (inclusive)
>   *
>   * This loads the OS to a RAM location. load_address must be a valid
> - * address. If the image_data doesn't have a OS specified it's considered
> + * address. If the image_data doesn't have an OS specified it's considered
>   * an error.
>   *
> - * Return: 0 on success, negative error code otherwise
> + * Return: the OS resource on success, or an error pointer on failure
>   */
> -int bootm_load_os(struct image_data *data, unsigned long load_address)
> +const struct resource *bootm_load_os(struct image_data *data,
> +             ulong load_address, ulong end_address)
>  {
> +     int err;
> +
>       if (data->os_res)
> -             return 0;
> +             return data->os_res;
>  
>       if (load_address == UIMAGE_INVALID_ADDRESS)
> -             return -EINVAL;
> +             return ERR_PTR(-EINVAL);
> +     if (end_address <= load_address)
> +             return ERR_PTR(-EINVAL);
>  
> -     if (data->os_fit)
> -             return bootm_load_fit_os(data, load_address);
> +     if (data->os_fit) {
> +             err = bootm_load_fit_os(data, load_address);
> +     } else if (image_is_uimage(data)) {
> +             err = bootm_load_uimage_os(data, load_address);
> +     } else if (data->os_file) {
> +             data->os_res = file_to_sdram(data->os_file, load_address, 
> MEMTYPE_LOADER_CODE);
> +             err = data->os_res ? 0 : -EBUSY;
> +     } else {
> +             err = -EINVAL;
> +     }
>  
> -     if (image_is_uimage(data))
> -             return bootm_load_uimage_os(data, load_address);
> +     if (err)
> +             return ERR_PTR(err);
>  
> -     if (!data->os_file)
> -             return -EINVAL;
> +     /* FIXME: We need some more rework to be able to detect this overflow
> +      * before it happens, but for now, let's at least detect it.
> +      */
> +     if (WARN_ON(data->os_res->end > end_address))
> +             return ERR_PTR(-ENOSPC);
>  
> -     data->os_res = file_to_sdram(data->os_file, load_address, 
> MEMTYPE_LOADER_CODE);
> -     if (!data->os_res)
> -             return -ENOMEM;
> -
> -     return 0;
> +     return data->os_res;
>  }
>  
> -/*
> +/**
>   * bootm_load_initrd() - load initrd to RAM
> - *
>   * @data:            image data context
>   * @load_address:    The address where the initrd should be loaded to
> + * @end_address:     The end address of the load buffer (inclusive)
>   *
>   * This loads the initrd to a RAM location. load_address must be a valid
> - * address. If the image_data doesn't have a initrd specified this function
> - * still returns successful as an initrd is optional. Check data->initrd_res
> - * to see if an initrd has been loaded.
> + * address. If the image_data doesn't have an initrd specified this function
> + * still returns successful as an initrd is optional.
>   *
> - * Return: 0 on success, negative error code otherwise
> + * Return: the initrd resource if one was loaded, NULL if no initrd was
> + *         specified, or an error pointer on failure
>   */
>  const struct resource *
> -bootm_load_initrd(struct image_data *data, unsigned long load_address)
> +bootm_load_initrd(struct image_data *data, ulong load_address, ulong 
> end_address)
>  {
>       struct resource *res = NULL;
>       const char *initrd, *initrd_part = NULL;
> @@ -293,6 +305,8 @@ bootm_load_initrd(struct image_data *data, unsigned long 
> load_address)
>        */
>       if (WARN_ON(data->initrd_res))
>               return data->initrd_res;
> +     if (end_address <= load_address)
> +             return ERR_PTR(-EINVAL);
>  
>       bootm_get_override(&data->initrd_file, bootm_overrides.initrd_file);
>  
> @@ -313,7 +327,7 @@ bootm_load_initrd(struct image_data *data, unsigned long 
> load_address)
>  
>       } else if (initrd) {
>               res = file_to_sdram(initrd, load_address, MEMTYPE_LOADER_DATA)
> -                     ?: ERR_PTR(-ENOMEM);
> +                     ?: ERR_PTR(-EBUSY);
>  
>       } else if (data->os_fit) {
>               res = bootm_load_fit_initrd(data, load_address);
> @@ -324,6 +338,12 @@ bootm_load_initrd(struct image_data *data, unsigned long 
> load_address)
>       if (IS_ERR_OR_NULL(res))
>               return res;
>  
> +     /* FIXME: We need some more rework to be able to detect this overflow
> +      * before it happens, but for now, let's at least detect it.
> +      */
> +     if (WARN_ON(data->initrd_res->end > end_address))
> +             return ERR_PTR(-ENOSPC);
> +
>       pr_info("Loaded initrd from %s %s%s%s to %pa-%pa\n",
>               file_type_to_string(type), initrd,
>               initrd_part ? "@" : "", initrd_part ?: "",
> @@ -425,33 +445,38 @@ void *bootm_get_devicetree(struct image_data *data)
>       return oftree;
>  }
>  
> -/*
> - * bootm_load_devicetree() - load devicetree
> - *
> +/**
> + * bootm_load_devicetree() - load devicetree into specified memory range
>   * @data:            image data context
>   * @fdt:             The flat device tree to load
>   * @load_address:    The address where the devicetree should be loaded to
> + * @end_address:     The end address of the load buffer (inclusive)
>   *
>   * This loads the devicetree to a RAM location. load_address must be a valid
>   * address which is requested with request_sdram_region. The associated 
> region
>   * is released automatically in the bootm error path.
>   *
> - * Return: 0 on success, negative error code otherwise
> + * Return: the devicetree resource on success, or an error pointer on failure
>   */
> -int bootm_load_devicetree(struct image_data *data, void *fdt,
> -                         unsigned long load_address)
> +const struct resource *
> +bootm_load_devicetree(struct image_data *data, void *fdt,
> +                   ulong load_address, ulong end_address)
>  {
>       int fdt_size;
>  
>       if (!IS_ENABLED(CONFIG_OFTREE))
> -             return -ENOSYS;
> +             return ERR_PTR(-ENOSYS);
> +     if (end_address <= load_address)
> +             return ERR_PTR(-EINVAL);
>  
>       fdt_size = be32_to_cpu(((struct fdt_header *)fdt)->totalsize);
> +     if (load_address + fdt_size - 1 > end_address)
> +             return ERR_PTR(-ENOSPC);
>  
>       data->oftree_res = request_sdram_region("oftree", load_address,
>                       fdt_size, MEMTYPE_LOADER_DATA, MEMATTRS_RW);
>       if (!data->oftree_res)
> -             return -ENOMEM;
> +             return ERR_PTR(-EBUSY);
>  
>       memcpy((void *)data->oftree_res->start, fdt, fdt_size);
>  
> @@ -461,7 +486,7 @@ int bootm_load_devicetree(struct image_data *data, void 
> *fdt,
>               fdt_print_reserve_map(fdt);
>       }
>  
> -     return 0;
> +     return data->oftree_res;
>  }
>  
>  int bootm_get_os_size(struct image_data *data)
> diff --git a/efi/loader/bootm.c b/efi/loader/bootm.c
> index da664847def8..b40263ce6eb3 100644
> --- a/efi/loader/bootm.c
> +++ b/efi/loader/bootm.c
> @@ -171,7 +171,8 @@ static efi_status_t efi_install_fdt(void *fdt)
>  static efi_status_t efi_install_initrd(struct image_data *data,
>                                      struct resource *source)
>  {
> -     const struct resource *initrd_res;
> +     const struct resource *initrd_res, *sdram;
> +     struct resource gap;
>       unsigned long initrd_start;
>  
>       if (!IS_ENABLED(CONFIG_BOOTM_INITRD))
> @@ -182,7 +183,11 @@ static efi_status_t efi_install_initrd(struct image_data 
> *data,
>       else
>               initrd_start = EFI_PAGE_ALIGN(source->end + 1);
>  
> -     initrd_res = bootm_load_initrd(data, initrd_start);
> +     sdram = memory_bank_lookup_region(data->os_address, &gap);
> +     if (sdram != &gap)
> +             return sdram ? EFI_OUT_OF_RESOURCES : EFI_INVALID_PARAMETER;
> +
> +     initrd_res = bootm_load_initrd(data, initrd_start, gap.end);
>       if (IS_ERR(initrd_res))
>               return PTR_ERR(initrd_res);
>       if (initrd_res)
> diff --git a/include/bootm.h b/include/bootm.h
> index e56a999f0b11..1c3bb8899b38 100644
> --- a/include/bootm.h
> +++ b/include/bootm.h
> @@ -150,14 +150,19 @@ static inline int bootm_verbose(struct image_data *data)
>  void bootm_data_init_defaults(struct bootm_data *data);
>  void bootm_data_restore_defaults(const struct bootm_data *data);
>  
> -int bootm_load_os(struct image_data *data, unsigned long load_address);
> +const struct resource *
> +bootm_load_os(struct image_data *data,
> +           ulong load_address, ulong end_address);
>  
>  const struct resource *
> -bootm_load_initrd(struct image_data *data, unsigned long load_address);
> +bootm_load_initrd(struct image_data *data,
> +               ulong load_address, ulong end_address);
>  
>  void *bootm_get_devicetree(struct image_data *data);
> -int bootm_load_devicetree(struct image_data *data, void *fdt,
> -                       unsigned long load_address);
> +
> +const struct resource *
> +bootm_load_devicetree(struct image_data *data, void *fdt,
> +                   ulong load_address, ulong end_address);
>  int bootm_get_os_size(struct image_data *data);
>  
>  enum bootm_verify bootm_get_verify_mode(void);

-- 
Pengutronix e.K.                  |                             |
Steuerwalder Str. 21              | http://www.pengutronix.de/  |
31137 Hildesheim, Germany         | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686  | Fax:   +49-5121-206917-5555 |


Reply via email to