Re: [PATCH 00/10] Enable QEMU to run on browsers

2025-04-09 Thread Stefan Hajnoczi
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
> 
> # Add

Re: [PATCH] hw/nvme: fix attachment of private namespaces

2025-04-09 Thread Klaus Jensen
On Apr  8 20:56, Philippe Mathieu-Daudé wrote:
> On 8/4/25 12:20, Klaus Jensen wrote:
> > From: Klaus Jensen 
> > 
> > Fix regression when attaching private namespaces that gets attached to
> > the wrong controller.
> > 
> > Keep track of the original controller "owner" of private namespaces, and
> > only attach if this matches on controller enablement.
> > 
> > Fixes: 6ccca4b6bb9f ("hw/nvme: rework csi handling")
> > Reported-by: Alan Adamson 
> > Suggested-by: Alan Adamson 
> > Signed-off-by: Klaus Jensen 
> > ---
> >   hw/nvme/ctrl.c   | 7 ++-
> >   hw/nvme/ns.c | 4 
> >   hw/nvme/nvme.h   | 3 +++
> >   hw/nvme/subsys.c | 9 +
> >   4 files changed, 14 insertions(+), 9 deletions(-)
> 
> 
> Patch queued, thanks!

Hi Philippe,

Thanks for picking this up!


signature.asc
Description: PGP signature


Re: [PATCH 0/1] hw/nvme: create parameter to enable/disable cmic on subsystem

2025-04-09 Thread alan . adamson



On 4/8/25 11:47 PM, Klaus Jensen wrote:

On Apr  8 15:56, Alan Adamson wrote:

While testing Linux atomic writes with qemu-nvme v10.0.0-rc1, Linux was
incorrectly displaying atomic_write_max_bytes
# cat /sys/block/nvme0n1/queue/atomic_write_max_bytes
0
# nvme id-ctrl /dev/nvme0n1 | grep awupf
awupf : 15
#
Since AWUPF was set to 15, it was expected atomic_write_max_bytes would
be set to 8192.

The commit cd59f50ab017 ("hw/nvme: always initialize a subsystem")
introduced this behavior. The commit hardcodes the subsystem cmic bit
to ON which caused the Linux NVMe driver to treat the namespace as
multi-pathed which uncovered a bug with how Atomic Write Queue Limits
were being inherited.  This Linux issue is being addressed, but the
question was asked of why the subsystem cmic bit was hardcoded to ON.
Most NVMe devices today don't set cmic to ON. Shouldn't the setting of
this bit be a settable parameter?

,cmic=BOOLEAN (default: off)

Example:
 -device nvme-subsys,id=subsys0,cmic=on \
 -device 
nvme,serial=deadbeef,id=nvme0,subsys=subsys0,atomic.dn=off,atomic.awun=31,atomic.awupf=15
 \
 -drive id=ns1,file=/dev/nullb3,if=none \
 -device nvme-ns,drive=ns1,bus=nvme0,nsid=1,shared=false

Alan Adamson (1):
   hw/nvme: create parameter to enable/disable cmic on subsystem

  hw/nvme/ctrl.c   | 5 -
  hw/nvme/nvme.h   | 1 +
  hw/nvme/subsys.c | 1 +
  3 files changed, 6 insertions(+), 1 deletion(-)

--
2.43.5



Hi Alan,

I agree that it would be better for CMIC.MCTRS to remain zero for
single-controller subsystems, but I'd rather not add the parameter
without verifying it (it would be invalid to have a multi-controller
subsystem with CMIC.MCTRS zeroed).

An improvement would be to just set it if the subsystems contains
multiple controllers.

Prior to commit cd59f50ab017 we would also statically set CMIC.MCTRS to
1 if a subsystem was configured, regardless of the number of
controllers.


Klaus,

I'll send out a v2 that automatically sets CMIC.MCTRS for each 
controller of a multi-controller subsystem.  For single controller 
subsystems, CMIC.MCTRS will default to off and the cmic parameter can be 
used to change CMIC.MCTRS to on.


Thanks!

Alan




[PATCH 1/2] file-posix: probe discard alignment on Linux block devices

2025-04-09 Thread Stefan Hajnoczi
Populate the pdiscard_alignment block limit so the block layer is able
align discard requests correctly.

Signed-off-by: Stefan Hajnoczi 
---
 block/file-posix.c | 56 +-
 1 file changed, 55 insertions(+), 1 deletion(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index 56d1972d15..2a1e1f48c0 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1276,10 +1276,10 @@ static int get_sysfs_zoned_model(struct stat *st, 
BlockZoneModel *zoned)
 }
 #endif /* defined(CONFIG_BLKZONED) */
 
+#ifdef CONFIG_LINUX
 /*
  * Get a sysfs attribute value as a long integer.
  */
-#ifdef CONFIG_LINUX
 static long get_sysfs_long_val(struct stat *st, const char *attribute)
 {
 g_autofree char *str = NULL;
@@ -1299,6 +1299,30 @@ static long get_sysfs_long_val(struct stat *st, const 
char *attribute)
 }
 return ret;
 }
+
+/*
+ * Get a sysfs attribute value as a uint32_t.
+ */
+static int get_sysfs_u32_val(struct stat *st, const char *attribute,
+ uint32_t *u32)
+{
+g_autofree char *str = NULL;
+const char *end;
+unsigned int val;
+int ret;
+
+ret = get_sysfs_str_val(st, attribute, &str);
+if (ret < 0) {
+return ret;
+}
+
+/* The file is ended with '\n', pass 'end' to accept that. */
+ret = qemu_strtoui(str, &end, 10, &val);
+if (ret == 0 && end && *end == '\0') {
+*u32 = val;
+}
+return ret;
+}
 #endif
 
 static int hdev_get_max_segments(int fd, struct stat *st)
@@ -1318,6 +1342,23 @@ static int hdev_get_max_segments(int fd, struct stat *st)
 #endif
 }
 
+/*
+ * Fills in *dalign with the discard alignment and returns 0 on success,
+ * -errno otherwise.
+ */
+static int hdev_get_pdiscard_alignment(struct stat *st, uint32_t *dalign)
+{
+#ifdef CONFIG_LINUX
+/*
+ * Note that Linux "discard_granularity" is QEMU "discard_alignment". Linux
+ * "discard_alignment" is something else.
+ */
+return get_sysfs_u32_val(st, "discard_granularity", dalign);
+#else
+return -ENOTSUP;
+#endif
+}
+
 #if defined(CONFIG_BLKZONED)
 /*
  * If the reset_all flag is true, then the wps of zone whose state is
@@ -1527,6 +1568,19 @@ static void raw_refresh_limits(BlockDriverState *bs, 
Error **errp)
 }
 }
 
+if (S_ISBLK(st.st_mode)) {
+uint32_t dalign = 0;
+int ret;
+
+ret = hdev_get_pdiscard_alignment(&st, &dalign);
+if (ret == 0) {
+/* Must be a multiple of request_alignment */
+assert(dalign % bs->bl.request_alignment == 0);
+
+bs->bl.pdiscard_alignment = dalign;
+}
+}
+
 raw_refresh_zoned_limits(bs, &st, errp);
 }
 
-- 
2.49.0




Re: [PATCH 07/10] tcg: Add a TCG backend for WebAssembly

2025-04-09 Thread Kohei Tokunaga
> Eh TBH this is too much to review as a single patch.
>
> Do you already have an idea how different the wasm64 implementation can
be?

Sorry for the large patch. I'll split it into smaller patches in the next
version of the series.

With wasm64, instructions that manipulate pointers (e.g., ld/st, qemu_ld/st)
will be updated to handle 64bit pointers. I believe wasm64 will not require
large changes to other parts, such as label handling, goto_tb/goto_ptr, or
the forked TCI.


[PATCH 0/2] block: discard alignment fixes

2025-04-09 Thread Stefan Hajnoczi
Two discard alignment issues were identified in
https://issues.redhat.com/browse/RHEL-86032:
1. pdiscard_alignment is not populated for host_device in file-posix.c.
2. Misaligned head/tail discard requests are not skipped when file-posix.c
   returns -EINVAL. This causes an undesired pause when guests are configured
   with werror=stop.

Stefan Hajnoczi (2):
  file-posix: probe discard alignment on Linux block devices
  block/io: skip head/tail requests on EINVAL

 block/file-posix.c | 56 +-
 block/io.c |  6 -
 2 files changed, 60 insertions(+), 2 deletions(-)

-- 
2.49.0




[PATCH 2/2] block/io: skip head/tail requests on EINVAL

2025-04-09 Thread Stefan Hajnoczi
When guests send misaligned discard requests, the block layer breaks
them up into a misaligned head, an aligned main body, and a misaligned
tail.

The file-posix block driver on Linux returns -EINVAL on misaligned
discard requests. This causes bdrv_co_pdiscard() to fail and guests
configured with werror=stop will pause.

Add a special case for misaligned head/tail requests. Simply continue
when EINVAL is encountered so that the aligned main body of the request
can be completed and the guest is not paused. This is the best we can do
when guest discard limits do not match the host discard limits.

Fixes: https://issues.redhat.com/browse/RHEL-86032
Signed-off-by: Stefan Hajnoczi 
---
 block/io.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/block/io.c b/block/io.c
index 1ba8d1aeea..5975f4e9a3 100644
--- a/block/io.c
+++ b/block/io.c
@@ -3180,7 +3180,11 @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, 
int64_t offset,
 }
 }
 if (ret && ret != -ENOTSUP) {
-goto out;
+if (ret == -EINVAL && (offset % align == 0 || num % align == 0)) {
+/* Silently skip rejected unaligned head/tail requests */
+} else {
+goto out; /* bail out */
+}
 }
 
 offset += num;
-- 
2.49.0




Re: [PATCH 01/10] various: Fix type conflict of GLib function pointers

2025-04-09 Thread Kohei Tokunaga
Hi Philippe, thank you for the comments.

> > +static gpointer g_qtest_set_command_cb(
> > +bool (*pc_cb)(CharBackend *chr, gchar **words))
> > +{
>
> Why not use a GThreadFunc prototype, casting the argument?

Sure, I'll fix this.

> OK for the rest, but it might help to merge by corresponding maintainers
> if split in 3 distinct patches.

Thank you for the suggestion. I'll split it to distinct patches in the next
version of the series.


Re: [PATCH 05/10] meson: Add wasm build in build scripts

2025-04-09 Thread Paolo Bonzini

On 4/9/25 12:55, Philippe Mathieu-Daudé wrote:

Cc'ing Pierrick

On 7/4/25 16:45, Kohei Tokunaga wrote:

has_int128_type is set to false on emscripten as of now to avoid errors by
libffi.


What is the error here?  How hard would it be to test for it?


And tests aren't integrated with Wasm execution environment as of
now so this commit disables tests.


Perhaps it would be enough to add

[binaries]
exe_wrapper = 'node'

to the emscripten.txt file?


+[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']


At least -g -O3 -pthread should not be necessary.

For -Wno-unused-command-line-argument what are the warnings/errors that 
you are getting?



+elif host_os == 'emscripten'
+  supported_backends += ['fiber']


Can you rename the backend to 'wasm' since the 'windows' backend also 
uses an API called Fibers?


Otherwise the changes look good.

Paolo




Re: [PULL 0/4] Block layer patches

2025-04-09 Thread Stefan Hajnoczi
Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/10.0 for any 
user-visible changes.


signature.asc
Description: PGP signature


[PATCH v3 1/2] qapi: synchronize jobs and block-jobs documentation

2025-04-09 Thread Vladimir Sementsov-Ogievskiy
Actualize documentation and synchronize it for commands which actually
call the same functions internally.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 qapi/block-core.json | 61 ++--
 qapi/job.json| 30 --
 2 files changed, 64 insertions(+), 27 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index b1937780e1..6beab0dc12 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2956,13 +2956,14 @@
 #
 # Pause an active background block operation.
 #
-# This command returns immediately after marking the active background
-# block operation for pausing.  It is an error to call this command if
-# no operation is in progress or if the job is already paused.
+# This command returns immediately after marking the active job for
+# pausing.  Pausing an already paused job is an error.
+#
+# The job will pause as soon as possible, which means transitioning
+# into the PAUSED state if it was RUNNING, or into STANDBY if it was
+# READY.  The corresponding JOB_STATUS_CHANGE event will be emitted.
 #
-# The operation will pause as soon as possible.  No event is emitted
-# when the operation is actually paused.  Cancelling a paused job
-# automatically resumes it.
+# Cancelling a paused job automatically resumes it.
 #
 # @device: The job identifier.  This used to be a device name (hence
 # the name of the parameter), but since QEMU 2.7 it can have other
@@ -2982,9 +2983,8 @@
 #
 # Resume an active background block operation.
 #
-# This command returns immediately after resuming a paused background
-# block operation.  It is an error to call this command if no
-# operation is in progress or if the job is not paused.
+# This command returns immediately after resuming a paused job.
+# Resuming an already running job is an error.
 #
 # This command also clears the error status of the job.
 #
@@ -3004,10 +3004,15 @@
 ##
 # @block-job-complete:
 #
-# Manually trigger completion of an active background block operation.
-# This is supported for drive mirroring, where it also switches the
-# device to write to the target path only.  The ability to complete is
-# signaled with a BLOCK_JOB_READY event.
+# Manually trigger completion of an active job in the READY or STANDBY
+# state.  Completing the job in any other state is an error.
+#
+# This is supported only for drive mirroring, where it also switches
+# the device to write to the target path only. Note that drive
+# mirroring includes drive-mirror, blockdev-mirror and block-commit
+# job (only in case of "active commit", when the node being commited
+# is used by the guest). The ability to complete is signaled with a
+# BLOCK_JOB_READY event.
 #
 # This command completes an active background block operation
 # synchronously.  The ordering of this command's return with the
@@ -3017,8 +3022,6 @@
 # rerror/werror arguments that were specified when starting the
 # operation.
 #
-# A cancelled or paused job cannot be completed.
-#
 # @device: The job identifier.  This used to be a device name (hence
 # the name of the parameter), but since QEMU 2.7 it can have other
 # values.
@@ -3035,10 +3038,13 @@
 ##
 # @block-job-dismiss:
 #
-# For jobs that have already concluded, remove them from the
-# block-job-query list.  This command only needs to be run for jobs
-# which were started with QEMU 2.12+ job lifetime management
-# semantics.
+# Deletes a job that is in the CONCLUDED state.  This command only
+# needs to be run explicitly for jobs that don't have automatic
+# dismiss enabled. In turn, automatic dismiss may be enabled only
+# for jobs that have @auto-dismiss option, which are drive-backup,
+# blockdev-backup, drive-mirror, blockdev-mirror, block-commit and
+# block-stream. @auto-dismiss is enabled by default for these
+# jobs.
 #
 # This command will refuse to operate on any job that has not yet
 # reached its terminal state, JOB_STATUS_CONCLUDED.  For jobs that
@@ -3055,12 +3061,17 @@
 ##
 # @block-job-finalize:
 #
-# Once a job that has manual=true reaches the pending state, it can be
-# instructed to finalize any graph changes and do any necessary
-# cleanup via this command.  For jobs in a transaction, instructing
-# one job to finalize will force ALL jobs in the transaction to
-# finalize, so it is only necessary to instruct a single member job to
-# finalize.
+# Instructs all jobs in a transaction (or a single job if it is not
+# part of any transaction) to finalize any graph changes and do any
+# necessary cleanup.  This command requires that all involved jobs are
+# in the PENDING state.
+#
+# For jobs in a transaction, instructing one job to finalize will
+# force ALL jobs in the transaction to finalize, so it is only
+# necessary to instruct a single member job to finalize.
+#
+# The command is applicable only to jobs which have @auto-finalize option
+# and only when this option is set to false.
 #
 # @id: The job identifier.
 #
diff --git a/qapi/job.js

[PATCH v3 2/2] qapi/block-core: deprecate some block-job- APIs

2025-04-09 Thread Vladimir Sementsov-Ogievskiy
For change, pause, resume, complete, dismiss and finalize actions
corresponding job- and block-job commands are almost equal. The
difference is in find_block_job_locked() vs find_job_locked()
functions. What's different?

1. find_block_job_locked() checks whether the found job is a block-job.
   This is OK when moving to more generic API, no needs to document this
   change.

2. find_block_job_locked() reports DeviceNotActive on failure, when
   find_job_locked() reports GenericError. So, let's document this
   difference in deprecated.txt. Still, for dismiss and finalize errors
   are not documented at all, so be silent in deprecated.txt as well.

ACKed-by: Peter Krempa 
Reviewed-by: Eric Blake 
Reviewed-by: Markus Armbruster 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 docs/about/deprecated.rst | 31 +++
 qapi/block-core.json  | 30 ++
 2 files changed, 61 insertions(+)

diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index 76291fdfd6..afa7075051 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -148,6 +148,37 @@ options are removed in favor of using explicit 
``blockdev-create`` and
 ``blockdev-add`` calls. See :doc:`/interop/live-block-operations` for
 details.
 
+``block-job-pause`` (since 10.1)
+
+
+Use ``job-pause`` instead. The only difference is that ``job-pause``
+always reports GenericError on failure when ``block-job-pause`` reports
+DeviceNotActive when block-job is not found.
+
+``block-job-resume`` (since 10.1)
+'
+
+Use ``job-resume`` instead. The only difference is that ``job-resume``
+always reports GenericError on failure when ``block-job-resume`` reports
+DeviceNotActive when block-job is not found.
+
+``block-job-complete`` (since 10.1)
+'''
+
+Use ``job-complete`` instead. The only difference is that ``job-complete``
+always reports GenericError on failure when ``block-job-complete`` reports
+DeviceNotActive when block-job is not found.
+
+``block-job-dismiss`` (since 10.1)
+''
+
+Use ``job-dismiss`` instead.
+
+``block-job-finalize`` (since 10.1)
+'''
+
+Use ``job-finalize`` instead.
+
 ``query-migrationthreads`` (since 9.2)
 ''
 
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 6beab0dc12..22061227ca 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2969,6 +2969,11 @@
 # the name of the parameter), but since QEMU 2.7 it can have other
 # values.
 #
+# Features:
+#
+# @deprecated: This command is deprecated.  Use @job-pause
+# instead.
+#
 # Errors:
 # - If no background operation is active on this device,
 #   DeviceNotActive
@@ -2976,6 +2981,7 @@
 # Since: 1.3
 ##
 { 'command': 'block-job-pause', 'data': { 'device': 'str' },
+  'features': ['deprecated'],
   'allow-preconfig': true }
 
 ##
@@ -2992,6 +2998,11 @@
 # the name of the parameter), but since QEMU 2.7 it can have other
 # values.
 #
+# Features:
+#
+# @deprecated: This command is deprecated.  Use @job-resume
+# instead.
+#
 # Errors:
 # - If no background operation is active on this device,
 #   DeviceNotActive
@@ -2999,6 +3010,7 @@
 # Since: 1.3
 ##
 { 'command': 'block-job-resume', 'data': { 'device': 'str' },
+  'features': ['deprecated'],
   'allow-preconfig': true }
 
 ##
@@ -3026,6 +3038,11 @@
 # the name of the parameter), but since QEMU 2.7 it can have other
 # values.
 #
+# Features:
+#
+# @deprecated: This command is deprecated.  Use @job-complete
+# instead.
+#
 # Errors:
 # - If no background operation is active on this device,
 #   DeviceNotActive
@@ -3033,6 +3050,7 @@
 # Since: 1.3
 ##
 { 'command': 'block-job-complete', 'data': { 'device': 'str' },
+  'features': ['deprecated'],
   'allow-preconfig': true }
 
 ##
@@ -3053,9 +3071,15 @@
 #
 # @id: The job identifier.
 #
+# Features:
+#
+# @deprecated: This command is deprecated.  Use @job-dismiss
+# instead.
+#
 # Since: 2.12
 ##
 { 'command': 'block-job-dismiss', 'data': { 'id': 'str' },
+  'features': ['deprecated'],
   'allow-preconfig': true }
 
 ##
@@ -3075,9 +3099,15 @@
 #
 # @id: The job identifier.
 #
+# Features:
+#
+# @deprecated: This command is deprecated.  Use @job-finalize
+# instead.
+#
 # Since: 2.12
 ##
 { 'command': 'block-job-finalize', 'data': { 'id': 'str' },
+  'features': ['deprecated'],
   'allow-preconfig': true }
 
 ##
-- 
2.48.1




[PATCH v3 0/2] deprecate some block-job- APIs

2025-04-09 Thread Vladimir Sementsov-Ogievskiy
This is for 10.1, of course.

v3: fix wording, typos
v2: Update documentation: add patch 01

v1 was:
[PATCH] [for-10.1] qapi/block-core: derpecate some block-job- APIs
Supersedes: <20250401155730.103718-1-vsement...@yandex-team.ru>

Vladimir Sementsov-Ogievskiy (2):
  qapi: synchronize jobs and block-jobs documentation
  qapi/block-core: deprecate some block-job- APIs

 docs/about/deprecated.rst | 31 +
 qapi/block-core.json  | 91 ---
 qapi/job.json | 30 -
 3 files changed, 125 insertions(+), 27 deletions(-)

-- 
2.48.1




Re: [PATCH 01/10] various: Fix type conflict of GLib function pointers

2025-04-09 Thread Philippe Mathieu-Daudé

Hi Kohei,

On 7/4/25 16:45, Kohei Tokunaga wrote:

On emscripten, function pointer casts can cause function call failure.
This commit fixes the function definition to match to the type of the
function call.

- qtest_set_command_cb passed to g_once should match to GThreadFunc
- object_class_cmp and cpreg_key_compare are passed to g_list_sort as
   GCopmareFunc but GLib cast them to GCompareDataFunc.

Signed-off-by: Kohei Tokunaga 
---
  hw/riscv/riscv_hart.c | 9 -
  qom/object.c  | 5 +++--
  target/arm/helper.c   | 4 ++--
  3 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
index a55d156668..e37317dcbd 100644
--- a/hw/riscv/riscv_hart.c
+++ b/hw/riscv/riscv_hart.c
@@ -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))
+{


Why not use a GThreadFunc prototype, casting the argument?


+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
  


OK for the rest, but it might help to merge by corresponding maintainers
if split in 3 distinct patches.


diff --git a/qom/object.c b/qom/object.c
index 01618d06bd..19698aae4c 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1191,7 +1191,8 @@ GSList *object_class_get_list(const char *implements_type,
  return list;
  }
  
-static gint object_class_cmp(gconstpointer a, gconstpointer b)

+static gint object_class_cmp(gconstpointer a, gconstpointer b,
+ gpointer user_data)
  {
  return strcasecmp(object_class_get_name((ObjectClass *)a),
object_class_get_name((ObjectClass *)b));
@@ -1201,7 +1202,7 @@ GSList *object_class_get_list_sorted(const char 
*implements_type,
   bool include_abstract)
  {
  return g_slist_sort(object_class_get_list(implements_type, 
include_abstract),
-object_class_cmp);
+(GCompareFunc)object_class_cmp);
  }
  
  Object *object_ref(void *objptr)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index bb445e30cd..68f81fadfc 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -220,7 +220,7 @@ static void count_cpreg(gpointer key, gpointer opaque)
  }
  }
  
-static gint cpreg_key_compare(gconstpointer a, gconstpointer b)

+static gint cpreg_key_compare(gconstpointer a, gconstpointer b, void *d)
  {
  uint64_t aidx = cpreg_to_kvm_id((uintptr_t)a);
  uint64_t bidx = cpreg_to_kvm_id((uintptr_t)b);
@@ -244,7 +244,7 @@ void init_cpreg_list(ARMCPU *cpu)
  int arraylen;
  
  keys = g_hash_table_get_keys(cpu->cp_regs);

-keys = g_list_sort(keys, cpreg_key_compare);
+keys = g_list_sort(keys, (GCompareFunc)cpreg_key_compare);
  
  cpu->cpreg_array_len = 0;
  





Re: [PATCH 05/10] meson: Add wasm build in build scripts

2025-04-09 Thread Philippe Mathieu-Daudé

Cc'ing Pierrick

On 7/4/25 16:45, Kohei Tokunaga wrote:

has_int128_type is set to false on emscripten as of now to avoid errors by
libffi. And tests aren't integrated with Wasm execution environment as of
now so this commit disables tests.

Signed-off-by: Kohei Tokunaga 
---
  configs/meson/emscripten.txt  |  6 ++
  configure |  7 +++
  meson.build   | 14 ++
  meson_options.txt |  2 +-
  scripts/meson-buildoptions.sh |  2 +-
  5 files changed, 25 insertions(+), 6 deletions(-)
  create mode 100644 configs/meson/emscripten.txt

diff --git a/configs/meson/emscripten.txt b/configs/meson/emscripten.txt
new file mode 100644
index 00..054b263814
--- /dev/null
+++ b/configs/meson/emscripten.txt
@@ -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']
diff --git a/configure b/configure
index 02f1dd2311..a1fe6e11cd 100755
--- a/configure
+++ b/configure
@@ -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
@@ -526,6 +530,9 @@ case "$cpu" in
  linux_arch=x86
  CPU_CFLAGS="-m64"
  ;;
+  wasm32)
+CPU_CFLAGS="-m32"
+;;
  esac
  
  if test -n "$host_arch" && {

diff --git a/meson.build b/meson.build
index 41f68d3806..bcf1e33ddf 100644
--- a/meson.build
+++ b/meson.build
@@ -50,9 +50,9 @@ genh = []
  qapi_trace_events = []
  
  bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin']

-supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 
'sunos', 'linux']
+supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 
'sunos', 'linux', 'emscripten']
  supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 
'x86_64',
-  'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc64']
+  'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc64', 'wasm32']
  
  cpu = host_machine.cpu_family()
  
@@ -353,6 +353,8 @@ foreach lang : all_languages

# endif
#endif''')
  # ok
+  elif compiler.get_id() == 'emscripten'
+# ok
else
  error('You either need GCC v7.4 or Clang v10.0 (or XCode Clang v15.0) to 
compile QEMU')
endif
@@ -514,6 +516,8 @@ ucontext_probe = '''
  supported_backends = []
  if host_os == 'windows'
supported_backends += ['windows']
+elif host_os == 'emscripten'
+  supported_backends += ['fiber']
  else
if host_os != 'darwin' and cc.links(ucontext_probe)
  supported_backends += ['ucontext']
@@ -2962,7 +2966,7 @@ config_host_data.set('CONFIG_ATOMIC64', cc.links('''
  return 0;
}''', args: qemu_isa_flags))
  
-has_int128_type = cc.compiles('''

+has_int128_type = host_os != 'emscripten' and cc.compiles('''
__int128_t a;
__uint128_t b;
int main(void) { b = a; }''')
@@ -4456,7 +4460,9 @@ subdir('scripts')
  subdir('tools')
  subdir('pc-bios')
  subdir('docs')
-subdir('tests')
+if host_os != 'emscripten'
+  subdir('tests')
+endif
  if gtk.found()
subdir('po')
  endif
diff --git a/meson_options.txt b/meson_options.txt
index 59d973bca0..6d73aafe91 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -34,7 +34,7 @@ option('fuzzing_engine', type : 'string', value : '',
  option('trace_file', type: 'string', value: 'trace',
 description: 'Trace file prefix for simple backend')
  option('coroutine_backend', type: 'combo',
-   choices: ['ucontext', 'sigaltstack', 'windows', 'auto'],
+   choices: ['ucontext', 'sigaltstack', 'windows', 'auto', 'fiber'],
 value: 'auto', description: 'coroutine backend to use')
  
  # Everything else can be set via --enable/--disable-* option

diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
index 3e8e00852b..cbba2f248c 100644
--- a/scripts/meson-buildoptions.sh
+++ b/scripts/meson-buildoptions.sh
@@ -80,7 +80,7 @@ meson_options_help() {
printf "%s\n" '  --tls-priority=VALUE Default TLS protocol/cipher

Re: [PATCH v6] block/file-posix.c: Use pwritev2() with RWF_DSYNC for FUA

2025-04-09 Thread Kevin Wolf
Am 07.04.2025 um 17:47 hat Pinku Deb Nath geschrieben:
> Full Unit Access (FUA) is an optimization where a disk write with the
> flag set will be persisted to disk immediately instead of potentially
> remaining in the disk's write cache.
> 
> This commit address the todo task
> for using pwritev2() with RWF_DSYNC in the thread pool section of
> raw_co_prw(), if pwritev2() with RWF_DSYNC is available in the host,
> which is always the case for Linux kernel >= 4.7.
> 
> The intent for FUA is indicated with the BDRV_REQ_FUA flag.
> The old code paths are preserved in case BDRV_REQ_FUA is off
> or pwritev2() with RWF_DSYNC is not available.
> 
> Support for disk writes with FUA is handled in qemu_pwritev_fua(),
> which uses pwritev2() with RWF_DSYNC if available, otherwise falls
> back to pwritev2() with no flags followed by flush using
> handle_aiocb_flush().
> 
> If pwritev2() is not implemented, then disk write in the linear FUA
> will fallback to pwrite() + handle_aiocb_flush().
> 
> Signed-off-by: Pinku Deb Nath 
> 
> ---
> 
> v5:
> - Use pwritev for unsupported OSes
> 
> v4:
> - Add fallback when qemu_pwritev_fua() returns ENOSYS
> - Similar fallback was not added for handle_aiocb_rw_vector()
> since there is a preadv_present check in handle_aiocb_rw()
> 
> v3:
> - Changed signature to add fd, iov, nr_iov
> - Return -ENOSYS for non-Linux hosts
> 
> v2:
> - Moved handle_aiocb_flush() into qemu_pwritev_fua()
> - In handle_aiocb_rw_linear(), iovec with iovcnt=1 is created
> based on the assumption that there will be only one buffer
> ---
>  block/file-posix.c | 68 ++
>  1 file changed, 56 insertions(+), 12 deletions(-)
> 
> diff --git a/block/file-posix.c b/block/file-posix.c
> index 56d1972d15..380f709917 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -229,6 +229,7 @@ typedef struct RawPosixAIOData {
>  unsigned long op;
>  } zone_mgmt;
>  };
> +BdrvRequestFlags flags;
>  } RawPosixAIOData;
>  
>  #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
> @@ -1674,6 +1675,20 @@ qemu_pwritev(int fd, const struct iovec *iov, int 
> nr_iov, off_t offset)
>  return pwritev(fd, iov, nr_iov, offset);
>  }
>  
> +static ssize_t
> +qemu_pwritev_fua(int fd, struct iovec *iov, int nr_iov, off_t offset, 
> RawPosixAIOData *aiocb)
> +{
> +#ifdef RWF_DSYNC
> +return pwritev2(fd, iov, nr_iov, offset, RWF_DSYNC);

If pwritev2() fails with ENOSYS, we'll disable even pwritev(). I think
we should only try pwritev2(), and if it returns ENOSYS, we can execute
the code below with pwritev() + handle_aiocb_flush(), which would then
be outside the #ifdef.

Similar to preadv_present, we can have a bool pwritev2_present to avoid
trying pwritev2() every time when we already know it's not there.

> +#else
> +ssize_t len = pwritev(fd, iov, nr_iov, offset);
> +if (len == 0) {

pwritev() doesn't return 0, but the number of written bytes on success
(you even called the result 'len'!), so with len == 0, we would only
flush if someone tries to write at EOF of a block device or something.

> +len = handle_aiocb_flush(aiocb);
> +}
> +return len;
> +#endif
> +}
> +
>  #else
>  
>  static bool preadv_present = false;
> @@ -1690,6 +1705,11 @@ qemu_pwritev(int fd, const struct iovec *iov, int 
> nr_iov, off_t offset)
>  return -ENOSYS;
>  }
>  
> +static ssize_t
> +qemu_pwritev_fua(int fd, struct iovec *iov, int nr_iov, off_t offset, const 
> RawPosixAIOData *aiocb)
> +{
> +return -ENOSYS;
> +}

This is inconsistent with the interface of the function above. The
function above returns -1 with errno set on error, this one directly
returns a negative errno code. We need to pick one interface and stick
to it.

The existing definitions for qemu_preadv() are misleading because they
have the same problem - but they are never actually called because
preadv_present is always false. But qemu_pwritev_fua() is called below
in handle_aiocb_rw_linear() without checking preadv_present, so it
doesn't have the same excuse.

If you check a new pwritev2_present in handle_aiocb_rw_linear() and
initialise it as false in this #else block, then what we return here
doesn't matter any more and you can keep it consistent with the other
(misleading) functions.

(I think we should actually replace the existing return -ENOSYS with
g_assert_not_reached(), but that is for a separate patch.)

>  #endif
>  
>  static ssize_t handle_aiocb_rw_vector(RawPosixAIOData *aiocb)
> @@ -1698,10 +1718,16 @@ static ssize_t handle_aiocb_rw_vector(RawPosixAIOData 
> *aiocb)
>  
>  len = RETRY_ON_EINTR(
>  (aiocb->aio_type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) ?
> -qemu_pwritev(aiocb->aio_fildes,
> -   aiocb->io.iov,
> -   aiocb->io.niov,
> -   aiocb->aio_offset) :
> +(aiocb->flags &  BDRV_REQ_FUA) ?

Double space.

> +qemu_pwritev_fua(ai