Skip to content

Rebase on the latest #21

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 11 commits into
base: sync-upstream
Choose a base branch
from
27 changes: 27 additions & 0 deletions .gitlab-ci.d/buildtest-template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,30 @@
- du -chs ${CI_PROJECT_DIR}/*-cache
variables:
QEMU_JOB_AVOCADO: 1

.wasm_build_job_template:
extends: .base_job_template
stage: build
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:$QEMU_CI_CONTAINER_TAG
before_script:
- source scripts/ci/gitlab-ci-section
- section_start setup "Pre-script setup"
- JOBS=$(expr $(nproc) + 1)
- section_end setup
script:
- du -sh .git
- mkdir build
- cd build
- section_start configure "Running configure"
- emconfigure ../configure --disable-docs
${TARGETS:+--target-list="$TARGETS"}
$CONFIGURE_ARGS ||
{ cat config.log meson-logs/meson-log.txt && exit 1; }
- if test -n "$LD_JOBS";
then
pyvenv/bin/meson configure . -Dbackend_max_links="$LD_JOBS" ;
fi || exit 1;
- section_end configure
- section_start build "Building QEMU"
- emmake make -j"$JOBS"
- section_end build
9 changes: 9 additions & 0 deletions .gitlab-ci.d/buildtest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -801,3 +801,12 @@ coverity:
when: never
# Always manual on forks even if $QEMU_CI == "2"
- when: manual

build-wasm:
extends: .wasm_build_job_template
timeout: 2h
needs:
job: wasm-emsdk-cross-container
variables:
IMAGE: emsdk-wasm32-cross
CONFIGURE_ARGS: --static --disable-tools --enable-debug
5 changes: 5 additions & 0 deletions .gitlab-ci.d/container-cross.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,8 @@ win64-fedora-cross-container:
extends: .container_job_template
variables:
NAME: fedora-win64-cross

wasm-emsdk-cross-container:
extends: .container_job_template
variables:
NAME: emsdk-wasm32-cross
11 changes: 11 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -3903,6 +3903,17 @@ F: tcg/tci/
F: tcg/tci.c
F: disas/tci.c

WebAssembly TCG target
M: Kohei Tokunaga <[email protected]>
S: Maintained
F: configs/meson/emscripten.txt
F: hw/9pfs/9p-util-stub.c
F: tcg/wasm32/
F: tcg/wasm32.c
F: tcg/wasm32.h
F: tests/docker/dockerfiles/emsdk-wasm32-cross.docker
F: util/coroutine-fiber.c

Block drivers
-------------
VMDK
Expand Down
8 changes: 4 additions & 4 deletions accel/tcg/cputlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,13 @@ static inline uint64_t tlb_read_idx(const CPUTLBEntry *entry,
{
/* Do not rearrange the CPUTLBEntry structure members. */
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_read) !=
MMU_DATA_LOAD * sizeof(uintptr_t));
MMU_DATA_LOAD * sizeof(tlb_addr));
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_write) !=
MMU_DATA_STORE * sizeof(uintptr_t));
MMU_DATA_STORE * sizeof(tlb_addr));
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_code) !=
MMU_INST_FETCH * sizeof(uintptr_t));
MMU_INST_FETCH * sizeof(tlb_addr));

const uintptr_t *ptr = &entry->addr_idx[access_type];
const tlb_addr *ptr = &entry->addr_idx[access_type];
/* ofs might correspond to .addr_write, so use qatomic_read */
return qatomic_read(ptr);
}
Expand Down
18 changes: 18 additions & 0 deletions block/file-posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@
#include <sys/diskslice.h>
#endif

#ifdef EMSCRIPTEN
#include <sys/ioctl.h>
#endif

/* OS X does not have O_DSYNC */
#ifndef O_DSYNC
#ifdef O_SYNC
Expand Down Expand Up @@ -2011,6 +2015,19 @@ static int handle_aiocb_write_zeroes_unmap(void *opaque)
}

#ifndef HAVE_COPY_FILE_RANGE
#ifdef EMSCRIPTEN
/*
* emscripten exposes copy_file_range declaration but doesn't provide the
* implementation in the final link. Define the stub here but avoid type
* conflict with the emscripten's header.
*/
ssize_t copy_file_range(int in_fd, off_t *in_off, int out_fd,
off_t *out_off, size_t len, unsigned int flags)
{
errno = ENOSYS;
return -1;
}
#else
static off_t copy_file_range(int in_fd, off_t *in_off, int out_fd,
off_t *out_off, size_t len, unsigned int flags)
{
Expand All @@ -2023,6 +2040,7 @@ static off_t copy_file_range(int in_fd, off_t *in_off, int out_fd,
#endif
}
#endif
#endif

/*
* parse_zone - Fill a zone descriptor
Expand Down
6 changes: 6 additions & 0 deletions configs/meson/emscripten.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[built-in options]
c_args = ['-Wno-unused-command-line-argument','-g','-O3','-pthread']
cpp_args = ['-Wno-unused-command-line-argument','-g','-O3','-pthread']
objc_args = ['-Wno-unused-command-line-argument','-g','-O3','-pthread']
c_link_args = ['-Wno-unused-command-line-argument','-g','-O3','-pthread','-sASYNCIFY=1','-sPROXY_TO_PTHREAD=1','-sFORCE_FILESYSTEM','-sALLOW_TABLE_GROWTH','-sTOTAL_MEMORY=2GB','-sWASM_BIGINT','-sEXPORT_ES6=1','-sASYNCIFY_IMPORTS=ffi_call_js','-sEXPORTED_RUNTIME_METHODS=addFunction,removeFunction,TTY,FS']
cpp_link_args = ['-Wno-unused-command-line-argument','-g','-O3','-pthread','-sASYNCIFY=1','-sPROXY_TO_PTHREAD=1','-sFORCE_FILESYSTEM','-sALLOW_TABLE_GROWTH','-sTOTAL_MEMORY=2GB','-sWASM_BIGINT','-sEXPORT_ES6=1','-sASYNCIFY_IMPORTS=ffi_call_js','-sEXPORTED_RUNTIME_METHODS=addFunction,removeFunction,TTY,FS']
7 changes: 7 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,10 @@ elif check_define __NetBSD__; then
host_os=netbsd
elif check_define __APPLE__; then
host_os=darwin
elif check_define EMSCRIPTEN ; then
host_os=emscripten
cpu=wasm32
cross_compile="yes"
else
# This is a fatal error, but don't report it yet, because we
# might be going to just print the --help text, or it might
Expand Down Expand Up @@ -526,6 +530,9 @@ case "$cpu" in
linux_arch=x86
CPU_CFLAGS="-m64"
;;
wasm32)
CPU_CFLAGS="-m32"
;;
esac

if test -n "$host_arch" && {
Expand Down
3 changes: 3 additions & 0 deletions fsdev/file-op-9p.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
# include <sys/param.h>
# include <sys/mount.h>
#endif
#ifdef EMSCRIPTEN
#include <sys/vfs.h>
#endif

#define SM_LOCAL_MODE_BITS 0600
#define SM_LOCAL_DIR_MODE_BITS 0700
Expand Down
2 changes: 1 addition & 1 deletion fsdev/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ fsdev_ss.add(when: ['CONFIG_FSDEV_9P'], if_true: files(
'9p-marshal.c',
'qemu-fsdev.c',
), if_false: files('qemu-fsdev-dummy.c'))
if host_os in ['linux', 'darwin']
if host_os in ['linux', 'darwin', 'emscripten']
system_ss.add_all(fsdev_ss)
endif
43 changes: 43 additions & 0 deletions hw/9pfs/9p-util-stub.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* 9p utilities stub functions
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/

#include "qemu/osdep.h"
#include "9p-util.h"

ssize_t fgetxattrat_nofollow(int dirfd, const char *path, const char *name,
void *value, size_t size)
{
return -1;
}

ssize_t flistxattrat_nofollow(int dirfd, const char *filename,
char *list, size_t size)
{
return -1;
}

ssize_t fremovexattrat_nofollow(int dirfd, const char *filename,
const char *name)
{
return -1;
}

int fsetxattrat_nofollow(int dirfd, const char *path, const char *name,
void *value, size_t size, int flags)
{
return -1;

}

int qemu_mknodat(int dirfd, const char *filename, mode_t mode, dev_t dev)
{
return -1;
}

ssize_t fgetxattr(int fd, const char *name, void *value, size_t size)
{
return -1;
}
18 changes: 18 additions & 0 deletions hw/9pfs/9p-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,24 @@ static inline int errno_to_dotl(int err) {
} else if (err == EOPNOTSUPP) {
err = 95; /* ==EOPNOTSUPP on Linux */
}
#elif defined(EMSCRIPTEN)
/*
* FIXME: Only most important errnos translated here yet, this should be
* extended to as many errnos being translated as possible in future.
*/
if (err == ENAMETOOLONG) {
err = 36; /* ==ENAMETOOLONG on Linux */
} else if (err == ENOTEMPTY) {
err = 39; /* ==ENOTEMPTY on Linux */
} else if (err == ELOOP) {
err = 40; /* ==ELOOP on Linux */
} else if (err == ENODATA) {
err = 61; /* ==ENODATA on Linux */
} else if (err == ENOTSUP) {
err = 95; /* ==EOPNOTSUPP on Linux */
} else if (err == EOPNOTSUPP) {
err = 95; /* ==EOPNOTSUPP on Linux */
}
#else
#error Missing errno translation to Linux for this host system
#endif
Expand Down
3 changes: 3 additions & 0 deletions hw/9pfs/9p.c
Original file line number Diff line number Diff line change
Expand Up @@ -4013,6 +4013,9 @@ static void coroutine_fn v9fs_xattrwalk(void *opaque)
* Linux guests.
*/
#define P9_XATTR_SIZE_MAX 65536
#elif defined(EMSCRIPTEN)
/* No support for xattr */
#define P9_XATTR_SIZE_MAX 0
#else
#error Missing definition for P9_XATTR_SIZE_MAX for this host system
#endif
Expand Down
12 changes: 12 additions & 0 deletions hw/9pfs/coth.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "qemu/coroutine-core.h"
#include "9p.h"

#ifndef EMSCRIPTEN
/*
* we want to use bottom half because we want to make sure the below
* sequence of events.
Expand Down Expand Up @@ -57,6 +58,17 @@
/* re-enter back to qemu thread */ \
qemu_coroutine_yield(); \
} while (0)
#else
/*
* FIXME: implement this on emscripten but emscripten's coroutine
* implementation (fiber) doesn't support submitting a coroutine to other
* threads.
*/
#define v9fs_co_run_in_worker(code_block) \
do { \
code_block; \
} while (0)
#endif

void co_run_in_worker_bh(void *);
int coroutine_fn v9fs_co_readlink(V9fsPDU *, V9fsPath *, V9fsString *);
Expand Down
2 changes: 2 additions & 0 deletions hw/9pfs/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ if host_os == 'darwin'
fs_ss.add(files('9p-util-darwin.c'))
elif host_os == 'linux'
fs_ss.add(files('9p-util-linux.c'))
elif host_os == 'emscripten'
fs_ss.add(files('9p-util-stub.c'))
endif
fs_ss.add(when: 'CONFIG_XEN_BUS', if_true: files('xen-9p-backend.c'))
system_ss.add_all(when: 'CONFIG_FSDEV_9P', if_true: fs_ss)
Expand Down
9 changes: 8 additions & 1 deletion hw/riscv/riscv_hart.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,17 @@ static bool csr_qtest_callback(CharBackend *chr, gchar **words)
return false;
}

static gpointer g_qtest_set_command_cb(
bool (*pc_cb)(CharBackend *chr, gchar **words))
{
qtest_set_command_cb(pc_cb);
return NULL;
}

static void riscv_cpu_register_csr_qtest_callback(void)
{
static GOnce once;
g_once(&once, (GThreadFunc)qtest_set_command_cb, csr_qtest_callback);
g_once(&once, (GThreadFunc)g_qtest_set_command_cb, csr_qtest_callback);
}
#endif

Expand Down
2 changes: 1 addition & 1 deletion include/accel/tcg/getpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#endif

/* GETPC is the true target of the return instruction that we'll execute. */
#ifdef CONFIG_TCG_INTERPRETER
#if defined(CONFIG_TCG_INTERPRETER) || defined(EMSCRIPTEN)
extern __thread uintptr_t tci_tb_ptr;
# define GETPC() tci_tb_ptr
#else
Expand Down
14 changes: 10 additions & 4 deletions include/exec/tlb-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,20 @@
#ifndef EXEC_TLB_COMMON_H
#define EXEC_TLB_COMMON_H 1

#ifndef EMSCRIPTEN
#define CPU_TLB_ENTRY_BITS (HOST_LONG_BITS == 32 ? 4 : 5)
typedef uintptr_t tlb_addr;
#else
#define CPU_TLB_ENTRY_BITS 5
typedef uint64_t tlb_addr;
#endif

/* Minimalized TLB entry for use by TCG fast path. */
typedef union CPUTLBEntry {
struct {
uintptr_t addr_read;
uintptr_t addr_write;
uintptr_t addr_code;
tlb_addr addr_read;
tlb_addr addr_write;
tlb_addr addr_code;
/*
* Addend to virtual address to get host address. IO accesses
* use the corresponding iotlb value.
Expand All @@ -37,7 +43,7 @@ typedef union CPUTLBEntry {
* Padding to get a power of two size, as well as index
* access to addr_{read,write,code}.
*/
uintptr_t addr_idx[(1 << CPU_TLB_ENTRY_BITS) / sizeof(uintptr_t)];
tlb_addr addr_idx[(1 << CPU_TLB_ENTRY_BITS) / sizeof(tlb_addr)];
} CPUTLBEntry;

QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS));
Expand Down
11 changes: 11 additions & 0 deletions include/exec/vaddr.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,23 @@
* We do not support 64-bit guest on 32-host and detect at configure time.
* Therefore, a host pointer width will always fit a guest pointer.
*/
#ifndef EMSCRIPTEN
typedef uintptr_t vaddr;
#define VADDR_PRId PRIdPTR
#define VADDR_PRIu PRIuPTR
#define VADDR_PRIo PRIoPTR
#define VADDR_PRIx PRIxPTR
#define VADDR_PRIX PRIXPTR
#define VADDR_MAX UINTPTR_MAX
#else
/* Explicitly define this as 64bit on emscripten */
typedef uint64_t vaddr;
#define VADDR_PRId PRId64
#define VADDR_PRIu PRIu64
#define VADDR_PRIo PRIo64
#define VADDR_PRIx PRIx64
#define VADDR_PRIX PRIX64
#define VADDR_MAX UINT64_MAX
#endif

#endif
4 changes: 4 additions & 0 deletions include/qemu/atomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,17 @@
*/
#define signal_barrier() __atomic_signal_fence(__ATOMIC_SEQ_CST)

#ifndef EMSCRIPTEN
/*
* Sanity check that the size of an atomic operation isn't "overly large".
* Despite the fact that e.g. i686 has 64-bit atomic operations, we do not
* want to use them because we ought not need them, and this lets us do a
* bit of sanity checking that other 32-bit hosts might build.
*/
#define ATOMIC_REG_SIZE sizeof(void *)
#else
#define ATOMIC_REG_SIZE 8 /* wasm supports 64bit atomics */
#endif

/* Weak atomic operations prevent the compiler moving other
* loads/stores past the atomic operation load/store. However there is
Expand Down
Loading