From a7e6799365b2eab2f2b44dda732fea66edbf34e4 Mon Sep 17 00:00:00 2001 From: ChinYikMing Date: Tue, 18 Mar 2025 22:58:28 +0800 Subject: [PATCH] Dynamically configure VirtIO node of Device Tree PR #584 initializes the vblk only when the vblk CLI option is provided. This leads to a segmentation fault when vblk is not specified, as the capacity of the vblk device is left uninitialized (not set to 0). Previously, the code would always initialize vblk but set its capacity to 0, preventing the VirtIO block driver from interacting with it and avoiding the segmentation fault. However, this original approach was functionally redundant. A better solution is to dynamically load or unload the VirtIO node in the SoC node of the Device Tree based on configuration. To support future others VirtIO devices, the interface of load_dtb() has been refined, it now can parse all options stored in the attribute. --- src/riscv.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/riscv.c b/src/riscv.c index f1f47475..a5f344ec 100644 --- a/src/riscv.c +++ b/src/riscv.c @@ -285,9 +285,11 @@ static char *realloc_property(char *fdt, return fdt; } -static void load_dtb(char **ram_loc, char *bootargs) +static void load_dtb(char **ram_loc, vm_attr_t *attr) { #include "minimal_dtb.h" + char *bootargs = attr->data.system.bootargs; + char *vblk = attr->data.system.vblk_device; char *blob = *ram_loc; char *buf; size_t len; @@ -314,6 +316,18 @@ static void load_dtb(char **ram_loc, char *bootargs) assert(!err); } + /* remove the vblk node from soc if it is not specified */ + if (!vblk) { + int subnode; + node = fdt_path_offset(blob, "/soc@F0000000"); + assert(node >= 0); + + subnode = fdt_subnode_offset(blob, node, "virtio@4200000"); + assert(subnode >= 0); + + assert(fdt_del_node(blob, subnode) == 0); + } + totalsize = fdt_totalsize(blob); *ram_loc += totalsize; return; @@ -499,7 +513,7 @@ riscv_t *rv_create(riscv_user_t rv_attr) uint32_t dtb_addr = attr->mem->mem_size - DTB_SIZE; ram_loc = ((char *) attr->mem->mem_base) + dtb_addr; - load_dtb(&ram_loc, attr->data.system.bootargs); + load_dtb(&ram_loc, attr); rv_log_info("DTB loaded"); /* * Load optional initrd image at last 8 MiB before the dtb region to