Compare commits

...

2 Commits

15 changed files with 1472 additions and 2 deletions

2
.gitignore vendored
View File

@ -2,4 +2,4 @@ SOURCES/qemu-6.2.0.tar.xz
SOURCES/tests_data_acpi_pc_SSDT.dimmpxm
SOURCES/tests_data_acpi_q35_FACP.slic
SOURCES/tests_data_acpi_q35_SSDT.dimmpxm
SOURCES/tests_data_acpi_virt_SSDT.memhp
SOURCES/tests_data_acpi_virt_SSDT.memhp

View File

@ -0,0 +1,189 @@
From b57e930ad6e2e2aea35c046a2a5ea6b04c472c5b Mon Sep 17 00:00:00 2001
From: Jon Maloy <jmaloy@redhat.com>
Date: Tue, 4 Nov 2025 17:28:47 -0500
Subject: [PATCH 2/2] io: fix use after free in websocket handshake code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Jon Maloy <jmaloy@redhat.com>
RH-MergeRequest: 499: io: fix use after free in websocket handshake code
RH-Jira: RHEL-120119
RH-Acked-by: Daniel P. Berrangé <berrange@redhat.com>
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Commit: [2/2] d9a0db83d83e8275decdba615338a9dee3a8d33c (redhat/rhel/src/qemu-kvm/jons-qemu-kvm-2)
JIRA: https://issues.redhat.com/browse/RHEL-120119
CVE: CVE-2025-11234
commit b7a1f2ca45c7865b9e98e02ae605a65fc9458ae9
Author: Daniel P. Berrangé <berrange@redhat.com>
Date: Tue Sep 30 12:03:15 2025 +0100
io: fix use after free in websocket handshake code
If the QIOChannelWebsock object is freed while it is waiting to
complete a handshake, a GSource is leaked. This can lead to the
callback firing later on and triggering a use-after-free in the
use of the channel. This was observed in the VNC server with the
following trace from valgrind:
==2523108== Invalid read of size 4
==2523108== at 0x4054A24: vnc_disconnect_start (vnc.c:1296)
==2523108== by 0x4054A24: vnc_client_error (vnc.c:1392)
==2523108== by 0x4068A09: vncws_handshake_done (vnc-ws.c:105)
==2523108== by 0x44863B4: qio_task_complete (task.c:197)
==2523108== by 0x448343D: qio_channel_websock_handshake_io (channel-websock.c:588)
==2523108== by 0x6EDB862: UnknownInlinedFun (gmain.c:3398)
==2523108== by 0x6EDB862: g_main_context_dispatch_unlocked.lto_priv.0 (gmain.c:4249)
==2523108== by 0x6EDBAE4: g_main_context_dispatch (gmain.c:4237)
==2523108== by 0x45EC79F: glib_pollfds_poll (main-loop.c:287)
==2523108== by 0x45EC79F: os_host_main_loop_wait (main-loop.c:310)
==2523108== by 0x45EC79F: main_loop_wait (main-loop.c:589)
==2523108== by 0x423A56D: qemu_main_loop (runstate.c:835)
==2523108== by 0x454F300: qemu_default_main (main.c:37)
==2523108== by 0x73D6574: (below main) (libc_start_call_main.h:58)
==2523108== Address 0x57a6e0dc is 28 bytes inside a block of size 103,608 free'd
==2523108== at 0x5F2FE43: free (vg_replace_malloc.c:989)
==2523108== by 0x6EDC444: g_free (gmem.c:208)
==2523108== by 0x4053F23: vnc_update_client (vnc.c:1153)
==2523108== by 0x4053F23: vnc_refresh (vnc.c:3225)
==2523108== by 0x4042881: dpy_refresh (console.c:880)
==2523108== by 0x4042881: gui_update (console.c:90)
==2523108== by 0x45EFA1B: timerlist_run_timers.part.0 (qemu-timer.c:562)
==2523108== by 0x45EFC8F: timerlist_run_timers (qemu-timer.c:495)
==2523108== by 0x45EFC8F: qemu_clock_run_timers (qemu-timer.c:576)
==2523108== by 0x45EFC8F: qemu_clock_run_all_timers (qemu-timer.c:663)
==2523108== by 0x45EC765: main_loop_wait (main-loop.c:600)
==2523108== by 0x423A56D: qemu_main_loop (runstate.c:835)
==2523108== by 0x454F300: qemu_default_main (main.c:37)
==2523108== by 0x73D6574: (below main) (libc_start_call_main.h:58)
==2523108== Block was alloc'd at
==2523108== at 0x5F343F3: calloc (vg_replace_malloc.c:1675)
==2523108== by 0x6EE2F81: g_malloc0 (gmem.c:133)
==2523108== by 0x4057DA3: vnc_connect (vnc.c:3245)
==2523108== by 0x448591B: qio_net_listener_channel_func (net-listener.c:54)
==2523108== by 0x6EDB862: UnknownInlinedFun (gmain.c:3398)
==2523108== by 0x6EDB862: g_main_context_dispatch_unlocked.lto_priv.0 (gmain.c:4249)
==2523108== by 0x6EDBAE4: g_main_context_dispatch (gmain.c:4237)
==2523108== by 0x45EC79F: glib_pollfds_poll (main-loop.c:287)
==2523108== by 0x45EC79F: os_host_main_loop_wait (main-loop.c:310)
==2523108== by 0x45EC79F: main_loop_wait (main-loop.c:589)
==2523108== by 0x423A56D: qemu_main_loop (runstate.c:835)
==2523108== by 0x454F300: qemu_default_main (main.c:37)
==2523108== by 0x73D6574: (below main) (libc_start_call_main.h:58)
==2523108==
The above can be reproduced by launching QEMU with
$ qemu-system-x86_64 -vnc localhost:0,websocket=5700
and then repeatedly running:
for i in {1..100}; do
(echo -n "GET / HTTP/1.1" && sleep 0.05) | nc -w 1 localhost 5700 &
done
CVE-2025-11234
Reported-by: Grant Millar | Cylo <rid@cylo.io>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Jon Maloy <jmaloy@redhat.com>
---
include/io/channel-websock.h | 3 ++-
io/channel-websock.c | 22 ++++++++++++++++------
2 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/include/io/channel-websock.h b/include/io/channel-websock.h
index e180827c57..6700cf8946 100644
--- a/include/io/channel-websock.h
+++ b/include/io/channel-websock.h
@@ -61,7 +61,8 @@ struct QIOChannelWebsock {
size_t payload_remain;
size_t pong_remain;
QIOChannelWebsockMask mask;
- guint io_tag;
+ guint hs_io_tag; /* tracking handshake task */
+ guint io_tag; /* tracking watch task */
Error *io_err;
gboolean io_eof;
uint8_t opcode;
diff --git a/io/channel-websock.c b/io/channel-websock.c
index ade319cb71..1b80d77f7d 100644
--- a/io/channel-websock.c
+++ b/io/channel-websock.c
@@ -545,6 +545,7 @@ static gboolean qio_channel_websock_handshake_send(QIOChannel *ioc,
trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err));
qio_task_set_error(task, err);
qio_task_complete(task);
+ wioc->hs_io_tag = 0;
return FALSE;
}
@@ -560,6 +561,7 @@ static gboolean qio_channel_websock_handshake_send(QIOChannel *ioc,
trace_qio_channel_websock_handshake_complete(ioc);
qio_task_complete(task);
}
+ wioc->hs_io_tag = 0;
return FALSE;
}
trace_qio_channel_websock_handshake_pending(ioc, G_IO_OUT);
@@ -586,6 +588,7 @@ static gboolean qio_channel_websock_handshake_io(QIOChannel *ioc,
trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err));
qio_task_set_error(task, err);
qio_task_complete(task);
+ wioc->hs_io_tag = 0;
return FALSE;
}
if (ret == 0) {
@@ -597,7 +600,7 @@ static gboolean qio_channel_websock_handshake_io(QIOChannel *ioc,
error_propagate(&wioc->io_err, err);
trace_qio_channel_websock_handshake_reply(ioc);
- qio_channel_add_watch(
+ wioc->hs_io_tag = qio_channel_add_watch(
wioc->master,
G_IO_OUT,
qio_channel_websock_handshake_send,
@@ -906,11 +909,12 @@ void qio_channel_websock_handshake(QIOChannelWebsock *ioc,
trace_qio_channel_websock_handshake_start(ioc);
trace_qio_channel_websock_handshake_pending(ioc, G_IO_IN);
- qio_channel_add_watch(ioc->master,
- G_IO_IN,
- qio_channel_websock_handshake_io,
- task,
- NULL);
+ ioc->hs_io_tag = qio_channel_add_watch(
+ ioc->master,
+ G_IO_IN,
+ qio_channel_websock_handshake_io,
+ task,
+ NULL);
}
@@ -921,6 +925,9 @@ static void qio_channel_websock_finalize(Object *obj)
buffer_free(&ioc->encinput);
buffer_free(&ioc->encoutput);
buffer_free(&ioc->rawinput);
+ if (ioc->hs_io_tag) {
+ g_source_remove(ioc->hs_io_tag);
+ }
if (ioc->io_tag) {
g_source_remove(ioc->io_tag);
}
@@ -1221,6 +1228,9 @@ static int qio_channel_websock_close(QIOChannel *ioc,
buffer_free(&wioc->encinput);
buffer_free(&wioc->encoutput);
buffer_free(&wioc->rawinput);
+ if (wioc->hs_io_tag) {
+ g_clear_handle_id(&wioc->hs_io_tag, g_source_remove);
+ }
if (wioc->io_tag) {
g_clear_handle_id(&wioc->io_tag, g_source_remove);
}
--
2.50.1

View File

@ -0,0 +1,84 @@
From c8540f2b17b85d539b50915f50aff4a4c817921f Mon Sep 17 00:00:00 2001
From: Jon Maloy <jmaloy@redhat.com>
Date: Tue, 4 Nov 2025 17:23:29 -0500
Subject: [PATCH 1/2] io: move websock resource release to close method
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Jon Maloy <jmaloy@redhat.com>
RH-MergeRequest: 499: io: fix use after free in websocket handshake code
RH-Jira: RHEL-120119
RH-Acked-by: Daniel P. Berrangé <berrange@redhat.com>
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Commit: [1/2] 20cbfece57dcbef55caebf33812065465de567df (redhat/rhel/src/qemu-kvm/jons-qemu-kvm-2)
JIRA: https://issues.redhat.com/browse/RHEL-120119
CVE: CVE-2025-11234
commit 322c3c4f3abee616a18b3bfe563ec29dd67eae63
Author: Daniel P. Berrangé <berrange@redhat.com>
Date: Tue Sep 30 11:58:35 2025 +0100
io: move websock resource release to close method
The QIOChannelWebsock object releases all its resources in the
finalize callback. This is later than desired, as callers expect
to be able to call qio_channel_close() to fully close a channel
and release resources related to I/O.
The logic in the finalize method is at most a failsafe to handle
cases where a consumer forgets to call qio_channel_close.
This adds equivalent logic to the close method to release the
resources, using g_clear_handle_id/g_clear_pointer to be robust
against repeated invocations. The finalize method is tweaked
so that the GSource is removed before releasing the underlying
channel.
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Jon Maloy <jmaloy@redhat.com>
---
io/channel-websock.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/io/channel-websock.c b/io/channel-websock.c
index 13c94f2afe..ade319cb71 100644
--- a/io/channel-websock.c
+++ b/io/channel-websock.c
@@ -921,13 +921,13 @@ static void qio_channel_websock_finalize(Object *obj)
buffer_free(&ioc->encinput);
buffer_free(&ioc->encoutput);
buffer_free(&ioc->rawinput);
- object_unref(OBJECT(ioc->master));
if (ioc->io_tag) {
g_source_remove(ioc->io_tag);
}
if (ioc->io_err) {
error_free(ioc->io_err);
}
+ object_unref(OBJECT(ioc->master));
}
@@ -1218,6 +1218,15 @@ static int qio_channel_websock_close(QIOChannel *ioc,
QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);
trace_qio_channel_websock_close(ioc);
+ buffer_free(&wioc->encinput);
+ buffer_free(&wioc->encoutput);
+ buffer_free(&wioc->rawinput);
+ if (wioc->io_tag) {
+ g_clear_handle_id(&wioc->io_tag, g_source_remove);
+ }
+ if (wioc->io_err) {
+ g_clear_pointer(&wioc->io_err, error_free);
+ }
return qio_channel_close(wioc->master, errp);
}
--
2.50.1

View File

@ -0,0 +1,94 @@
From 661c0fee958d993b5c8d4600998ba0fdbf43da11 Mon Sep 17 00:00:00 2001
From: Konstantin Kostiuk <kkostiuk@redhat.com>
Date: Wed, 18 Dec 2024 18:49:04 +0200
Subject: [PATCH] qga: skip bind mounts in fs list
RH-Author: Konstantin Kostiuk <None>
RH-MergeRequest: 423: qga: skip bind mounts in fs list
RH-Jira: RHEL-59214
RH-Acked-by: yvugenfi <None>
RH-Acked-by: Jon Maloy <jmaloy@redhat.com>
RH-Commit: [1/1] 2ebf2a4dba0e2da9d077c116accd12dc7f3dbcd1
The filesystem list in build_fs_mount_list should skip bind mounts.
This because we end up in locking situations when doing fsFreeze. Like
mentioned in [1] and [2].
Next to that, the build_fs_mount_list call did a fallback via
build_fs_mount_list_from_mtab if mountinfo did not exist.
There it skipped bind mounts, but this is broken for newer OS.
This as mounts does not return the path of the bind mount but the
underlying dev/partition, so S_ISDIR will never return true in
dev_major_minor call.
This patch simply checks the existing devmajor:devminor tuple in the
mounts, and if it already exists, this means we have the same devices
mounted again, a bind mount. So skip this.
Same approach is used in open-vm-tools [3].
[1]: https://gitlab.com/qemu-project/qemu/-/issues/592
[2]: https://gitlab.com/qemu-project/qemu/-/issues/520
[3]: https://github.com/vmware/open-vm-tools/commit/d58847b497e212737007958c945af1df22a8ab58
Signed-off-by: Jean-Louis Dupond <jean-louis@dupond.be>
Reviewed-by: Konstantin Kostiuk <kkostiuk@redhat.com>
Link: https://lore.kernel.org/r/20241002100634.162499-2-jean-louis@dupond.be
Signed-off-by: Konstantin Kostiuk <kkostiuk@redhat.com>
---
qga/commands-posix.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 75dbaab68e..dce0d1551f 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -668,6 +668,22 @@ static int dev_major_minor(const char *devpath,
return -1;
}
+/*
+ * Check if we already have the devmajor:devminor in the mounts
+ * If thats the case return true.
+ */
+static bool dev_exists(FsMountList *mounts, unsigned int devmajor, unsigned int devminor)
+{
+ FsMount *mount;
+
+ QTAILQ_FOREACH(mount, mounts, next) {
+ if (mount->devmajor == devmajor && mount->devminor == devminor) {
+ return true;
+ }
+ }
+ return false;
+}
+
/*
* Walk the mount table and build a list of local file systems
*/
@@ -701,6 +717,10 @@ static void build_fs_mount_list_from_mtab(FsMountList *mounts, Error **errp)
/* Skip bind mounts */
continue;
}
+ if (dev_exists(mounts, devmajor, devminor)) {
+ /* Skip already existing devices (bind mounts) */
+ continue;
+ }
mount = g_new0(FsMount, 1);
mount->dirname = g_strdup(ment->mnt_dir);
@@ -780,6 +800,11 @@ static void build_fs_mount_list(FsMountList *mounts, Error **errp)
continue;
}
}
+
+ if (dev_exists(mounts, devmajor, devminor)) {
+ /* Skip already existing devices (bind mounts) */
+ continue;
+ }
mount = g_new0(FsMount, 1);
mount->dirname = g_strdup(line + dir_s);
--
2.47.1

View File

@ -0,0 +1,52 @@
From 1c0887f9a108a237fc87834c87e9d0358dd98dd9 Mon Sep 17 00:00:00 2001
From: Thomas Huth <thuth@redhat.com>
Date: Wed, 23 Apr 2025 12:54:42 +0200
Subject: [PATCH 5/5] redhat: Adjust indentation in qapi/machine-target.json
for QEMU v6.2
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 449: Fix for live-migrating guests from IBM z16 to z17 host machines
RH-Jira: RHEL-88701
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [5/5] 1a50aac42e2b8e2990f5a00f69117a58911c8107
Upstream Status: RHEL-only
JIRA: https://issues.redhat.com/browse/RHEL-88701
The QAPI parser of QEMU v6.2 is stricter with the indentation rules,
so we have to adjust the indentation with the colon of the previous
line here.
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
qapi/machine-target.json | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/qapi/machine-target.json b/qapi/machine-target.json
index 320688cd21..415e0fc3c6 100644
--- a/qapi/machine-target.json
+++ b/qapi/machine-target.json
@@ -210,11 +210,11 @@
# @model: the expanded CpuModelInfo.
#
# @deprecated-props: a list of properties that are flagged as deprecated
-# by the CPU vendor. The list depends on the CpuModelExpansionType:
-# "static" properties are a subset of the enabled-properties for
-# the expanded model; "full" properties are a set of properties
-# that are deprecated across all models for the architecture.
-# (since: 9.1).
+# by the CPU vendor. The list depends on the CpuModelExpansionType:
+# "static" properties are a subset of the enabled-properties for
+# the expanded model; "full" properties are a set of properties
+# that are deprecated across all models for the architecture.
+# (since: 9.1).
#
# Since: 2.8
##
--
2.48.1

View File

@ -0,0 +1,79 @@
From 7ec344bf9285cf854db5a643af5b9111aa47eee5 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Wed, 31 Jul 2024 14:32:05 +0200
Subject: [PATCH 2/5] scsi-block: Don't skip callback for sgio error
status/driver_status
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 513: scsi-block: Fix error handling with r/werror=stop
RH-Jira: RHEL-120737
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [2/5] 29d87d7eb1241586a852a7f63e0ec0232a28a3ac (kmwolf/rhel-qemu-kvm)
Instead of calling into scsi_handle_rw_error() directly from
scsi_block_sgio_complete() and skipping the normal callback, go through
the normal cleanup path by calling the callback with a positive error
value.
The important difference here is not only that the code path is cleaner,
but that the callbacks set r->req.aiocb = NULL. If we skip setting this
and the error action is BLOCK_ERROR_ACTION_STOP, resuming the VM runs
into an assertion failure in scsi_read_data() or scsi_write_data()
because the dangling aiocb pointer is unexpected.
Fixes: a108557bbf ("scsi: inline sg_io_sense_from_errno() into the callers.")
Buglink: https://issues.redhat.com/browse/RHEL-50000
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Message-ID: <20240731123207.27636-3-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 622a70161ac258e4a166a7dca4b5be267e0652d9)
Conflicts:
hw/scsi/scsi-disk.c
RHEL 8.10 still uses AioContext locks, so the removed code is slightly
different. The callbacks that replace it have all the necessary locking
in place.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
hw/scsi/scsi-disk.c | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 463c14590f..a677ad8a92 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2703,7 +2703,6 @@ static void scsi_block_sgio_complete(void *opaque, int ret)
{
SCSIBlockReq *req = (SCSIBlockReq *)opaque;
SCSIDiskReq *r = &req->req;
- SCSIDevice *s = r->req.dev;
sg_io_hdr_t *io_hdr = &req->io_header;
if (ret == 0) {
@@ -2718,19 +2717,6 @@ static void scsi_block_sgio_complete(void *opaque, int ret)
} else {
ret = io_hdr->status;
}
-
- if (ret > 0) {
- aio_context_acquire(blk_get_aio_context(s->conf.blk));
- if (scsi_handle_rw_error(r, ret, true)) {
- aio_context_release(blk_get_aio_context(s->conf.blk));
- scsi_req_unref(&r->req);
- return;
- }
- aio_context_release(blk_get_aio_context(s->conf.blk));
-
- /* Ignore error. */
- ret = 0;
- }
}
req->cb(req->cb_opaque, ret);
--
2.51.1

View File

@ -0,0 +1,79 @@
From e471621283748a1de44f4765be0dda5d38267e21 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Wed, 31 Jul 2024 14:32:06 +0200
Subject: [PATCH 3/5] scsi-disk: Add warning comments that host_status errors
take a shortcut
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 513: scsi-block: Fix error handling with r/werror=stop
RH-Jira: RHEL-120737
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [3/5] 9ab9eae6eaa6465d021f438c56bcfd92dd528ffd (kmwolf/rhel-qemu-kvm)
scsi_block_sgio_complete() has surprising behaviour in that there are
error cases in which it directly completes the request and never calls
the passed callback. In the current state of the code, this doesn't seem
to result in bugs, but with future code changes, we must be careful to
never rely on the callback doing some cleanup until this code smell is
fixed. For now, just add warnings to make people aware of the trap.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Message-ID: <20240731123207.27636-4-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 8a0495624f23f8f01dfb1484f367174f3b3572e8)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
hw/scsi/scsi-disk.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index a677ad8a92..72ce420bfc 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -63,6 +63,9 @@ struct SCSIDiskClass {
/*
* Callbacks receive ret == 0 for success. Errors are represented either as
* negative errno values, or as positive SAM status codes.
+ *
+ * Beware: For errors returned in host_status, the function may directly
+ * complete the request and never call the callback.
*/
DMAIOFunc *dma_readv;
DMAIOFunc *dma_writev;
@@ -356,6 +359,7 @@ done:
}
/* Called with AioContext lock held */
+/* May not be called in all error cases, don't rely on cleanup here */
static void scsi_dma_complete(void *opaque, int ret)
{
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
@@ -391,6 +395,7 @@ done:
scsi_req_unref(&r->req);
}
+/* May not be called in all error cases, don't rely on cleanup here */
static void scsi_read_complete(void *opaque, int ret)
{
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
@@ -531,6 +536,7 @@ done:
scsi_req_unref(&r->req);
}
+/* May not be called in all error cases, don't rely on cleanup here */
static void scsi_write_complete(void * opaque, int ret)
{
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
@@ -2706,6 +2712,7 @@ static void scsi_block_sgio_complete(void *opaque, int ret)
sg_io_hdr_t *io_hdr = &req->io_header;
if (ret == 0) {
+ /* FIXME This skips calling req->cb() and any cleanup in it */
if (io_hdr->host_status != SCSI_HOST_OK) {
scsi_req_complete_failed(&r->req, io_hdr->host_status);
scsi_req_unref(&r->req);
--
2.51.1

View File

@ -0,0 +1,105 @@
From 1347455e52ebe93e52c56d1d1b3107f35242dbcb Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Wed, 31 Jul 2024 14:32:07 +0200
Subject: [PATCH 4/5] scsi-disk: Always report RESERVATION_CONFLICT to guest
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 513: scsi-block: Fix error handling with r/werror=stop
RH-Jira: RHEL-120737
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [4/5] 651265ef6da28e1371b1f945921004f84784a840 (kmwolf/rhel-qemu-kvm)
In the case of scsi-block, RESERVATION_CONFLICT is not a backend error,
but indicates that the guest tried to make a request that it isn't
allowed to execute. Pass the error to the guest so that it can decide
what to do with it.
Without this, if we stop the VM in response to a RESERVATION_CONFLICT
(as is the default policy in management software such as oVirt or
KubeVirt), it can happen that the VM cannot be resumed any more because
every attempt to resume it immediately runs into the same error and
stops the VM again.
One case that expects RESERVATION_CONFLICT errors to be visible in the
guest is running the validation tests in Windows 2019's Failover Cluster
Manager, which intentionally tries to execute invalid requests to see if
they are properly rejected.
Buglink: https://issues.redhat.com/browse/RHEL-50000
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Message-ID: <20240731123207.27636-5-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 9da6bd39f92434f55573acd017841b195c60188f)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
hw/scsi/scsi-disk.c | 35 ++++++++++++++++++++++++++++++-----
1 file changed, 30 insertions(+), 5 deletions(-)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 72ce420bfc..4e70cf1342 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -199,7 +199,7 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int ret, bool acct_failed)
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s));
SCSISense sense = SENSE_CODE(NO_SENSE);
- int error = 0;
+ int error;
bool req_has_sense = false;
BlockErrorAction action;
int status;
@@ -210,11 +210,35 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int ret, bool acct_failed)
} else {
/* A passthrough command has completed with nonzero status. */
status = ret;
- if (status == CHECK_CONDITION) {
+ switch (status) {
+ case CHECK_CONDITION:
req_has_sense = true;
error = scsi_sense_buf_to_errno(r->req.sense, sizeof(r->req.sense));
- } else {
+ break;
+ case RESERVATION_CONFLICT:
+ /*
+ * Don't apply the error policy, always report to the guest.
+ *
+ * This is a passthrough code path, so it's not a backend error, but
+ * a response to an invalid guest request.
+ *
+ * Windows Failover Cluster validation intentionally sends invalid
+ * requests to verify that reservations work as intended. It is
+ * crucial that it sees the resulting errors.
+ *
+ * Treating a reservation conflict as a guest-side error is obvious
+ * when a pr-manager is in use. Without one, the situation is less
+ * clear, but there might be nothing that can be fixed on the host
+ * (like in the above example), and we don't want to be stuck in a
+ * loop where resuming the VM and retrying the request immediately
+ * stops it again. So always reporting is still the safer option in
+ * this case, too.
+ */
+ error = 0;
+ break;
+ default:
error = EINVAL;
+ break;
}
}
@@ -224,8 +248,9 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int ret, bool acct_failed)
* are usually retried immediately, so do not post them to QMP and
* do not account them as failed I/O.
*/
- if (req_has_sense &&
- scsi_sense_buf_is_guest_recoverable(r->req.sense, sizeof(r->req.sense))) {
+ if (!error || (req_has_sense &&
+ scsi_sense_buf_is_guest_recoverable(r->req.sense,
+ sizeof(r->req.sense)))) {
action = BLOCK_ERROR_ACTION_REPORT;
acct_failed = false;
} else {
--
2.51.1

View File

@ -0,0 +1,155 @@
From 5e021a147a211ef2a75e9293f5f54951e1c87d7f Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Mon, 7 Apr 2025 17:59:49 +0200
Subject: [PATCH 5/5] scsi-disk: Apply error policy for host_status errors
again
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 513: scsi-block: Fix error handling with r/werror=stop
RH-Jira: RHEL-120737
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [5/5] d4316323cf0d28c42e06a485b9569cc548494337 (kmwolf/rhel-qemu-kvm)
Originally, all failed SG_IO requests called scsi_handle_rw_error() to
apply the configured error policy. However, commit f3126d65, which was
supposed to be a mere refactoring for scsi-disk.c, broke this and
accidentally completed the SCSI request without considering the error
policy any more if the error was signalled in the host_status field.
Apart from the commit message not describing the change as intended,
errors indicated in host_status are also obviously backend errors and
not something the guest must deal with independently of the error
policy.
This behaviour means that some recoverable errors (such as a path error
in multipath configurations) were reported to the guest anyway, which
might not expect it and might consider its disk broken.
Make sure that we apply the error policy again for host_status errors,
too. This addresses an existing FIXME comment and allows us to remove
some comments warning that callbacks weren't always called. With this
fix, they are called in all cases again.
The return value passed to the request callback doesn't have more free
values that could be used to indicate host_status errors as well as SAM
status codes and negative errno. Store the value in the host_status
field of the SCSIRequest instead and use -ENODEV as the return value (if
a path hasn't been reachable for a while, blk_aio_ioctl() will return
-ENODEV instead of just setting host_status, so just reuse it here -
it's not necessarily entirely accurate, but it's as good as any errno).
Cc: qemu-stable@nongnu.org
Fixes: f3126d65b393 ('scsi: move host_status handling into SCSI drivers')
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20250407155949.44736-1-kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 61b6d9b749ba233784c7214cfe9585ea321159dc)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
hw/scsi/scsi-disk.c | 39 +++++++++++++++++++++++++--------------
1 file changed, 25 insertions(+), 14 deletions(-)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 4e70cf1342..46fbee1a64 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -62,10 +62,9 @@ struct SCSIDiskClass {
SCSIDeviceClass parent_class;
/*
* Callbacks receive ret == 0 for success. Errors are represented either as
- * negative errno values, or as positive SAM status codes.
- *
- * Beware: For errors returned in host_status, the function may directly
- * complete the request and never call the callback.
+ * negative errno values, or as positive SAM status codes. For host_status
+ * errors, the function passes ret == -ENODEV and sets the host_status field
+ * of the SCSIRequest.
*/
DMAIOFunc *dma_readv;
DMAIOFunc *dma_writev;
@@ -199,11 +198,26 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int ret, bool acct_failed)
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s));
SCSISense sense = SENSE_CODE(NO_SENSE);
+ int16_t host_status;
int error;
bool req_has_sense = false;
BlockErrorAction action;
int status;
+ /*
+ * host_status should only be set for SG_IO requests that came back with a
+ * host_status error in scsi_block_sgio_complete(). This error path passes
+ * -ENODEV as the return value.
+ *
+ * Reset host_status in the request because we may still want to complete
+ * the request successfully with the 'stop' or 'ignore' error policy.
+ */
+ host_status = r->req.host_status;
+ if (host_status != -1) {
+ assert(ret == -ENODEV);
+ r->req.host_status = -1;
+ }
+
if (ret < 0) {
status = scsi_sense_from_errno(-ret, &sense);
error = -ret;
@@ -263,6 +277,10 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int ret, bool acct_failed)
if (acct_failed) {
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
}
+ if (host_status != -1) {
+ scsi_req_complete_failed(&r->req, host_status);
+ return true;
+ }
if (req_has_sense) {
sdc->update_sense(&r->req);
} else if (status == CHECK_CONDITION) {
@@ -384,7 +402,6 @@ done:
}
/* Called with AioContext lock held */
-/* May not be called in all error cases, don't rely on cleanup here */
static void scsi_dma_complete(void *opaque, int ret)
{
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
@@ -420,7 +437,6 @@ done:
scsi_req_unref(&r->req);
}
-/* May not be called in all error cases, don't rely on cleanup here */
static void scsi_read_complete(void *opaque, int ret)
{
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
@@ -561,7 +577,6 @@ done:
scsi_req_unref(&r->req);
}
-/* May not be called in all error cases, don't rely on cleanup here */
static void scsi_write_complete(void * opaque, int ret)
{
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
@@ -2737,14 +2752,10 @@ static void scsi_block_sgio_complete(void *opaque, int ret)
sg_io_hdr_t *io_hdr = &req->io_header;
if (ret == 0) {
- /* FIXME This skips calling req->cb() and any cleanup in it */
if (io_hdr->host_status != SCSI_HOST_OK) {
- scsi_req_complete_failed(&r->req, io_hdr->host_status);
- scsi_req_unref(&r->req);
- return;
- }
-
- if (io_hdr->driver_status & SG_ERR_DRIVER_TIMEOUT) {
+ r->req.host_status = io_hdr->host_status;
+ ret = -ENODEV;
+ } else if (io_hdr->driver_status & SG_ERR_DRIVER_TIMEOUT) {
ret = BUSY;
} else {
ret = io_hdr->status;
--
2.51.1

View File

@ -0,0 +1,125 @@
From 0a4b86ebcaf5c2e6623ec49374a0dea500b448b7 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Wed, 31 Jul 2024 14:32:04 +0200
Subject: [PATCH 1/5] scsi-disk: Use positive return value for status in
dma_readv/writev
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 513: scsi-block: Fix error handling with r/werror=stop
RH-Jira: RHEL-120737
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [1/5] 4e93ed1eb1d760b95b93a5a5709725c927afd3c9 (kmwolf/rhel-qemu-kvm)
In some error cases, scsi_block_sgio_complete() never calls the passed
callback, but directly completes the request. This leads to bugs because
its error paths are not exact copies of what the callback would normally
do.
In preparation to fix this, allow passing positive return values to the
callbacks that represent the status code that should be used to complete
the request.
scsi_handle_rw_error() already handles positive values for its ret
parameter because scsi_block_sgio_complete() calls directly into it.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Message-ID: <20240731123207.27636-2-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit cfe0880835cd364b590ffd27ef8dbd2ad8838bc5)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
hw/scsi/scsi-disk.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index c8109a673e..463c14590f 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -60,6 +60,10 @@ OBJECT_DECLARE_TYPE(SCSIDiskState, SCSIDiskClass, SCSI_DISK_BASE)
struct SCSIDiskClass {
SCSIDeviceClass parent_class;
+ /*
+ * Callbacks receive ret == 0 for success. Errors are represented either as
+ * negative errno values, or as positive SAM status codes.
+ */
DMAIOFunc *dma_readv;
DMAIOFunc *dma_writev;
bool (*need_fua_emulation)(SCSICommand *cmd);
@@ -258,7 +262,7 @@ static bool scsi_disk_req_check_error(SCSIDiskReq *r, int ret, bool acct_failed)
return true;
}
- if (ret < 0) {
+ if (ret != 0) {
return scsi_handle_rw_error(r, ret, acct_failed);
}
@@ -334,7 +338,7 @@ static void scsi_write_do_fua(SCSIDiskReq *r)
static void scsi_dma_complete_noio(SCSIDiskReq *r, int ret)
{
assert(r->req.aiocb == NULL);
- if (scsi_disk_req_check_error(r, ret, false)) {
+ if (scsi_disk_req_check_error(r, ret, ret > 0)) {
goto done;
}
@@ -360,9 +364,10 @@ static void scsi_dma_complete(void *opaque, int ret)
assert(r->req.aiocb != NULL);
r->req.aiocb = NULL;
+ /* ret > 0 is accounted for in scsi_disk_req_check_error() */
if (ret < 0) {
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
- } else {
+ } else if (ret == 0) {
block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
}
scsi_dma_complete_noio(r, ret);
@@ -373,7 +378,7 @@ static void scsi_read_complete_noio(SCSIDiskReq *r, int ret)
uint32_t n;
assert(r->req.aiocb == NULL);
- if (scsi_disk_req_check_error(r, ret, false)) {
+ if (scsi_disk_req_check_error(r, ret, ret > 0)) {
goto done;
}
@@ -396,9 +401,10 @@ static void scsi_read_complete(void *opaque, int ret)
assert(r->req.aiocb != NULL);
r->req.aiocb = NULL;
+ /* ret > 0 is accounted for in scsi_disk_req_check_error() */
if (ret < 0) {
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
- } else {
+ } else if (ret == 0) {
block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
trace_scsi_disk_read_complete(r->req.tag, r->qiov.size);
}
@@ -505,7 +511,7 @@ static void scsi_write_complete_noio(SCSIDiskReq *r, int ret)
uint32_t n;
assert (r->req.aiocb == NULL);
- if (scsi_disk_req_check_error(r, ret, false)) {
+ if (scsi_disk_req_check_error(r, ret, ret > 0)) {
goto done;
}
@@ -535,9 +541,10 @@ static void scsi_write_complete(void * opaque, int ret)
assert (r->req.aiocb != NULL);
r->req.aiocb = NULL;
+ /* ret > 0 is accounted for in scsi_disk_req_check_error() */
if (ret < 0) {
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
- } else {
+ } else if (ret == 0) {
block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
}
scsi_write_complete_noio(r, ret);
--
2.51.1

View File

@ -0,0 +1,110 @@
From 31c0a5fb90575b85dc9510417d6b8317319d0b57 Mon Sep 17 00:00:00 2001
From: Collin Walling <walling@linux.ibm.com>
Date: Fri, 19 Jul 2024 14:17:41 -0400
Subject: [PATCH 3/5] target/s390x: filter deprecated properties based on model
expansion type
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 449: Fix for live-migrating guests from IBM z16 to z17 host machines
RH-Jira: RHEL-88701
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [3/5] dd1889f1de28aa4c40df34fcad7898dc600374fd
Currently, there is no way to execute the query-cpu-model-expansion
command to retrieve a comprehenisve list of deprecated properties, as
the result is dependent per-model. To enable this, the expansion output
is modified as such:
When reporting a "full" CPU model, show the *entire* list of deprecated
properties regardless if they are supported on the model. A full
expansion outputs all known CPU model properties anyway, so it makes
sense to report all deprecated properties here too.
This allows management apps to query a single model (e.g. host) to
acquire the full list of deprecated properties.
Additionally, when reporting a "static" CPU model, the command will
only show deprecated properties that are a subset of the model's
*enabled* properties. This is more accurate than how the query was
handled before, which blindly reported deprecated properties that
were never otherwise introduced for certain models.
Acked-by: David Hildenbrand <david@redhat.com>
Suggested-by: Jiri Denemark <jdenemar@redhat.com>
Signed-off-by: Collin Walling <walling@linux.ibm.com>
Message-ID: <20240719181741.35146-1-walling@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit eed0e8ffa38f0695c0519508f6e4f5a3297cbd67)
---
qapi/machine-target.json | 5 +++--
target/s390x/cpu_models_sysemu.c | 16 +++++++++-------
2 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/qapi/machine-target.json b/qapi/machine-target.json
index c93c811dbc..d32dc6958f 100644
--- a/qapi/machine-target.json
+++ b/qapi/machine-target.json
@@ -18,8 +18,9 @@
# @props: a dictionary of QOM properties to be applied
#
# @deprecated-props: a list of properties that are flagged as deprecated
-# by the CPU vendor. These props are a subset of the full model's
-# definition list of properties. (since 9.1)
+# by the CPU vendor. These properties are either a subset of the
+# properties enabled on the CPU model, or a set of properties
+# deprecated across all models for the architecture.
#
# Since: 2.8
##
diff --git a/target/s390x/cpu_models_sysemu.c b/target/s390x/cpu_models_sysemu.c
index 7ed94b4117..edb81769cd 100644
--- a/target/s390x/cpu_models_sysemu.c
+++ b/target/s390x/cpu_models_sysemu.c
@@ -183,11 +183,15 @@ static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model,
bool delta_changes)
{
QDict *qdict = qdict_new();
- S390FeatBitmap bitmap;
+ S390FeatBitmap bitmap, deprecated;
/* always fallback to the static base model */
info->name = g_strdup_printf("%s-base", model->def->name);
+ /* features flagged as deprecated */
+ bitmap_zero(deprecated, S390_FEAT_MAX);
+ s390_get_deprecated_features(deprecated);
+
if (delta_changes) {
/* features deleted from the base feature set */
bitmap_andnot(bitmap, model->def->base_feat, model->features,
@@ -202,6 +206,9 @@ static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model,
if (!bitmap_empty(bitmap, S390_FEAT_MAX)) {
s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_enabled_feat);
}
+
+ /* deprecated features that are a subset of the model's enabled features */
+ bitmap_and(deprecated, deprecated, model->features, S390_FEAT_MAX);
} else {
/* expand all features */
s390_feat_bitmap_to_ascii(model->features, qdict,
@@ -217,12 +224,7 @@ static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model,
info->has_props = true;
}
- /* features flagged as deprecated */
- bitmap_zero(bitmap, S390_FEAT_MAX);
- s390_get_deprecated_features(bitmap);
-
- bitmap_and(bitmap, bitmap, model->def->full_feat, S390_FEAT_MAX);
- s390_feat_bitmap_to_ascii(bitmap, &info->deprecated_props, list_add_feat);
+ s390_feat_bitmap_to_ascii(deprecated, &info->deprecated_props, list_add_feat);
info->has_deprecated_props = !!info->deprecated_props;
}
--
2.48.1

View File

@ -0,0 +1,44 @@
From a851c0768ce192035014cce72d231a8df62dc011 Mon Sep 17 00:00:00 2001
From: Collin Walling <walling@linux.ibm.com>
Date: Mon, 29 Apr 2024 15:10:59 -0400
Subject: [PATCH 2/5] target/s390x: flag te and cte as deprecated
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 449: Fix for live-migrating guests from IBM z16 to z17 host machines
RH-Jira: RHEL-88701
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [2/5] d00d9654126596e31603ddec04ede4227b982739
Add the CONSTRAINT_TRANSACTIONAL_EXE (cte) and TRANSACTIONAL_EXE (te)
to the list of deprecated features.
Signed-off-by: Collin Walling <walling@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Message-ID: <20240429191059.11806-3-walling@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 6e55b32d45976a8e78cbd3bbdf6ed1148cb2662a)
---
target/s390x/cpu_features.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c
index 40be75c90a..59f1d6d81e 100644
--- a/target/s390x/cpu_features.c
+++ b/target/s390x/cpu_features.c
@@ -218,6 +218,9 @@ void s390_get_deprecated_features(S390FeatBitmap features)
/* CSSKE is deprecated on newer generations */
S390_FEAT_CONDITIONAL_SSKE,
S390_FEAT_BPB,
+ /* Deprecated on z16 */
+ S390_FEAT_CONSTRAINT_TRANSACTIONAL_EXE,
+ S390_FEAT_TRANSACTIONAL_EXE
};
int i;
--
2.48.1

View File

@ -0,0 +1,163 @@
From 1142610383e66712cfa4d11cc02d7661f68d7193 Mon Sep 17 00:00:00 2001
From: Collin Walling <walling@linux.ibm.com>
Date: Fri, 26 Jul 2024 16:36:46 -0400
Subject: [PATCH 4/5] target/s390x: move @deprecated-props to CpuModelExpansion
Info
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 449: Fix for live-migrating guests from IBM z16 to z17 host machines
RH-Jira: RHEL-88701
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [4/5] 2c66f3000c44742b02d1cd4b64e3d091b4be05cb
CpuModelInfo is used both as command argument and in command
returns.
Its @deprecated-props array does not make any sense in arguments,
and is silently ignored. We actually want it only as return value
of query-cpu-model-expansion.
Move it from CpuModelInfo to CpuModelExpansionType, and document
its dependence on expansion type property.
This was identified late during review [1] and we have to fix it up
while it's not part of an official QEMU release yet.
[1] https://lore.kernel.org/qemu-devel/20240719181741.35146-1-walling@linux.ibm.com/
Message-ID: <20240726203646.20279-1-walling@linux.ibm.com>
Fixes: eed0e8ffa38f ("target/s390x: filter deprecated properties based on model expansion type")
Signed-off-by: Collin Walling <walling@linux.ibm.com>
[ david: - add "Fixes", adjust description, reference v3 instead
- make property s390x-only and non-optional
- fixup "populate" vs. "populated" ]
Signed-off-by: David Hildenbrand <david@redhat.com>
(cherry picked from commit 442110bc6f3f308aedf884103fdba87ba906dfe7)
---
qapi/machine-target.json | 19 +++++++++++--------
target/s390x/cpu_models_sysemu.c | 29 ++++++++++++++++++-----------
2 files changed, 29 insertions(+), 19 deletions(-)
diff --git a/qapi/machine-target.json b/qapi/machine-target.json
index d32dc6958f..320688cd21 100644
--- a/qapi/machine-target.json
+++ b/qapi/machine-target.json
@@ -17,17 +17,11 @@
# @name: the name of the CPU definition the model is based on
# @props: a dictionary of QOM properties to be applied
#
-# @deprecated-props: a list of properties that are flagged as deprecated
-# by the CPU vendor. These properties are either a subset of the
-# properties enabled on the CPU model, or a set of properties
-# deprecated across all models for the architecture.
-#
# Since: 2.8
##
{ 'struct': 'CpuModelInfo',
'data': { 'name': 'str',
- '*props': 'any',
- '*deprecated-props': ['str'] } }
+ '*props': 'any' } }
##
# @CpuModelExpansionType:
@@ -215,10 +209,19 @@
#
# @model: the expanded CpuModelInfo.
#
+# @deprecated-props: a list of properties that are flagged as deprecated
+# by the CPU vendor. The list depends on the CpuModelExpansionType:
+# "static" properties are a subset of the enabled-properties for
+# the expanded model; "full" properties are a set of properties
+# that are deprecated across all models for the architecture.
+# (since: 9.1).
+#
# Since: 2.8
##
{ 'struct': 'CpuModelExpansionInfo',
- 'data': { 'model': 'CpuModelInfo' },
+ 'data': { 'model': 'CpuModelInfo',
+ 'deprecated-props' : { 'type': ['str'],
+ 'if': 'TARGET_S390X' } },
'if': { 'any': [ 'TARGET_S390X',
'TARGET_I386',
'TARGET_ARM' ] } }
diff --git a/target/s390x/cpu_models_sysemu.c b/target/s390x/cpu_models_sysemu.c
index edb81769cd..6680724bfe 100644
--- a/target/s390x/cpu_models_sysemu.c
+++ b/target/s390x/cpu_models_sysemu.c
@@ -183,15 +183,11 @@ static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model,
bool delta_changes)
{
QDict *qdict = qdict_new();
- S390FeatBitmap bitmap, deprecated;
+ S390FeatBitmap bitmap;
/* always fallback to the static base model */
info->name = g_strdup_printf("%s-base", model->def->name);
- /* features flagged as deprecated */
- bitmap_zero(deprecated, S390_FEAT_MAX);
- s390_get_deprecated_features(deprecated);
-
if (delta_changes) {
/* features deleted from the base feature set */
bitmap_andnot(bitmap, model->def->base_feat, model->features,
@@ -206,9 +202,6 @@ static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model,
if (!bitmap_empty(bitmap, S390_FEAT_MAX)) {
s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_enabled_feat);
}
-
- /* deprecated features that are a subset of the model's enabled features */
- bitmap_and(deprecated, deprecated, model->features, S390_FEAT_MAX);
} else {
/* expand all features */
s390_feat_bitmap_to_ascii(model->features, qdict,
@@ -223,9 +216,6 @@ static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model,
info->props = QOBJECT(qdict);
info->has_props = true;
}
-
- s390_feat_bitmap_to_ascii(deprecated, &info->deprecated_props, list_add_feat);
- info->has_deprecated_props = !!info->deprecated_props;
}
CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
@@ -236,6 +226,7 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
CpuModelExpansionInfo *expansion_info = NULL;
S390CPUModel s390_model;
bool delta_changes = false;
+ S390FeatBitmap deprecated_feats;
/* convert it to our internal representation */
cpu_model_from_info(&s390_model, model, &err);
@@ -255,6 +246,22 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
expansion_info = g_new0(CpuModelExpansionInfo, 1);
expansion_info->model = g_malloc0(sizeof(*expansion_info->model));
cpu_info_from_model(expansion_info->model, &s390_model, delta_changes);
+
+ /* populate list of deprecated features */
+ bitmap_zero(deprecated_feats, S390_FEAT_MAX);
+ s390_get_deprecated_features(deprecated_feats);
+
+ if (delta_changes) {
+ /*
+ * Only populate deprecated features that are a
+ * subset of the features enabled on the CPU model.
+ */
+ bitmap_and(deprecated_feats, deprecated_feats,
+ s390_model.features, S390_FEAT_MAX);
+ }
+
+ s390_feat_bitmap_to_ascii(deprecated_feats,
+ &expansion_info->deprecated_props, list_add_feat);
return expansion_info;
}
--
2.48.1

View File

@ -0,0 +1,136 @@
From 1955d06f0ffcdcacdf1eec5c9fee99a2a9e81350 Mon Sep 17 00:00:00 2001
From: Collin Walling <walling@linux.ibm.com>
Date: Mon, 29 Apr 2024 15:10:58 -0400
Subject: [PATCH 1/5] target/s390x: report deprecated-props in
cpu-model-expansion reply
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 449: Fix for live-migrating guests from IBM z16 to z17 host machines
RH-Jira: RHEL-88701
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/5] 9cecba35e831615bc1c899730b4f32de0fd7ba83
Retain a list of deprecated features disjoint from any particular
CPU model. A query-cpu-model-expansion reply will now provide a list of
properties (i.e. features) that are flagged as deprecated. Example:
{
"return": {
"model": {
"name": "z14.2-base",
"deprecated-props": [
"bpb",
"csske"
],
"props": {
"pfmfi": false,
"exrl": true,
...a lot more props...
"skey": false,
"vxpdeh2": false
}
}
}
}
It is recommended that s390 guests operate with these features
explicitly disabled to ensure compatibility with future hardware.
Signed-off-by: Collin Walling <walling@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Message-ID: <20240429191059.11806-2-walling@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 8aa2211e855df79ddd363e5f0d8c4d7d4c376e16)
---
qapi/machine-target.json | 7 ++++++-
target/s390x/cpu_features.c | 14 ++++++++++++++
target/s390x/cpu_features.h | 1 +
target/s390x/cpu_models_sysemu.c | 8 ++++++++
4 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/qapi/machine-target.json b/qapi/machine-target.json
index f5ec4bc172..c93c811dbc 100644
--- a/qapi/machine-target.json
+++ b/qapi/machine-target.json
@@ -17,11 +17,16 @@
# @name: the name of the CPU definition the model is based on
# @props: a dictionary of QOM properties to be applied
#
+# @deprecated-props: a list of properties that are flagged as deprecated
+# by the CPU vendor. These props are a subset of the full model's
+# definition list of properties. (since 9.1)
+#
# Since: 2.8
##
{ 'struct': 'CpuModelInfo',
'data': { 'name': 'str',
- '*props': 'any' } }
+ '*props': 'any',
+ '*deprecated-props': ['str'] } }
##
# @CpuModelExpansionType:
diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c
index ebb155ce1c..40be75c90a 100644
--- a/target/s390x/cpu_features.c
+++ b/target/s390x/cpu_features.c
@@ -212,6 +212,20 @@ void s390_feat_bitmap_to_ascii(const S390FeatBitmap features, void *opaque,
};
}
+void s390_get_deprecated_features(S390FeatBitmap features)
+{
+ static const int feats[] = {
+ /* CSSKE is deprecated on newer generations */
+ S390_FEAT_CONDITIONAL_SSKE,
+ S390_FEAT_BPB,
+ };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(feats); i++) {
+ set_bit(feats[i], features);
+ }
+}
+
#define FEAT_GROUP_INIT(_name, _group, _desc) \
{ \
.name = _name, \
diff --git a/target/s390x/cpu_features.h b/target/s390x/cpu_features.h
index a9bd68a2e1..661a8cd6db 100644
--- a/target/s390x/cpu_features.h
+++ b/target/s390x/cpu_features.h
@@ -69,6 +69,7 @@ void s390_add_from_feat_block(S390FeatBitmap features, S390FeatType type,
uint8_t *data);
void s390_feat_bitmap_to_ascii(const S390FeatBitmap features, void *opaque,
void (*fn)(const char *name, void *opaque));
+void s390_get_deprecated_features(S390FeatBitmap features);
/* Definition of a CPU feature group */
typedef struct {
diff --git a/target/s390x/cpu_models_sysemu.c b/target/s390x/cpu_models_sysemu.c
index 6a04ccab1b..7ed94b4117 100644
--- a/target/s390x/cpu_models_sysemu.c
+++ b/target/s390x/cpu_models_sysemu.c
@@ -216,6 +216,14 @@ static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model,
info->props = QOBJECT(qdict);
info->has_props = true;
}
+
+ /* features flagged as deprecated */
+ bitmap_zero(bitmap, S390_FEAT_MAX);
+ s390_get_deprecated_features(bitmap);
+
+ bitmap_and(bitmap, bitmap, model->def->full_feat, S390_FEAT_MAX);
+ s390_feat_bitmap_to_ascii(bitmap, &info->deprecated_props, list_add_feat);
+ info->has_deprecated_props = !!info->deprecated_props;
}
CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
--
2.48.1

View File

@ -83,7 +83,7 @@ Obsoletes: %1-rhev <= %{epoch}:%{version}-%{release}
Summary: QEMU is a machine emulator and virtualizer
Name: qemu-kvm
Version: 6.2.0
Release: 53%{?rcrel}%{?dist}.2
Release: 53%{?rcrel}%{?dist}.6
# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
Epoch: 15
License: GPLv2 and GPLv2+ and CC-BY
@ -891,6 +891,32 @@ Patch364: kvm-block-move-bdrv_qiov_is_aligned-to-file-posix.patch
Patch365: kvm-block-use-the-request-length-for-iov-alignment.patch
# For RHEL-26197 - virtiofsd --help and manpage does not agree on --thread-pool-size default value
Patch366: kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch
# For RHEL-59214 - qemu-ga cannot freeze filesystems with sentinelone
Patch367: kvm-qga-skip-bind-mounts-in-fs-list.patch
# For RHEL-88701 - [RHEL 8.10 qemu] KVM - Live migration of guest fails from z16-z17 [rhel-8.10.z]
Patch368: kvm-target-s390x-report-deprecated-props-in-cpu-model-ex.patch
# For RHEL-88701 - [RHEL 8.10 qemu] KVM - Live migration of guest fails from z16-z17 [rhel-8.10.z]
Patch369: kvm-target-s390x-flag-te-and-cte-as-deprecated.patch
# For RHEL-88701 - [RHEL 8.10 qemu] KVM - Live migration of guest fails from z16-z17 [rhel-8.10.z]
Patch370: kvm-target-s390x-filter-deprecated-properties-based-on-m.patch
# For RHEL-88701 - [RHEL 8.10 qemu] KVM - Live migration of guest fails from z16-z17 [rhel-8.10.z]
Patch371: kvm-target-s390x-move-deprecated-props-to-CpuModelExpans.patch
# For RHEL-88701 - [RHEL 8.10 qemu] KVM - Live migration of guest fails from z16-z17 [rhel-8.10.z]
Patch372: kvm-redhat-Adjust-indentation-in-qapi-machine-target.jso.patch
# For RHEL-120119 - CVE-2025-11234 virt:rhel/qemu-kvm: VNC WebSocket handshake use-after-free [rhel-8.10.z]
Patch373: kvm-io-move-websock-resource-release-to-close-method.patch
# For RHEL-120119 - CVE-2025-11234 virt:rhel/qemu-kvm: VNC WebSocket handshake use-after-free [rhel-8.10.z]
Patch374: kvm-io-fix-use-after-free-in-websocket-handshake-code.patch
# For RHEL-120737 - qemu hit io error and crash scsi-disk.c:554: scsi_write_data: Assertion `r->req.aiocb == NULL' failed
Patch375: kvm-scsi-disk-Use-positive-return-value-for-status-in-dm.patch
# For RHEL-120737 - qemu hit io error and crash scsi-disk.c:554: scsi_write_data: Assertion `r->req.aiocb == NULL' failed
Patch376: kvm-scsi-block-Don-t-skip-callback-for-sgio-error-status.patch
# For RHEL-120737 - qemu hit io error and crash scsi-disk.c:554: scsi_write_data: Assertion `r->req.aiocb == NULL' failed
Patch377: kvm-scsi-disk-Add-warning-comments-that-host_status-erro.patch
# For RHEL-120737 - qemu hit io error and crash scsi-disk.c:554: scsi_write_data: Assertion `r->req.aiocb == NULL' failed
Patch378: kvm-scsi-disk-Always-report-RESERVATION_CONFLICT-to-gues.patch
# For RHEL-120737 - qemu hit io error and crash scsi-disk.c:554: scsi_write_data: Assertion `r->req.aiocb == NULL' failed
Patch379: kvm-scsi-disk-Apply-error-policy-for-host_status-errors-.patch
BuildRequires: wget
BuildRequires: rpm-build
@ -2060,6 +2086,35 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || :
%changelog
* Tue Dec 02 2025 Jon Maloy <jmaloy@redhat.com> - 6.2.0-53.el8.6
- kvm-scsi-disk-Use-positive-return-value-for-status-in-dm.patch [RHEL-120737]
- kvm-scsi-block-Don-t-skip-callback-for-sgio-error-status.patch [RHEL-120737]
- kvm-scsi-disk-Add-warning-comments-that-host_status-erro.patch [RHEL-120737]
- kvm-scsi-disk-Always-report-RESERVATION_CONFLICT-to-gues.patch [RHEL-120737]
- kvm-scsi-disk-Apply-error-policy-for-host_status-errors-.patch [RHEL-120737]
- Resolves: RHEL-120737
(qemu hit io error and crash scsi-disk.c:554: scsi_write_data: Assertion `r->req.aiocb == NULL' failed)
* Wed Nov 19 2025 Jon Maloy <jmaloy@redhat.com> - 6.2.0-53.el8.5
- kvm-io-move-websock-resource-release-to-close-method.patch [RHEL-120119]
- kvm-io-fix-use-after-free-in-websocket-handshake-code.patch [RHEL-120119]
- Resolves: RHEL-120119
(CVE-2025-11234 virt:rhel/qemu-kvm: VNC WebSocket handshake use-after-free [rhel-8.10.z])
* Mon May 05 2025 Jon Maloy <jmaloy@redhat.com> - 6.2.0-53.el8.4
- kvm-target-s390x-report-deprecated-props-in-cpu-model-ex.patch [RHEL-88701]
- kvm-target-s390x-flag-te-and-cte-as-deprecated.patch [RHEL-88701]
- kvm-target-s390x-filter-deprecated-properties-based-on-m.patch [RHEL-88701]
- kvm-target-s390x-move-deprecated-props-to-CpuModelExpans.patch [RHEL-88701]
- kvm-redhat-Adjust-indentation-in-qapi-machine-target.jso.patch [RHEL-88701]
- Resolves: RHEL-88701
([RHEL 8.10 qemu] KVM - Live migration of guest fails from z16-z17 [rhel-8.10.z])
* Sun Jan 05 2025 Jon Maloy <jmaloy@redhat.com> - 6.2.0-53.el8.3
- kvm-qga-skip-bind-mounts-in-fs-list.patch [RHEL-59214]
- Resolves: RHEL-59214
(qemu-ga cannot freeze filesystems with sentinelone)
* Tue Oct 15 2024 Jon Maloy <jmaloy@redhat.com> - 6.2.0-53.el8.2
- kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch [RHEL-26197]
- Resolves: RHEL-26197