qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/10] Enable QEMU to run on browsers
@ 2025-04-07 14:45 Kohei Tokunaga
  2025-04-07 14:45 ` [PATCH 01/10] various: Fix type conflict of GLib function pointers Kohei Tokunaga
                   ` (10 more replies)
  0 siblings, 11 replies; 46+ messages in thread
From: Kohei Tokunaga @ 2025-04-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, Philippe Mathieu-Daudé, Thomas Huth,
	Richard Henderson, Paolo Bonzini, Kevin Wolf, Hanna Reitz,
	Kohei Tokunaga, Christian Schoenebeck, Greg Kurz, Palmer Dabbelt,
	Alistair Francis, Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei,
	Marc-André Lureau, Daniel P . Berrangé, Eduardo Habkost,
	Peter Maydell, Stefan Hajnoczi, qemu-block, qemu-riscv, qemu-arm

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



^ permalink raw reply	[flat|nested] 46+ messages in thread

end of thread, other threads:[~2025-04-13  8:13 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-07 14:45 [PATCH 00/10] Enable QEMU to run on browsers Kohei Tokunaga
2025-04-07 14:45 ` [PATCH 01/10] various: Fix type conflict of GLib function pointers Kohei Tokunaga
2025-04-09 10:54   ` Philippe Mathieu-Daudé
2025-04-09 13:43     ` Kohei Tokunaga
2025-04-10 15:58   ` Paolo Bonzini
2025-04-11 10:55     ` Kohei Tokunaga
2025-04-07 14:45 ` [PATCH 02/10] various: Define macros for dependencies on emscripten Kohei Tokunaga
2025-04-10 15:53   ` Paolo Bonzini
2025-04-11 10:59     ` Kohei Tokunaga
2025-04-07 14:45 ` [PATCH 03/10] util/mmap-alloc: Add qemu_ram_mmap implementation for emscripten Kohei Tokunaga
2025-04-07 14:45 ` [PATCH 04/10] util: Add coroutine backend " Kohei Tokunaga
2025-04-07 14:45 ` [PATCH 05/10] meson: Add wasm build in build scripts Kohei Tokunaga
2025-04-09 10:55   ` Philippe Mathieu-Daudé
2025-04-09 13:35     ` Paolo Bonzini
2025-04-10 12:24       ` Kohei Tokunaga
2025-04-10 12:55         ` Paolo Bonzini
2025-04-11 11:23           ` Kohei Tokunaga
2025-04-07 14:45 ` [PATCH 06/10] include/exec: Allow using 64bit guest addresses on emscripten Kohei Tokunaga
2025-04-07 14:45 ` [PATCH 07/10] tcg: Add a TCG backend for WebAssembly Kohei Tokunaga
2025-04-09 10:58   ` Philippe Mathieu-Daudé
2025-04-09 13:53     ` Kohei Tokunaga
2025-04-11 10:50   ` Philippe Mathieu-Daudé
2025-04-12  9:04     ` Kohei Tokunaga
2025-04-12  9:12       ` Kohei Tokunaga
2025-04-07 14:45 ` [PATCH 08/10] hw/9pfs: Allow using hw/9pfs with emscripten Kohei Tokunaga
2025-04-10 11:27   ` Christian Schoenebeck
2025-04-11 10:47     ` Kohei Tokunaga
2025-04-12  8:21       ` Christian Schoenebeck
2025-04-12 10:21         ` Christian Schoenebeck
2025-04-12 10:38           ` Christian Schoenebeck
2025-04-13  8:12             ` Kohei Tokunaga
2025-04-10 16:29   ` Paolo Bonzini
2025-04-11 14:03     ` Kohei Tokunaga
2025-04-07 14:46 ` [PATCH 09/10] gitlab: Enable CI for wasm build Kohei Tokunaga
2025-04-07 14:46 ` [PATCH 10/10] MAINTAINERS: Update MAINTAINERS file for wasm-related files Kohei Tokunaga
2025-04-09 19:21 ` [PATCH 00/10] Enable QEMU to run on browsers Stefan Hajnoczi
2025-04-10 12:20   ` Philippe Mathieu-Daudé
2025-04-10 13:11     ` Kohei Tokunaga
2025-04-10 13:13       ` Kohei Tokunaga
2025-04-10 21:17         ` Pierrick Bouvier
2025-04-11 14:36           ` Kohei Tokunaga
2025-04-11 15:28             ` Pierrick Bouvier
2025-04-11  9:07         ` Paolo Bonzini
2025-04-11 14:41           ` Kohei Tokunaga
2025-04-11 10:34   ` Daniel P. Berrangé
2025-04-11 15:17     ` Kohei Tokunaga

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).