Skip to content

Rebase TCI-related patches on the latest #22

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 20 commits into
base: sync-upstream-tcidev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
2898d81
hw/core/loader.c: Fix type conflict of GLib function pointers
ktock Apr 14, 2025
128ace3
qom/object.c: Fix type conflict of GLib function pointers
ktock Apr 14, 2025
1349103
system/vl.c: Fix type conflict of GLib function pointers
ktock Apr 14, 2025
7d56c82
target/arm/helper.c: Fix type conflict of GLib function pointers
ktock Apr 14, 2025
8ee6c2b
target/i386/cpu.c: Fix type conflict of GLib function pointers
ktock Apr 14, 2025
cffa825
contrib/plugins: Fix type conflict of GLib function pointers
ktock Apr 16, 2025
937d1fe
hw/net/can: Fix type conflict of GLib function pointers
ktock Apr 16, 2025
d917055
target/ppc: Fix type conflict of GLib function pointers
ktock Apr 16, 2025
e91c4e2
target/s390x: Fix type conflict of GLib function pointers
ktock Apr 16, 2025
fa57c80
include/glib-compat.h: Poison g_list_sort and g_slist_sort
ktock Apr 14, 2025
2926a79
util/cacheflush.c: Update cache flushing mechanism for Emscripten
ktock Apr 14, 2025
49b6ecd
block: Add including of ioctl header for Emscripten build
ktock Apr 21, 2025
938d2be
block: Fix type confict of the copy_file_range stub
ktock Apr 21, 2025
9fc7b10
include/qemu/osdep.h: Add Emscripten-specific OS dependencies
ktock Apr 21, 2025
79c5e59
Disable options unsupported on Emscripten
ktock Apr 14, 2025
76834f9
util: exclude mmap-alloc.c from compilation target on Emscripten
ktock Apr 21, 2025
006b683
util: Add coroutine backend for emscripten
ktock Apr 21, 2025
ad03b3b
meson: Add wasm build in build scripts
ktock Apr 21, 2025
8bed6e9
tests: Add Dockerfile containing dependencies for Emscripten build
ktock Apr 21, 2025
ade0deb
gitlab: Enable CI for wasm build
ktock Apr 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .gitlab-ci.d/buildtest-template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,30 @@
- du -chs ${CI_PROJECT_DIR}/*-cache
variables:
QEMU_JOB_FUNCTIONAL: 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 @@ -792,3 +792,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 --enable-tcg-interpreter
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
9 changes: 9 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,15 @@ F: .gitlab-ci.d/cirrus/macos-*
F: */*.m
F: scripts/entitlement.sh

WebAssembly
M: Kohei Tokunaga <[email protected]>
S: Maintained
F: include/system/os-wasm.h
F: os-wasm.c
F: util/coroutine-wasm.c
F: configs/meson/emscripten.txt
F: tests/docker/dockerfiles/emsdk-wasm32-cross.docker

Alpha Machines
--------------
M: Richard Henderson <[email protected]>
Expand Down
6 changes: 4 additions & 2 deletions backends/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ system_ss.add([files(

if host_os != 'windows'
system_ss.add(files('rng-random.c'))
system_ss.add(files('hostmem-file.c'))
system_ss.add([files('hostmem-shm.c'), rt])
if host_os != 'emscripten'
system_ss.add(files('hostmem-file.c'))
system_ss.add([files('hostmem-shm.c'), rt])
endif
endif
if host_os == 'linux'
system_ss.add(files('hostmem-memfd.c'))
Expand Down
8 changes: 6 additions & 2 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,8 +2015,8 @@ static int handle_aiocb_write_zeroes_unmap(void *opaque)
}

#ifndef HAVE_COPY_FILE_RANGE
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)
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)
{
#ifdef __NR_copy_file_range
return syscall(__NR_copy_file_range, in_fd, in_off, out_fd,
Expand Down
8 changes: 8 additions & 0 deletions configs/meson/emscripten.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[built-in options]
c_args = ['-pthread']
cpp_args = ['-pthread']
objc_args = ['-pthread']
# -sPROXY_TO_PTHREAD link time flag always requires -pthread even during
# configuration so explicitly add the flag here.
c_link_args = ['-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 = ['-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
12 changes: 6 additions & 6 deletions contrib/plugins/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -576,23 +576,23 @@ static void sum_stats(void)
}
}

static int dcmp(gconstpointer a, gconstpointer b)
static int dcmp(gconstpointer a, gconstpointer b, gpointer d)
{
InsnData *insn_a = (InsnData *) a;
InsnData *insn_b = (InsnData *) b;

return insn_a->l1_dmisses < insn_b->l1_dmisses ? 1 : -1;
}

static int icmp(gconstpointer a, gconstpointer b)
static int icmp(gconstpointer a, gconstpointer b, gpointer d)
{
InsnData *insn_a = (InsnData *) a;
InsnData *insn_b = (InsnData *) b;

return insn_a->l1_imisses < insn_b->l1_imisses ? 1 : -1;
}

static int l2_cmp(gconstpointer a, gconstpointer b)
static int l2_cmp(gconstpointer a, gconstpointer b, gpointer d)
{
InsnData *insn_a = (InsnData *) a;
InsnData *insn_b = (InsnData *) b;
Expand Down Expand Up @@ -645,7 +645,7 @@ static void log_top_insns(void)
InsnData *insn;

miss_insns = g_hash_table_get_values(miss_ht);
miss_insns = g_list_sort(miss_insns, dcmp);
miss_insns = g_list_sort_with_data(miss_insns, dcmp, NULL);
g_autoptr(GString) rep = g_string_new("");
g_string_append_printf(rep, "%s", "address, data misses, instruction\n");

Expand All @@ -659,7 +659,7 @@ static void log_top_insns(void)
insn->l1_dmisses, insn->disas_str);
}

miss_insns = g_list_sort(miss_insns, icmp);
miss_insns = g_list_sort_with_data(miss_insns, icmp, NULL);
g_string_append_printf(rep, "%s", "\naddress, fetch misses, instruction\n");

for (curr = miss_insns, i = 0; curr && i < limit; i++, curr = curr->next) {
Expand All @@ -676,7 +676,7 @@ static void log_top_insns(void)
goto finish;
}

miss_insns = g_list_sort(miss_insns, l2_cmp);
miss_insns = g_list_sort_with_data(miss_insns, l2_cmp, NULL);
g_string_append_printf(rep, "%s", "\naddress, L2 misses, instruction\n");

for (curr = miss_insns, i = 0; curr && i < limit; i++, curr = curr->next) {
Expand Down
10 changes: 5 additions & 5 deletions contrib/plugins/cflow.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ static GHashTable *nodes;
struct qemu_plugin_scoreboard *state;

/* SORT_HOTTEST */
static gint hottest(gconstpointer a, gconstpointer b)
static gint hottest(gconstpointer a, gconstpointer b, gpointer d)
{
NodeData *na = (NodeData *) a;
NodeData *nb = (NodeData *) b;
Expand All @@ -107,7 +107,7 @@ static gint hottest(gconstpointer a, gconstpointer b)
na->dest_count == nb->dest_count ? 0 : 1;
}

static gint exception(gconstpointer a, gconstpointer b)
static gint exception(gconstpointer a, gconstpointer b, gpointer d)
{
NodeData *na = (NodeData *) a;
NodeData *nb = (NodeData *) b;
Expand All @@ -116,7 +116,7 @@ static gint exception(gconstpointer a, gconstpointer b)
na->early_exit == nb->early_exit ? 0 : 1;
}

static gint popular(gconstpointer a, gconstpointer b)
static gint popular(gconstpointer a, gconstpointer b, gpointer d)
{
NodeData *na = (NodeData *) a;
NodeData *nb = (NodeData *) b;
Expand All @@ -138,7 +138,7 @@ static void plugin_exit(qemu_plugin_id_t id, void *p)
{
g_autoptr(GString) result = g_string_new("collected ");
GList *data;
GCompareFunc sort = &hottest;
GCompareDataFunc sort = &hottest;
int i = 0;

g_mutex_lock(&node_lock);
Expand All @@ -162,7 +162,7 @@ static void plugin_exit(qemu_plugin_id_t id, void *p)
break;
}

data = g_list_sort(data, sort);
data = g_list_sort_with_data(data, sort, NULL);

for (GList *l = data;
l != NULL && i < topn;
Expand Down
4 changes: 2 additions & 2 deletions contrib/plugins/hotblocks.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ typedef struct {
unsigned long insns;
} ExecCount;

static gint cmp_exec_count(gconstpointer a, gconstpointer b)
static gint cmp_exec_count(gconstpointer a, gconstpointer b, gpointer d)
{
ExecCount *ea = (ExecCount *) a;
ExecCount *eb = (ExecCount *) b;
Expand Down Expand Up @@ -79,7 +79,7 @@ static void plugin_exit(qemu_plugin_id_t id, void *p)
g_string_append_printf(report, "%d entries in the hash table\n",
g_hash_table_size(hotblocks));
counts = g_hash_table_get_values(hotblocks);
it = g_list_sort(counts, cmp_exec_count);
it = g_list_sort_with_data(counts, cmp_exec_count, NULL);

if (it) {
g_string_append_printf(report, "pc, tcount, icount, ecount\n");
Expand Down
4 changes: 2 additions & 2 deletions contrib/plugins/hotpages.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ typedef struct {
static GMutex lock;
static GHashTable *pages;

static gint cmp_access_count(gconstpointer a, gconstpointer b)
static gint cmp_access_count(gconstpointer a, gconstpointer b, gpointer d)
{
PageCounters *ea = (PageCounters *) a;
PageCounters *eb = (PageCounters *) b;
Expand Down Expand Up @@ -83,7 +83,7 @@ static void plugin_exit(qemu_plugin_id_t id, void *p)
if (counts && g_list_next(counts)) {
GList *it;

it = g_list_sort(counts, cmp_access_count);
it = g_list_sort_with_data(counts, cmp_access_count, NULL);

for (i = 0; i < limit && it->next; i++, it = it->next) {
PageCounters *rec = (PageCounters *) it->data;
Expand Down
4 changes: 2 additions & 2 deletions contrib/plugins/howvec.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ static ClassSelector class_tables[] = {
static InsnClassExecCount *class_table;
static int class_table_sz;

static gint cmp_exec_count(gconstpointer a, gconstpointer b)
static gint cmp_exec_count(gconstpointer a, gconstpointer b, gpointer d)
{
InsnExecCount *ea = (InsnExecCount *) a;
InsnExecCount *eb = (InsnExecCount *) b;
Expand Down Expand Up @@ -208,7 +208,7 @@ static void plugin_exit(qemu_plugin_id_t id, void *p)
counts = g_hash_table_get_values(insns);
if (counts && g_list_next(counts)) {
g_string_append_printf(report, "Individual Instructions:\n");
counts = g_list_sort(counts, cmp_exec_count);
counts = g_list_sort_with_data(counts, cmp_exec_count, NULL);

for (i = 0; i < limit && g_list_next(counts);
i++, counts = g_list_next(counts)) {
Expand Down
8 changes: 4 additions & 4 deletions contrib/plugins/hwprofile.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,15 @@ static void plugin_init(void)
devices = g_hash_table_new(NULL, NULL);
}

static gint sort_cmp(gconstpointer a, gconstpointer b)
static gint sort_cmp(gconstpointer a, gconstpointer b, gpointer d)
{
DeviceCounts *ea = (DeviceCounts *) a;
DeviceCounts *eb = (DeviceCounts *) b;
return ea->totals.reads + ea->totals.writes >
eb->totals.reads + eb->totals.writes ? -1 : 1;
}

static gint sort_loc(gconstpointer a, gconstpointer b)
static gint sort_loc(gconstpointer a, gconstpointer b, gpointer d)
{
IOLocationCounts *ea = (IOLocationCounts *) a;
IOLocationCounts *eb = (IOLocationCounts *) b;
Expand Down Expand Up @@ -126,13 +126,13 @@ static void plugin_exit(qemu_plugin_id_t id, void *p)
if (counts && g_list_next(counts)) {
GList *it;

it = g_list_sort(counts, sort_cmp);
it = g_list_sort_with_data(counts, sort_cmp, NULL);

while (it) {
DeviceCounts *rec = (DeviceCounts *) it->data;
if (rec->detail) {
GList *accesses = g_hash_table_get_values(rec->detail);
GList *io_it = g_list_sort(accesses, sort_loc);
GList *io_it = g_list_sort_with_data(accesses, sort_loc, NULL);
const char *prefix = pattern ? "off" : "pc";
g_string_append_printf(report, "%s @ 0x%"PRIx64"\n",
rec->name, rec->base);
Expand Down
4 changes: 2 additions & 2 deletions hw/core/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -1410,7 +1410,7 @@ typedef struct RomSec {
* work, but this way saves a little work later by avoiding
* dealing with "gaps" of 0 length.
*/
static gint sort_secs(gconstpointer a, gconstpointer b)
static gint sort_secs(gconstpointer a, gconstpointer b, gpointer d)
{
RomSec *ra = (RomSec *) a;
RomSec *rb = (RomSec *) b;
Expand Down Expand Up @@ -1463,7 +1463,7 @@ RomGap rom_find_largest_gap_between(hwaddr base, size_t size)
/* sentinel */
secs = add_romsec_to_list(secs, base + size, 1);

secs = g_list_sort(secs, sort_secs);
secs = g_list_sort_with_data(secs, sort_secs, NULL);

for (it = g_list_first(secs); it; it = g_list_next(it)) {
cand = (RomSec *) it->data;
Expand Down
4 changes: 2 additions & 2 deletions hw/net/can/xlnx-versal-canfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1278,7 +1278,7 @@ static void tx_fifo_stamp(XlnxVersalCANFDState *s, uint32_t tb0_regid)
}
}

static gint g_cmp_ids(gconstpointer data1, gconstpointer data2)
static gint g_cmp_ids(gconstpointer data1, gconstpointer data2, gpointer d)
{
tx_ready_reg_info *tx_reg_1 = (tx_ready_reg_info *) data1;
tx_ready_reg_info *tx_reg_2 = (tx_ready_reg_info *) data2;
Expand Down Expand Up @@ -1316,7 +1316,7 @@ static GSList *prepare_tx_data(XlnxVersalCANFDState *s)
temp->can_id = s->regs[reg_num];
temp->reg_num = reg_num;
list = g_slist_prepend(list, temp);
list = g_slist_sort(list, g_cmp_ids);
list = g_slist_sort_with_data(list, g_cmp_ids, NULL);
}

reg_ready >>= 1;
Expand Down
7 changes: 7 additions & 0 deletions include/glib-compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@
#include <pwd.h>
#endif

/*
* These functions perform function pointer casts which can cause function call
* failure on Emscripten. Use g_slist_sort_with_data and g_list_sort_with_data
* instead of these functions.
*/
#pragma GCC poison g_slist_sort g_list_sort

/*
* Note that because of the GLIB_VERSION_MAX_ALLOWED constant above, allowing
* use of functions from newer GLib via this compat header needs a little
Expand Down
7 changes: 7 additions & 0 deletions include/qemu/cacheflush.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ static inline void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len)
/* icache is coherent and does not require flushing. */
}

#elif defined(EMSCRIPTEN)

static inline void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len)
{
/* Wasm doesn't have executable region of memory. */
}

#else

void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len);
Expand Down
Loading