mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-25 11:01:52 -06:00
hw/riscv: Add the checking if DTB overlaps to kernel or initrd
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> Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Message-ID: <20241120153935.24706-4-jim.shu@sifive.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
d3592955af
commit
1a65064c1f
2 changed files with 27 additions and 1 deletions
|
@ -70,6 +70,7 @@ char *riscv_plic_hart_config_string(int hart_count)
|
||||||
void riscv_boot_info_init(RISCVBootInfo *info, RISCVHartArrayState *harts)
|
void riscv_boot_info_init(RISCVBootInfo *info, RISCVHartArrayState *harts)
|
||||||
{
|
{
|
||||||
info->kernel_size = 0;
|
info->kernel_size = 0;
|
||||||
|
info->initrd_size = 0;
|
||||||
info->is_32bit = riscv_is_32bit(harts);
|
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. */
|
/* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
|
||||||
if (fdt) {
|
if (fdt) {
|
||||||
end = start + size;
|
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);
|
int ret = fdt_pack(ms->fdt);
|
||||||
hwaddr dram_end, temp;
|
hwaddr dram_end, temp;
|
||||||
int fdtsize;
|
int fdtsize;
|
||||||
|
uint64_t dtb_start, dtb_start_limit;
|
||||||
|
|
||||||
/* Should only fail if we've built a corrupted tree */
|
/* Should only fail if we've built a corrupted tree */
|
||||||
g_assert(ret == 0);
|
g_assert(ret == 0);
|
||||||
|
@ -319,6 +324,17 @@ uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr dram_size,
|
||||||
exit(1);
|
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,
|
* A dram_size == 0, usually from a MemMapEntry[].size element,
|
||||||
* means that the DRAM block goes all the way to ms->ram_size.
|
* 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;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -32,6 +32,9 @@ typedef struct RISCVBootInfo {
|
||||||
hwaddr image_low_addr;
|
hwaddr image_low_addr;
|
||||||
hwaddr image_high_addr;
|
hwaddr image_high_addr;
|
||||||
|
|
||||||
|
hwaddr initrd_start;
|
||||||
|
ssize_t initrd_size;
|
||||||
|
|
||||||
bool is_32bit;
|
bool is_32bit;
|
||||||
} RISCVBootInfo;
|
} RISCVBootInfo;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue