Skip to content

Commit

Permalink
hw/riscv: Add the checking if DTB overlaps to kernel or initrd
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Alistair Francis <[email protected]>
Reviewed-by: Daniel Henrique Barboza <[email protected]>
Message-ID: <[email protected]>
  • Loading branch information
cwshu authored and alistair23 committed Dec 16, 2024
1 parent a4fa332 commit 9422ac2
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
25 changes: 24 additions & 1 deletion hw/riscv/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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.
Expand All @@ -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;
}

/*
Expand Down
3 changes: 3 additions & 0 deletions include/hw/riscv/boot.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit 9422ac2

Please sign in to comment.