--- /dev/null
+From ce414263e9ebe5080381a50cbdf9065c29816202 Mon Sep 17 00:00:00 2001
+From: Nickolay Goppen <setotau@mainlining.org>
+Date: Wed, 29 Apr 2026 12:30:11 +0300
+Subject: arm64: dts: qcom: sdm630: describe adsp_mem region properly
+
+From: Nickolay Goppen <setotau@mainlining.org>
+
+commit ce414263e9ebe5080381a50cbdf9065c29816202 upstream.
+
+Downstream [1] this region is marked as shared, reusable and dynamic so
+describe it that way.
+
+[1]: https://github.com/xiaomi-sdm660/android_kernel_xiaomi_sdm660/blob/11-EAS/arch/arm/boot/dts/qcom/sdm660.dtsi#L448
+
+Fixes: b190fb010664 ("arm64: dts: qcom: sdm630: Add sdm630 dts file")
+Cc: stable@vger.kernel.org
+Reviewed-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Nickolay Goppen <setotau@mainlining.org>
+Link: https://lore.kernel.org/r/20260429-qcom-sdm660-cdsp-adsp-fastrpc-dts-fix-v5-4-16bc82e622ad@mainlining.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/boot/dts/qcom/sdm630.dtsi | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
+@@ -491,9 +491,12 @@
+ no-map;
+ };
+
+- adsp_mem: adsp-region@f6000000 {
+- reg = <0x0 0xf6000000 0x0 0x800000>;
+- no-map;
++ adsp_mem: adsp-region {
++ compatible = "shared-dma-pool";
++ alloc-ranges = <0x0 0x80000000 0x0 0x80000000>;
++ alignment = <0x0 0x400000>;
++ size = <0x0 0x800000>;
++ reusable;
+ };
+
+ qseecom_mem: qseecom-region@f6800000 {
--- /dev/null
+From ae24f6b06e90681ec36b9c21c3f5c09618350f5a Mon Sep 17 00:00:00 2001
+From: Mark Rutland <mark.rutland@arm.com>
+Date: Wed, 3 Jun 2026 12:06:11 +0100
+Subject: arm64: fpsimd: Fix type mismatch in sve_{save,load}_state()
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+commit ae24f6b06e90681ec36b9c21c3f5c09618350f5a upstream.
+
+The sve_save_state() and sve_load_state() functions take a 32-bit int
+argument that describes whether to save/restore the FFR. Their assembly
+implementations consume the entire 64-bit register containing this
+32-bit value, and will attempt to save/restore the FFR if any bit of
+that 64-bit register is non-zero.
+
+Per the AAPCS64 parameter passing rules, the callee is responsible for
+any necessary widening, and the upper 32-bits are permitted to contain
+arbitrary values. If the upper 32 bits are non-zero, this could result
+in an unexpected attempt to save/restore the FFR, and consequently could
+lead to unexpected traps/undefs/faults.
+
+In practice compilers are very unlikely to generate code where the upper
+32-bits would be non-zero, but they are permitted to do so.
+
+Fix this by only consuming the low 32 bits of the register, and update
+comments accordingly.
+
+The hyp code __sve_save_state() and __sve_restore_state() functions
+don't have the same latent bug as they override the full 64-bit register
+containing the argument.
+
+Fixes: 9f5848665788 ("arm64/sve: Make access to FFR optional")
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Fuad Tabba <tabba@google.com>
+Cc: James Morse <james.morse@arm.com>
+Cc: Marc Zyngier <maz@kernel.org>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Oliver Upton <oupton@kernel.org>
+Cc: Vladimir Murzin <vladimir.murzin@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kernel/entry-fpsimd.S | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/arch/arm64/kernel/entry-fpsimd.S
++++ b/arch/arm64/kernel/entry-fpsimd.S
+@@ -38,10 +38,10 @@ SYM_FUNC_END(fpsimd_load_state)
+ *
+ * x0 - pointer to buffer for state
+ * x1 - pointer to storage for FPSR
+- * x2 - Save FFR if non-zero
++ * w2 - Save FFR if non-zero
+ */
+ SYM_FUNC_START(sve_save_state)
+- sve_save 0, x1, x2, 3
++ sve_save 0, x1, w2, 3
+ ret
+ SYM_FUNC_END(sve_save_state)
+
+@@ -50,10 +50,10 @@ SYM_FUNC_END(sve_save_state)
+ *
+ * x0 - pointer to buffer for state
+ * x1 - pointer to storage for FPSR
+- * x2 - Restore FFR if non-zero
++ * w2 - Restore FFR if non-zero
+ */
+ SYM_FUNC_START(sve_load_state)
+- sve_load 0, x1, x2, 4
++ sve_load 0, x1, w2, 4
+ ret
+ SYM_FUNC_END(sve_load_state)
+
--- /dev/null
+From 1f97760417b5faa60e9642fd0ed61eb17d0b1b39 Mon Sep 17 00:00:00 2001
+From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Date: Tue, 9 Jun 2026 11:34:57 +0300
+Subject: ASoC: SOF: ipc3-control: Fix TOCTOU in bytes_put and bytes_get
+
+From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+
+commit 1f97760417b5faa60e9642fd0ed61eb17d0b1b39 upstream.
+
+In sof_ipc3_bytes_put(), the size used for the memcpy is derived from
+the old data->size already in the buffer, not the incoming new data's
+size field. If the new data has a different size, the copy length is
+wrong: it may truncate valid data or copy stale bytes.
+
+Similarly, sof_ipc3_bytes_get() checks data->size against max_size
+without accounting for the sizeof(struct sof_ipc_ctrl_data) offset
+of the flex array within the allocation.
+
+Fix bytes_put to validate and use the incoming data's sof_abi_hdr.size
+from ucontrol before copying. Fix bytes_get to subtract sizeof(*cdata)
+from the bounds check to match the actual available space.
+
+Fixes: 544ac8858f24 ("ASoC: SOF: Add bytes_get/put control IPC ops for IPC3")
+Cc: stable@vger.kernel.org
+Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Reviewed-by: Liam Girdwood <liam.r.girdwood@intel.com>
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Link: https://patch.msgid.link/20260609083458.31193-6-peter.ujfalusi@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/sof/ipc3-control.c | 23 ++++++++++++++++-------
+ 1 file changed, 16 insertions(+), 7 deletions(-)
+
+--- a/sound/soc/sof/ipc3-control.c
++++ b/sound/soc/sof/ipc3-control.c
+@@ -315,10 +315,13 @@ static int sof_ipc3_bytes_get(struct snd
+ }
+
+ /* be->max has been verified to be >= sizeof(struct sof_abi_hdr) */
+- if (data->size > scontrol->max_size - sizeof(*data)) {
++ if (data->size > scontrol->max_size - sizeof(*cdata) -
++ sizeof(*data)) {
+ dev_err_ratelimited(scomp->dev,
+ "%u bytes of control data is invalid, max is %zu\n",
+- data->size, scontrol->max_size - sizeof(*data));
++ data->size,
++ scontrol->max_size - sizeof(*cdata) -
++ sizeof(*data));
+ return -EINVAL;
+ }
+
+@@ -336,6 +339,8 @@ static int sof_ipc3_bytes_put(struct snd
+ struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data;
+ struct snd_soc_component *scomp = scontrol->scomp;
+ struct sof_abi_hdr *data = cdata->data;
++ const struct sof_abi_hdr *new_hdr =
++ (const struct sof_abi_hdr *)ucontrol->value.bytes.data;
+ size_t size;
+
+ if (scontrol->max_size > sizeof(ucontrol->value.bytes.data)) {
+@@ -344,14 +349,18 @@ static int sof_ipc3_bytes_put(struct snd
+ return -EINVAL;
+ }
+
+- /* scontrol->max_size has been verified to be >= sizeof(struct sof_abi_hdr) */
+- if (data->size > scontrol->max_size - sizeof(*data)) {
+- dev_err_ratelimited(scomp->dev, "data size too big %u bytes max is %zu\n",
+- data->size, scontrol->max_size - sizeof(*data));
++ /* Validate the new data's size, not the old one */
++ if (new_hdr->size > scontrol->max_size - sizeof(*cdata) -
++ sizeof(*new_hdr)) {
++ dev_err_ratelimited(scomp->dev,
++ "data size too big %u bytes max is %zu\n",
++ new_hdr->size,
++ scontrol->max_size - sizeof(*cdata) -
++ sizeof(*new_hdr));
+ return -EINVAL;
+ }
+
+- size = data->size + sizeof(*data);
++ size = new_hdr->size + sizeof(*new_hdr);
+
+ /* copy from kcontrol */
+ memcpy(data, ucontrol->value.bytes.data, size);
--- /dev/null
+From 8791977d7289f6e9d2b014f60a5455f053a7bc04 Mon Sep 17 00:00:00 2001
+From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Date: Tue, 9 Jun 2026 11:34:55 +0300
+Subject: ASoC: SOF: ipc3-control: Use overflow checks in control_update size calc
+
+From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+
+commit 8791977d7289f6e9d2b014f60a5455f053a7bc04 upstream.
+
+In sof_ipc3_control_update(), the expected_size calculation uses
+firmware-provided cdata->num_elems in arithmetic that could overflow
+on 32-bit platforms, wrapping to a small value. This would allow the
+cdata->rhdr.hdr.size comparison to pass with mismatched sizes,
+potentially leading to out-of-bounds access in snd_sof_update_control.
+
+Use check_mul_overflow() and check_add_overflow() to detect and reject
+overflowed size calculations.
+
+Fixes: 10f461d79c2d ("ASoC: SOF: Add IPC3 topology control ops")
+Cc: stable@vger.kernel.org
+Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Reviewed-by: Liam Girdwood <liam.r.girdwood@intel.com>
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Link: https://patch.msgid.link/20260609083458.31193-4-peter.ujfalusi@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/sof/ipc3-control.c | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+--- a/sound/soc/sof/ipc3-control.c
++++ b/sound/soc/sof/ipc3-control.c
+@@ -626,16 +626,28 @@ static void sof_ipc3_control_update(stru
+ return;
+ }
+
+- expected_size = sizeof(struct sof_ipc_ctrl_data);
+ switch (cdata->type) {
+ case SOF_CTRL_TYPE_VALUE_CHAN_GET:
+ case SOF_CTRL_TYPE_VALUE_CHAN_SET:
+- expected_size += cdata->num_elems *
+- sizeof(struct sof_ipc_ctrl_value_chan);
++ if (check_mul_overflow((size_t)cdata->num_elems,
++ sizeof(struct sof_ipc_ctrl_value_chan),
++ &expected_size))
++ return;
++ if (check_add_overflow(expected_size,
++ sizeof(struct sof_ipc_ctrl_data),
++ &expected_size))
++ return;
+ break;
+ case SOF_CTRL_TYPE_DATA_GET:
+ case SOF_CTRL_TYPE_DATA_SET:
+- expected_size += cdata->num_elems + sizeof(struct sof_abi_hdr);
++ if (check_add_overflow((size_t)cdata->num_elems,
++ sizeof(struct sof_abi_hdr),
++ &expected_size))
++ return;
++ if (check_add_overflow(expected_size,
++ sizeof(struct sof_ipc_ctrl_data),
++ &expected_size))
++ return;
+ break;
+ default:
+ return;
--- /dev/null
+From 3ad673e7139cf214afd24321a829aad6575f4163 Mon Sep 17 00:00:00 2001
+From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Date: Tue, 9 Jun 2026 11:34:53 +0300
+Subject: ASoC: SOF: ipc4-control: Fix TOCTOU in sof_ipc4_bytes_put
+
+From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+
+commit 3ad673e7139cf214afd24321a829aad6575f4163 upstream.
+
+In sof_ipc4_bytes_put(), the copy size is derived from the old
+data->size in the buffer rather than the incoming new data's size
+field from ucontrol. If the new data has a different size, the copy
+uses the wrong length: it may truncate valid data or copy stale bytes.
+
+Fix by validating and using the incoming data's sof_abi_hdr.size from
+ucontrol before copying.
+
+Fixes: a062c8899fed ("ASoC: SOF: ipc4-control: Add support for bytes control get and put")
+Cc: stable@vger.kernel.org
+Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Reviewed-by: Liam Girdwood <liam.r.girdwood@intel.com>
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Link: https://patch.msgid.link/20260609083458.31193-2-peter.ujfalusi@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/sof/ipc4-control.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+--- a/sound/soc/sof/ipc4-control.c
++++ b/sound/soc/sof/ipc4-control.c
+@@ -407,6 +407,8 @@ static int sof_ipc4_bytes_put(struct snd
+ struct snd_soc_component *scomp = scontrol->scomp;
+ struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
+ struct sof_abi_hdr *data = cdata->data;
++ const struct sof_abi_hdr *new_hdr =
++ (const struct sof_abi_hdr *)ucontrol->value.bytes.data;
+ size_t size;
+ int ret;
+
+@@ -417,15 +419,16 @@ static int sof_ipc4_bytes_put(struct snd
+ return -EINVAL;
+ }
+
+- /* scontrol->max_size has been verified to be >= sizeof(struct sof_abi_hdr) */
+- if (data->size > scontrol->max_size - sizeof(*data)) {
++ /* Validate the new data's size, not the old one */
++ if (new_hdr->size > scontrol->max_size - sizeof(*new_hdr)) {
+ dev_err_ratelimited(scomp->dev,
+ "data size too big %u bytes max is %zu\n",
+- data->size, scontrol->max_size - sizeof(*data));
++ new_hdr->size,
++ scontrol->max_size - sizeof(*new_hdr));
+ return -EINVAL;
+ }
+
+- size = data->size + sizeof(*data);
++ size = new_hdr->size + sizeof(*new_hdr);
+
+ /* copy from kcontrol */
+ memcpy(data, ucontrol->value.bytes.data, size);
--- /dev/null
+From 8468dd79cfb2ffbdeaf7c353f63d64941cb8ba05 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?C=C3=A1ssio=20Gabriel?= <cassiogabrielcontato@gmail.com>
+Date: Wed, 3 Jun 2026 14:57:54 -0300
+Subject: ASoC: SOF: topology: validate vendor array size before parsing
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+commit 8468dd79cfb2ffbdeaf7c353f63d64941cb8ba05 upstream.
+
+sof_parse_token_sets() reads array->size while iterating over topology
+private data. The loop condition only checks that some data remains, so a
+malformed topology with a truncated trailing vendor array can make the
+parser read the size field before a full vendor-array header is available.
+
+Validate that the remaining private data contains a complete
+snd_soc_tplg_vendor_array header before reading array->size.
+
+The declared array size check also needs to remain signed. asize is an int,
+but sizeof(*array) has type size_t, so comparing them directly promotes
+negative asize values to unsigned and lets them pass the check,
+as reported in the stable review thread reference below.
+
+Cast sizeof(*array) to int when validating the declared array size. This
+rejects negative, zero and otherwise too-small sizes before the parser
+dispatches to the tuple-specific code.
+
+Link: https://lore.kernel.org/stable/CANiDSCsjR5NHqu_Ui5cOqWdJgFqmYsQ9WR8O7m0WOhngaYXFpw@mail.gmail.com/t/#m9b3be379221e79327cc13fd71009287368ef4f23
+Fixes: 215e5fe75881 ("ASoC: SOF: topology: reject invalid vendor array size in token parser")
+Cc: stable@vger.kernel.org
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260603-sof-topology-array-size-signed-v1-1-84f97879a4ef@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/sof/topology.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/sound/soc/sof/topology.c
++++ b/sound/soc/sof/topology.c
+@@ -719,10 +719,13 @@ static int sof_parse_token_sets(struct s
+ int ret;
+
+ while (array_size > 0 && total < count * token_instance_num) {
++ if (array_size < (int)sizeof(*array))
++ return -EINVAL;
++
+ asize = le32_to_cpu(array->size);
+
+ /* validate asize */
+- if (asize < sizeof(*array)) {
++ if (asize < (int)sizeof(*array)) {
+ dev_err(scomp->dev, "error: invalid array size 0x%x\n",
+ asize);
+ return -EINVAL;
--- /dev/null
+From 0074b82cdfcb5fd13710a0ac308ade68ac6f6fbe Mon Sep 17 00:00:00 2001
+From: Hyunwoo Kim <imv4bel@gmail.com>
+Date: Fri, 5 Jun 2026 05:59:15 +0900
+Subject: KVM: arm64: vgic: Check the interrupt is still ours before migrating it
+
+From: Hyunwoo Kim <imv4bel@gmail.com>
+
+commit 0074b82cdfcb5fd13710a0ac308ade68ac6f6fbe upstream.
+
+vgic_prune_ap_list() drops both ap_list_lock and irq_lock while migrating
+an interrupt to another vCPU. After reacquiring the locks it only checks
+that the affinity is unchanged (target_vcpu == vgic_target_oracle(irq))
+before moving the interrupt, which assumes that an interrupt whose affinity
+is preserved is still queued on this vCPU's ap_list.
+
+That assumption no longer holds if the interrupt is taken off the ap_list
+while the locks are dropped. vgic_flush_pending_lpis() removes the
+interrupt from the list and sets irq->vcpu to NULL, but leaves
+enabled/pending/target_vcpu untouched. As the interrupt is still enabled
+and pending, vgic_target_oracle() returns the same target_vcpu, so the
+affinity check passes and list_del() is run a second time on an entry that
+has already been removed.
+
+Also check that the interrupt is still assigned to this vCPU
+(irq->vcpu == vcpu) before moving it.
+
+Fixes: 0919e84c0fc1 ("KVM: arm/arm64: vgic-new: Add IRQ sync/flush framework")
+Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
+Link: https://patch.msgid.link/aiHnI1mu6SGQrgnz@v4bel
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kvm/vgic/vgic.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/arch/arm64/kvm/vgic/vgic.c
++++ b/arch/arm64/kvm/vgic/vgic.c
+@@ -701,15 +701,16 @@ retry:
+ raw_spin_lock(&irq->irq_lock);
+
+ /*
+- * If the affinity has been preserved, move the
+- * interrupt around. Otherwise, it means things have
+- * changed while the interrupt was unlocked, and we
+- * need to replay this.
++ * If the interrupt is still ours and its affinity has
++ * been preserved, move it around. Otherwise, it means
++ * things have changed while the interrupt was unlocked
++ * (it may even have been taken off the list with its
++ * affinity left untouched), and we need to replay this.
+ *
+ * In all cases, we cannot trust the list not to have
+ * changed, so we restart from the beginning.
+ */
+- if (target_vcpu == vgic_target_oracle(irq)) {
++ if (irq->vcpu == vcpu && target_vcpu == vgic_target_oracle(irq)) {
+ struct vgic_cpu *new_cpu = &target_vcpu->arch.vgic_cpu;
+
+ list_del(&irq->ap_list);
--- /dev/null
+From 7258770e5814f15e8308ebda82ac9acf6964ba8e Mon Sep 17 00:00:00 2001
+From: Marc Zyngier <maz@kernel.org>
+Date: Mon, 15 Jun 2026 19:16:25 +0100
+Subject: KVM: arm64: vgic: Handle race between interrupt affinity change and LPI disabling
+
+From: Marc Zyngier <maz@kernel.org>
+
+commit 7258770e5814f15e8308ebda82ac9acf6964ba8e upstream.
+
+Hyunwoo Kim reports some really bad races should the following
+situation occur:
+
+- LPI-I is pending in vcpu-B's AP list
+- vcpu-A writes to vcpu-B's RD to disable its LPIs
+- vcpu-C moves I from B to C
+
+If the last two race nicely enough, vgic_prune_ap_list() can drop
+the irq and AP list locks, reacquire them, and in the interval
+the irq has been freed. UAF follows.
+
+The fix is two-fold:
+
+- Before dropping the irq and ap_list locks, take a reference on
+ the irq
+
+- Do not try to handle migration of the pending bit: there is no
+ expectation that this state is retained, as per the architecture
+
+With that, we're sure that the interrupt is still around, and we
+safely remove it from the AP list as it has no target at this
+stage (unless another interrupt fires, but that's another story).
+
+Reported-by: Hyunwoo Kim <imv4bel@gmail.com>
+Tested-by: Hyunwoo Kim <imv4bel@gmail.com>
+Link: https://lore.kernel.org/r/ailsCnyoS82r_QRz@v4bel
+Link: https://patch.msgid.link/20260615181625.3029352-1-maz@kernel.org
+Fixes: 5dd4b924e390a ("KVM: arm/arm64: vgic: Add refcounting for IRQs")
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kvm/vgic/vgic.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/kvm/vgic/vgic.c
++++ b/arch/arm64/kvm/vgic/vgic.c
+@@ -160,6 +160,7 @@ void vgic_flush_pending_lpis(struct kvm_
+ list_for_each_entry_safe(irq, tmp, &vgic_cpu->ap_list_head, ap_list) {
+ if (irq->intid >= VGIC_MIN_LPI) {
+ raw_spin_lock(&irq->irq_lock);
++ irq->pending_latch = false;
+ list_del(&irq->ap_list);
+ irq->vcpu = NULL;
+ raw_spin_unlock(&irq->irq_lock);
+@@ -678,7 +679,11 @@ retry:
+ continue;
+ }
+
+- /* This interrupt looks like it has to be migrated. */
++ /*
++ * This interrupt looks like it has to be migrated,
++ * make sure it is kept alive while locks are dropped.
++ */
++ vgic_get_irq_ref(irq);
+
+ raw_spin_unlock(&irq->irq_lock);
+ raw_spin_unlock(&vgic_cpu->ap_list_lock);
+@@ -723,6 +728,8 @@ retry:
+ raw_spin_unlock(&vcpuB->arch.vgic_cpu.ap_list_lock);
+ raw_spin_unlock(&vcpuA->arch.vgic_cpu.ap_list_lock);
+
++ deleted_lpis |= vgic_put_irq_norelease(vcpu->kvm, irq);
++
+ if (target_vcpu_needs_kick) {
+ kvm_make_request(KVM_REQ_IRQ_PENDING, target_vcpu);
+ kvm_vcpu_kick(target_vcpu);
--- /dev/null
+From 7b69729046a4c58f4cb457184e5ac4aaa179bff4 Mon Sep 17 00:00:00 2001
+From: Haoxiang Li <haoxiang_li2024@163.com>
+Date: Wed, 24 Jun 2026 14:19:10 +0800
+Subject: KVM: s390: pci: Fix GISC refcount leak on AIF enable failure
+
+From: Haoxiang Li <haoxiang_li2024@163.com>
+
+commit 7b69729046a4c58f4cb457184e5ac4aaa179bff4 upstream.
+
+kvm_s390_gisc_register() registers the guest ISC before pinning
+the guest interrupt forwarding pages and allocating the AISB bit.
+If any of the later setup steps fails, the function unwinds the
+pinned pages and other local state, but does not unregister the
+GISC reference. Add the missing kvm_s390_gisc_unregister() to the
+error unwind path.
+
+Fixes: 3c5a1b6f0a18 ("KVM: s390: pci: provide routines for enabling/disabling interrupt forwarding")
+Cc: stable@vger.kernel.org
+Signed-off-by: Haoxiang Li <haoxiang_li2024@163.com>
+Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
+Tested-by: Matthew Rosato <mjrosato@linux.ibm.com>
+Acked-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Reviewed-by: Christian Borntraeger <borntraeger@linux.ibm.com>
+Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Message-ID: <20260624061910.2794734-1-haoxiang_li2024@163.com>
+Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/kvm/pci.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/s390/kvm/pci.c
++++ b/arch/s390/kvm/pci.c
+@@ -330,6 +330,7 @@ unpin2:
+ unpin1:
+ unpin_user_page(aibv_page);
+ out:
++ kvm_s390_gisc_unregister(kvm, fib->fmt0.isc);
+ return rc;
+ }
+
--- /dev/null
+From 3e3aa6da87d30a0064a17b836685cd43c90a3572 Mon Sep 17 00:00:00 2001
+From: Matthew Rosato <mjrosato@linux.ibm.com>
+Date: Thu, 9 Jul 2026 09:54:04 -0400
+Subject: KVM: s390: pci: Fix handling of AIF enable without AISB
+
+From: Matthew Rosato <mjrosato@linux.ibm.com>
+
+commit 3e3aa6da87d30a0064a17b836685cd43c90a3572 upstream.
+
+When a guest seeks to register IRQs without a summary bit specified,
+ensure that the associated GAITE then stores 0 for the guest AISB
+location instead of virt_to_phys(page_address(NULL)).
+
+Fixes: 3c5a1b6f0a18 ("KVM: s390: pci: provide routines for enabling/disabling interrupt forwarding")
+Cc: stable@vger.kernel.org
+Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
+Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
+Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/kvm/pci.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/arch/s390/kvm/pci.c
++++ b/arch/s390/kvm/pci.c
+@@ -302,9 +302,14 @@ static int kvm_s390_pci_aif_enable(struc
+
+ gaite->gisc = fib->fmt0.isc;
+ gaite->count++;
+- gaite->aisbo = fib->fmt0.aisbo;
+- gaite->aisb = virt_to_phys(page_address(aisb_page) + (fib->fmt0.aisb &
+- ~PAGE_MASK));
++ if (fib->fmt0.sum == 1) {
++ gaite->aisbo = fib->fmt0.aisbo;
++ gaite->aisb = virt_to_phys(page_address(aisb_page) +
++ (fib->fmt0.aisb & ~PAGE_MASK));
++ } else {
++ gaite->aisbo = 0;
++ gaite->aisb = 0;
++ }
+ aift->kzdev[zdev->aisb] = zdev->kzdev;
+ spin_unlock_irq(&aift->gait_lock);
+
--- /dev/null
+From 9285e4070df2c40585c3d7ec9571faa7a2b97e17 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Wed, 24 Jun 2026 15:05:16 -0700
+Subject: KVM: x86: Ignore pending PV EOI if the vCPU has since disabled PV EOIs
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit 9285e4070df2c40585c3d7ec9571faa7a2b97e17 upstream.
+
+Ignore KVM's internal "service pending PV EOI" request if the vCPU has
+disabled PV EOIs since the request was made. Asserting that PV EOIs are
+enabled can fail if reading guest memory in pv_eoi_get_user() fails, i.e.
+if pv_eoi_test_and_clr_pending() bails early, *and* the vCPU also disables
+PV EOIs.
+
+ kernel BUG at arch/x86/kvm/lapic.c:3338!
+ Oops: invalid opcode: 0000 [#1] SMP
+ CPU: 4 UID: 1000 PID: 890 Comm: pv_eoi_test Not tainted 7.0.0-d585aa5894d8-vm #337 PREEMPT
+ Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
+ RIP: 0010:kvm_lapic_sync_from_vapic+0x12b/0x140 [kvm]
+ Call Trace:
+ <TASK>
+ kvm_arch_vcpu_ioctl_run+0x1075/0x1c30 [kvm]
+ kvm_vcpu_ioctl+0x2d5/0x980 [kvm]
+ __x64_sys_ioctl+0x8a/0xd0
+ do_syscall_64+0xb5/0xb40
+ entry_SYSCALL_64_after_hwframe+0x4b/0x53
+ </TASK>
+ Modules linked in: kvm_intel kvm irqbypass
+ ---[ end trace 0000000000000000 ]---
+
+Fixes: ae7a2a3fb6f8 ("KVM: host side for eoi optimization")
+Cc: stable@vger.kernel.org
+Reviewed-by: Kai Huang <kai.huang@intel.com>
+Link: https://patch.msgid.link/20260624220516.3033391-1-seanjc@google.com
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/lapic.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/kvm/lapic.c
++++ b/arch/x86/kvm/lapic.c
+@@ -3138,6 +3138,12 @@ static void apic_sync_pv_eoi_from_guest(
+ struct kvm_lapic *apic)
+ {
+ int vector;
++
++ if (unlikely(!pv_eoi_enabled(vcpu))) {
++ __clear_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention);
++ return;
++ }
++
+ /*
+ * PV EOI state is derived from KVM_APIC_PV_EOI_PENDING in host
+ * and KVM_PV_EOI_ENABLED in guest memory as follows:
+@@ -3149,8 +3155,6 @@ static void apic_sync_pv_eoi_from_guest(
+ * KVM_APIC_PV_EOI_PENDING is set, KVM_PV_EOI_ENABLED is unset:
+ * -> host enabled PV EOI, guest executed EOI.
+ */
+- BUG_ON(!pv_eoi_enabled(vcpu));
+-
+ if (pv_eoi_test_and_clr_pending(vcpu))
+ return;
+ vector = apic_set_eoi(apic);
--- /dev/null
+From 41c8c1d65b32beacd8d916a22457b4f6e47f45af Mon Sep 17 00:00:00 2001
+From: Wentao Liang <vulab@iscas.ac.cn>
+Date: Tue, 9 Jun 2026 08:37:09 +0000
+Subject: mlxsw: fix refcount leak in mlxsw_sp_port_lag_join()
+
+From: Wentao Liang <vulab@iscas.ac.cn>
+
+commit 41c8c1d65b32beacd8d916a22457b4f6e47f45af upstream.
+
+When mlxsw_sp_port_lag_index_get() fails, mlxsw_sp_port_lag_join()
+returns an error without releasing the lag reference obtained by
+the earlier mlxsw_sp_lag_get(). All other error paths in the
+function jump to the cleanup label that ends with
+mlxsw_sp_lag_put(), so this is a single missed release.
+
+Fix the leak by replacing the bare 'return err' with a goto to the
+existing error cleanup label, which will drop the reference safely.
+
+Cc: stable@vger.kernel.org
+Fixes: 0d65fc13042f ("mlxsw: spectrum: Implement LAG port join/leave")
+Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260609083709.209743-1-vulab@iscas.ac.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+@@ -4427,7 +4427,7 @@ static int mlxsw_sp_port_lag_join(struct
+
+ err = mlxsw_sp_port_lag_index_get(mlxsw_sp, lag_id, &port_index);
+ if (err)
+- return err;
++ goto err_lag_uppers_bridge_join;
+
+ err = mlxsw_sp_lag_uppers_bridge_join(mlxsw_sp_port, lag_dev,
+ extack);
--- /dev/null
+From 21cf8dc478a49e8de039c2739b1646a774cb1944 Mon Sep 17 00:00:00 2001
+From: Wentao Liang <vulab@iscas.ac.cn>
+Date: Tue, 9 Jun 2026 08:47:30 +0000
+Subject: mlxsw: fix refcount leak in mlxsw_sp_vrs_lpm_tree_replace()
+
+From: Wentao Liang <vulab@iscas.ac.cn>
+
+commit 21cf8dc478a49e8de039c2739b1646a774cb1944 upstream.
+
+When mlxsw_sp_vrs_lpm_tree_replace() fails after replacing some VRs,
+the error rollback loop does not correctly revert the preceding
+replacements. The loop decrements the index but fails to update the
+vr pointer, which still points to the VR that caused the failure. As
+a result, the condition and the rollback call always operate on the
+same VR, potentially calling mlxsw_sp_vr_lpm_tree_replace() multiple
+times on it while never rolling back the earlier VRs. Those VRs
+continue to hold a reference to new_tree acquired via
+mlxsw_sp_lpm_tree_hold(), leaking the reference count of new_tree.
+
+Fix by reinitializing vr inside the error loop with the updated index:
+
+ vr = &mlxsw_sp->router->vrs[i];
+
+so that the loop correctly iterates over all VRs that were actually
+replaced.
+
+Cc: stable@vger.kernel.org
+Fixes: fc922bb0dd94 ("mlxsw: spectrum_router: Use one LPM tree for all virtual routers")
+Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260609084730.215732-1-vulab@iscas.ac.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+@@ -1018,6 +1018,7 @@ static int mlxsw_sp_vrs_lpm_tree_replace
+
+ err_tree_replace:
+ for (i--; i >= 0; i--) {
++ vr = &mlxsw_sp->router->vrs[i];
+ if (!mlxsw_sp_vr_lpm_tree_should_replace(vr, proto, new_id))
+ continue;
+ mlxsw_sp_vr_lpm_tree_replace(mlxsw_sp,
--- /dev/null
+From cdf19f380e46192e7084be559638aab1f6ed86a2 Mon Sep 17 00:00:00 2001
+From: Zhengchuan Liang <zcliangcn@gmail.com>
+Date: Tue, 9 Jun 2026 16:34:37 +0800
+Subject: net: atm: reject out-of-range traffic classes in QoS validation
+
+From: Zhengchuan Liang <zcliangcn@gmail.com>
+
+commit cdf19f380e46192e7084be559638aab1f6ed86a2 upstream.
+
+Reject ATM traffic classes above ATM_ANYCLASS in check_tp().
+SO_ATMQOS stores the supplied QoS after check_qos() succeeds, so
+accepting larger values leaves invalid traffic_class values in
+vcc->qos.
+
+That bad state later reaches pvc_info(), which indexes class_name[]
+with vcc->qos.{rx,tp}.traffic_class. Values above ATM_ANYCLASS cause
+an out-of-bounds read when /proc/net/atm/pvc is read.
+
+Tighten the existing QoS validation so invalid traffic_class values
+are rejected at the point where user supplied QoS is accepted.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Signed-off-by: Zhengchuan Liang <zcliangcn@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/58f02c6f73d9818fd5d2022e1116759fdde6116b.1780965530.git.zcliangcn@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/atm/common.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/atm/common.c
++++ b/net/atm/common.c
+@@ -720,6 +720,8 @@ static int atm_change_qos(struct atm_vcc
+ static int check_tp(const struct atm_trafprm *tp)
+ {
+ /* @@@ Should be merged with adjust_tp */
++ if (tp->traffic_class > ATM_ANYCLASS)
++ return -EINVAL;
+ if (!tp->traffic_class || tp->traffic_class == ATM_ANYCLASS)
+ return 0;
+ if (tp->traffic_class != ATM_UBR && !tp->min_pcr && !tp->pcr &&
--- /dev/null
+From 9406f6012b7343661efb516a11c62d4db2b62f75 Mon Sep 17 00:00:00 2001
+From: Yong Wang <edragain@163.com>
+Date: Thu, 11 Jun 2026 02:37:43 +0800
+Subject: net: ife: require ETH_HLEN to be pullable in ife_decode()
+
+From: Yong Wang <edragain@163.com>
+
+commit 9406f6012b7343661efb516a11c62d4db2b62f75 upstream.
+
+ife decode may return after making only the outer IFE header and
+metadata pullable. The caller then passes the decapsulated packet to
+eth_type_trans(), which expects the inner Ethernet header to be
+accessible from the linear data area.
+
+With a malformed IFE frame, the inner Ethernet header may still be
+shorter than ETH_HLEN in the linear area, which can lead to a crash in
+the original code.
+
+Fix this by extending the pull check in ife_decode() so that the inner
+Ethernet header is also guaranteed to be pullable before returning.
+
+Fixes: ef6980b6becb ("introduce IFE action")
+Cc: stable@vger.kernel.org
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Signed-off-by: Yong Wang <edragain@163.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Link: https://patch.msgid.link/20260610183814.1648888-2-n05ec@lzu.edu.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ife/ife.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ife/ife.c
++++ b/net/ife/ife.c
+@@ -79,7 +79,7 @@ void *ife_decode(struct sk_buff *skb, u1
+ if (unlikely(ifehdrln < 2))
+ return NULL;
+
+- if (unlikely(!pskb_may_pull(skb, total_pull)))
++ if (unlikely(!pskb_may_pull(skb, total_pull + ETH_HLEN)))
+ return NULL;
+
+ ifehdr = (struct ifeheadr *)(skb->data + skb->dev->hard_header_len);
--- /dev/null
+From 20054869770c7df060c5ecee3e8bbf9029c47191 Mon Sep 17 00:00:00 2001
+From: Michael Bommarito <michael.bommarito@gmail.com>
+Date: Thu, 11 Jun 2026 08:54:55 -0400
+Subject: net: qrtr: fix 32-bit integer overflow in qrtr_endpoint_post()
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+commit 20054869770c7df060c5ecee3e8bbf9029c47191 upstream.
+
+qrtr_endpoint_post() validates an incoming packet with
+
+ if (!size || len != ALIGN(size, 4) + hdrlen)
+ goto err;
+
+where size comes from the wire. On 32-bit, size_t is 32 bits and
+ALIGN(size, 4) wraps to 0 for size >= 0xfffffffd, so the check
+passes and skb_put_data(skb, data + hdrlen, size) writes past the
+hdrlen-sized skb and oopses the kernel. 64-bit is unaffected.
+
+This is the 32-bit residual of ad9d24c9429e2 ("net: qrtr: fix OOB
+Read in qrtr_endpoint_post"), which fixed only the 64-bit case.
+
+Reject any size that cannot fit the buffer before the ALIGN.
+
+Fixes: ad9d24c9429e2 ("net: qrtr: fix OOB Read in qrtr_endpoint_post")
+Cc: stable@vger.kernel.org
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260611125455.2352279-1-michael.bommarito@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/qrtr/af_qrtr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/qrtr/af_qrtr.c
++++ b/net/qrtr/af_qrtr.c
+@@ -496,7 +496,7 @@ int qrtr_endpoint_post(struct qrtr_endpo
+ if (cb->dst_port == QRTR_PORT_CTRL_LEGACY)
+ cb->dst_port = QRTR_PORT_CTRL;
+
+- if (!size || len != ALIGN(size, 4) + hdrlen)
++ if (!size || size > len || len != ALIGN(size, 4) + hdrlen)
+ goto err;
+
+ if ((cb->type == QRTR_TYPE_NEW_SERVER ||
net-mlx5-fix-l3-tunnel-entropy-refcount-leak.patch
octeontx2-af-fix-vf-bringup-affecting-pf-promiscuous.patch
smb-client-fix-overflow-in-passthrough-ioctl-bounds-.patch
+mlxsw-fix-refcount-leak-in-mlxsw_sp_port_lag_join.patch
+mlxsw-fix-refcount-leak-in-mlxsw_sp_vrs_lpm_tree_replace.patch
+vduse-fix-race-in-vduse_dev_msg_sync-and-vduse_dev_read_iter.patch
+asoc-sof-ipc4-control-fix-toctou-in-sof_ipc4_bytes_put.patch
+asoc-sof-ipc3-control-use-overflow-checks-in-control_update-size-calc.patch
+asoc-sof-ipc3-control-fix-toctou-in-bytes_put-and-bytes_get.patch
+asoc-sof-topology-validate-vendor-array-size-before-parsing.patch
+net-qrtr-fix-32-bit-integer-overflow-in-qrtr_endpoint_post.patch
+net-atm-reject-out-of-range-traffic-classes-in-qos-validation.patch
+net-ife-require-eth_hlen-to-be-pullable-in-ife_decode.patch
+arm64-fpsimd-fix-type-mismatch-in-sve_-save-load-_state.patch
+arm64-dts-qcom-sdm630-describe-adsp_mem-region-properly.patch
+kvm-s390-pci-fix-gisc-refcount-leak-on-aif-enable-failure.patch
+kvm-arm64-vgic-check-the-interrupt-is-still-ours-before-migrating-it.patch
+kvm-arm64-vgic-handle-race-between-interrupt-affinity-change-and-lpi-disabling.patch
+kvm-s390-pci-fix-handling-of-aif-enable-without-aisb.patch
+kvm-x86-ignore-pending-pv-eoi-if-the-vcpu-has-since-disabled-pv-eois.patch
--- /dev/null
+From ae9c13b6fd79087cc5a216ee1649b6f012c2a238 Mon Sep 17 00:00:00 2001
+From: Zhang Tianci <zhangtianci.1997@bytedance.com>
+Date: Thu, 26 Feb 2026 19:55:50 +0800
+Subject: vduse: Fix race in vduse_dev_msg_sync and vduse_dev_read_iter
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zhang Tianci <zhangtianci.1997@bytedance.com>
+
+commit ae9c13b6fd79087cc5a216ee1649b6f012c2a238 upstream.
+
+There is one race case in vduse_dev_msg_sync and vduse_dev_read_iter:
+
+vduse_dev_read_iter():
+ lock(msg_lock);
+ dequeue_msg(send_list);
+ unlock(msg_lock);
+vduse_dev_msg_sync():
+ wait_timeout() finish
+ lock(msg_lock);
+ check msg->complete is false
+ list_del(msg); <- double list_del() crash!
+
+To fix this case, we shall ensure vduse_msg is on send_list or recv_list
+outside the msg_lock critical section.
+
+Fixes: c8a6153b6c59 ("vduse: Introduce VDUSE - vDPA Device in Userspace")
+Cc: stable@vger.kernel.org
+Signed-off-by: Zhang Tianci <zhangtianci.1997@bytedance.com>
+Reviewed-by: Xie Yongji <xieyongji@bytedance.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Acked-by: Eugenio Pérez <eperezma@redhat.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Message-ID: <20260226115550.1814-3-zhangtianci.1997@bytedance.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/vdpa/vdpa_user/vduse_dev.c | 37 +++++++++++++++++++++++++++----------
+ 1 file changed, 27 insertions(+), 10 deletions(-)
+
+--- a/drivers/vdpa/vdpa_user/vduse_dev.c
++++ b/drivers/vdpa/vdpa_user/vduse_dev.c
+@@ -330,6 +330,7 @@ static ssize_t vduse_dev_read_iter(struc
+ struct file *file = iocb->ki_filp;
+ struct vduse_dev *dev = file->private_data;
+ struct vduse_dev_msg *msg;
++ struct vduse_dev_request req;
+ int size = sizeof(struct vduse_dev_request);
+ ssize_t ret;
+
+@@ -341,12 +342,11 @@ static ssize_t vduse_dev_read_iter(struc
+ msg = vduse_dequeue_msg(&dev->send_list);
+ if (msg)
+ break;
++ spin_unlock(&dev->msg_lock);
+
+- ret = -EAGAIN;
+ if (file->f_flags & O_NONBLOCK)
+- goto unlock;
++ return -EAGAIN;
+
+- spin_unlock(&dev->msg_lock);
+ ret = wait_event_interruptible_exclusive(dev->waitq,
+ !list_empty(&dev->send_list));
+ if (ret)
+@@ -354,17 +354,34 @@ static ssize_t vduse_dev_read_iter(struc
+
+ spin_lock(&dev->msg_lock);
+ }
++
++ memcpy(&req, &msg->req, sizeof(req));
++ /*
++ * We must ensure vduse_msg is on send_list or recv_list before unlock
++ * dev->msg_lock. Because vduse_dev_msg_sync() may be timeout when we
++ * copy data to userspace, and will call list_del() for this msg.
++ */
++ vduse_enqueue_msg(&dev->recv_list, msg);
+ spin_unlock(&dev->msg_lock);
+- ret = copy_to_iter(&msg->req, size, to);
+- spin_lock(&dev->msg_lock);
++
++ ret = copy_to_iter(&req, size, to);
+ if (ret != size) {
++ /*
++ * Roll back: move msg back to send_list if still pending.
++ *
++ * NOTE:
++ * vduse_find_msg() must use req.request_id instead of `msg`.
++ * A malicious userspace may reply to this request, and wake up
++ * the caller, after which `msg` will have already been freed.
++ * And here vduse_find_msg() will return NULL then do nothing.
++ */
++ spin_lock(&dev->msg_lock);
++ msg = vduse_find_msg(&dev->recv_list, req.request_id);
++ if (msg)
++ vduse_enqueue_msg_head(&dev->send_list, msg);
++ spin_unlock(&dev->msg_lock);
+ ret = -EFAULT;
+- vduse_enqueue_msg_head(&dev->send_list, msg);
+- goto unlock;
+ }
+- vduse_enqueue_msg(&dev->recv_list, msg);
+-unlock:
+- spin_unlock(&dev->msg_lock);
+
+ return ret;
+ }