diff --git a/arch/wasm/configs/defconfig b/arch/wasm/configs/defconfig index 94a10d7b58941c..e25f0847e602f1 100644 --- a/arch/wasm/configs/defconfig +++ b/arch/wasm/configs/defconfig @@ -66,7 +66,12 @@ CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y # CONFIG_DNOTIFY is not set # CONFIG_INOTIFY_USER is not set +CONFIG_OVERLAY_FS=y CONFIG_SQUASHFS=y +CONFIG_EROFS_FS=y +# CONFIG_EROFS_FS_XATTR is not set +# CONFIG_EROFS_FS_BACKED_BY_FILE is not set +# CONFIG_EROFS_FS_ZIP is not set # CONFIG_DEBUG_MISC is not set # CONFIG_RCU_TRACE is not set # CONFIG_RUNTIME_TESTING_MENU is not set diff --git a/arch/wasm/include/asm/wasm_imports.h b/arch/wasm/include/asm/wasm_imports.h index b5083bf7a2fb05..478a78561e58bf 100644 --- a/arch/wasm/include/asm/wasm_imports.h +++ b/arch/wasm/include/asm/wasm_imports.h @@ -7,7 +7,7 @@ __attribute__((import_module(#ns), import_name(#name))) \ wasm_##ns##_##name -void wasm_import(boot, get_devicetree)(char *buf, size_t size); +size_t wasm_import(boot, get_devicetree)(char *buf, size_t size); int wasm_import(boot, get_initramfs)(char *buf, size_t size); void wasm_import(kernel, breakpoint)(void); diff --git a/arch/wasm/kernel/setup.c b/arch/wasm/kernel/setup.c index 17fc815f14e96b..73095089f5438c 100644 --- a/arch/wasm/kernel/setup.c +++ b/arch/wasm/kernel/setup.c @@ -26,10 +26,41 @@ static void do_start_kernel(void *unused) start_kernel(); } +static void *__init load_devicetree(size_t *size) +{ + phys_addr_t bootstrap_size; + void *devicetree; + size_t copied; + + *size = wasm_boot_get_devicetree(NULL, 0); + BUG_ON(!*size || *size > INT_MAX); + + /* + * memblock has no memory ranges until it reads /memory from the FDT. + * Temporarily describe the materialized linear memory plus enough space + * for this exact blob, then remove that description before the FDT scan + * installs the authoritative range. + */ + bootstrap_size = PFN_PHYS(__builtin_wasm_memory_size(0)); + BUG_ON(bootstrap_size > PHYS_ADDR_MAX - PAGE_SIZE); + BUG_ON(*size > PHYS_ADDR_MAX - bootstrap_size - PAGE_SIZE); + bootstrap_size = PAGE_ALIGN(bootstrap_size + *size); + BUG_ON(memblock_add(0, bootstrap_size)); + + devicetree = memblock_alloc_or_panic( + *size, roundup_pow_of_two(FDT_V17_SIZE)); + copied = wasm_boot_get_devicetree(devicetree, *size); + BUG_ON(copied != *size || fdt_check_header(devicetree) || + fdt_totalsize(devicetree) > *size); + BUG_ON(memblock_remove(0, bootstrap_size)); + return devicetree; +} + __attribute__((export_name("boot"))) void __init _start(void) { - static char devicetree[2048]; static char initramfs[512]; + void *devicetree; + size_t devicetree_size; int node; memblock_set_bottom_up(true); @@ -41,8 +72,9 @@ __attribute__((export_name("boot"))) void __init _start(void) __initramfs_start = initramfs; __initramfs_size = wasm_boot_get_initramfs(initramfs, ARRAY_SIZE(initramfs)); - wasm_boot_get_devicetree(devicetree, ARRAY_SIZE(devicetree)); + devicetree = load_devicetree(&devicetree_size); BUG_ON(!early_init_dt_scan(devicetree, __pa(devicetree))); + BUG_ON(!memblock_is_region_memory(__pa(devicetree), devicetree_size)); early_init_fdt_scan_reserved_mem(); node = fdt_path_offset(devicetree, "/chosen/sections"); diff --git a/tools/wasm/src/index.ts b/tools/wasm/src/index.ts index 1158b30c795e95..6f2c41e985f0a4 100644 --- a/tools/wasm/src/index.ts +++ b/tools/wasm/src/index.ts @@ -437,6 +437,8 @@ export async function spawnMachine( get_devicetree: (buf, size) => { const address = buf >>> 0; const capacity = size >>> 0; + if (capacity === 0) return generated_devicetree.byteLength; + assert( capacity >= generated_devicetree.byteLength, "Device tree truncated", @@ -445,6 +447,7 @@ export async function spawnMachine( generated_devicetree, address, ); + return generated_devicetree.byteLength; }, get_initramfs: (buf, size) => { const address = buf >>> 0; diff --git a/tools/wasm/src/wasm.ts b/tools/wasm/src/wasm.ts index 9b4b64502a8fe2..d38302385bd531 100644 --- a/tools/wasm/src/wasm.ts +++ b/tools/wasm/src/wasm.ts @@ -129,7 +129,7 @@ export type MachineTerminationReason = export interface Imports { env: { memory: WebAssembly.Memory }; boot: { - get_devicetree(buf: number, size: number): void; + get_devicetree(buf: number, size: number): number; get_initramfs(buf: number, size: number): number; }; kernel: {