qemu-devel
[Top][All Lists]
Advanced

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

Re: [PATCH v4 3/3] hw/riscv: Add the checking if DTB overlaps to kernel


From: Alistair Francis
Subject: Re: [PATCH v4 3/3] hw/riscv: Add the checking if DTB overlaps to kernel or initrd
Date: Tue, 3 Dec 2024 15:43:11 +0900

On Thu, Nov 21, 2024 at 12:42 AM Jim Shu <jim.shu@sifive.com> wrote:
>
> DTB is placed to the end of memory, so we will check if the start
> address of DTB overlaps to the address of kernel/initrd.
>
> Signed-off-by: Jim Shu <jim.shu@sifive.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  hw/riscv/boot.c         | 25 ++++++++++++++++++++++++-
>  include/hw/riscv/boot.h |  3 +++
>  2 files changed, 27 insertions(+), 1 deletion(-)
>
> diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
> index 81d27f935e..bc8074fec8 100644
> --- a/hw/riscv/boot.c
> +++ b/hw/riscv/boot.c
> @@ -70,6 +70,7 @@ char *riscv_plic_hart_config_string(int hart_count)
>  void riscv_boot_info_init(RISCVBootInfo *info, RISCVHartArrayState *harts)
>  {
>      info->kernel_size = 0;
> +    info->initrd_size = 0;
>      info->is_32bit = riscv_is_32bit(harts);
>  }
>
> @@ -213,6 +214,9 @@ static void riscv_load_initrd(MachineState *machine, 
> RISCVBootInfo *info)
>          }
>      }
>
> +    info->initrd_start = start;
> +    info->initrd_size = size;
> +
>      /* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
>      if (fdt) {
>          end = start + size;
> @@ -309,6 +313,7 @@ uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr 
> dram_size,
>      int ret = fdt_pack(ms->fdt);
>      hwaddr dram_end, temp;
>      int fdtsize;
> +    uint64_t dtb_start, dtb_start_limit;
>
>      /* Should only fail if we've built a corrupted tree */
>      g_assert(ret == 0);
> @@ -319,6 +324,17 @@ uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr 
> dram_size,
>          exit(1);
>      }
>
> +    if (info->initrd_size) {
> +        /* If initrd is successfully loaded, place DTB after it. */
> +        dtb_start_limit = info->initrd_start + info->initrd_size;
> +    } else if (info->kernel_size) {
> +        /* If only kernel is successfully loaded, place DTB after it. */
> +        dtb_start_limit = info->image_high_addr;
> +    } else {
> +        /* Otherwise, do not check DTB overlapping */
> +        dtb_start_limit = 0;
> +    }
> +
>      /*
>       * A dram_size == 0, usually from a MemMapEntry[].size element,
>       * means that the DRAM block goes all the way to ms->ram_size.
> @@ -338,7 +354,14 @@ uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr 
> dram_size,
>          temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : 
> dram_end;
>      }
>
> -    return QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB);
> +    dtb_start = QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB);
> +
> +    if (dtb_start_limit && (dtb_start < dtb_start_limit)) {
> +        error_report("No enough memory to place DTB after kernel/initrd");
> +        exit(1);
> +    }
> +
> +    return dtb_start;
>  }
>
>  /*
> diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
> index 06b51ed086..7d59b2e6c6 100644
> --- a/include/hw/riscv/boot.h
> +++ b/include/hw/riscv/boot.h
> @@ -32,6 +32,9 @@ typedef struct RISCVBootInfo {
>      hwaddr image_low_addr;
>      hwaddr image_high_addr;
>
> +    hwaddr initrd_start;
> +    ssize_t initrd_size;
> +
>      bool is_32bit;
>  } RISCVBootInfo;
>
> --
> 2.17.1
>
>



reply via email to

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