.gitlab-ci.d/buildtest-template.yml | 27 + .gitlab-ci.d/buildtest.yml | 9 + .gitlab-ci.d/container-cross.yml | 5 + MAINTAINERS | 11 + accel/tcg/cputlb.c | 8 +- block/file-posix.c | 18 + configs/meson/emscripten.txt | 6 + configure | 7 + fsdev/file-op-9p.h | 3 + fsdev/meson.build | 2 +- hw/9pfs/9p-util-stub.c | 43 + hw/9pfs/9p-util.h | 18 + hw/9pfs/9p.c | 3 + hw/9pfs/coth.h | 12 + hw/9pfs/meson.build | 2 + hw/riscv/riscv_hart.c | 9 +- include/accel/tcg/getpc.h | 2 +- include/exec/tlb-common.h | 14 +- include/exec/vaddr.h | 11 + include/qemu/atomic.h | 4 + include/qemu/cacheflush.h | 3 +- include/tcg/helper-info.h | 4 +- include/tcg/tcg.h | 2 +- meson.build | 30 +- meson_options.txt | 2 +- os-posix.c | 5 + qom/object.c | 5 +- scripts/meson-buildoptions.sh | 2 +- target/arm/helper.c | 4 +- tcg/meson.build | 5 + tcg/tcg.c | 26 +- tcg/wasm32.c | 1260 +++++ tcg/wasm32.h | 39 + tcg/wasm32/tcg-target-con-set.h | 18 + tcg/wasm32/tcg-target-con-str.h | 8 + tcg/wasm32/tcg-target-has.h | 102 + tcg/wasm32/tcg-target-mo.h | 12 + tcg/wasm32/tcg-target-opc.h.inc | 4 + tcg/wasm32/tcg-target-reg-bits.h | 12 + tcg/wasm32/tcg-target.c.inc | 4484 +++++++++++++++++ tcg/wasm32/tcg-target.h | 65 + .../dockerfiles/emsdk-wasm32-cross.docker | 145 + util/cacheflush.c | 3 +- util/coroutine-fiber.c | 127 + util/mmap-alloc.c | 18 + 45 files changed, 6561 insertions(+), 38 deletions(-) create mode 100644 configs/meson/emscripten.txt create mode 100644 hw/9pfs/9p-util-stub.c create mode 100644 tcg/wasm32.c create mode 100644 tcg/wasm32.h create mode 100644 tcg/wasm32/tcg-target-con-set.h create mode 100644 tcg/wasm32/tcg-target-con-str.h create mode 100644 tcg/wasm32/tcg-target-has.h create mode 100644 tcg/wasm32/tcg-target-mo.h create mode 100644 tcg/wasm32/tcg-target-opc.h.inc create mode 100644 tcg/wasm32/tcg-target-reg-bits.h create mode 100644 tcg/wasm32/tcg-target.c.inc create mode 100644 tcg/wasm32/tcg-target.h create mode 100644 tests/docker/dockerfiles/emsdk-wasm32-cross.docker create mode 100644 util/coroutine-fiber.c
This patch series enables QEMU's system emulator to run in a browser using
Emscripten.
It includes implementations and workarounds to address browser environment
limitations, as shown in the following.
# New TCG Backend for Browsers
A new TCG backend translates IR instructions into Wasm instructions and runs
them using the browser's WebAssembly APIs (WebAssembly.Module and
WebAssembly.instantiate). To minimize compilation overhead and avoid hitting
the browser's limitation of the number of instances, this backend integrates
a forked TCI. TBs run on TCI by default, with frequently executed TBs
compiled into WebAssembly.
# Workaround for Running 64-bit Guests
The current implementation uses Wasm's 32-bit memory model, even though Wasm
supports 64-bit variables and instructions. This patch explores implementing
TCG 64-bit instructions while leveraging SoftMMU for address translation. To
enable 64-bit guest support in Wasm today, it was necessary to partially
revert recent changes that removed support for different pointer widths
between the host and guest (e.g., commits
a70af12addd9060fdf8f3dbd42b42e3072c3914f and
bf455ec50b6fea15b4d2493059365bf94c706273) when compiling with
Emscripten. While this serves as a temporary workaround, a long-term
solution could involve adopting Wasm's 64-bit memory model once it gains
broader support, as it is currently not widely adopted (e.g., unsupported by
Safari and libffi). Feedback and suggestions on this approach are welcome.
# 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. So this patch series modifies
hw/9pfs/coth.h to disable this behavior when compiled with Emscripten.
# 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=x86_64-softmmu
emmake make -j$(nproc)
This process generates the following files:
- qemu-system-x86_64.js
- qemu-system-x86_64.wasm
- qemu-system-x86_64.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-x86_64.data --preload pack > load.js
This process generates the following files:
- qemu-system-x86_64.data
- load.js
Emscripten allows passing arguments to the QEMU command via the Module
object in JavaScript:
Module['arguments'] = [
'-nographic', '-m', '512M', '-accel', 'tcg,tb-size=500',
'-L', 'pack/',
'-drive', 'if=virtio,format=raw,file=pack/rootfs.bin',
'-kernel', 'pack/bzImage',
'-append', 'earlyprintk=ttyS0 console=ttyS0 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
# Additional references
- A talk at FOSDEM 2025:
https://fosdem.org/2025/schedule/event/fosdem-2025-6290-running-qemu-inside-browser/
- Demo page on GitHub Pages: https://ktock.github.io/qemu-wasm-demo/
Kohei Tokunaga (10):
various: Fix type conflict of GLib function pointers
various: Define macros for dependencies on emscripten
util/mmap-alloc: Add qemu_ram_mmap implementation for emscripten
util: Add coroutine backend for emscripten
meson: Add wasm build in build scripts
include/exec: Allow using 64bit guest addresses on emscripten
tcg: Add a TCG backend for WebAssembly
hw/9pfs: Allow using hw/9pfs with emscripten
gitlab: Enable CI for wasm build
MAINTAINERS: Update MAINTAINERS file for wasm-related files
.gitlab-ci.d/buildtest-template.yml | 27 +
.gitlab-ci.d/buildtest.yml | 9 +
.gitlab-ci.d/container-cross.yml | 5 +
MAINTAINERS | 11 +
accel/tcg/cputlb.c | 8 +-
block/file-posix.c | 18 +
configs/meson/emscripten.txt | 6 +
configure | 7 +
fsdev/file-op-9p.h | 3 +
fsdev/meson.build | 2 +-
hw/9pfs/9p-util-stub.c | 43 +
hw/9pfs/9p-util.h | 18 +
hw/9pfs/9p.c | 3 +
hw/9pfs/coth.h | 12 +
hw/9pfs/meson.build | 2 +
hw/riscv/riscv_hart.c | 9 +-
include/accel/tcg/getpc.h | 2 +-
include/exec/tlb-common.h | 14 +-
include/exec/vaddr.h | 11 +
include/qemu/atomic.h | 4 +
include/qemu/cacheflush.h | 3 +-
include/tcg/helper-info.h | 4 +-
include/tcg/tcg.h | 2 +-
meson.build | 30 +-
meson_options.txt | 2 +-
os-posix.c | 5 +
qom/object.c | 5 +-
scripts/meson-buildoptions.sh | 2 +-
target/arm/helper.c | 4 +-
tcg/meson.build | 5 +
tcg/tcg.c | 26 +-
tcg/wasm32.c | 1260 +++++
tcg/wasm32.h | 39 +
tcg/wasm32/tcg-target-con-set.h | 18 +
tcg/wasm32/tcg-target-con-str.h | 8 +
tcg/wasm32/tcg-target-has.h | 102 +
tcg/wasm32/tcg-target-mo.h | 12 +
tcg/wasm32/tcg-target-opc.h.inc | 4 +
tcg/wasm32/tcg-target-reg-bits.h | 12 +
tcg/wasm32/tcg-target.c.inc | 4484 +++++++++++++++++
tcg/wasm32/tcg-target.h | 65 +
.../dockerfiles/emsdk-wasm32-cross.docker | 145 +
util/cacheflush.c | 3 +-
util/coroutine-fiber.c | 127 +
util/mmap-alloc.c | 18 +
45 files changed, 6561 insertions(+), 38 deletions(-)
create mode 100644 configs/meson/emscripten.txt
create mode 100644 hw/9pfs/9p-util-stub.c
create mode 100644 tcg/wasm32.c
create mode 100644 tcg/wasm32.h
create mode 100644 tcg/wasm32/tcg-target-con-set.h
create mode 100644 tcg/wasm32/tcg-target-con-str.h
create mode 100644 tcg/wasm32/tcg-target-has.h
create mode 100644 tcg/wasm32/tcg-target-mo.h
create mode 100644 tcg/wasm32/tcg-target-opc.h.inc
create mode 100644 tcg/wasm32/tcg-target-reg-bits.h
create mode 100644 tcg/wasm32/tcg-target.c.inc
create mode 100644 tcg/wasm32/tcg-target.h
create mode 100644 tests/docker/dockerfiles/emsdk-wasm32-cross.docker
create mode 100644 util/coroutine-fiber.c
--
2.25.1
On Mon, Apr 07, 2025 at 11:45:51PM +0900, Kohei Tokunaga wrote: > This patch series enables QEMU's system emulator to run in a browser using > Emscripten. > It includes implementations and workarounds to address browser environment > limitations, as shown in the following. I think it would be great to merge this even if there are limitations once code review comments have been addressed. Developing WebAssembly support in-tree is likely to allow this effort to develop further than if done in personal repos (and with significant efforts required to rebase the code periodically). > # New TCG Backend for Browsers > > A new TCG backend translates IR instructions into Wasm instructions and runs > them using the browser's WebAssembly APIs (WebAssembly.Module and > WebAssembly.instantiate). To minimize compilation overhead and avoid hitting > the browser's limitation of the number of instances, this backend integrates > a forked TCI. TBs run on TCI by default, with frequently executed TBs > compiled into WebAssembly. > > # Workaround for Running 64-bit Guests > > The current implementation uses Wasm's 32-bit memory model, even though Wasm > supports 64-bit variables and instructions. This patch explores implementing > TCG 64-bit instructions while leveraging SoftMMU for address translation. To > enable 64-bit guest support in Wasm today, it was necessary to partially > revert recent changes that removed support for different pointer widths > between the host and guest (e.g., commits > a70af12addd9060fdf8f3dbd42b42e3072c3914f and > bf455ec50b6fea15b4d2493059365bf94c706273) when compiling with > Emscripten. While this serves as a temporary workaround, a long-term > solution could involve adopting Wasm's 64-bit memory model once it gains > broader support, as it is currently not widely adopted (e.g., unsupported by > Safari and libffi). Feedback and suggestions on this approach are welcome. > > # 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. So this patch series modifies > hw/9pfs/coth.h to disable this behavior when compiled with Emscripten. QEMU's block job coroutines also rely on switching between threads. See how job_co_entry() schedules job_exit(). It's not very likely that users will run jobs in a WebAssembly environment, so maybe this is more of a theoretical problem for the time being. > # 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=x86_64-softmmu > emmake make -j$(nproc) > > This process generates the following files: > > - qemu-system-x86_64.js > - qemu-system-x86_64.wasm > - qemu-system-x86_64.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-x86_64.data --preload pack > load.js > > This process generates the following files: > > - qemu-system-x86_64.data > - load.js > > Emscripten allows passing arguments to the QEMU command via the Module > object in JavaScript: > > Module['arguments'] = [ > '-nographic', '-m', '512M', '-accel', 'tcg,tb-size=500', > '-L', 'pack/', > '-drive', 'if=virtio,format=raw,file=pack/rootfs.bin', > '-kernel', 'pack/bzImage', > '-append', 'earlyprintk=ttyS0 console=ttyS0 root=/dev/vda loglevel=7', > ]; > > The sample repository[1] provides a complete setup, including an HTML file > that implements a terminal UI. If I understand correctly the QEMU project is only build the statically linked wasm binary in the CI system and not distributing it (e.g. making it available for download)? I'm asking because if the QEMU project wants to distribute the wasm binary it may be necessary to put together a combined software license to meet the license requirements of glib and other dependencies that are statically linked. > > [1] https://github.com/ktock/qemu-wasm-sample > > # Additional references > > - A talk at FOSDEM 2025: > https://fosdem.org/2025/schedule/event/fosdem-2025-6290-running-qemu-inside-browser/ > - Demo page on GitHub Pages: https://ktock.github.io/qemu-wasm-demo/ > > Kohei Tokunaga (10): > various: Fix type conflict of GLib function pointers > various: Define macros for dependencies on emscripten > util/mmap-alloc: Add qemu_ram_mmap implementation for emscripten > util: Add coroutine backend for emscripten > meson: Add wasm build in build scripts > include/exec: Allow using 64bit guest addresses on emscripten > tcg: Add a TCG backend for WebAssembly > hw/9pfs: Allow using hw/9pfs with emscripten > gitlab: Enable CI for wasm build > MAINTAINERS: Update MAINTAINERS file for wasm-related files > > .gitlab-ci.d/buildtest-template.yml | 27 + > .gitlab-ci.d/buildtest.yml | 9 + > .gitlab-ci.d/container-cross.yml | 5 + > MAINTAINERS | 11 + > accel/tcg/cputlb.c | 8 +- > block/file-posix.c | 18 + > configs/meson/emscripten.txt | 6 + > configure | 7 + > fsdev/file-op-9p.h | 3 + > fsdev/meson.build | 2 +- > hw/9pfs/9p-util-stub.c | 43 + > hw/9pfs/9p-util.h | 18 + > hw/9pfs/9p.c | 3 + > hw/9pfs/coth.h | 12 + > hw/9pfs/meson.build | 2 + > hw/riscv/riscv_hart.c | 9 +- > include/accel/tcg/getpc.h | 2 +- > include/exec/tlb-common.h | 14 +- > include/exec/vaddr.h | 11 + > include/qemu/atomic.h | 4 + > include/qemu/cacheflush.h | 3 +- > include/tcg/helper-info.h | 4 +- > include/tcg/tcg.h | 2 +- > meson.build | 30 +- > meson_options.txt | 2 +- > os-posix.c | 5 + > qom/object.c | 5 +- > scripts/meson-buildoptions.sh | 2 +- > target/arm/helper.c | 4 +- > tcg/meson.build | 5 + > tcg/tcg.c | 26 +- > tcg/wasm32.c | 1260 +++++ > tcg/wasm32.h | 39 + > tcg/wasm32/tcg-target-con-set.h | 18 + > tcg/wasm32/tcg-target-con-str.h | 8 + > tcg/wasm32/tcg-target-has.h | 102 + > tcg/wasm32/tcg-target-mo.h | 12 + > tcg/wasm32/tcg-target-opc.h.inc | 4 + > tcg/wasm32/tcg-target-reg-bits.h | 12 + > tcg/wasm32/tcg-target.c.inc | 4484 +++++++++++++++++ > tcg/wasm32/tcg-target.h | 65 + > .../dockerfiles/emsdk-wasm32-cross.docker | 145 + > util/cacheflush.c | 3 +- > util/coroutine-fiber.c | 127 + > util/mmap-alloc.c | 18 + > 45 files changed, 6561 insertions(+), 38 deletions(-) > create mode 100644 configs/meson/emscripten.txt > create mode 100644 hw/9pfs/9p-util-stub.c > create mode 100644 tcg/wasm32.c > create mode 100644 tcg/wasm32.h > create mode 100644 tcg/wasm32/tcg-target-con-set.h > create mode 100644 tcg/wasm32/tcg-target-con-str.h > create mode 100644 tcg/wasm32/tcg-target-has.h > create mode 100644 tcg/wasm32/tcg-target-mo.h > create mode 100644 tcg/wasm32/tcg-target-opc.h.inc > create mode 100644 tcg/wasm32/tcg-target-reg-bits.h > create mode 100644 tcg/wasm32/tcg-target.c.inc > create mode 100644 tcg/wasm32/tcg-target.h > create mode 100644 tests/docker/dockerfiles/emsdk-wasm32-cross.docker > create mode 100644 util/coroutine-fiber.c > > -- > 2.25.1 >
On Wed, Apr 09, 2025 at 03:21:15PM -0400, Stefan Hajnoczi wrote: > On Mon, Apr 07, 2025 at 11:45:51PM +0900, Kohei Tokunaga wrote: > > This patch series enables QEMU's system emulator to run in a browser using > > Emscripten. > > It includes implementations and workarounds to address browser environment > > limitations, as shown in the following. > > I think it would be great to merge this even if there are limitations > once code review comments have been addressed. Developing WebAssembly > support in-tree is likely to allow this effort to develop further than > if done in personal repos (and with significant efforts required to > rebase the code periodically). It is certainly impressive & clever but first two critical questions.. Is there a committment to long term (many years) development & maintenance of this, or is it just a short term experiment which will have attention dwindle in a year's time ? Is there a compelling real world use case for this that will justify carrying it in QEMU, or is it a case of "it exists because it can" ? With regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
Hi Daniel, > On Wed, Apr 09, 2025 at 03:21:15PM -0400, Stefan Hajnoczi wrote: > > On Mon, Apr 07, 2025 at 11:45:51PM +0900, Kohei Tokunaga wrote: > > > This patch series enables QEMU's system emulator to run in a browser using > > > Emscripten. > > > It includes implementations and workarounds to address browser environment > > > limitations, as shown in the following. > > > > I think it would be great to merge this even if there are limitations > > once code review comments have been addressed. Developing WebAssembly > > support in-tree is likely to allow this effort to develop further than > > if done in personal repos (and with significant efforts required to > > rebase the code periodically). > > It is certainly impressive & clever but first two critical questions.. > > Is there a committment to long term (many years) development & maintenance > of this, or is it just a short term experiment which will have attention > dwindle in a year's time ? > > Is there a compelling real world use case for this that will justify > carrying it in QEMU, or is it a case of "it exists because it can" ? Thank you for the qeustions. In recent years, I've observed several use cases for on-browser VM environments. One potential application is an on-browser development environment, similar to VSCode's on-browser Python execution environment [1], but with QEMU offering enhanced compatibility for existing software Another use case could be an on-browser playground or demo environment. Several programming languages, such as Ruby [2] and Swift [3], have already leveraged WebAssembly for this purpose. On-browser QEMU would extend this capability, allowing a wider variety of software to run within browsers. Although the current Wasm backend implementation is still in its early stages and has room for improvement (e.g., the aforementioned workarounds, performance, etc.), I believe the examples above represent promising use cases. Of course, I am committed to maintaining and improving this backend. [1] https://code.visualstudio.com/docs/python/python-web [2] https://github.com/ruby/ruby.wasm/blob/d4a9a03aae6b84327d29783b75edb63549df7e6c/README.md#try-rubywasm-no-installation-needed [3] https://swiftwasm.org/
On 9/4/25 21:21, Stefan Hajnoczi wrote: > On Mon, Apr 07, 2025 at 11:45:51PM +0900, Kohei Tokunaga wrote: >> This patch series enables QEMU's system emulator to run in a browser using >> Emscripten. >> It includes implementations and workarounds to address browser environment >> limitations, as shown in the following. > > I think it would be great to merge this even if there are limitations > once code review comments have been addressed. Developing WebAssembly > support in-tree is likely to allow this effort to develop further than > if done in personal repos (and with significant efforts required to > rebase the code periodically). > >> # New TCG Backend for Browsers >> >> A new TCG backend translates IR instructions into Wasm instructions and runs >> them using the browser's WebAssembly APIs (WebAssembly.Module and >> WebAssembly.instantiate). To minimize compilation overhead and avoid hitting >> the browser's limitation of the number of instances, this backend integrates >> a forked TCI. TBs run on TCI by default, with frequently executed TBs >> compiled into WebAssembly. >> >> # Workaround for Running 64-bit Guests >> >> The current implementation uses Wasm's 32-bit memory model, even though Wasm >> supports 64-bit variables and instructions. This patch explores implementing >> TCG 64-bit instructions while leveraging SoftMMU for address translation. To >> enable 64-bit guest support in Wasm today, it was necessary to partially >> revert recent changes that removed support for different pointer widths >> between the host and guest (e.g., commits >> a70af12addd9060fdf8f3dbd42b42e3072c3914f and >> bf455ec50b6fea15b4d2493059365bf94c706273) when compiling with >> Emscripten. While this serves as a temporary workaround, a long-term >> solution could involve adopting Wasm's 64-bit memory model once it gains >> broader support, as it is currently not widely adopted (e.g., unsupported by >> Safari and libffi). Feedback and suggestions on this approach are welcome. The biggest problem I'm seeing is we no longer support 64-bit guests on 32-bit hosts, and don't plan to revert that.
Hi Stefan, > > This patch series enables QEMU's system emulator to run in a browser using > > Emscripten. > > It includes implementations and workarounds to address browser environment > > limitations, as shown in the following. > > I think it would be great to merge this even if there are limitations > once code review comments have been addressed. Developing WebAssembly > support in-tree is likely to allow this effort to develop further than > if done in personal repos (and with significant efforts required to > rebase the code periodically). > > > # New TCG Backend for Browsers > > > > A new TCG backend translates IR instructions into Wasm instructions and runs > > them using the browser's WebAssembly APIs (WebAssembly.Module and > > WebAssembly.instantiate). To minimize compilation overhead and avoid hitting > > the browser's limitation of the number of instances, this backend integrates > > a forked TCI. TBs run on TCI by default, with frequently executed TBs > > compiled into WebAssembly. > > > > # Workaround for Running 64-bit Guests > > > > The current implementation uses Wasm's 32-bit memory model, even though Wasm > > supports 64-bit variables and instructions. This patch explores implementing > > TCG 64-bit instructions while leveraging SoftMMU for address translation. To > > enable 64-bit guest support in Wasm today, it was necessary to partially > > revert recent changes that removed support for different pointer widths > > between the host and guest (e.g., commits > > a70af12addd9060fdf8f3dbd42b42e3072c3914f and > > bf455ec50b6fea15b4d2493059365bf94c706273) when compiling with > > Emscripten. While this serves as a temporary workaround, a long-term > > solution could involve adopting Wasm's 64-bit memory model once it gains > > broader support, as it is currently not widely adopted (e.g., unsupported by > > Safari and libffi). Feedback and suggestions on this approach are welcome. > > > > # 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. So this patch series modifies > > hw/9pfs/coth.h to disable this behavior when compiled with Emscripten. > > QEMU's block job coroutines also rely on switching between threads. See > how job_co_entry() schedules job_exit(). It's not very likely that users > will run jobs in a WebAssembly environment, so maybe this is more of a > theoretical problem for the time being. Thank you for the feedback. I'll investigate the block job coroutines further. As you pointed out, I agree that users aren't likely to run block jobs in the WebAssembly environment. > If I understand correctly the QEMU project is only build the statically > linked wasm binary in the CI system and not distributing it (e.g. making > it available for download)? I'm asking because if the QEMU project wants > to distribute the wasm binary it may be necessary to put together a > combined software license to meet the license requirements of glib and > other dependencies that are statically linked. Yes, it doesn't distribute the statically linked wasm binary.
Hi Philippe,
> On 9/4/25 21:21, Stefan Hajnoczi wrote:
> > On Mon, Apr 07, 2025 at 11:45:51PM +0900, Kohei Tokunaga wrote:
> >> This patch series enables QEMU's system emulator to run in a browser
using
> >> Emscripten.
> >> It includes implementations and workarounds to address browser
environment
> >> limitations, as shown in the following.
> >
> > I think it would be great to merge this even if there are limitations
> > once code review comments have been addressed. Developing WebAssembly
> > support in-tree is likely to allow this effort to develop further than
> > if done in personal repos (and with significant efforts required to
> > rebase the code periodically).
> >
> >> # New TCG Backend for Browsers
> >>
> >> A new TCG backend translates IR instructions into Wasm instructions
and runs
> >> them using the browser's WebAssembly APIs (WebAssembly.Module and
> >> WebAssembly.instantiate). To minimize compilation overhead and avoid
hitting
> >> the browser's limitation of the number of instances, this backend
integrates
> >> a forked TCI. TBs run on TCI by default, with frequently executed TBs
> >> compiled into WebAssembly.
> >>
> >> # Workaround for Running 64-bit Guests
> >>
> >> The current implementation uses Wasm's 32-bit memory model, even
though Wasm
> >> supports 64-bit variables and instructions. This patch explores
implementing
> >> TCG 64-bit instructions while leveraging SoftMMU for address
translation. To
> >> enable 64-bit guest support in Wasm today, it was necessary to
partially
> >> revert recent changes that removed support for different pointer widths
> >> between the host and guest (e.g., commits
> >> a70af12addd9060fdf8f3dbd42b42e3072c3914f and
> >> bf455ec50b6fea15b4d2493059365bf94c706273) when compiling with
> >> Emscripten. While this serves as a temporary workaround, a long-term
> >> solution could involve adopting Wasm's 64-bit memory model once it
gains
> >> broader support, as it is currently not widely adopted (e.g.,
unsupported by
> >> Safari and libffi). Feedback and suggestions on this approach are
welcome.
>
> The biggest problem I'm seeing is we no longer support 64-bit guests on
> 32-bit hosts, and don't plan to revert that.
Yes, so the sixth patch ("[PATCH 06/10] include/exec: Allow using 64bit
guest addresses on emscripten") should be considered as a temporary
workaround, enabled only for Emsripten builds. It will be removed once
wasm64 gains broader support and is adopted in the Wasm backend.
On 4/10/25 15:13, Kohei Tokunaga wrote:
> > The biggest problem I'm seeing is we no longer support 64-bit guests on
> > 32-bit hosts, and don't plan to revert that.
>
> Yes, so the sixth patch ("[PATCH 06/10] include/exec: Allow using 64bit
> guest addresses on emscripten") should be considered as a temporary
> workaround, enabled only for Emsripten builds. It will be removed once
> wasm64 gains broader support and is adopted in the Wasm backend.
Maybe there's a way though. Currently we don't support 64-bit guests on
32-bit hosts, but more precisely we don't support 64-bit guests with
32-bit host word size.
The wasm TCG backend is able to compile with 64-bit words:
+#define TCG_TARGET_HAS_div_i64 1
+#define TCG_TARGET_HAS_rem_i64 1
etc.
and if x32 was a thing it would as well. In fact the changes in patch
6/10 are not a full revert, and the "#ifdef EMSCRIPTEN" could be changed to
#if HOST_LONG_BITS >= TARGET_LONG_BITS
... use uintptr_t
#else
... use uint64_t
#endif
Paolo
Hi Paolo,
> > > The biggest problem I'm seeing is we no longer support 64-bit guests
on
> > > 32-bit hosts, and don't plan to revert that.
> >
> > Yes, so the sixth patch ("[PATCH 06/10] include/exec: Allow using 64bit
> > guest addresses on emscripten") should be considered as a temporary
> > workaround, enabled only for Emsripten builds. It will be removed once
> > wasm64 gains broader support and is adopted in the Wasm backend.
>
> Maybe there's a way though. Currently we don't support 64-bit guests on
> 32-bit hosts, but more precisely we don't support 64-bit guests with
> 32-bit host word size.
>
>
> The wasm TCG backend is able to compile with 64-bit words:
>
> +#define TCG_TARGET_HAS_div_i64 1
> +#define TCG_TARGET_HAS_rem_i64 1
> etc.
>
> and if x32 was a thing it would as well. In fact the changes in patch
> 6/10 are not a full revert, and the "#ifdef EMSCRIPTEN" could be changed
to
>
> #if HOST_LONG_BITS >= TARGET_LONG_BITS
> ... use uintptr_t
> #else
> ... use uint64_t
> #endif
Thank you for the feedback.
Yes, the Wasm backend can be compiled with 64-bit words. The change
regarding the macro looks good to me.
Hi Kohei,
first, congrats for this work!
It would be really nice to have this available upstream, starting with a
modest TCI port, before having the tcg backend also.
On 4/10/25 06:13, Kohei Tokunaga wrote:
> Hi Philippe,
>
> >
> > The biggest problem I'm seeing is we no longer support 64-bit guests on
> > 32-bit hosts, and don't plan to revert that.
>
> Yes, so the sixth patch ("[PATCH 06/10] include/exec: Allow using 64bit
> guest addresses on emscripten") should be considered as a temporary
> workaround, enabled only for Emsripten builds. It will be removed once
> wasm64 gains broader support and is adopted in the Wasm backend.
>
Do you have recent information about wasm64? It seems to be something
that has been discussed for several years, without really seeing any
progress.
As Philippe said, we can't really revert that (it's now an assumption
for our softmmu implementation, and would break code if we enabled it
again now.)
That said, we can always have a first version supporting only 32 bits
targets. And later, when wasm64 will be available, we can extend this to
all remaining ones.
Regards,
Pierrick
Hi Pierrick, thank you for the feedback. > first, congrats for this work! > It would be really nice to have this available upstream, starting with a > modest TCI port, before having the tcg backend also. Sure, I'll split the patch series, starting with the TCI port. > Do you have recent information about wasm64? It seems to be something > that has been discussed for several years, without really seeing any > progress. According to the adoption status [1], wasm64 is supported by recent versions of Chrome and Firefox. Emscripten also supports wasm64 [2]. However, it is not yet supported by Safari or libffi [3], and I haven't found a roadmap for the adoption. [1] https://webassembly.org/features/ [2] https://emscripten.org/docs/tools_reference/settings_reference.html#memory64 [3] https://github.com/libffi/libffi/blob/6a99edb8082f75e523e0d6ebaba42218b80e10c8/README.md#supported-platforms > As Philippe said, we can't really revert that (it's now an assumption > for our softmmu implementation, and would break code if we enabled it > again now.) > > That said, we can always have a first version supporting only 32 bits > targets. And later, when wasm64 will be available, we can extend this to > all remaining ones. The main challenge I'm seeing is that I couldn't find a clear timeline for wasm64 adoption so it's difficult to predict when it will be widely available. Regarding the revert, the wasm backend supports 64-bit words, so the revert introduced in patch 06/10 is partial, as also pointed out by Paolo.
On 4/11/25 07:36, Kohei Tokunaga wrote: > Hi Pierrick, thank you for the feedback. > > > first, congrats for this work! > > It would be really nice to have this available upstream, starting with a > > modest TCI port, before having the tcg backend also. > > Sure, I'll split the patch series, starting with the TCI port. > > > Do you have recent information about wasm64? It seems to be something > > that has been discussed for several years, without really seeing any > > progress. > > According to the adoption status [1], wasm64 is supported by recent versions > of Chrome and Firefox. Emscripten also supports wasm64 [2]. However, it is > not yet supported by Safari or libffi [3], and I haven't found a roadmap for > the adoption. > Great, I didn't notice major browsers were already supporting it. Even if Safari does not support it, maybe having the two other major ones would be enough to target this. Regarding libffi, our usage of it seems limited in tci, I wonder if we could not workaround this. Or eventually see if enabling wasm64 is a big work in libffi itself. > [1] https://webassembly.org/features/ <https://webassembly.org/features/> > [2] https://emscripten.org/docs/tools_reference/ > settings_reference.html#memory64 <https://emscripten.org/docs/ > tools_reference/settings_reference.html#memory64> > [3] https://github.com/libffi/libffi/ > blob/6a99edb8082f75e523e0d6ebaba42218b80e10c8/README.md#supported- > platforms <https://github.com/libffi/libffi/ > blob/6a99edb8082f75e523e0d6ebaba42218b80e10c8/README.md#supported-platforms> > > > As Philippe said, we can't really revert that (it's now an assumption > > for our softmmu implementation, and would break code if we enabled it > > again now.) > > > > That said, we can always have a first version supporting only 32 bits > > targets. And later, when wasm64 will be available, we can extend this to > > all remaining ones. > > The main challenge I'm seeing is that I couldn't find a clear timeline for > wasm64 adoption so it's difficult to predict when it will be widely > available. > > Regarding the revert, the wasm backend supports 64-bit words, so the revert > introduced in patch 06/10 is partial, as also pointed out by Paolo. > Ok, thanks for pointing it, I didn't really read into details of the patch, and simply assumed you wanted to revert this change completely. If we can have a solution only affecting emscripten builds, I think it's ok. Regards, Pierrick
© 2016 - 2025 Red Hat, Inc.