import OL qemu-kvm-10.0.0-14.el10_1.5

This commit is contained in:
eabdullin 2026-02-05 11:37:33 +00:00
parent ebba3a1505
commit de096331bf
9 changed files with 917 additions and 1 deletions

View File

@ -0,0 +1,74 @@
From 688540b82cdb18de5a8815035157fb4b310d6287 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Fri, 12 Dec 2025 00:48:42 +0100
Subject: [PATCH] Revert "i386/cpu: Move adjustment of CPUID_EXT_PDCM before
feature_dependencies[] check"
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 526: Revert "i386/cpu: Move adjustment of CPUID_EXT_PDCM before feature_dependencies[] check"
RH-Jira: RHEL-135453
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [1/1] 171bef2088b6010b44c269c6d34d95d5135be758
JIRA: https://issues.redhat.com/browse/RHEL-135453
This reverts commit e8ce1b2ea0eecc36e6bf6df777c6d395d5679e26.
Quoting from commit 6529f31e0dc ("target/i386: add compatibility
property for pdcm feature", 2025-10-07):
The pdcm feature is supposed to be disabled when PMU is not
available. Up until v10.1, pdcm feature is enabled even when PMU
is off. This behavior has been fixed but this change breaks the
migration of VMs that are run with QEMU < 10.0 and expect the pdcm
feature to be enabled on the destination host.
This commit restores the legacy behavior for machines with version
prior to 10.1 to allow the migration from older QEMU to QEMU 10.1.
Signed-off-by: Hector Cao <hector.cao@canonical.com>
Link: https://lore.kernel.org/r/20250910115733.21149-3-hector.cao@canonical.com
Fixes: e68ec298090 ("i386/cpu: Move adjustment of CPUID_EXT_PDCM before feature_dependencies[] check", 2025-06-20)
[Move property from migration object to CPU. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
For RHEL10.1 we don't have machine types so just revert, while keeping only
the TDX check.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/cpu.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 8ba92de50c..5a768805f3 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -7311,6 +7311,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
if (threads_per_pkg > 1) {
*ebx |= threads_per_pkg << 16;
}
+ /* PDCM is fixed1 bit for TDX */
+ if (!cpu->enable_pmu && !is_tdx_vm()) {
+ *ecx &= ~CPUID_EXT_PDCM;
+ }
break;
case 2:
/* cache info: needed for Pentium Pro compatibility */
@@ -8301,11 +8305,6 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
}
}
- /* PDCM is fixed1 bit for TDX */
- if (!cpu->enable_pmu && !is_tdx_vm()) {
- env->features[FEAT_1_ECX] &= ~CPUID_EXT_PDCM;
- }
-
for (i = 0; i < ARRAY_SIZE(feature_dependencies); i++) {
FeatureDep *d = &feature_dependencies[i];
if (!(env->features[d->from.index] & d->from.mask)) {
--
2.47.3

View File

@ -0,0 +1,155 @@
From 51078ffb1274b7e75faab6a09aeefae2c9c1d552 Mon Sep 17 00:00:00 2001
From: Cornelia Huck <cohuck@redhat.com>
Date: Thu, 11 Sep 2025 17:41:59 +0200
Subject: [PATCH] arm/kvm: report registers we failed to set
RH-Author: Eric Auger <eric.auger@redhat.com>
RH-MergeRequest: 487: [10.1-z] arm/kvm: report registers we failed to set
RH-Jira: RHEL-120074
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
RH-Acked-by: Gavin Shan <gshan@redhat.com>
RH-Commit: [1/1] bc937c7e7b613078248649a897e19606444b298e
JIRA: https://issues.redhat.com/browse/RHEL-120074
If we fail migration because of a mismatch of some registers between
source and destination, the error message is not very informative:
qemu-system-aarch64: error while loading state for instance 0x0 ofdevice 'cpu'
qemu-system-aarch64: Failed to put registers after init: Invalid argument
At least try to give the user a hint which registers had a problem,
even if they cannot really do anything about it right now.
Sample output:
Could not set register op0:3 op1:0 crn:0 crm:0 op2:0 to c00fac31 (is 413fd0c1)
We could be even more helpful once we support writable ID registers,
at which point the user might actually be able to configure something
that is migratable.
Suggested-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Sebastian Ott <sebott@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Message-id: 20250911154159.158046-1-cohuck@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 19f6dcfe6b8b2a3523362812fc696ab83050d316)
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
target/arm/kvm.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 86 insertions(+)
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index d53ac64bf1..d139a965e9 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -932,6 +932,58 @@ bool write_kvmstate_to_list(ARMCPU *cpu)
return ok;
}
+/* pretty-print a KVM register */
+#define CP_REG_ARM64_SYSREG_OP(_reg, _op) \
+ ((uint8_t)((_reg & CP_REG_ARM64_SYSREG_ ## _op ## _MASK) >> \
+ CP_REG_ARM64_SYSREG_ ## _op ## _SHIFT))
+
+static gchar *kvm_print_sve_register_name(uint64_t regidx)
+{
+ uint16_t sve_reg = regidx & 0x000000000000ffff;
+
+ if (regidx == KVM_REG_ARM64_SVE_VLS) {
+ return g_strdup_printf("SVE VLS");
+ }
+ /* zreg, preg, ffr */
+ switch (sve_reg & 0xfc00) {
+ case 0:
+ return g_strdup_printf("SVE zreg n:%d slice:%d",
+ (sve_reg & 0x03e0) >> 5, sve_reg & 0x001f);
+ case 0x04:
+ return g_strdup_printf("SVE preg n:%d slice:%d",
+ (sve_reg & 0x01e0) >> 5, sve_reg & 0x001f);
+ case 0x06:
+ return g_strdup_printf("SVE ffr slice:%d", sve_reg & 0x001f);
+ default:
+ return g_strdup_printf("SVE ???");
+ }
+}
+
+static gchar *kvm_print_register_name(uint64_t regidx)
+{
+ switch ((regidx & KVM_REG_ARM_COPROC_MASK)) {
+ case KVM_REG_ARM_CORE:
+ return g_strdup_printf("core reg %"PRIx64, regidx);
+ case KVM_REG_ARM_DEMUX:
+ return g_strdup_printf("demuxed reg %"PRIx64, regidx);
+ case KVM_REG_ARM64_SYSREG:
+ return g_strdup_printf("op0:%d op1:%d crn:%d crm:%d op2:%d",
+ CP_REG_ARM64_SYSREG_OP(regidx, OP0),
+ CP_REG_ARM64_SYSREG_OP(regidx, OP1),
+ CP_REG_ARM64_SYSREG_OP(regidx, CRN),
+ CP_REG_ARM64_SYSREG_OP(regidx, CRM),
+ CP_REG_ARM64_SYSREG_OP(regidx, OP2));
+ case KVM_REG_ARM_FW:
+ return g_strdup_printf("fw reg %d", (int)(regidx & 0xffff));
+ case KVM_REG_ARM64_SVE:
+ return kvm_print_sve_register_name(regidx);
+ case KVM_REG_ARM_FW_FEAT_BMAP:
+ return g_strdup_printf("fw feat reg %d", (int)(regidx & 0xffff));
+ default:
+ return g_strdup_printf("%"PRIx64, regidx);
+ }
+}
+
bool write_list_to_kvmstate(ARMCPU *cpu, int level)
{
CPUState *cs = CPU(cpu);
@@ -959,11 +1011,45 @@ bool write_list_to_kvmstate(ARMCPU *cpu, int level)
g_assert_not_reached();
}
if (ret) {
+ gchar *reg_str = kvm_print_register_name(regidx);
+
/* We might fail for "unknown register" and also for
* "you tried to set a register which is constant with
* a different value from what it actually contains".
*/
ok = false;
+ switch (ret) {
+ case -ENOENT:
+ error_report("Could not set register %s: unknown to KVM",
+ reg_str);
+ break;
+ case -EINVAL:
+ if ((regidx & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U32) {
+ if (!kvm_get_one_reg(cs, regidx, &v32)) {
+ error_report("Could not set register %s to %x (is %x)",
+ reg_str, (uint32_t)cpu->cpreg_values[i],
+ v32);
+ } else {
+ error_report("Could not set register %s to %x",
+ reg_str, (uint32_t)cpu->cpreg_values[i]);
+ }
+ } else /* U64 */ {
+ uint64_t v64;
+
+ if (!kvm_get_one_reg(cs, regidx, &v64)) {
+ error_report("Could not set register %s to %"PRIx64" (is %"PRIx64")",
+ reg_str, cpu->cpreg_values[i], v64);
+ } else {
+ error_report("Could not set register %s to %"PRIx64,
+ reg_str, cpu->cpreg_values[i]);
+ }
+ }
+ break;
+ default:
+ error_report("Could not set register %s: %s",
+ reg_str, strerror(-ret));
+ }
+ g_free(reg_str);
}
}
return ok;
--
2.47.3

View File

@ -0,0 +1,73 @@
From 6f335cf5480889940e43a5359f718f1b5ea8b6aa Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Wed, 19 Nov 2025 18:27:20 +0100
Subject: [PATCH 2/2] block-backend: Fix race when resuming queued requests
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 519: block-backend: Fix race when resuming queued requests [10.1.z]
RH-Jira: RHEL-133527
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [1/1] fa127e3871427f65c754d5bd912c2853050a911e (kmwolf/rhel-qemu-kvm)
When new requests arrive at a BlockBackend that is currently drained,
these requests are queued until the drain section ends.
There is a race window between blk_root_drained_end() waking up a queued
request in an iothread from the main thread and blk_wait_while_drained()
actually being woken up in the iothread and calling blk_inc_in_flight().
If the BlockBackend is drained again during this window, drain won't
wait for this request and it will sneak in when the BlockBackend is
already supposed to be quiesced. This causes assertion failures in
bdrv_drain_all_begin() and can have other unintended consequences.
Fix this by increasing the in_flight counter immediately when scheduling
the request to be resumed so that the next drain will wait for it to
complete.
Cc: qemu-stable@nongnu.org
Reported-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20251119172720.135424-1-kwolf@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
Tested-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Reviewed-by: Fiona Ebner <f.ebner@proxmox.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 8eeaa706ba73251063cb80d87ae838d2d5b08e9a)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/block-backend.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index 68209bb2f7..626b84c96a 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -1322,9 +1322,9 @@ static void coroutine_fn blk_wait_while_drained(BlockBackend *blk)
* section.
*/
qemu_mutex_lock(&blk->queued_requests_lock);
+ /* blk_root_drained_end() has the corresponding blk_inc_in_flight() */
blk_dec_in_flight(blk);
qemu_co_queue_wait(&blk->queued_requests, &blk->queued_requests_lock);
- blk_inc_in_flight(blk);
qemu_mutex_unlock(&blk->queued_requests_lock);
}
}
@@ -2771,9 +2771,11 @@ static void blk_root_drained_end(BdrvChild *child)
blk->dev_ops->drained_end(blk->dev_opaque);
}
qemu_mutex_lock(&blk->queued_requests_lock);
- while (qemu_co_enter_next(&blk->queued_requests,
- &blk->queued_requests_lock)) {
+ while (!qemu_co_queue_empty(&blk->queued_requests)) {
/* Resume all queued requests */
+ blk_inc_in_flight(blk);
+ qemu_co_enter_next(&blk->queued_requests,
+ &blk->queued_requests_lock);
}
qemu_mutex_unlock(&blk->queued_requests_lock);
}
--
2.47.3

View File

@ -0,0 +1,123 @@
From de31859a877ad2db185399d50dc6a97f9d7be0ed Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Fri, 28 Nov 2025 23:14:40 +0100
Subject: [PATCH 1/2] file-posix: Handle suspended dm-multipath better for
SG_IO
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 520: file-posix: Handle suspended dm-multipath better for SG_IO
RH-Jira: RHEL-133521
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [1/1] 18d03efe156e6ec0ccff3e05e678de4adc829488 (kmwolf/rhel-qemu-kvm)
When introducing DM_MPATH_PROBE_PATHS, we already anticipated that
dm-multipath devices might be suspended for a short time when the DM
tables are reloaded and that they return -EAGAIN in this case. We then
wait for a millisecond and retry.
However, meanwhile it has also turned out that libmpathpersist (which is
used by qemu-pr-helper) may need to perform more complex recovery
operations to get reservations back to expected state if a path failure
happened in the middle of a PR operation. In this case, the device is
suspended for a longer time compared to the case we originally expected.
This patch changes hdev_co_ioctl() to treat -EAGAIN separately so that
it doesn't result in an immediate failure if the device is suspended for
more than 1ms, and moves to incremental backoff to cover both quick and
slow cases without excessive delays.
Buglink: https://issues.redhat.com/browse/RHEL-121543
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20251128221440.89125-1-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 2c3165a1a61c299b4a3ae30899e1cc738d20e004)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/file-posix.c | 56 ++++++++++++++++++++++++++++------------------
1 file changed, 34 insertions(+), 22 deletions(-)
diff --git a/block/file-posix.c b/block/file-posix.c
index d3c7dcc7e4..d5ce09700b 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -4293,25 +4293,8 @@ hdev_open_Mac_error:
static bool coroutine_fn sgio_path_error(int ret, sg_io_hdr_t *io_hdr)
{
if (ret < 0) {
- switch (ret) {
- case -ENODEV:
- return true;
- case -EAGAIN:
- /*
- * The device is probably suspended. This happens while the dm table
- * is reloaded, e.g. because a path is added or removed. This is an
- * operation that should complete within 1ms, so just wait a bit and
- * retry.
- *
- * If the device was suspended for another reason, we'll wait and
- * retry SG_IO_MAX_RETRIES times. This is a tolerable delay before
- * we return an error and potentially stop the VM.
- */
- qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 1000000);
- return true;
- default:
- return false;
- }
+ /* Path errors sometimes result in -ENODEV */
+ return ret == -ENODEV;
}
if (io_hdr->host_status != SCSI_HOST_OK) {
@@ -4380,6 +4363,7 @@ hdev_co_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
{
BDRVRawState *s = bs->opaque;
RawPosixAIOData acb;
+ uint64_t eagain_sleep_ns = 1 * SCALE_MS;
int retries = SG_IO_MAX_RETRIES;
int ret;
@@ -4408,9 +4392,37 @@ hdev_co_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
},
};
- do {
- ret = raw_thread_pool_submit(handle_aiocb_ioctl, &acb);
- } while (req == SG_IO && retries-- && hdev_co_ioctl_sgio_retry(&acb, ret));
+retry:
+ ret = raw_thread_pool_submit(handle_aiocb_ioctl, &acb);
+ if (req == SG_IO && s->use_mpath) {
+ if (ret == -EAGAIN && eagain_sleep_ns < NANOSECONDS_PER_SECOND) {
+ /*
+ * If this is a multipath device, it is probably suspended.
+ *
+ * This can happen while the dm table is reloaded, e.g. because a
+ * path is added or removed. This is an operation that should
+ * complete within 1ms, so just wait a bit and retry.
+ *
+ * There are also some cases in which libmpathpersist must recover
+ * from path failure during its operation, which can leave the
+ * device suspended for a bit longer while the library brings back
+ * reservations into the expected state.
+ *
+ * Use increasing delays to cover both cases without waiting
+ * excessively, and stop after a bit more than a second (1023 ms).
+ * This is a tolerable delay before we return an error and
+ * potentially stop the VM.
+ */
+ qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, eagain_sleep_ns);
+ eagain_sleep_ns *= 2;
+ goto retry;
+ }
+
+ /* Even for ret == 0, the SG_IO header can contain an error */
+ if (retries-- && hdev_co_ioctl_sgio_retry(&acb, ret)) {
+ goto retry;
+ }
+ }
return ret;
}
--
2.47.3

View File

@ -0,0 +1,187 @@
From 5e1e2e3af9e186df5b123ed11001ba2a4412d301 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: 496: io: fix use after free in websocket handshake code
RH-Jira: RHEL-120118
RH-Commit: [2/2] 171bbdf9e5b13cf940aceb09dcf511d1a679f41d (redhat/rhel/src/qemu-kvm/jons-qemu-kvm-2)
JIRA: https://issues.redhat.com/browse/RHEL-120118
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 5c0df9d6af..7f8eded4ff 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,
@@ -907,11 +910,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);
}
@@ -922,6 +926,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);
}
@@ -1222,6 +1229,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.47.3

View File

@ -0,0 +1,82 @@
From 6ef494fa4caec6626fa3cdcbece91eb23dd50643 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: 496: io: fix use after free in websocket handshake code
RH-Jira: RHEL-120118
RH-Commit: [1/2] a819c17311adf0aa17b119ee85df12ac0c3fdcc8 (redhat/rhel/src/qemu-kvm/jons-qemu-kvm-2)
JIRA: https://issues.redhat.com/browse/RHEL-120118
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 55192b770a..5c0df9d6af 100644
--- a/io/channel-websock.c
+++ b/io/channel-websock.c
@@ -922,13 +922,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));
}
@@ -1219,6 +1219,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.47.3

View File

@ -0,0 +1,49 @@
From 24f76c77375b46b35a9de30d34bd96a84afcd6ec Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Wed, 19 Nov 2025 12:51:32 +0100
Subject: [PATCH 2/2] ram-block-attributes: Unify the retrieval of the block
size
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 512: Fix hugetlb memory backends in confidential VMs
RH-Jira: RHEL-129549
RH-Acked-by: Yash Mankad <None>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Acked-by: Peter Xu <peterx@redhat.com>
RH-Commit: [2/2] d14d64df579b902a719812a61fb442285875fc4d
JIRA: https://issues.redhat.com/browse/RHEL-126549
Y-JIRA: https://issues.redhat.com/browse/RHEL-126708
There's an existing helper function designed to obtain the block size.
Modify ram_block_attribute_create() to use this function for
consistency.
Tested-by: Farrah Chen <farrah.chen@intel.com>
Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com>
Link: https://lore.kernel.org/r/20251023095526.48365-3-chenyi.qiang@intel.com
[peterx: fix double spaces, per david]
Signed-off-by: Peter Xu <peterx@redhat.com>
(cherry picked from commit b2ceb87b1a210d91a29d525590eb164d1121b8a1)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
system/ram-block-attributes.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/system/ram-block-attributes.c b/system/ram-block-attributes.c
index 116d281fd9..abfa2fbda0 100644
--- a/system/ram-block-attributes.c
+++ b/system/ram-block-attributes.c
@@ -390,7 +390,7 @@ int ram_block_attributes_state_change(RamBlockAttributes *attr,
RamBlockAttributes *ram_block_attributes_create(RAMBlock *ram_block)
{
- const int block_size = qemu_real_host_page_size();
+ const int block_size = ram_block_attributes_get_block_size();
RamBlockAttributes *attr;
MemoryRegion *mr = ram_block->mr;
--
2.51.1

View File

@ -0,0 +1,127 @@
From a100d5322915ba31f15a2e8a1a98c3dae5282a47 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Wed, 19 Nov 2025 12:51:32 +0100
Subject: [PATCH 1/2] ram-block-attributes: fix interaction with hugetlb memory
backends
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 512: Fix hugetlb memory backends in confidential VMs
RH-Jira: RHEL-129549
RH-Acked-by: Yash Mankad <None>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Acked-by: Peter Xu <peterx@redhat.com>
RH-Commit: [1/2] 6ffa958b8cf7ee4b7f2f75f84f118dd956158140
JIRA: https://issues.redhat.com/browse/RHEL-126549
Y-JIRA: https://issues.redhat.com/browse/RHEL-126708
Currently, CoCo VMs can perform conversion at the base page granularity,
which is the granularity that has to be tracked. In relevant setups, the
target page size is assumed to be equal to the host page size, thus
fixing the block size to the host page size.
However, since private memory and shared memory have different backend
at present, users can specify shared memory with a hugetlbfs backend
while private memory with guest_memfd backend only supports 4K page
size. In this scenario, ram_block->page_size is different from the host
page size which will trigger an assertion when retrieving the block
size.
To address this, return the host page size directly to relax the
restriction. This changes fixes a regression of using hugetlbfs backend
for shared memory within CoCo VMs, with or without VFIO devices' presence.
Acked-by: David Hildenbrand <david@redhat.com>
Tested-by: Farrah Chen <farrah.chen@intel.com>
Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com>
Link: https://lore.kernel.org/r/20251023095526.48365-2-chenyi.qiang@intel.com
[peterx: fix subject, per david]
Cc: qemu-stable <qemu-stable@nongnu.org>
Signed-off-by: Peter Xu <peterx@redhat.com>
(cherry picked from commit 8922a758b29251d9009ec509e7f580b76509ab3d)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
system/ram-block-attributes.c | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/system/ram-block-attributes.c b/system/ram-block-attributes.c
index 4ebf242ae1..116d281fd9 100644
--- a/system/ram-block-attributes.c
+++ b/system/ram-block-attributes.c
@@ -22,16 +22,14 @@ OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(RamBlockAttributes,
{ })
static size_t
-ram_block_attributes_get_block_size(const RamBlockAttributes *attr)
+ram_block_attributes_get_block_size(void)
{
/*
* Because page conversion could be manipulated in the size of at least 4K
* or 4K aligned, Use the host page size as the granularity to track the
* memory attribute.
*/
- g_assert(attr && attr->ram_block);
- g_assert(attr->ram_block->page_size == qemu_real_host_page_size());
- return attr->ram_block->page_size;
+ return qemu_real_host_page_size();
}
@@ -40,7 +38,7 @@ ram_block_attributes_rdm_is_populated(const RamDiscardManager *rdm,
const MemoryRegionSection *section)
{
const RamBlockAttributes *attr = RAM_BLOCK_ATTRIBUTES(rdm);
- const size_t block_size = ram_block_attributes_get_block_size(attr);
+ const size_t block_size = ram_block_attributes_get_block_size();
const uint64_t first_bit = section->offset_within_region / block_size;
const uint64_t last_bit =
first_bit + int128_get64(section->size) / block_size - 1;
@@ -81,7 +79,7 @@ ram_block_attributes_for_each_populated_section(const RamBlockAttributes *attr,
{
unsigned long first_bit, last_bit;
uint64_t offset, size;
- const size_t block_size = ram_block_attributes_get_block_size(attr);
+ const size_t block_size = ram_block_attributes_get_block_size();
int ret = 0;
first_bit = section->offset_within_region / block_size;
@@ -122,7 +120,7 @@ ram_block_attributes_for_each_discarded_section(const RamBlockAttributes *attr,
{
unsigned long first_bit, last_bit;
uint64_t offset, size;
- const size_t block_size = ram_block_attributes_get_block_size(attr);
+ const size_t block_size = ram_block_attributes_get_block_size();
int ret = 0;
first_bit = section->offset_within_region / block_size;
@@ -163,7 +161,7 @@ ram_block_attributes_rdm_get_min_granularity(const RamDiscardManager *rdm,
const RamBlockAttributes *attr = RAM_BLOCK_ATTRIBUTES(rdm);
g_assert(mr == attr->ram_block->mr);
- return ram_block_attributes_get_block_size(attr);
+ return ram_block_attributes_get_block_size();
}
static void
@@ -265,7 +263,7 @@ ram_block_attributes_is_valid_range(RamBlockAttributes *attr, uint64_t offset,
g_assert(mr);
uint64_t region_size = memory_region_size(mr);
- const size_t block_size = ram_block_attributes_get_block_size(attr);
+ const size_t block_size = ram_block_attributes_get_block_size();
if (!QEMU_IS_ALIGNED(offset, block_size) ||
!QEMU_IS_ALIGNED(size, block_size)) {
@@ -322,7 +320,7 @@ int ram_block_attributes_state_change(RamBlockAttributes *attr,
uint64_t offset, uint64_t size,
bool to_discard)
{
- const size_t block_size = ram_block_attributes_get_block_size(attr);
+ const size_t block_size = ram_block_attributes_get_block_size();
const unsigned long first_bit = offset / block_size;
const unsigned long nbits = size / block_size;
const unsigned long last_bit = first_bit + nbits - 1;
--
2.51.1

View File

@ -143,7 +143,7 @@ Obsoletes: %{name}-block-ssh <= %{epoch}:%{version} \
Summary: QEMU is a machine emulator and virtualizer
Name: qemu-kvm
Version: 10.0.0
Release: 14%{?rcrel}%{?dist}%{?cc_suffix}
Release: 14%{?rcrel}%{?dist}%{?cc_suffix}.5
# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
# Epoch 15 used for RHEL 8
# Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5)
@ -526,6 +526,22 @@ Patch231: kvm-hw-uefi-clear-uefi-vars-buffer-in-uefi_vars_write-ca.patch
Patch232: kvm-hw-uefi-return-success-for-notifications.patch
# For RHEL-108614 - CVE-2025-8860 qemu-kvm: uefi-vars: information disclosure vulnerability in uefi_vars_write callback [rhel-10.1]
Patch233: kvm-hw-uefi-check-access-for-first-variable.patch
# For RHEL-120074 - [rhel10] Backport "arm/kvm: report registers we failed to set" [rhel-10.1.z]
Patch234: kvm-arm-kvm-report-registers-we-failed-to-set.patch
# For RHEL-120118 - CVE-2025-11234 qemu-kvm: VNC WebSocket handshake use-after-free [rhel-10.1.z]
Patch235: kvm-io-move-websock-resource-release-to-close-method.patch
# For RHEL-120118 - CVE-2025-11234 qemu-kvm: VNC WebSocket handshake use-after-free [rhel-10.1.z]
Patch236: kvm-io-fix-use-after-free-in-websocket-handshake-code.patch
# For RHEL-129549 - [RHEL 10]snp guest fail to boot with hugepage [rhel-10.1.z]
Patch237: kvm-ram-block-attributes-fix-interaction-with-hugetlb-me.patch
# For RHEL-129549 - [RHEL 10]snp guest fail to boot with hugepage [rhel-10.1.z]
Patch238: kvm-ram-block-attributes-Unify-the-retrieval-of-the-bloc.patch
# For RHEL-133521 - The VM hit io error when do S3-PR integration on the pass-through failover multipath device [rhel-10.1.z]
Patch239: kvm-file-posix-Handle-suspended-dm-multipath-better-for-.patch
# For RHEL-133527 - Assertion failure on drain with iothread and I/O load [rhel-10.1.z]
Patch240: kvm-block-backend-Fix-race-when-resuming-queued-requests.patch
# For RHEL-135453 - Live migration after workload update fails with operation failed: guest CPU doesn't match specification: missing features: pdcm [rhel-10.1.z]
Patch241: kvm-Revert-i386-cpu-Move-adjustment-of-CPUID_EXT_PDCM-be.patch
%if %{have_clang}
BuildRequires: clang
@ -1609,6 +1625,36 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \
%endif
%changelog
* Mon Dec 15 2025 Miroslav Rezanina <mrezanin@redhat.com> - 10.0.0-14.el10_1.5
- kvm-Revert-i386-cpu-Move-adjustment-of-CPUID_EXT_PDCM-be.patch [RHEL-135453]
- Resolves: RHEL-135453
(Live migration after workload update fails with operation failed: guest CPU doesn't match specification: missing features: pdcm [rhel-10.1.z])
* Wed Dec 10 2025 Miroslav Rezanina <mrezanin@redhat.com> - 10.0.0-14.el10_1.4
- kvm-file-posix-Handle-suspended-dm-multipath-better-for-.patch [RHEL-133521]
- kvm-block-backend-Fix-race-when-resuming-queued-requests.patch [RHEL-133527]
- Resolves: RHEL-133521
(The VM hit io error when do S3-PR integration on the pass-through failover multipath device [rhel-10.1.z])
- Resolves: RHEL-133527
(Assertion failure on drain with iothread and I/O load [rhel-10.1.z])
* Tue Nov 25 2025 Jon Maloy <jmaloy@redhat.com> - 10.0.0-14.el10_1.3
- kvm-ram-block-attributes-fix-interaction-with-hugetlb-me.patch [RHEL-129549]
- kvm-ram-block-attributes-Unify-the-retrieval-of-the-bloc.patch [RHEL-129549]
- Resolves: RHEL-129549
([RHEL 10]snp guest fail to boot with hugepage [rhel-10.1.z])
* Mon Nov 10 2025 Miroslav Rezanina <mrezanin@redhat.com> - 10.0.0-14.el10_1.2
- kvm-io-move-websock-resource-release-to-close-method.patch [RHEL-120118]
- kvm-io-fix-use-after-free-in-websocket-handshake-code.patch [RHEL-120118]
- Resolves: RHEL-120118
(CVE-2025-11234 qemu-kvm: VNC WebSocket handshake use-after-free [rhel-10.1.z])
* Fri Oct 31 2025 Miroslav Rezanina <mrezanin@redhat.com> - 10.0.0-14.el10_1.1
- kvm-arm-kvm-report-registers-we-failed-to-set.patch [RHEL-120074]
- Resolves: RHEL-120074
([rhel10] Backport "arm/kvm: report registers we failed to set" [rhel-10.1.z])
* Wed Sep 17 2025 Miroslav Rezanina <mrezanin@redhat.com> - 10.0.0-14
- kvm-hw-uefi-clear-uefi-vars-buffer-in-uefi_vars_write-ca.patch [RHEL-108614]
- kvm-hw-uefi-return-success-for-notifications.patch [RHEL-108614]