This patch series is split from the original "Enable QEMU to run on
browsers" series, focusing solely on supporting 64bit guest on QEMU TCI
compiled with Emscripten. The implementation is based on discussions from
the thread in the "tcg: Add WebAssembly backend" patch series, particulalrly
Paolo Bonzini's suggestion to introduce TCG_VADDR_BITS. Thank you for the
feedback in that thread.

# Running 64bit Guests on WebAssembly

The current implementation uses Wasm's 32bit memory model. This series
explores supporting 64bit guests while relying on SoftMMU for address
translation. To achieve this in Wasm today, it was necessary to partially
revert recent changes that removed support for 64bit guests on 32bit hosts,
specifically those related to pointer width differences between 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 migrating to Wasm's 64bit memory model once it gains
broader support, as it is currently not widely adopted (e.g. unsupported by
Safari and libffi).

# 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 --enable-tcg-interpreter
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',
    '-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/

Kohei Tokunaga (5):
  meson.build: add TCG_VADDR_BITS for defining the vaddr size
  include: define vaddr based on TCG_VADDR_BITS
  tlb: specify address field size based on TCG_VADDR_BITS
  tci: define TCG_TARGET_REG_BITS based on TCG_VADDR_BITS
  tci: use tcg_target_ulong when retrieving the pool data

 accel/tcg/cputlb.c             |  8 ++++----
 include/exec/helper-head.h.inc |  9 +++++----
 include/exec/tlb-common.h      | 18 +++++++++++++-----
 include/exec/vaddr.h           | 28 +++++++++++++++++++---------
 include/qemu/atomic.h          |  4 ++++
 include/tcg/tcg.h              |  6 +++---
 meson.build                    |  5 ++++-
 tcg/tci.c                      |  6 ++++--
 tcg/tci/tcg-target-reg-bits.h  |  4 ++--
 9 files changed, 58 insertions(+), 30 deletions(-)

-- 
2.43.0


Reply via email to