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 |