V3: - Fixed the argument type of cpreg_key_compare to use gpointer instead of void*. - Fixed the multiline comment to ensure it starts with "/*" on a separate line. - Fixed the commit message to remove a confusing link in the util/cacheflush.c patch. - Resolved patch conflicts against the latest upstream master branch in the gitlab CI configuration patch. - The patches 01, 02, 03, 06, and 07 are included in this series sololy to ensure successful builds. They have already been picked up by the pull requests, so please ignore them.
V2: - Updated the commit message to explicitly explain that function pointer casts are performed internally by GLib. - Fixed typo in the comment in include/glib-compat.h: s/insted/instead/ - In util/cacheflush.c patch, added an explanation for the change to both the code comment and the commit message. - Split the block/file-posix.c hunk that adds "#include <sys/ioctl.h>" into a separate commit and revised the commit message to clarify the purpose of the patch. - Removed the Emscripten-specific stub of copy_file_range in stubs/emscripten.c. Instead, updated the type of the existing copy_file_range stub in block/file-posix.c to match the declaration in the Emscripten headers and avoid a compilation error. - Moved the change that was incorrectly applied to os-posix.h into os-wasm.h - Split MAINTAINERS file change to each commit that adds new files. - Unified two consecutive #ifndef macros into a single condition in qemu-options.hx. - Instead of porting mmap-alloc.c to Emscripten, this version excludes the file entirely. The rationale is described in the commit message. - In meson.build, added a check to ensure TCI is enabled for the wasm build. - Split the Dockerfile addition from the previous 18th patch into a separate commit. V1: This patch series is split from the original "Enable QEMU to run on browsers" series, focusing solely on the essential code changes needed to compile QEMU TCI with Emscripten. It also inclues fixes based on feedback received in the original series, thank you for the comments. # Supported features in this series This patch series enables TCI interpreter mode with 32bit guest support. While the original series included the non-TCI backend and 9pfs patches, those components are not included here. They will be reintroduced in follow-up series after the foundational patches have been merged. # Emscripten-Based Coroutine Backend Emscripten does not support couroutine methods currently used by QEMU but provides a coroutine implementation called "fiber". This patch series introduces a coroutine backend using fiber. However, fiber does not support submitting coroutines to other threads. As a result, this patch series doesn't support components like hw/9pfs, which rely on that behavior. # Overview of build process This section provides an overview of the build process for compiling QEMU using Emscripten. Full instructions are available in the sample repository[1]. To compile QEMU with Emscripten, the following dependencies are required. The emsdk-wasm32-cross.docker environment includes all necessary components and can be used as the build environment: - Emscripten SDK (emsdk) v3.1.50 - Libraries cross-compiled with Emscripten (refer to emsdk-wasm32-cross.docker for build steps) - GLib v2.84.0 - zlib v1.3.1 - libffi v3.4.7 - Pixman v0.44.2 QEMU can be compiled using Emscripten's emconfigure and emmake, which automatically set environment variables such as CC for targeting Emscripten. emconfigure configure --static --disable-tools \ --target-list=arm-softmmu --enable-tcg-interpreter emmake make -j$(nproc) This process generates the following files: - qemu-system-arm.js - qemu-system-arm.wasm - qemu-system-arm.worker.js Guest images can be packaged using Emscripten's file_packager.py tool. For example, if the images are stored in a directory named "pack", the following command packages them, allowing QEMU to access them through Emscripten's virtual filesystem: /path/to/file_packager.py qemu-system-arm.data --preload pack > load.js This process generates the following files: - qemu-system-arm.data - load.js Emscripten allows passing arguments to the QEMU command via the Module object in JavaScript: Module['arguments'] = [ '-nographic', '-m', '512M', '-machine', 'virt', '-L', 'pack/', '-global', 'virtio-mmio.force-legacy=false', '-device', 'virtio-blk-device,drive=d0', '-drive', 'file=pack/rootfs.bin,if=none,format=raw,id=d0', '-kernel', 'pack/kernel.img', '-append', 'console=ttyAMA0 root=/dev/vda loglevel=7', ]; The sample repository[1] provides a complete setup, including an HTML file that implements a terminal UI. [1] https://github.com/ktock/qemu-wasm-sample/tree/tcidev # Additional references - Original patch series "Enable QEMU to run on browsers": https://patchew.org/QEMU/cover.1744032780.git.ktokunaga.m...@gmail.com/ - A talk at FOSDEM 2025: https://fosdem.org/2025/schedule/event/fosdem-2025-6290-running-qemu-inside-browser/ Kohei Tokunaga (20): hw/core/loader.c: Fix type conflict of GLib function pointers qom/object.c: Fix type conflict of GLib function pointers system/vl.c: Fix type conflict of GLib function pointers target/arm/helper.c: Fix type conflict of GLib function pointers target/i386/cpu.c: Fix type conflict of GLib function pointers contrib/plugins: Fix type conflict of GLib function pointers hw/net/can: Fix type conflict of GLib function pointers target/ppc: Fix type conflict of GLib function pointers target/s390x: Fix type conflict of GLib function pointers include/glib-compat.h: Poison g_list_sort and g_slist_sort util/cacheflush.c: Update cache flushing mechanism for Emscripten block: Add including of ioctl header for Emscripten build block: Fix type confict of the copy_file_range stub include/qemu/osdep.h: Add Emscripten-specific OS dependencies Disable options unsupported on Emscripten util: exclude mmap-alloc.c from compilation target on Emscripten util: Add coroutine backend for emscripten meson: Add wasm build in build scripts tests: Add Dockerfile containing dependencies for Emscripten build gitlab: Enable CI for wasm build .gitlab-ci.d/buildtest-template.yml | 27 ++++ .gitlab-ci.d/buildtest.yml | 9 ++ .gitlab-ci.d/container-cross.yml | 5 + MAINTAINERS | 9 ++ backends/meson.build | 6 +- block/file-posix.c | 8 +- configs/meson/emscripten.txt | 8 + configure | 7 + contrib/plugins/cache.c | 12 +- contrib/plugins/cflow.c | 10 +- contrib/plugins/hotblocks.c | 4 +- contrib/plugins/hotpages.c | 4 +- contrib/plugins/howvec.c | 4 +- contrib/plugins/hwprofile.c | 8 +- hw/core/loader.c | 4 +- hw/net/can/xlnx-versal-canfd.c | 4 +- include/glib-compat.h | 7 + include/qemu/cacheflush.h | 7 + include/qemu/osdep.h | 8 +- include/system/os-wasm.h | 104 +++++++++++++ meson.build | 29 +++- meson_options.txt | 2 +- os-wasm.c | 119 ++++++++++++++ qemu-options.hx | 4 +- qom/object.c | 7 +- scripts/meson-buildoptions.sh | 2 +- system/memory.c | 2 +- system/physmem.c | 9 +- system/vl.c | 8 +- target/arm/helper.c | 4 +- target/i386/cpu.c | 11 +- target/ppc/cpu_init.c | 4 +- target/s390x/cpu_models.c | 4 +- .../dockerfiles/emsdk-wasm32-cross.docker | 145 ++++++++++++++++++ tests/tcg/plugins/mem.c | 4 +- tests/tcg/plugins/syscall.c | 4 +- util/cacheflush.c | 4 + util/coroutine-wasm.c | 127 +++++++++++++++ util/meson.build | 4 +- util/oslib-posix.c | 28 ++++ 40 files changed, 710 insertions(+), 66 deletions(-) create mode 100644 configs/meson/emscripten.txt create mode 100644 include/system/os-wasm.h create mode 100644 os-wasm.c create mode 100644 tests/docker/dockerfiles/emsdk-wasm32-cross.docker create mode 100644 util/coroutine-wasm.c -- 2.43.0