From: Greg Kroah-Hartman Date: Mon, 30 Mar 2026 10:05:02 +0000 (+0200) Subject: 6.12-stable patches X-Git-Tag: v6.6.131~37 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=893eb22b26e56c3c8a775db37a1a45ec3d1b6e17;p=thirdparty%2Fkernel%2Fstable-queue.git 6.12-stable patches added patches: alarmtimer-fix-argument-order-in-alarm_timer_forward.patch dmaengine-fsl-edma-fix-channel-parameter-config-for-fixed-channel-requests.patch dmaengine-sh-rz-dmac-move-chctrl-updates-under-spinlock.patch dmaengine-sh-rz-dmac-protect-the-driver-specific-lists.patch drm-amdgpu-prevent-immediate-pasid-reuse-case.patch drm-i915-dp_tunnel-fix-error-handling-when-clearing-stream-bw-in-atomic-state.patch futex-clear-stale-exiting-pointer-in-futex_lock_pi-retry-path.patch irqchip-qcom-mpm-add-missing-mailbox-tx-done-acknowledgment.patch jbd2-gracefully-abort-on-checkpointing-state-corruptions.patch kvm-x86-mmu-drop-zap-existing-present-spte-even-when-creating-an-mmio-spte.patch loongarch-fix-missing-null-checks-for-kstrdup.patch loongarch-kvm-make-kvm_get_vcpu_by_cpuid-more-robust.patch loongarch-workaround-ls2k-ls7a-gpu-dma-hang-bug.patch net-macb-move-devm_-free-request-_irq-out-of-spin-lock-area.patch net-macb-protect-access-to-net_device-ip_ptr-with-rcu-lock.patch net-macb-use-dev_consume_skb_any-to-free-tx-skbs.patch ovl-fix-wrong-detection-of-32bit-inode-numbers.patch phy-qcom-qmp-ufs-fix-sm8650-pcs-table-for-gear-4.patch scsi-ibmvfc-fix-oob-access-in-ibmvfc_discover_targets_done.patch scsi-ses-handle-positive-scsi-error-from-ses_recv_diag.patch x86-cpu-enable-fsgsbase-early-in-cpu_init_exception_handling.patch x86-cpu-remove-x86_cr4_fred-from-the-cr4-pinned-bits-mask.patch xfs-don-t-irele-after-failing-to-iget-in-xfs_attri_recover_work.patch xfs-fix-ri_total-validation-in-xlog_recover_attri_commit_pass2.patch xfs-remove-file_path-tracepoint-data.patch xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch xfs-scrub-unlock-dquot-before-early-return-in-quota-scrub.patch xfs-stop-reclaim-before-pushing-ail-during-unmount.patch --- diff --git a/queue-6.12/alarmtimer-fix-argument-order-in-alarm_timer_forward.patch b/queue-6.12/alarmtimer-fix-argument-order-in-alarm_timer_forward.patch new file mode 100644 index 0000000000..5281121bd2 --- /dev/null +++ b/queue-6.12/alarmtimer-fix-argument-order-in-alarm_timer_forward.patch @@ -0,0 +1,51 @@ +From 5d16467ae56343b9205caedf85e3a131e0914ad8 Mon Sep 17 00:00:00 2001 +From: Zhan Xusheng +Date: Mon, 23 Mar 2026 14:11:30 +0800 +Subject: alarmtimer: Fix argument order in alarm_timer_forward() + +From: Zhan Xusheng + +commit 5d16467ae56343b9205caedf85e3a131e0914ad8 upstream. + +alarm_timer_forward() passes arguments to alarm_forward() in the wrong +order: + + alarm_forward(alarm, timr->it_interval, now); + +However, alarm_forward() is defined as: + + u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval); + +and uses the second argument as the current time: + + delta = ktime_sub(now, alarm->node.expires); + +Passing the interval as "now" results in incorrect delta computation, +which can lead to missed expirations or incorrect overrun accounting. + +This issue has been present since the introduction of +alarm_timer_forward(). + +Fix this by swapping the arguments. + +Fixes: e7561f1633ac ("alarmtimer: Implement forward callback") +Signed-off-by: Zhan Xusheng +Signed-off-by: Thomas Gleixner +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20260323061130.29991-1-zhanxusheng@xiaomi.com +Signed-off-by: Greg Kroah-Hartman +--- + kernel/time/alarmtimer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/time/alarmtimer.c ++++ b/kernel/time/alarmtimer.c +@@ -614,7 +614,7 @@ static s64 alarm_timer_forward(struct k_ + { + struct alarm *alarm = &timr->it.alarm.alarmtimer; + +- return alarm_forward(alarm, timr->it_interval, now); ++ return alarm_forward(alarm, now, timr->it_interval); + } + + /** diff --git a/queue-6.12/dmaengine-fsl-edma-fix-channel-parameter-config-for-fixed-channel-requests.patch b/queue-6.12/dmaengine-fsl-edma-fix-channel-parameter-config-for-fixed-channel-requests.patch new file mode 100644 index 0000000000..5358d24190 --- /dev/null +++ b/queue-6.12/dmaengine-fsl-edma-fix-channel-parameter-config-for-fixed-channel-requests.patch @@ -0,0 +1,75 @@ +From 2e7b5cf72e51c9cf9c8b75190189c757df31ddd9 Mon Sep 17 00:00:00 2001 +From: Joy Zou +Date: Wed, 17 Sep 2025 17:53:42 +0800 +Subject: dmaengine: fsl-edma: fix channel parameter config for fixed channel requests + +From: Joy Zou + +commit 2e7b5cf72e51c9cf9c8b75190189c757df31ddd9 upstream. + +Configure only the requested channel when a fixed channel is specified +to avoid modifying other channels unintentionally. + +Fix parameter configuration when a fixed DMA channel is requested on +i.MX9 AON domain and i.MX8QM/QXP/DXL platforms. When a client requests +a fixed channel (e.g., channel 6), the driver traverses channels 0-5 +and may unintentionally modify their configuration if they are unused. + +This leads to issues such as setting the `is_multi_fifo` flag unexpectedly, +causing memcpy tests to fail when using the dmatest tool. + +Only affect edma memcpy test when the channel is fixed. + +Fixes: 72f5801a4e2b ("dmaengine: fsl-edma: integrate v3 support") +Signed-off-by: Joy Zou +Cc: stable@vger.kernel.org +Reviewed-by: Frank Li +Link: https://patch.msgid.link/20250917-b4-edma-chanconf-v1-1-886486e02e91@nxp.com +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman +--- + drivers/dma/fsl-edma-main.c | 26 +++++++++++--------------- + 1 file changed, 11 insertions(+), 15 deletions(-) + +--- a/drivers/dma/fsl-edma-main.c ++++ b/drivers/dma/fsl-edma-main.c +@@ -185,10 +185,8 @@ static struct dma_chan *fsl_edma3_xlate( + return NULL; + i = fsl_chan - fsl_edma->chans; + +- fsl_chan->priority = dma_spec->args[1]; +- fsl_chan->is_rxchan = dma_spec->args[2] & FSL_EDMA_RX; +- fsl_chan->is_remote = dma_spec->args[2] & FSL_EDMA_REMOTE; +- fsl_chan->is_multi_fifo = dma_spec->args[2] & FSL_EDMA_MULTI_FIFO; ++ if (!b_chmux && i != dma_spec->args[0]) ++ continue; + + if ((dma_spec->args[2] & FSL_EDMA_EVEN_CH) && (i & 0x1)) + continue; +@@ -196,17 +194,15 @@ static struct dma_chan *fsl_edma3_xlate( + if ((dma_spec->args[2] & FSL_EDMA_ODD_CH) && !(i & 0x1)) + continue; + +- if (!b_chmux && i == dma_spec->args[0]) { +- chan = dma_get_slave_channel(chan); +- chan->device->privatecnt++; +- return chan; +- } else if (b_chmux && !fsl_chan->srcid) { +- /* if controller support channel mux, choose a free channel */ +- chan = dma_get_slave_channel(chan); +- chan->device->privatecnt++; +- fsl_chan->srcid = dma_spec->args[0]; +- return chan; +- } ++ fsl_chan->srcid = dma_spec->args[0]; ++ fsl_chan->priority = dma_spec->args[1]; ++ fsl_chan->is_rxchan = dma_spec->args[2] & FSL_EDMA_RX; ++ fsl_chan->is_remote = dma_spec->args[2] & FSL_EDMA_REMOTE; ++ fsl_chan->is_multi_fifo = dma_spec->args[2] & FSL_EDMA_MULTI_FIFO; ++ ++ chan = dma_get_slave_channel(chan); ++ chan->device->privatecnt++; ++ return chan; + } + return NULL; + } diff --git a/queue-6.12/dmaengine-sh-rz-dmac-move-chctrl-updates-under-spinlock.patch b/queue-6.12/dmaengine-sh-rz-dmac-move-chctrl-updates-under-spinlock.patch new file mode 100644 index 0000000000..6223515719 --- /dev/null +++ b/queue-6.12/dmaengine-sh-rz-dmac-move-chctrl-updates-under-spinlock.patch @@ -0,0 +1,67 @@ +From 89a8567d84bde88cb7cdbbac2ab2299c4f991490 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea +Date: Mon, 16 Mar 2026 15:32:46 +0200 +Subject: dmaengine: sh: rz-dmac: Move CHCTRL updates under spinlock + +From: Claudiu Beznea + +commit 89a8567d84bde88cb7cdbbac2ab2299c4f991490 upstream. + +Both rz_dmac_disable_hw() and rz_dmac_irq_handle_channel() update the +CHCTRL register. To avoid concurrency issues when configuring +functionalities exposed by this registers, take the virtual channel lock. +All other CHCTRL updates were already protected by the same lock. + +Previously, rz_dmac_disable_hw() disabled and re-enabled local IRQs, before +accessing CHCTRL registers but this does not ensure race-free access. +Remove the local IRQ disable/enable code as well. + +Fixes: 5000d37042a6 ("dmaengine: sh: Add DMAC driver for RZ/G2L SoC") +Cc: stable@vger.kernel.org +Reviewed-by: Biju Das +Reviewed-by: Frank Li +Signed-off-by: Claudiu Beznea +Link: https://patch.msgid.link/20260316133252.240348-3-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman +--- + drivers/dma/sh/rz-dmac.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/drivers/dma/sh/rz-dmac.c ++++ b/drivers/dma/sh/rz-dmac.c +@@ -286,13 +286,10 @@ static void rz_dmac_disable_hw(struct rz + { + struct dma_chan *chan = &channel->vc.chan; + struct rz_dmac *dmac = to_rz_dmac(chan->device); +- unsigned long flags; + + dev_dbg(dmac->dev, "%s channel %d\n", __func__, channel->index); + +- local_irq_save(flags); + rz_dmac_ch_writel(channel, CHCTRL_DEFAULT, CHCTRL, 1); +- local_irq_restore(flags); + } + + static void rz_dmac_set_dmars_register(struct rz_dmac *dmac, int nr, u32 dmars) +@@ -545,8 +542,8 @@ static int rz_dmac_terminate_all(struct + unsigned int i; + LIST_HEAD(head); + +- rz_dmac_disable_hw(channel); + spin_lock_irqsave(&channel->vc.lock, flags); ++ rz_dmac_disable_hw(channel); + for (i = 0; i < DMAC_NR_LMDESC; i++) + lmdesc[i].header = 0; + +@@ -677,7 +674,9 @@ static void rz_dmac_irq_handle_channel(s + if (chstat & CHSTAT_ER) { + dev_err(dmac->dev, "DMAC err CHSTAT_%d = %08X\n", + channel->index, chstat); +- rz_dmac_ch_writel(channel, CHCTRL_DEFAULT, CHCTRL, 1); ++ ++ scoped_guard(spinlock_irqsave, &channel->vc.lock) ++ rz_dmac_ch_writel(channel, CHCTRL_DEFAULT, CHCTRL, 1); + goto done; + } + diff --git a/queue-6.12/dmaengine-sh-rz-dmac-protect-the-driver-specific-lists.patch b/queue-6.12/dmaengine-sh-rz-dmac-protect-the-driver-specific-lists.patch new file mode 100644 index 0000000000..2db3cf18b8 --- /dev/null +++ b/queue-6.12/dmaengine-sh-rz-dmac-protect-the-driver-specific-lists.patch @@ -0,0 +1,126 @@ +From abb863e6213dc41a58ef8bb3289b7e77460dabf3 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea +Date: Mon, 16 Mar 2026 15:32:45 +0200 +Subject: dmaengine: sh: rz-dmac: Protect the driver specific lists + +From: Claudiu Beznea + +commit abb863e6213dc41a58ef8bb3289b7e77460dabf3 upstream. + +The driver lists (ld_free, ld_queue) are used in +rz_dmac_free_chan_resources(), rz_dmac_terminate_all(), +rz_dmac_issue_pending(), and rz_dmac_irq_handler_thread(), all under +the virtual channel lock. Take the same lock in rz_dmac_prep_slave_sg() +and rz_dmac_prep_dma_memcpy() as well to avoid concurrency issues, since +these functions also check whether the lists are empty and update or +remove list entries. + +Fixes: 5000d37042a6 ("dmaengine: sh: Add DMAC driver for RZ/G2L SoC") +Cc: stable@vger.kernel.org +Reviewed-by: Frank Li +Signed-off-by: Claudiu Beznea +Link: https://patch.msgid.link/20260316133252.240348-2-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman +--- + drivers/dma/sh/rz-dmac.c | 63 ++++++++++++++++++++++++++--------------------- + 1 file changed, 35 insertions(+), 28 deletions(-) + +--- a/drivers/dma/sh/rz-dmac.c ++++ b/drivers/dma/sh/rz-dmac.c +@@ -10,6 +10,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -424,6 +425,7 @@ static int rz_dmac_alloc_chan_resources( + if (!desc) + break; + ++ /* No need to lock. This is called only for the 1st client. */ + list_add_tail(&desc->node, &channel->ld_free); + channel->descs_allocated++; + } +@@ -479,18 +481,21 @@ rz_dmac_prep_dma_memcpy(struct dma_chan + dev_dbg(dmac->dev, "%s channel: %d src=0x%pad dst=0x%pad len=%zu\n", + __func__, channel->index, &src, &dest, len); + +- if (list_empty(&channel->ld_free)) +- return NULL; ++ scoped_guard(spinlock_irqsave, &channel->vc.lock) { ++ if (list_empty(&channel->ld_free)) ++ return NULL; ++ ++ desc = list_first_entry(&channel->ld_free, struct rz_dmac_desc, node); ++ ++ desc->type = RZ_DMAC_DESC_MEMCPY; ++ desc->src = src; ++ desc->dest = dest; ++ desc->len = len; ++ desc->direction = DMA_MEM_TO_MEM; + +- desc = list_first_entry(&channel->ld_free, struct rz_dmac_desc, node); +- +- desc->type = RZ_DMAC_DESC_MEMCPY; +- desc->src = src; +- desc->dest = dest; +- desc->len = len; +- desc->direction = DMA_MEM_TO_MEM; ++ list_move_tail(channel->ld_free.next, &channel->ld_queue); ++ } + +- list_move_tail(channel->ld_free.next, &channel->ld_queue); + return vchan_tx_prep(&channel->vc, &desc->vd, flags); + } + +@@ -506,27 +511,29 @@ rz_dmac_prep_slave_sg(struct dma_chan *c + int dma_length = 0; + int i = 0; + +- if (list_empty(&channel->ld_free)) +- return NULL; +- +- desc = list_first_entry(&channel->ld_free, struct rz_dmac_desc, node); ++ scoped_guard(spinlock_irqsave, &channel->vc.lock) { ++ if (list_empty(&channel->ld_free)) ++ return NULL; ++ ++ desc = list_first_entry(&channel->ld_free, struct rz_dmac_desc, node); ++ ++ for_each_sg(sgl, sg, sg_len, i) ++ dma_length += sg_dma_len(sg); ++ ++ desc->type = RZ_DMAC_DESC_SLAVE_SG; ++ desc->sg = sgl; ++ desc->sgcount = sg_len; ++ desc->len = dma_length; ++ desc->direction = direction; ++ ++ if (direction == DMA_DEV_TO_MEM) ++ desc->src = channel->src_per_address; ++ else ++ desc->dest = channel->dst_per_address; + +- for_each_sg(sgl, sg, sg_len, i) { +- dma_length += sg_dma_len(sg); ++ list_move_tail(channel->ld_free.next, &channel->ld_queue); + } + +- desc->type = RZ_DMAC_DESC_SLAVE_SG; +- desc->sg = sgl; +- desc->sgcount = sg_len; +- desc->len = dma_length; +- desc->direction = direction; +- +- if (direction == DMA_DEV_TO_MEM) +- desc->src = channel->src_per_address; +- else +- desc->dest = channel->dst_per_address; +- +- list_move_tail(channel->ld_free.next, &channel->ld_queue); + return vchan_tx_prep(&channel->vc, &desc->vd, flags); + } + diff --git a/queue-6.12/drm-amdgpu-prevent-immediate-pasid-reuse-case.patch b/queue-6.12/drm-amdgpu-prevent-immediate-pasid-reuse-case.patch new file mode 100644 index 0000000000..961201b84b --- /dev/null +++ b/queue-6.12/drm-amdgpu-prevent-immediate-pasid-reuse-case.patch @@ -0,0 +1,132 @@ +From 14b81abe7bdc25f8097906fc2f91276ffedb2d26 Mon Sep 17 00:00:00 2001 +From: Eric Huang +Date: Mon, 16 Mar 2026 11:01:30 -0400 +Subject: drm/amdgpu: prevent immediate PASID reuse case +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Eric Huang + +commit 14b81abe7bdc25f8097906fc2f91276ffedb2d26 upstream. + +PASID resue could cause interrupt issue when process +immediately runs into hw state left by previous +process exited with the same PASID, it's possible that +page faults are still pending in the IH ring buffer when +the process exits and frees up its PASID. To prevent the +case, it uses idr cyclic allocator same as kernel pid's. + +Signed-off-by: Eric Huang +Reviewed-by: Christian König +Signed-off-by: Alex Deucher +(cherry picked from commit 8f1de51f49be692de137c8525106e0fce2d1912d) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c | 45 ++++++++++++++++++++++---------- + drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 1 + 3 files changed, 34 insertions(+), 13 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c +@@ -35,10 +35,13 @@ + * PASIDs are global address space identifiers that can be shared + * between the GPU, an IOMMU and the driver. VMs on different devices + * may use the same PASID if they share the same address +- * space. Therefore PASIDs are allocated using a global IDA. VMs are +- * looked up from the PASID per amdgpu_device. ++ * space. Therefore PASIDs are allocated using IDR cyclic allocator ++ * (similar to kernel PID allocation) which naturally delays reuse. ++ * VMs are looked up from the PASID per amdgpu_device. + */ +-static DEFINE_IDA(amdgpu_pasid_ida); ++ ++static DEFINE_IDR(amdgpu_pasid_idr); ++static DEFINE_SPINLOCK(amdgpu_pasid_idr_lock); + + /* Helper to free pasid from a fence callback */ + struct amdgpu_pasid_cb { +@@ -50,8 +53,8 @@ struct amdgpu_pasid_cb { + * amdgpu_pasid_alloc - Allocate a PASID + * @bits: Maximum width of the PASID in bits, must be at least 1 + * +- * Allocates a PASID of the given width while keeping smaller PASIDs +- * available if possible. ++ * Uses kernel's IDR cyclic allocator (same as PID allocation). ++ * Allocates sequentially with automatic wrap-around. + * + * Returns a positive integer on success. Returns %-EINVAL if bits==0. + * Returns %-ENOSPC if no PASID was available. Returns %-ENOMEM on +@@ -59,14 +62,15 @@ struct amdgpu_pasid_cb { + */ + int amdgpu_pasid_alloc(unsigned int bits) + { +- int pasid = -EINVAL; ++ int pasid; + +- for (bits = min(bits, 31U); bits > 0; bits--) { +- pasid = ida_alloc_range(&amdgpu_pasid_ida, 1U << (bits - 1), +- (1U << bits) - 1, GFP_KERNEL); +- if (pasid != -ENOSPC) +- break; +- } ++ if (bits == 0) ++ return -EINVAL; ++ ++ spin_lock(&amdgpu_pasid_idr_lock); ++ pasid = idr_alloc_cyclic(&amdgpu_pasid_idr, NULL, 1, ++ 1U << bits, GFP_KERNEL); ++ spin_unlock(&amdgpu_pasid_idr_lock); + + if (pasid >= 0) + trace_amdgpu_pasid_allocated(pasid); +@@ -81,7 +85,10 @@ int amdgpu_pasid_alloc(unsigned int bits + void amdgpu_pasid_free(u32 pasid) + { + trace_amdgpu_pasid_freed(pasid); +- ida_free(&amdgpu_pasid_ida, pasid); ++ ++ spin_lock(&amdgpu_pasid_idr_lock); ++ idr_remove(&amdgpu_pasid_idr, pasid); ++ spin_unlock(&amdgpu_pasid_idr_lock); + } + + static void amdgpu_pasid_free_cb(struct dma_fence *fence, +@@ -635,3 +642,15 @@ void amdgpu_vmid_mgr_fini(struct amdgpu_ + } + } + } ++ ++/** ++ * amdgpu_pasid_mgr_cleanup - cleanup PASID manager ++ * ++ * Cleanup the IDR allocator. ++ */ ++void amdgpu_pasid_mgr_cleanup(void) ++{ ++ spin_lock(&amdgpu_pasid_idr_lock); ++ idr_destroy(&amdgpu_pasid_idr); ++ spin_unlock(&amdgpu_pasid_idr_lock); ++} +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h +@@ -75,6 +75,7 @@ int amdgpu_pasid_alloc(unsigned int bits + void amdgpu_pasid_free(u32 pasid); + void amdgpu_pasid_free_delayed(struct dma_resv *resv, + u32 pasid); ++void amdgpu_pasid_mgr_cleanup(void); + + bool amdgpu_vmid_had_gpu_reset(struct amdgpu_device *adev, + struct amdgpu_vmid *id); +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +@@ -2721,6 +2721,7 @@ void amdgpu_vm_manager_fini(struct amdgp + xa_destroy(&adev->vm_manager.pasids); + + amdgpu_vmid_mgr_fini(adev); ++ amdgpu_pasid_mgr_cleanup(); + } + + /** diff --git a/queue-6.12/drm-i915-dp_tunnel-fix-error-handling-when-clearing-stream-bw-in-atomic-state.patch b/queue-6.12/drm-i915-dp_tunnel-fix-error-handling-when-clearing-stream-bw-in-atomic-state.patch new file mode 100644 index 0000000000..810d74ee57 --- /dev/null +++ b/queue-6.12/drm-i915-dp_tunnel-fix-error-handling-when-clearing-stream-bw-in-atomic-state.patch @@ -0,0 +1,131 @@ +From 77fcf58df15edcf3f5b5421f24814fb72796def9 Mon Sep 17 00:00:00 2001 +From: Imre Deak +Date: Fri, 20 Mar 2026 11:29:00 +0200 +Subject: drm/i915/dp_tunnel: Fix error handling when clearing stream BW in atomic state +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Imre Deak + +commit 77fcf58df15edcf3f5b5421f24814fb72796def9 upstream. + +Clearing the DP tunnel stream BW in the atomic state involves getting +the tunnel group state, which can fail. Handle the error accordingly. + +This fixes at least one issue where drm_dp_tunnel_atomic_set_stream_bw() +failed to get the tunnel group state returning -EDEADLK, which wasn't +handled. This lead to the ctx->contended warn later in modeset_lock() +while taking a WW mutex for another object in the same atomic state, and +thus within the same already contended WW context. + +Moving intel_crtc_state_alloc() later would avoid freeing saved_state on +the error path; this stable patch leaves that simplification for a +follow-up. + +Cc: Uma Shankar +Cc: Ville Syrjälä +Cc: # v6.9+ +Fixes: a4efae87ecb2 ("drm/i915/dp: Compute DP tunnel BW during encoder state computation") +Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/7617 +Reviewed-by: Michał Grzelak +Reviewed-by: Uma Shankar +Signed-off-by: Imre Deak +Link: https://patch.msgid.link/20260320092900.13210-1-imre.deak@intel.com +(cherry picked from commit fb69d0076e687421188bc8103ab0e8e5825b1df1) +Signed-off-by: Joonas Lahtinen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/i915/display/intel_display.c | 8 +++++++- + drivers/gpu/drm/i915/display/intel_dp_tunnel.c | 20 ++++++++++++++------ + drivers/gpu/drm/i915/display/intel_dp_tunnel.h | 11 +++++++---- + 3 files changed, 28 insertions(+), 11 deletions(-) + +--- a/drivers/gpu/drm/i915/display/intel_display.c ++++ b/drivers/gpu/drm/i915/display/intel_display.c +@@ -4588,6 +4588,7 @@ intel_crtc_prepare_cleared_state(struct + intel_atomic_get_new_crtc_state(state, crtc); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_crtc_state *saved_state; ++ int err; + + saved_state = intel_crtc_state_alloc(crtc); + if (!saved_state) +@@ -4596,7 +4597,12 @@ intel_crtc_prepare_cleared_state(struct + /* free the old crtc_state->hw members */ + intel_crtc_free_hw_state(crtc_state); + +- intel_dp_tunnel_atomic_clear_stream_bw(state, crtc_state); ++ err = intel_dp_tunnel_atomic_clear_stream_bw(state, crtc_state); ++ if (err) { ++ kfree(saved_state); ++ ++ return err; ++ } + + /* FIXME: before the switch to atomic started, a new pipe_config was + * kzalloc'd. Code that depends on any field being zero should be +--- a/drivers/gpu/drm/i915/display/intel_dp_tunnel.c ++++ b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c +@@ -622,19 +622,27 @@ int intel_dp_tunnel_atomic_compute_strea + * + * Clear any DP tunnel stream BW requirement set by + * intel_dp_tunnel_atomic_compute_stream_bw(). ++ * ++ * Returns 0 in case of success, a negative error code otherwise. + */ +-void intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state, +- struct intel_crtc_state *crtc_state) ++int intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state, ++ struct intel_crtc_state *crtc_state) + { + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); ++ int err; + + if (!crtc_state->dp_tunnel_ref.tunnel) +- return; ++ return 0; ++ ++ err = drm_dp_tunnel_atomic_set_stream_bw(&state->base, ++ crtc_state->dp_tunnel_ref.tunnel, ++ crtc->pipe, 0); ++ if (err) ++ return err; + +- drm_dp_tunnel_atomic_set_stream_bw(&state->base, +- crtc_state->dp_tunnel_ref.tunnel, +- crtc->pipe, 0); + drm_dp_tunnel_ref_put(&crtc_state->dp_tunnel_ref); ++ ++ return 0; + } + + /** +--- a/drivers/gpu/drm/i915/display/intel_dp_tunnel.h ++++ b/drivers/gpu/drm/i915/display/intel_dp_tunnel.h +@@ -39,8 +39,8 @@ int intel_dp_tunnel_atomic_compute_strea + struct intel_dp *intel_dp, + const struct intel_connector *connector, + struct intel_crtc_state *crtc_state); +-void intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state, +- struct intel_crtc_state *crtc_state); ++int intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state, ++ struct intel_crtc_state *crtc_state); + + int intel_dp_tunnel_atomic_add_state_for_crtc(struct intel_atomic_state *state, + struct intel_crtc *crtc); +@@ -87,9 +87,12 @@ intel_dp_tunnel_atomic_compute_stream_bw + return 0; + } + +-static inline void ++static inline int + intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state, +- struct intel_crtc_state *crtc_state) {} ++ struct intel_crtc_state *crtc_state) ++{ ++ return 0; ++} + + static inline int + intel_dp_tunnel_atomic_add_state_for_crtc(struct intel_atomic_state *state, diff --git a/queue-6.12/futex-clear-stale-exiting-pointer-in-futex_lock_pi-retry-path.patch b/queue-6.12/futex-clear-stale-exiting-pointer-in-futex_lock_pi-retry-path.patch new file mode 100644 index 0000000000..096b9582fb --- /dev/null +++ b/queue-6.12/futex-clear-stale-exiting-pointer-in-futex_lock_pi-retry-path.patch @@ -0,0 +1,76 @@ +From 210d36d892de5195e6766c45519dfb1e65f3eb83 Mon Sep 17 00:00:00 2001 +From: Davidlohr Bueso +Date: Wed, 25 Mar 2026 17:17:59 -0700 +Subject: futex: Clear stale exiting pointer in futex_lock_pi() retry path + +From: Davidlohr Bueso + +commit 210d36d892de5195e6766c45519dfb1e65f3eb83 upstream. + +Fuzzying/stressing futexes triggered: + + WARNING: kernel/futex/core.c:825 at wait_for_owner_exiting+0x7a/0x80, CPU#11: futex_lock_pi_s/524 + +When futex_lock_pi_atomic() sees the owner is exiting, it returns -EBUSY +and stores a refcounted task pointer in 'exiting'. + +After wait_for_owner_exiting() consumes that reference, the local pointer +is never reset to nil. Upon a retry, if futex_lock_pi_atomic() returns a +different error, the bogus pointer is passed to wait_for_owner_exiting(). + + CPU0 CPU1 CPU2 + futex_lock_pi(uaddr) + // acquires the PI futex + exit() + futex_cleanup_begin() + futex_state = EXITING; + futex_lock_pi(uaddr) + futex_lock_pi_atomic() + attach_to_pi_owner() + // observes EXITING + *exiting = owner; // takes ref + return -EBUSY + wait_for_owner_exiting(-EBUSY, owner) + put_task_struct(); // drops ref + // exiting still points to owner + goto retry; + futex_lock_pi_atomic() + lock_pi_update_atomic() + cmpxchg(uaddr) + *uaddr ^= WAITERS // whatever + // value changed + return -EAGAIN; + wait_for_owner_exiting(-EAGAIN, exiting) // stale + WARN_ON_ONCE(exiting) + +Fix this by resetting upon retry, essentially aligning it with requeue_pi. + +Fixes: 3ef240eaff36 ("futex: Prevent exit livelock") +Signed-off-by: Davidlohr Bueso +Signed-off-by: Thomas Gleixner +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20260326001759.4129680-1-dave@stgolabs.net +Signed-off-by: Greg Kroah-Hartman +--- + kernel/futex/pi.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/kernel/futex/pi.c ++++ b/kernel/futex/pi.c +@@ -918,7 +918,7 @@ int fixup_pi_owner(u32 __user *uaddr, st + int futex_lock_pi(u32 __user *uaddr, unsigned int flags, ktime_t *time, int trylock) + { + struct hrtimer_sleeper timeout, *to; +- struct task_struct *exiting = NULL; ++ struct task_struct *exiting; + struct rt_mutex_waiter rt_waiter; + struct futex_hash_bucket *hb; + struct futex_q q = futex_q_init; +@@ -933,6 +933,7 @@ int futex_lock_pi(u32 __user *uaddr, uns + to = futex_setup_timer(time, &timeout, flags, 0); + + retry: ++ exiting = NULL; + ret = get_futex_key(uaddr, flags, &q.key, FUTEX_WRITE); + if (unlikely(ret != 0)) + goto out; diff --git a/queue-6.12/irqchip-qcom-mpm-add-missing-mailbox-tx-done-acknowledgment.patch b/queue-6.12/irqchip-qcom-mpm-add-missing-mailbox-tx-done-acknowledgment.patch new file mode 100644 index 0000000000..cfa589c164 --- /dev/null +++ b/queue-6.12/irqchip-qcom-mpm-add-missing-mailbox-tx-done-acknowledgment.patch @@ -0,0 +1,46 @@ +From cfe02147e86307a17057ee4e3604f5f5919571d2 Mon Sep 17 00:00:00 2001 +From: Jassi Brar +Date: Sun, 22 Mar 2026 12:15:33 -0500 +Subject: irqchip/qcom-mpm: Add missing mailbox TX done acknowledgment + +From: Jassi Brar + +commit cfe02147e86307a17057ee4e3604f5f5919571d2 upstream. + +The mbox_client for qcom-mpm sends NULL doorbell messages via +mbox_send_message() but never signals TX completion. + +Set knows_txdone=true and call mbox_client_txdone() after a successful +send, matching the pattern used by other Qualcomm mailbox clients (smp2p, +smsm, qcom_aoss etc). + +Fixes: a6199bb514d8a6 "irqchip: Add Qualcomm MPM controller driver" +Signed-off-by: Jassi Brar +Signed-off-by: Thomas Gleixner +Reviewed-by: Douglas Anderson +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20260322171533.608436-1-jassisinghbrar@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/irqchip/irq-qcom-mpm.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/irqchip/irq-qcom-mpm.c ++++ b/drivers/irqchip/irq-qcom-mpm.c +@@ -306,6 +306,8 @@ static int mpm_pd_power_off(struct gener + if (ret < 0) + return ret; + ++ mbox_client_txdone(priv->mbox_chan, 0); ++ + return 0; + } + +@@ -434,6 +436,7 @@ static int qcom_mpm_init(struct device_n + } + + priv->mbox_client.dev = dev; ++ priv->mbox_client.knows_txdone = true; + priv->mbox_chan = mbox_request_channel(&priv->mbox_client, 0); + if (IS_ERR(priv->mbox_chan)) { + ret = PTR_ERR(priv->mbox_chan); diff --git a/queue-6.12/jbd2-gracefully-abort-on-checkpointing-state-corruptions.patch b/queue-6.12/jbd2-gracefully-abort-on-checkpointing-state-corruptions.patch new file mode 100644 index 0000000000..536ba1442a --- /dev/null +++ b/queue-6.12/jbd2-gracefully-abort-on-checkpointing-state-corruptions.patch @@ -0,0 +1,66 @@ +From bac3190a8e79beff6ed221975e0c9b1b5f2a21da Mon Sep 17 00:00:00 2001 +From: Milos Nikic +Date: Tue, 10 Mar 2026 21:15:48 -0700 +Subject: jbd2: gracefully abort on checkpointing state corruptions + +From: Milos Nikic + +commit bac3190a8e79beff6ed221975e0c9b1b5f2a21da upstream. + +This patch targets two internal state machine invariants in checkpoint.c +residing inside functions that natively return integer error codes. + +- In jbd2_cleanup_journal_tail(): A blocknr of 0 indicates a severely +corrupted journal superblock. Replaced the J_ASSERT with a WARN_ON_ONCE +and a graceful journal abort, returning -EFSCORRUPTED. + +- In jbd2_log_do_checkpoint(): Replaced the J_ASSERT_BH checking for +an unexpected buffer_jwrite state. If the warning triggers, we +explicitly drop the just-taken get_bh() reference and call __flush_batch() +to safely clean up any previously queued buffers in the j_chkpt_bhs array, +preventing a memory leak before returning -EFSCORRUPTED. + +Signed-off-by: Milos Nikic +Reviewed-by: Andreas Dilger +Reviewed-by: Zhang Yi +Reviewed-by: Baokun Li +Reviewed-by: Jan Kara +Link: https://patch.msgid.link/20260311041548.159424-1-nikic.milos@gmail.com +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + fs/jbd2/checkpoint.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +--- a/fs/jbd2/checkpoint.c ++++ b/fs/jbd2/checkpoint.c +@@ -267,7 +267,15 @@ restart: + */ + BUFFER_TRACE(bh, "queue"); + get_bh(bh); +- J_ASSERT_BH(bh, !buffer_jwrite(bh)); ++ if (WARN_ON_ONCE(buffer_jwrite(bh))) { ++ put_bh(bh); /* drop the ref we just took */ ++ spin_unlock(&journal->j_list_lock); ++ /* Clean up any previously batched buffers */ ++ if (batch_count) ++ __flush_batch(journal, &batch_count); ++ jbd2_journal_abort(journal, -EFSCORRUPTED); ++ return -EFSCORRUPTED; ++ } + journal->j_chkpt_bhs[batch_count++] = bh; + transaction->t_chp_stats.cs_written++; + transaction->t_checkpoint_list = jh->b_cpnext; +@@ -325,7 +333,10 @@ int jbd2_cleanup_journal_tail(journal_t + + if (!jbd2_journal_get_log_tail(journal, &first_tid, &blocknr)) + return 1; +- J_ASSERT(blocknr != 0); ++ if (WARN_ON_ONCE(blocknr == 0)) { ++ jbd2_journal_abort(journal, -EFSCORRUPTED); ++ return -EFSCORRUPTED; ++ } + + /* + * We need to make sure that any blocks that were recently written out diff --git a/queue-6.12/kvm-x86-mmu-drop-zap-existing-present-spte-even-when-creating-an-mmio-spte.patch b/queue-6.12/kvm-x86-mmu-drop-zap-existing-present-spte-even-when-creating-an-mmio-spte.patch new file mode 100644 index 0000000000..060c84b0b7 --- /dev/null +++ b/queue-6.12/kvm-x86-mmu-drop-zap-existing-present-spte-even-when-creating-an-mmio-spte.patch @@ -0,0 +1,83 @@ +From aad885e774966e97b675dfe928da164214a71605 Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Thu, 5 Mar 2026 17:28:04 -0800 +Subject: KVM: x86/mmu: Drop/zap existing present SPTE even when creating an MMIO SPTE + +From: Sean Christopherson + +commit aad885e774966e97b675dfe928da164214a71605 upstream. + +When installing an emulated MMIO SPTE, do so *after* dropping/zapping the +existing SPTE (if it's shadow-present). While commit a54aa15c6bda3 was +right about it being impossible to convert a shadow-present SPTE to an +MMIO SPTE due to a _guest_ write, it failed to account for writes to guest +memory that are outside the scope of KVM. + +E.g. if host userspace modifies a shadowed gPTE to switch from a memslot +to emulted MMIO and then the guest hits a relevant page fault, KVM will +install the MMIO SPTE without first zapping the shadow-present SPTE. + + ------------[ cut here ]------------ + is_shadow_present_pte(*sptep) + WARNING: arch/x86/kvm/mmu/mmu.c:484 at mark_mmio_spte+0xb2/0xc0 [kvm], CPU#0: vmx_ept_stale_r/4292 + Modules linked in: kvm_intel kvm irqbypass + CPU: 0 UID: 1000 PID: 4292 Comm: vmx_ept_stale_r Not tainted 7.0.0-rc2-eafebd2d2ab0-sink-vm #319 PREEMPT + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 + RIP: 0010:mark_mmio_spte+0xb2/0xc0 [kvm] + Call Trace: + + mmu_set_spte+0x237/0x440 [kvm] + ept_page_fault+0x535/0x7f0 [kvm] + kvm_mmu_do_page_fault+0xee/0x1f0 [kvm] + kvm_mmu_page_fault+0x8d/0x620 [kvm] + vmx_handle_exit+0x18c/0x5a0 [kvm_intel] + kvm_arch_vcpu_ioctl_run+0xc55/0x1c20 [kvm] + kvm_vcpu_ioctl+0x2d5/0x980 [kvm] + __x64_sys_ioctl+0x8a/0xd0 + do_syscall_64+0xb5/0x730 + entry_SYSCALL_64_after_hwframe+0x4b/0x53 + RIP: 0033:0x47fa3f + + ---[ end trace 0000000000000000 ]--- + +Reported-by: Alexander Bulekov +Debugged-by: Alexander Bulekov +Suggested-by: Fred Griffoul +Fixes: a54aa15c6bda3 ("KVM: x86/mmu: Handle MMIO SPTEs directly in mmu_set_spte()") +Cc: stable@vger.kernel.org +Signed-off-by: Sean Christopherson +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/mmu/mmu.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +--- a/arch/x86/kvm/mmu/mmu.c ++++ b/arch/x86/kvm/mmu/mmu.c +@@ -2919,12 +2919,6 @@ static int mmu_set_spte(struct kvm_vcpu + bool prefetch = !fault || fault->prefetch; + bool write_fault = fault && fault->write; + +- if (unlikely(is_noslot_pfn(pfn))) { +- vcpu->stat.pf_mmio_spte_created++; +- mark_mmio_spte(vcpu, sptep, gfn, pte_access); +- return RET_PF_EMULATE; +- } +- + if (is_shadow_present_pte(*sptep)) { + /* + * If we overwrite a PTE page pointer with a 2MB PMD, unlink +@@ -2944,6 +2938,14 @@ static int mmu_set_spte(struct kvm_vcpu + was_rmapped = 1; + } + ++ if (unlikely(is_noslot_pfn(pfn))) { ++ vcpu->stat.pf_mmio_spte_created++; ++ mark_mmio_spte(vcpu, sptep, gfn, pte_access); ++ if (flush) ++ kvm_flush_remote_tlbs_gfn(vcpu->kvm, gfn, level); ++ return RET_PF_EMULATE; ++ } ++ + wrprot = make_spte(vcpu, sp, slot, pte_access, gfn, pfn, *sptep, prefetch, + true, host_writable, &spte); + diff --git a/queue-6.12/loongarch-fix-missing-null-checks-for-kstrdup.patch b/queue-6.12/loongarch-fix-missing-null-checks-for-kstrdup.patch new file mode 100644 index 0000000000..6f7601e236 --- /dev/null +++ b/queue-6.12/loongarch-fix-missing-null-checks-for-kstrdup.patch @@ -0,0 +1,45 @@ +From 3a28daa9b7d7c2ddf2c722e9e95d7e0928bf0cd1 Mon Sep 17 00:00:00 2001 +From: Li Jun +Date: Thu, 26 Mar 2026 14:29:08 +0800 +Subject: LoongArch: Fix missing NULL checks for kstrdup() + +From: Li Jun + +commit 3a28daa9b7d7c2ddf2c722e9e95d7e0928bf0cd1 upstream. + +1. Replace "of_find_node_by_path("/")" with "of_root" to avoid multiple +calls to "of_node_put()". + +2. Fix a potential kernel oops during early boot when memory allocation +fails while parsing CPU model from device tree. + +Cc: stable@vger.kernel.org +Signed-off-by: Li Jun +Signed-off-by: Huacai Chen +Signed-off-by: Greg Kroah-Hartman +--- + arch/loongarch/kernel/env.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/arch/loongarch/kernel/env.c ++++ b/arch/loongarch/kernel/env.c +@@ -42,16 +42,15 @@ static int __init init_cpu_fullname(void + int cpu, ret; + char *cpuname; + const char *model; +- struct device_node *root; + + /* Parsing cpuname from DTS model property */ +- root = of_find_node_by_path("/"); +- ret = of_property_read_string(root, "model", &model); ++ ret = of_property_read_string(of_root, "model", &model); + if (ret == 0) { + cpuname = kstrdup(model, GFP_KERNEL); ++ if (!cpuname) ++ return -ENOMEM; + loongson_sysconf.cpuname = strsep(&cpuname, " "); + } +- of_node_put(root); + + if (loongson_sysconf.cpuname && !strncmp(loongson_sysconf.cpuname, "Loongson", 8)) { + for (cpu = 0; cpu < NR_CPUS; cpu++) diff --git a/queue-6.12/loongarch-kvm-make-kvm_get_vcpu_by_cpuid-more-robust.patch b/queue-6.12/loongarch-kvm-make-kvm_get_vcpu_by_cpuid-more-robust.patch new file mode 100644 index 0000000000..498054c60e --- /dev/null +++ b/queue-6.12/loongarch-kvm-make-kvm_get_vcpu_by_cpuid-more-robust.patch @@ -0,0 +1,37 @@ +From 2db06c15d8c7a0ccb6108524e16cd9163753f354 Mon Sep 17 00:00:00 2001 +From: Huacai Chen +Date: Thu, 26 Mar 2026 14:29:09 +0800 +Subject: LoongArch: KVM: Make kvm_get_vcpu_by_cpuid() more robust + +From: Huacai Chen + +commit 2db06c15d8c7a0ccb6108524e16cd9163753f354 upstream. + +kvm_get_vcpu_by_cpuid() takes a cpuid parameter whose type is int, so +cpuid can be negative. Let kvm_get_vcpu_by_cpuid() return NULL for this +case so as to make it more robust. + +This fix an out-of-bounds access to kvm_arch::phyid_map::phys_map[]. + +Cc: +Fixes: 73516e9da512adc ("LoongArch: KVM: Add vcpu mapping from physical cpuid") +Reported-by: Aurelien Jarno +Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1131431 +Signed-off-by: Huacai Chen +Signed-off-by: Greg Kroah-Hartman +--- + arch/loongarch/kvm/vcpu.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/arch/loongarch/kvm/vcpu.c ++++ b/arch/loongarch/kvm/vcpu.c +@@ -531,6 +531,9 @@ struct kvm_vcpu *kvm_get_vcpu_by_cpuid(s + { + struct kvm_phyid_map *map; + ++ if (cpuid < 0) ++ return NULL; ++ + if (cpuid >= KVM_MAX_PHYID) + return NULL; + diff --git a/queue-6.12/loongarch-workaround-ls2k-ls7a-gpu-dma-hang-bug.patch b/queue-6.12/loongarch-workaround-ls2k-ls7a-gpu-dma-hang-bug.patch new file mode 100644 index 0000000000..035ede5fc7 --- /dev/null +++ b/queue-6.12/loongarch-workaround-ls2k-ls7a-gpu-dma-hang-bug.patch @@ -0,0 +1,131 @@ +From 95db0c9f526d583634cddb2e5914718570fbac87 Mon Sep 17 00:00:00 2001 +From: Huacai Chen +Date: Thu, 26 Mar 2026 14:29:09 +0800 +Subject: LoongArch: Workaround LS2K/LS7A GPU DMA hang bug + +From: Huacai Chen + +commit 95db0c9f526d583634cddb2e5914718570fbac87 upstream. + +1. Hardware limitation: GPU, DC and VPU are typically PCI device 06.0, +06.1 and 06.2. They share some hardware resources, so when configure the +PCI 06.0 device BAR1, DMA memory access cannot be performed through this +BAR, otherwise it will cause hardware abnormalities. + +2. In typical scenarios of reboot or S3/S4, DC access to memory through +BAR is not prohibited, resulting in GPU DMA hangs. + +3. Workaround method: When configuring the 06.0 device BAR1, turn off +the memory access of DC, GPU and VPU (via DC's CRTC registers). + +Cc: stable@vger.kernel.org +Signed-off-by: Qianhai Wu +Signed-off-by: Huacai Chen +Signed-off-by: Greg Kroah-Hartman +--- + arch/loongarch/pci/pci.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 80 insertions(+) + +--- a/arch/loongarch/pci/pci.c ++++ b/arch/loongarch/pci/pci.c +@@ -6,9 +6,11 @@ + #include + #include + #include ++#include + #include + #include + #include ++#include + #include + #include + +@@ -16,6 +18,9 @@ + #define PCI_DEVICE_ID_LOONGSON_DC1 0x7a06 + #define PCI_DEVICE_ID_LOONGSON_DC2 0x7a36 + #define PCI_DEVICE_ID_LOONGSON_DC3 0x7a46 ++#define PCI_DEVICE_ID_LOONGSON_GPU1 0x7a15 ++#define PCI_DEVICE_ID_LOONGSON_GPU2 0x7a25 ++#define PCI_DEVICE_ID_LOONGSON_GPU3 0x7a35 + + int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn, + int reg, int len, u32 *val) +@@ -100,3 +105,78 @@ static void pci_fixup_vgadev(struct pci_ + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, PCI_DEVICE_ID_LOONGSON_DC1, pci_fixup_vgadev); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, PCI_DEVICE_ID_LOONGSON_DC2, pci_fixup_vgadev); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, PCI_DEVICE_ID_LOONGSON_DC3, pci_fixup_vgadev); ++ ++#define CRTC_NUM_MAX 2 ++#define CRTC_OUTPUT_ENABLE 0x100 ++ ++static void loongson_gpu_fixup_dma_hang(struct pci_dev *pdev, bool on) ++{ ++ u32 i, val, count, crtc_offset, device; ++ void __iomem *crtc_reg, *base, *regbase; ++ static u32 crtc_status[CRTC_NUM_MAX] = { 0 }; ++ ++ base = pdev->bus->ops->map_bus(pdev->bus, pdev->devfn + 1, 0); ++ device = readw(base + PCI_DEVICE_ID); ++ ++ regbase = ioremap(readq(base + PCI_BASE_ADDRESS_0) & ~0xffull, SZ_64K); ++ if (!regbase) { ++ pci_err(pdev, "Failed to ioremap()\n"); ++ return; ++ } ++ ++ switch (device) { ++ case PCI_DEVICE_ID_LOONGSON_DC2: ++ crtc_reg = regbase + 0x1240; ++ crtc_offset = 0x10; ++ break; ++ case PCI_DEVICE_ID_LOONGSON_DC3: ++ crtc_reg = regbase; ++ crtc_offset = 0x400; ++ break; ++ } ++ ++ for (i = 0; i < CRTC_NUM_MAX; i++, crtc_reg += crtc_offset) { ++ val = readl(crtc_reg); ++ ++ if (!on) ++ crtc_status[i] = val; ++ ++ /* No need to fixup if the status is off at startup. */ ++ if (!(crtc_status[i] & CRTC_OUTPUT_ENABLE)) ++ continue; ++ ++ if (on) ++ val |= CRTC_OUTPUT_ENABLE; ++ else ++ val &= ~CRTC_OUTPUT_ENABLE; ++ ++ mb(); ++ writel(val, crtc_reg); ++ ++ for (count = 0; count < 40; count++) { ++ val = readl(crtc_reg) & CRTC_OUTPUT_ENABLE; ++ if ((on && val) || (!on && !val)) ++ break; ++ udelay(1000); ++ } ++ ++ pci_info(pdev, "DMA hang fixup at reg[0x%lx]: 0x%x\n", ++ (unsigned long)crtc_reg & 0xffff, readl(crtc_reg)); ++ } ++ ++ iounmap(regbase); ++} ++ ++static void pci_fixup_dma_hang_early(struct pci_dev *pdev) ++{ ++ loongson_gpu_fixup_dma_hang(pdev, false); ++} ++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, PCI_DEVICE_ID_LOONGSON_GPU2, pci_fixup_dma_hang_early); ++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, PCI_DEVICE_ID_LOONGSON_GPU3, pci_fixup_dma_hang_early); ++ ++static void pci_fixup_dma_hang_final(struct pci_dev *pdev) ++{ ++ loongson_gpu_fixup_dma_hang(pdev, true); ++} ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, PCI_DEVICE_ID_LOONGSON_GPU2, pci_fixup_dma_hang_final); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, PCI_DEVICE_ID_LOONGSON_GPU3, pci_fixup_dma_hang_final); diff --git a/queue-6.12/net-macb-move-devm_-free-request-_irq-out-of-spin-lock-area.patch b/queue-6.12/net-macb-move-devm_-free-request-_irq-out-of-spin-lock-area.patch new file mode 100644 index 0000000000..9d410f3cbe --- /dev/null +++ b/queue-6.12/net-macb-move-devm_-free-request-_irq-out-of-spin-lock-area.patch @@ -0,0 +1,144 @@ +From 317e49358ebbf6390fa439ef3c142f9239dd25fb Mon Sep 17 00:00:00 2001 +From: Kevin Hao +Date: Wed, 18 Mar 2026 14:36:58 +0800 +Subject: net: macb: Move devm_{free,request}_irq() out of spin lock area +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kevin Hao + +commit 317e49358ebbf6390fa439ef3c142f9239dd25fb upstream. + +The devm_free_irq() and devm_request_irq() functions should not be +executed in an atomic context. + +During device suspend, all userspace processes and most kernel threads +are frozen. Additionally, we flush all tx/rx status, disable all macb +interrupts, and halt rx operations. Therefore, it is safe to split the +region protected by bp->lock into two independent sections, allowing +devm_free_irq() and devm_request_irq() to run in a non-atomic context. +This modification resolves the following lockdep warning: + BUG: sleeping function called from invalid context at kernel/locking/mutex.c:591 + in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 501, name: rtcwake + preempt_count: 1, expected: 0 + RCU nest depth: 1, expected: 0 + 7 locks held by rtcwake/501: + #0: ffff0008038c3408 (sb_writers#5){.+.+}-{0:0}, at: vfs_write+0xf8/0x368 + #1: ffff0008049a5e88 (&of->mutex#2){+.+.}-{4:4}, at: kernfs_fop_write_iter+0xbc/0x1c8 + #2: ffff00080098d588 (kn->active#70){.+.+}-{0:0}, at: kernfs_fop_write_iter+0xcc/0x1c8 + #3: ffff800081c84888 (system_transition_mutex){+.+.}-{4:4}, at: pm_suspend+0x1ec/0x290 + #4: ffff0008009ba0f8 (&dev->mutex){....}-{4:4}, at: device_suspend+0x118/0x4f0 + #5: ffff800081d00458 (rcu_read_lock){....}-{1:3}, at: rcu_lock_acquire+0x4/0x48 + #6: ffff0008031fb9e0 (&bp->lock){-.-.}-{3:3}, at: macb_suspend+0x144/0x558 + irq event stamp: 8682 + hardirqs last enabled at (8681): [] _raw_spin_unlock_irqrestore+0x44/0x88 + hardirqs last disabled at (8682): [] _raw_spin_lock_irqsave+0x38/0x98 + softirqs last enabled at (7322): [] handle_softirqs+0x52c/0x588 + softirqs last disabled at (7317): [] __do_softirq+0x20/0x2c + CPU: 1 UID: 0 PID: 501 Comm: rtcwake Not tainted 7.0.0-rc3-next-20260310-yocto-standard+ #125 PREEMPT + Hardware name: ZynqMP ZCU102 Rev1.1 (DT) + Call trace: + show_stack+0x24/0x38 (C) + __dump_stack+0x28/0x38 + dump_stack_lvl+0x64/0x88 + dump_stack+0x18/0x24 + __might_resched+0x200/0x218 + __might_sleep+0x38/0x98 + __mutex_lock_common+0x7c/0x1378 + mutex_lock_nested+0x38/0x50 + free_irq+0x68/0x2b0 + devm_irq_release+0x24/0x38 + devres_release+0x40/0x80 + devm_free_irq+0x48/0x88 + macb_suspend+0x298/0x558 + device_suspend+0x218/0x4f0 + dpm_suspend+0x244/0x3a0 + dpm_suspend_start+0x50/0x78 + suspend_devices_and_enter+0xec/0x560 + pm_suspend+0x194/0x290 + state_store+0x110/0x158 + kobj_attr_store+0x1c/0x30 + sysfs_kf_write+0xa8/0xd0 + kernfs_fop_write_iter+0x11c/0x1c8 + vfs_write+0x248/0x368 + ksys_write+0x7c/0xf8 + __arm64_sys_write+0x28/0x40 + invoke_syscall+0x4c/0xe8 + el0_svc_common+0x98/0xf0 + do_el0_svc+0x28/0x40 + el0_svc+0x54/0x1e0 + el0t_64_sync_handler+0x84/0x130 + el0t_64_sync+0x198/0x1a0 + +Fixes: 558e35ccfe95 ("net: macb: WoL support for GEM type of Ethernet controller") +Cc: stable@vger.kernel.org +Reviewed-by: Théo Lebrun +Signed-off-by: Kevin Hao +Link: https://patch.msgid.link/20260318-macb-irq-v2-1-f1179768ab24@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/cadence/macb_main.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -5410,6 +5410,7 @@ static int __maybe_unused macb_suspend(s + /* write IP address into register */ + tmp |= MACB_BFEXT(IP, be32_to_cpu(ifa->ifa_local)); + } ++ spin_unlock_irqrestore(&bp->lock, flags); + + /* Change interrupt handler and + * Enable WoL IRQ on queue 0 +@@ -5422,11 +5423,12 @@ static int __maybe_unused macb_suspend(s + dev_err(dev, + "Unable to request IRQ %d (error %d)\n", + bp->queues[0].irq, err); +- spin_unlock_irqrestore(&bp->lock, flags); + return err; + } ++ spin_lock_irqsave(&bp->lock, flags); + queue_writel(bp->queues, IER, GEM_BIT(WOL)); + gem_writel(bp, WOL, tmp); ++ spin_unlock_irqrestore(&bp->lock, flags); + } else { + err = devm_request_irq(dev, bp->queues[0].irq, macb_wol_interrupt, + IRQF_SHARED, netdev->name, bp->queues); +@@ -5434,13 +5436,13 @@ static int __maybe_unused macb_suspend(s + dev_err(dev, + "Unable to request IRQ %d (error %d)\n", + bp->queues[0].irq, err); +- spin_unlock_irqrestore(&bp->lock, flags); + return err; + } ++ spin_lock_irqsave(&bp->lock, flags); + queue_writel(bp->queues, IER, MACB_BIT(WOL)); + macb_writel(bp, WOL, tmp); ++ spin_unlock_irqrestore(&bp->lock, flags); + } +- spin_unlock_irqrestore(&bp->lock, flags); + + enable_irq_wake(bp->queues[0].irq); + } +@@ -5507,6 +5509,8 @@ static int __maybe_unused macb_resume(st + queue_readl(bp->queues, ISR); + if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) + queue_writel(bp->queues, ISR, -1); ++ spin_unlock_irqrestore(&bp->lock, flags); ++ + /* Replace interrupt handler on queue 0 */ + devm_free_irq(dev, bp->queues[0].irq, bp->queues); + err = devm_request_irq(dev, bp->queues[0].irq, macb_interrupt, +@@ -5515,10 +5519,8 @@ static int __maybe_unused macb_resume(st + dev_err(dev, + "Unable to request IRQ %d (error %d)\n", + bp->queues[0].irq, err); +- spin_unlock_irqrestore(&bp->lock, flags); + return err; + } +- spin_unlock_irqrestore(&bp->lock, flags); + + disable_irq_wake(bp->queues[0].irq); + diff --git a/queue-6.12/net-macb-protect-access-to-net_device-ip_ptr-with-rcu-lock.patch b/queue-6.12/net-macb-protect-access-to-net_device-ip_ptr-with-rcu-lock.patch new file mode 100644 index 0000000000..dd922add08 --- /dev/null +++ b/queue-6.12/net-macb-protect-access-to-net_device-ip_ptr-with-rcu-lock.patch @@ -0,0 +1,125 @@ +From baa35a698cea26930679a20a7550bbb4c8319725 Mon Sep 17 00:00:00 2001 +From: Kevin Hao +Date: Wed, 18 Mar 2026 14:36:59 +0800 +Subject: net: macb: Protect access to net_device::ip_ptr with RCU lock +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kevin Hao + +commit baa35a698cea26930679a20a7550bbb4c8319725 upstream. + +Access to net_device::ip_ptr and its associated members must be +protected by an RCU lock. Since we are modifying this piece of code, +let's also move it to execute only when WAKE_ARP is enabled. + +To minimize the duration of the RCU lock, a local variable is used to +temporarily store the IP address. This change resolves the following +RCU check warning: + WARNING: suspicious RCU usage + 7.0.0-rc3-next-20260310-yocto-standard+ #122 Not tainted + ----------------------------- + drivers/net/ethernet/cadence/macb_main.c:5944 suspicious rcu_dereference_check() usage! + + other info that might help us debug this: + + rcu_scheduler_active = 2, debug_locks = 1 + 5 locks held by rtcwake/518: + #0: ffff000803ab1408 (sb_writers#5){.+.+}-{0:0}, at: vfs_write+0xf8/0x368 + #1: ffff0008090bf088 (&of->mutex#2){+.+.}-{4:4}, at: kernfs_fop_write_iter+0xbc/0x1c8 + #2: ffff00080098d588 (kn->active#70){.+.+}-{0:0}, at: kernfs_fop_write_iter+0xcc/0x1c8 + #3: ffff800081c84888 (system_transition_mutex){+.+.}-{4:4}, at: pm_suspend+0x1ec/0x290 + #4: ffff0008009ba0f8 (&dev->mutex){....}-{4:4}, at: device_suspend+0x118/0x4f0 + + stack backtrace: + CPU: 3 UID: 0 PID: 518 Comm: rtcwake Not tainted 7.0.0-rc3-next-20260310-yocto-standard+ #122 PREEMPT + Hardware name: ZynqMP ZCU102 Rev1.1 (DT) + Call trace: + show_stack+0x24/0x38 (C) + __dump_stack+0x28/0x38 + dump_stack_lvl+0x64/0x88 + dump_stack+0x18/0x24 + lockdep_rcu_suspicious+0x134/0x1d8 + macb_suspend+0xd8/0x4c0 + device_suspend+0x218/0x4f0 + dpm_suspend+0x244/0x3a0 + dpm_suspend_start+0x50/0x78 + suspend_devices_and_enter+0xec/0x560 + pm_suspend+0x194/0x290 + state_store+0x110/0x158 + kobj_attr_store+0x1c/0x30 + sysfs_kf_write+0xa8/0xd0 + kernfs_fop_write_iter+0x11c/0x1c8 + vfs_write+0x248/0x368 + ksys_write+0x7c/0xf8 + __arm64_sys_write+0x28/0x40 + invoke_syscall+0x4c/0xe8 + el0_svc_common+0x98/0xf0 + do_el0_svc+0x28/0x40 + el0_svc+0x54/0x1e0 + el0t_64_sync_handler+0x84/0x130 + el0t_64_sync+0x198/0x1a0 + +Fixes: 0cb8de39a776 ("net: macb: Add ARP support to WOL") +Signed-off-by: Kevin Hao +Cc: stable@vger.kernel.org +Reviewed-by: Théo Lebrun +Link: https://patch.msgid.link/20260318-macb-irq-v2-2-f1179768ab24@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/cadence/macb_main.c | 25 ++++++++++++++++--------- + 1 file changed, 16 insertions(+), 9 deletions(-) + +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -5352,9 +5352,9 @@ static int __maybe_unused macb_suspend(s + struct macb_queue *queue; + struct in_device *idev; + unsigned long flags; ++ u32 tmp, ifa_local; + unsigned int q; + int err; +- u32 tmp; + + if (!device_may_wakeup(&bp->dev->dev)) + phy_exit(bp->sgmii_phy); +@@ -5363,14 +5363,21 @@ static int __maybe_unused macb_suspend(s + return 0; + + if (bp->wol & MACB_WOL_ENABLED) { +- /* Check for IP address in WOL ARP mode */ +- idev = __in_dev_get_rcu(bp->dev); +- if (idev) +- ifa = rcu_dereference(idev->ifa_list); +- if ((bp->wolopts & WAKE_ARP) && !ifa) { +- netdev_err(netdev, "IP address not assigned as required by WoL walk ARP\n"); +- return -EOPNOTSUPP; ++ if (bp->wolopts & WAKE_ARP) { ++ /* Check for IP address in WOL ARP mode */ ++ rcu_read_lock(); ++ idev = __in_dev_get_rcu(bp->dev); ++ if (idev) ++ ifa = rcu_dereference(idev->ifa_list); ++ if (!ifa) { ++ rcu_read_unlock(); ++ netdev_err(netdev, "IP address not assigned as required by WoL walk ARP\n"); ++ return -EOPNOTSUPP; ++ } ++ ifa_local = be32_to_cpu(ifa->ifa_local); ++ rcu_read_unlock(); + } ++ + spin_lock_irqsave(&bp->lock, flags); + + /* Disable Tx and Rx engines before disabling the queues, +@@ -5408,7 +5415,7 @@ static int __maybe_unused macb_suspend(s + if (bp->wolopts & WAKE_ARP) { + tmp |= MACB_BIT(ARP); + /* write IP address into register */ +- tmp |= MACB_BFEXT(IP, be32_to_cpu(ifa->ifa_local)); ++ tmp |= MACB_BFEXT(IP, ifa_local); + } + spin_unlock_irqrestore(&bp->lock, flags); + diff --git a/queue-6.12/net-macb-use-dev_consume_skb_any-to-free-tx-skbs.patch b/queue-6.12/net-macb-use-dev_consume_skb_any-to-free-tx-skbs.patch new file mode 100644 index 0000000000..cfdace7eab --- /dev/null +++ b/queue-6.12/net-macb-use-dev_consume_skb_any-to-free-tx-skbs.patch @@ -0,0 +1,73 @@ +From 647b8a2fe474474704110db6bd07f7a139e621eb Mon Sep 17 00:00:00 2001 +From: Kevin Hao +Date: Sat, 21 Mar 2026 22:04:41 +0800 +Subject: net: macb: Use dev_consume_skb_any() to free TX SKBs + +From: Kevin Hao + +commit 647b8a2fe474474704110db6bd07f7a139e621eb upstream. + +The napi_consume_skb() function is not intended to be called in an IRQ +disabled context. However, after commit 6bc8a5098bf4 ("net: macb: Fix +tx_ptr_lock locking"), the freeing of TX SKBs is performed with IRQs +disabled. To resolve the following call trace, use dev_consume_skb_any() +for freeing TX SKBs: + WARNING: kernel/softirq.c:430 at __local_bh_enable_ip+0x174/0x188, CPU#0: ksoftirqd/0/15 + Modules linked in: + CPU: 0 UID: 0 PID: 15 Comm: ksoftirqd/0 Not tainted 7.0.0-rc4-next-20260319-yocto-standard-dirty #37 PREEMPT + Hardware name: ZynqMP ZCU102 Rev1.1 (DT) + pstate: 200000c5 (nzCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--) + pc : __local_bh_enable_ip+0x174/0x188 + lr : local_bh_enable+0x24/0x38 + sp : ffff800082b3bb10 + x29: ffff800082b3bb10 x28: ffff0008031f3c00 x27: 000000000011ede0 + x26: ffff000800a7ff00 x25: ffff800083937ce8 x24: 0000000000017a80 + x23: ffff000803243a78 x22: 0000000000000040 x21: 0000000000000000 + x20: ffff000800394c80 x19: 0000000000000200 x18: 0000000000000001 + x17: 0000000000000001 x16: ffff000803240000 x15: 0000000000000000 + x14: ffffffffffffffff x13: 0000000000000028 x12: ffff000800395650 + x11: ffff8000821d1528 x10: ffff800081c2bc08 x9 : ffff800081c1e258 + x8 : 0000000100000301 x7 : ffff8000810426ec x6 : 0000000000000000 + x5 : 0000000000000001 x4 : 0000000000000001 x3 : 0000000000000000 + x2 : 0000000000000008 x1 : 0000000000000200 x0 : ffff8000810428dc + Call trace: + __local_bh_enable_ip+0x174/0x188 (P) + local_bh_enable+0x24/0x38 + skb_attempt_defer_free+0x190/0x1d8 + napi_consume_skb+0x58/0x108 + macb_tx_poll+0x1a4/0x558 + __napi_poll+0x50/0x198 + net_rx_action+0x1f4/0x3d8 + handle_softirqs+0x16c/0x560 + run_ksoftirqd+0x44/0x80 + smpboot_thread_fn+0x1d8/0x338 + kthread+0x120/0x150 + ret_from_fork+0x10/0x20 + irq event stamp: 29751 + hardirqs last enabled at (29750): [] _raw_spin_unlock_irqrestore+0x44/0x88 + hardirqs last disabled at (29751): [] _raw_spin_lock_irqsave+0x38/0x98 + softirqs last enabled at (29150): [] handle_softirqs+0x504/0x560 + softirqs last disabled at (29153): [] run_ksoftirqd+0x44/0x80 + +Fixes: 6bc8a5098bf4 ("net: macb: Fix tx_ptr_lock locking") +Signed-off-by: Kevin Hao +Cc: stable@vger.kernel.org +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260321-macb-tx-v1-1-b383a58dd4e6@gmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/cadence/macb_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -1129,7 +1129,7 @@ static void macb_tx_unmap(struct macb *b + } + + if (tx_skb->skb) { +- napi_consume_skb(tx_skb->skb, budget); ++ dev_consume_skb_any(tx_skb->skb); + tx_skb->skb = NULL; + } + } diff --git a/queue-6.12/ovl-fix-wrong-detection-of-32bit-inode-numbers.patch b/queue-6.12/ovl-fix-wrong-detection-of-32bit-inode-numbers.patch new file mode 100644 index 0000000000..ccb5077db7 --- /dev/null +++ b/queue-6.12/ovl-fix-wrong-detection-of-32bit-inode-numbers.patch @@ -0,0 +1,43 @@ +From 53a7c171e9dd833f0a96b545adcb89bd57387239 Mon Sep 17 00:00:00 2001 +From: Amir Goldstein +Date: Sun, 8 Mar 2026 12:02:21 +0100 +Subject: ovl: fix wrong detection of 32bit inode numbers + +From: Amir Goldstein + +commit 53a7c171e9dd833f0a96b545adcb89bd57387239 upstream. + +The implicit FILEID_INO32_GEN encoder was changed to be explicit, +so we need to fix the detection. + +When mounting overlayfs with upperdir and lowerdir on different ext4 +filesystems, the expected kmsg log is: + + overlayfs: "xino" feature enabled using 32 upper inode bits. + +But instead, since the regressing commit, the kmsg log was: + + overlayfs: "xino" feature enabled using 2 upper inode bits. + +Fixes: e21fc2038c1b9 ("exportfs: make ->encode_fh() a mandatory method for NFS export") +Cc: stable@vger.kernel.org # v6.7+ +Signed-off-by: Amir Goldstein +Signed-off-by: Greg Kroah-Hartman +--- + fs/overlayfs/util.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/fs/overlayfs/util.c ++++ b/fs/overlayfs/util.c +@@ -84,7 +84,10 @@ int ovl_can_decode_fh(struct super_block + if (!exportfs_can_decode_fh(sb->s_export_op)) + return 0; + +- return sb->s_export_op->encode_fh ? -1 : FILEID_INO32_GEN; ++ if (sb->s_export_op->encode_fh == generic_encode_ino32_fh) ++ return FILEID_INO32_GEN; ++ ++ return -1; + } + + struct dentry *ovl_indexdir(struct super_block *sb) diff --git a/queue-6.12/phy-qcom-qmp-ufs-fix-sm8650-pcs-table-for-gear-4.patch b/queue-6.12/phy-qcom-qmp-ufs-fix-sm8650-pcs-table-for-gear-4.patch new file mode 100644 index 0000000000..0c10f97530 --- /dev/null +++ b/queue-6.12/phy-qcom-qmp-ufs-fix-sm8650-pcs-table-for-gear-4.patch @@ -0,0 +1,59 @@ +From 81af9e40e2e4e1aa95f09fb34811760be6742c58 Mon Sep 17 00:00:00 2001 +From: Abel Vesa +Date: Thu, 19 Feb 2026 13:11:48 +0200 +Subject: phy: qcom: qmp-ufs: Fix SM8650 PCS table for Gear 4 + +From: Abel Vesa + +commit 81af9e40e2e4e1aa95f09fb34811760be6742c58 upstream. + +According to internal documentation, on SM8650, when the PHY is configured +in Gear 4, the QPHY_V6_PCS_UFS_PLL_CNTL register needs to have the same +value as for Gear 5. + +At the moment, there is no board that comes with a UFS 3.x device, so +this issue doesn't show up, but with the new Eliza SoC, which uses the +same init sequence as SM8650, on the MTP board, the link startup fails +with the current Gear 4 PCS table. + +So fix that by moving the entry into the PCS generic table instead, +while keeping the value from Gear 5 configuration. + +Cc: stable@vger.kernel.org # v6.10 +Fixes: b9251e64a96f ("phy: qcom: qmp-ufs: update SM8650 tables for Gear 4 & 5") +Suggested-by: Nitin Rawat +Signed-off-by: Abel Vesa +Reviewed-by: Konrad Dybcio +Reviewed-by: Neil Armstrong +Tested-by: Neil Armstrong # on SM8650-HDK +Link: https://patch.msgid.link/20260219-phy-qcom-qmp-ufs-fix-sm8650-pcs-g4-table-v1-1-f136505b57f6@oss.qualcomm.com +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman +--- + drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c ++++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c +@@ -927,6 +927,7 @@ static const struct qmp_phy_init_tbl sm8 + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PCS_CTRL1, 0xc1), ++ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x68), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S4, 0x0e), +@@ -936,13 +937,11 @@ static const struct qmp_phy_init_tbl sm8 + }; + + static const struct qmp_phy_init_tbl sm8650_ufsphy_g4_pcs[] = { +- QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x13), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04), + }; + + static const struct qmp_phy_init_tbl sm8650_ufsphy_g5_pcs[] = { +- QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x05), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x05), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY, 0x4d), diff --git a/queue-6.12/scsi-ibmvfc-fix-oob-access-in-ibmvfc_discover_targets_done.patch b/queue-6.12/scsi-ibmvfc-fix-oob-access-in-ibmvfc_discover_targets_done.patch new file mode 100644 index 0000000000..b07e259d6a --- /dev/null +++ b/queue-6.12/scsi-ibmvfc-fix-oob-access-in-ibmvfc_discover_targets_done.patch @@ -0,0 +1,45 @@ +From 61d099ac4a7a8fb11ebdb6e2ec8d77f38e77362f Mon Sep 17 00:00:00 2001 +From: Tyllis Xu +Date: Sat, 14 Mar 2026 12:01:50 -0500 +Subject: scsi: ibmvfc: Fix OOB access in ibmvfc_discover_targets_done() + +From: Tyllis Xu + +commit 61d099ac4a7a8fb11ebdb6e2ec8d77f38e77362f upstream. + +A malicious or compromised VIO server can return a num_written value in the +discover targets MAD response that exceeds max_targets. This value is +stored directly in vhost->num_targets without validation, and is then used +as the loop bound in ibmvfc_alloc_targets() to index into disc_buf[], which +is only allocated for max_targets entries. Indices at or beyond max_targets +access kernel memory outside the DMA-coherent allocation. The +out-of-bounds data is subsequently embedded in Implicit Logout and PLOGI +MADs that are sent back to the VIO server, leaking kernel memory. + +Fix by clamping num_written to max_targets before storing it. + +Fixes: 072b91f9c651 ("[SCSI] ibmvfc: IBM Power Virtual Fibre Channel Adapter Client Driver") +Reported-by: Yuhao Jiang +Cc: stable@vger.kernel.org +Signed-off-by: Tyllis Xu +Reviewed-by: Dave Marquardt +Acked-by: Tyrel Datwyler +Link: https://patch.msgid.link/20260314170151.548614-1-LivelyCarpet87@gmail.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/ibmvscsi/ibmvfc.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/ibmvscsi/ibmvfc.c ++++ b/drivers/scsi/ibmvscsi/ibmvfc.c +@@ -4963,7 +4963,8 @@ static void ibmvfc_discover_targets_done + switch (mad_status) { + case IBMVFC_MAD_SUCCESS: + ibmvfc_dbg(vhost, "Discover Targets succeeded\n"); +- vhost->num_targets = be32_to_cpu(rsp->num_written); ++ vhost->num_targets = min_t(u32, be32_to_cpu(rsp->num_written), ++ max_targets); + ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_ALLOC_TGTS); + break; + case IBMVFC_MAD_FAILED: diff --git a/queue-6.12/scsi-ses-handle-positive-scsi-error-from-ses_recv_diag.patch b/queue-6.12/scsi-ses-handle-positive-scsi-error-from-ses_recv_diag.patch new file mode 100644 index 0000000000..9f47cea602 --- /dev/null +++ b/queue-6.12/scsi-ses-handle-positive-scsi-error-from-ses_recv_diag.patch @@ -0,0 +1,36 @@ +From 7a9f448d44127217fabc4065c5ba070d4e0b5d37 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Mon, 23 Feb 2026 16:44:59 +0100 +Subject: scsi: ses: Handle positive SCSI error from ses_recv_diag() + +From: Greg Kroah-Hartman + +commit 7a9f448d44127217fabc4065c5ba070d4e0b5d37 upstream. + +ses_recv_diag() can return a positive value, which also means that an +error happened, so do not only test for negative values. + +Cc: James E.J. Bottomley +Cc: Martin K. Petersen +Cc: stable +Assisted-by: gkh_clanker_2000 +Signed-off-by: Greg Kroah-Hartman +Reviewed-by: Hannes Reinecke +Link: https://patch.msgid.link/2026022301-bony-overstock-a07f@gregkh +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/ses.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/ses.c ++++ b/drivers/scsi/ses.c +@@ -216,7 +216,7 @@ static unsigned char *ses_get_page2_desc + unsigned char *type_ptr = ses_dev->page1_types; + unsigned char *desc_ptr = ses_dev->page2 + 8; + +- if (ses_recv_diag(sdev, 2, ses_dev->page2, ses_dev->page2_len) < 0) ++ if (ses_recv_diag(sdev, 2, ses_dev->page2, ses_dev->page2_len)) + return NULL; + + for (i = 0; i < ses_dev->page1_num_types; i++, type_ptr += 4) { diff --git a/queue-6.12/series b/queue-6.12/series index 44e100c65d..afb686a7ad 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -152,3 +152,31 @@ hwmon-peci-cputemp-fix-off-by-one-in-cputemp_is_visible.patch media-mc-v4l2-serialize-reinit-and-reqbufs-with-req_queue_mutex.patch virtio_net-fix-uaf-on-dst_ops-when-iff_xmit_dst_release-is-cleared-and-napi_tx-is-false.patch erofs-add-gfp_noio-in-the-bio-completion-if-needed.patch +alarmtimer-fix-argument-order-in-alarm_timer_forward.patch +x86-cpu-enable-fsgsbase-early-in-cpu_init_exception_handling.patch +x86-cpu-remove-x86_cr4_fred-from-the-cr4-pinned-bits-mask.patch +phy-qcom-qmp-ufs-fix-sm8650-pcs-table-for-gear-4.patch +ovl-fix-wrong-detection-of-32bit-inode-numbers.patch +scsi-ibmvfc-fix-oob-access-in-ibmvfc_discover_targets_done.patch +scsi-ses-handle-positive-scsi-error-from-ses_recv_diag.patch +net-macb-move-devm_-free-request-_irq-out-of-spin-lock-area.patch +net-macb-protect-access-to-net_device-ip_ptr-with-rcu-lock.patch +net-macb-use-dev_consume_skb_any-to-free-tx-skbs.patch +kvm-x86-mmu-drop-zap-existing-present-spte-even-when-creating-an-mmio-spte.patch +jbd2-gracefully-abort-on-checkpointing-state-corruptions.patch +irqchip-qcom-mpm-add-missing-mailbox-tx-done-acknowledgment.patch +futex-clear-stale-exiting-pointer-in-futex_lock_pi-retry-path.patch +dmaengine-fsl-edma-fix-channel-parameter-config-for-fixed-channel-requests.patch +dmaengine-sh-rz-dmac-protect-the-driver-specific-lists.patch +dmaengine-sh-rz-dmac-move-chctrl-updates-under-spinlock.patch +drm-amdgpu-prevent-immediate-pasid-reuse-case.patch +drm-i915-dp_tunnel-fix-error-handling-when-clearing-stream-bw-in-atomic-state.patch +loongarch-fix-missing-null-checks-for-kstrdup.patch +loongarch-workaround-ls2k-ls7a-gpu-dma-hang-bug.patch +loongarch-kvm-make-kvm_get_vcpu_by_cpuid-more-robust.patch +xfs-stop-reclaim-before-pushing-ail-during-unmount.patch +xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch +xfs-scrub-unlock-dquot-before-early-return-in-quota-scrub.patch +xfs-fix-ri_total-validation-in-xlog_recover_attri_commit_pass2.patch +xfs-don-t-irele-after-failing-to-iget-in-xfs_attri_recover_work.patch +xfs-remove-file_path-tracepoint-data.patch diff --git a/queue-6.12/x86-cpu-enable-fsgsbase-early-in-cpu_init_exception_handling.patch b/queue-6.12/x86-cpu-enable-fsgsbase-early-in-cpu_init_exception_handling.patch new file mode 100644 index 0000000000..22e8f7e7f6 --- /dev/null +++ b/queue-6.12/x86-cpu-enable-fsgsbase-early-in-cpu_init_exception_handling.patch @@ -0,0 +1,137 @@ +From 05243d490bb7852a8acca7b5b5658019c7797a52 Mon Sep 17 00:00:00 2001 +From: Nikunj A Dadhania +Date: Wed, 18 Mar 2026 07:56:52 +0000 +Subject: x86/cpu: Enable FSGSBASE early in cpu_init_exception_handling() + +From: Nikunj A Dadhania + +commit 05243d490bb7852a8acca7b5b5658019c7797a52 upstream. + +Move FSGSBASE enablement from identify_cpu() to cpu_init_exception_handling() +to ensure it is enabled before any exceptions can occur on both boot and +secondary CPUs. + +== Background == + +Exception entry code (paranoid_entry()) uses ALTERNATIVE patching based on +X86_FEATURE_FSGSBASE to decide whether to use RDGSBASE/WRGSBASE instructions +or the slower RDMSR/SWAPGS sequence for saving/restoring GSBASE. + +On boot CPU, ALTERNATIVE patching happens after enabling FSGSBASE in CR4. +When the feature is available, the code is permanently patched to use +RDGSBASE/WRGSBASE, which require CR4.FSGSBASE=1 to execute without triggering + +== Boot Sequence == + +Boot CPU (with CR pinning enabled): + trap_init() + cpu_init() <- Uses unpatched code (RDMSR/SWAPGS) + x2apic_setup() + ... + arch_cpu_finalize_init() + identify_boot_cpu() + identify_cpu() + cr4_set_bits(X86_CR4_FSGSBASE) # Enables the feature + # This becomes part of cr4_pinned_bits + ... + alternative_instructions() <- Patches code to use RDGSBASE/WRGSBASE + +Secondary CPUs (with CR pinning enabled): + start_secondary() + cr4_init() <- Code already patched, CR4.FSGSBASE=1 + set implicitly via cr4_pinned_bits + + cpu_init() <- exceptions work because FSGSBASE is + already enabled + +Secondary CPU (with CR pinning disabled): + start_secondary() + cr4_init() <- Code already patched, CR4.FSGSBASE=0 + cpu_init() + x2apic_setup() + rdmsrq(MSR_IA32_APICBASE) <- Triggers #VC in SNP guests + exc_vmm_communication() + paranoid_entry() <- Uses RDGSBASE with CR4.FSGSBASE=0 + (patched code) + ... + ap_starting() + identify_secondary_cpu() + identify_cpu() + cr4_set_bits(X86_CR4_FSGSBASE) <- Enables the feature, which is + too late + +== CR Pinning == + +Currently, for secondary CPUs, CR4.FSGSBASE is set implicitly through +CR-pinning: the boot CPU sets it during identify_cpu(), it becomes part of +cr4_pinned_bits, and cr4_init() applies those pinned bits to secondary CPUs. +This works but creates an undocumented dependency between cr4_init() and the +pinning mechanism. + +== Problem == + +Secondary CPUs boot after alternatives have been applied globally. They +execute already-patched paranoid_entry() code that uses RDGSBASE/WRGSBASE +instructions, which require CR4.FSGSBASE=1. Upcoming changes to CR pinning +behavior will break the implicit dependency, causing secondary CPUs to +generate #UD. + +This issue manifests itself on AMD SEV-SNP guests, where the rdmsrq() in +x2apic_setup() triggers a #VC exception early during cpu_init(). The #VC +handler (exc_vmm_communication()) executes the patched paranoid_entry() path. +Without CR4.FSGSBASE enabled, RDGSBASE instructions trigger #UD. + +== Fix == + +Enable FSGSBASE explicitly in cpu_init_exception_handling() before loading +exception handlers. This makes the dependency explicit and ensures both +boot and secondary CPUs have FSGSBASE enabled before paranoid_entry() +executes. + +Fixes: c82965f9e530 ("x86/entry/64: Handle FSGSBASE enabled paranoid entry/exit") +Reported-by: Borislav Petkov +Suggested-by: Sohil Mehta +Signed-off-by: Nikunj A Dadhania +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Sohil Mehta +Cc: +Link: https://patch.msgid.link/20260318075654.1792916-2-nikunj@amd.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/cpu/common.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -1938,12 +1938,6 @@ static void identify_cpu(struct cpuinfo_ + setup_smap(c); + setup_umip(c); + +- /* Enable FSGSBASE instructions if available. */ +- if (cpu_has(c, X86_FEATURE_FSGSBASE)) { +- cr4_set_bits(X86_CR4_FSGSBASE); +- elf_hwcap2 |= HWCAP2_FSGSBASE; +- } +- + /* + * The vendor-specific functions might have changed features. + * Now we do "generic changes." +@@ -2286,6 +2280,18 @@ void cpu_init_exception_handling(bool bo + /* GHCB needs to be setup to handle #VC. */ + setup_ghcb(); + ++ /* ++ * On CPUs with FSGSBASE support, paranoid_entry() uses ++ * ALTERNATIVE-patched RDGSBASE/WRGSBASE instructions. Secondary CPUs ++ * boot after alternatives are patched globally, so early exceptions ++ * execute patched code that depends on FSGSBASE. Enable the feature ++ * before any exceptions occur. ++ */ ++ if (cpu_feature_enabled(X86_FEATURE_FSGSBASE)) { ++ cr4_set_bits(X86_CR4_FSGSBASE); ++ elf_hwcap2 |= HWCAP2_FSGSBASE; ++ } ++ + if (cpu_feature_enabled(X86_FEATURE_FRED)) { + /* The boot CPU has enabled FRED during early boot */ + if (!boot_cpu) diff --git a/queue-6.12/x86-cpu-remove-x86_cr4_fred-from-the-cr4-pinned-bits-mask.patch b/queue-6.12/x86-cpu-remove-x86_cr4_fred-from-the-cr4-pinned-bits-mask.patch new file mode 100644 index 0000000000..2819326a36 --- /dev/null +++ b/queue-6.12/x86-cpu-remove-x86_cr4_fred-from-the-cr4-pinned-bits-mask.patch @@ -0,0 +1,63 @@ +From 411df123c017169922cc767affce76282b8e6c85 Mon Sep 17 00:00:00 2001 +From: "Borislav Petkov (AMD)" +Date: Thu, 19 Mar 2026 12:07:59 +0100 +Subject: x86/cpu: Remove X86_CR4_FRED from the CR4 pinned bits mask + +From: Borislav Petkov (AMD) + +commit 411df123c017169922cc767affce76282b8e6c85 upstream. + +Commit in Fixes added the FRED CR4 bit to the CR4 pinned bits mask so +that whenever something else modifies CR4, that bit remains set. Which +in itself is a perfectly fine idea. + +However, there's an issue when during boot FRED is initialized: first on +the BSP and later on the APs. Thus, there's a window in time when +exceptions cannot be handled. + +This becomes particularly nasty when running as SEV-{ES,SNP} or TDX +guests which, when they manage to trigger exceptions during that short +window described above, triple fault due to FRED MSRs not being set up +yet. + +See Link tag below for a much more detailed explanation of the +situation. + +So, as a result, the commit in that Link URL tried to address this +shortcoming by temporarily disabling CR4 pinning when an AP is not +online yet. + +However, that is a problem in itself because in this case, an attack on +the kernel needs to only modify the online bit - a single bit in RW +memory - and then disable CR4 pinning and then disable SM*P, leading to +more and worse things to happen to the system. + +So, instead, remove the FRED bit from the CR4 pinning mask, thus +obviating the need to temporarily disable CR4 pinning. + +If someone manages to disable FRED when poking at CR4, then +idt_invalidate() would make sure the system would crash'n'burn on the +first exception triggered, which is a much better outcome security-wise. + +Fixes: ff45746fbf00 ("x86/cpu: Add X86_CR4_FRED macro") +Suggested-by: Dave Hansen +Suggested-by: Peter Zijlstra +Signed-off-by: Borislav Petkov (AMD) +Cc: # 6.12+ +Link: https://lore.kernel.org/r/177385987098.1647592.3381141860481415647.tip-bot2@tip-bot2 +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/cpu/common.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -405,7 +405,7 @@ out: + + /* These bits should not change their value after CPU init is finished. */ + static const unsigned long cr4_pinned_mask = X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_UMIP | +- X86_CR4_FSGSBASE | X86_CR4_CET | X86_CR4_FRED; ++ X86_CR4_FSGSBASE | X86_CR4_CET; + static DEFINE_STATIC_KEY_FALSE_RO(cr_pinning); + static unsigned long cr4_pinned_bits __ro_after_init; + diff --git a/queue-6.12/xfs-don-t-irele-after-failing-to-iget-in-xfs_attri_recover_work.patch b/queue-6.12/xfs-don-t-irele-after-failing-to-iget-in-xfs_attri_recover_work.patch new file mode 100644 index 0000000000..099131313f --- /dev/null +++ b/queue-6.12/xfs-don-t-irele-after-failing-to-iget-in-xfs_attri_recover_work.patch @@ -0,0 +1,34 @@ +From 70685c291ef82269180758130394ecdc4496b52c Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Mon, 23 Mar 2026 14:01:57 -0700 +Subject: xfs: don't irele after failing to iget in xfs_attri_recover_work + +From: Darrick J. Wong + +commit 70685c291ef82269180758130394ecdc4496b52c upstream. + +xlog_recovery_iget* never set @ip to a valid pointer if they return +an error, so this irele will walk off a dangling pointer. Fix that. + +Cc: stable@vger.kernel.org # v6.10 +Fixes: ae673f534a3097 ("xfs: record inode generation in xattr update log intent items") +Signed-off-by: Darrick J. Wong +Reviewed-by: Long Li +Reviewed-by: Christoph Hellwig +Reviewed-by: Carlos Maiolino +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/xfs_attr_item.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/fs/xfs/xfs_attr_item.c ++++ b/fs/xfs/xfs_attr_item.c +@@ -658,7 +658,6 @@ xfs_attri_recover_work( + break; + } + if (error) { +- xfs_irele(ip); + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, attrp, + sizeof(*attrp)); + return ERR_PTR(-EFSCORRUPTED); diff --git a/queue-6.12/xfs-fix-ri_total-validation-in-xlog_recover_attri_commit_pass2.patch b/queue-6.12/xfs-fix-ri_total-validation-in-xlog_recover_attri_commit_pass2.patch new file mode 100644 index 0000000000..36b6399fa5 --- /dev/null +++ b/queue-6.12/xfs-fix-ri_total-validation-in-xlog_recover_attri_commit_pass2.patch @@ -0,0 +1,61 @@ +From d72f2084e30966097c8eae762e31986a33c3c0ae Mon Sep 17 00:00:00 2001 +From: Long Li +Date: Fri, 20 Mar 2026 10:11:29 +0800 +Subject: xfs: fix ri_total validation in xlog_recover_attri_commit_pass2 + +From: Long Li + +commit d72f2084e30966097c8eae762e31986a33c3c0ae upstream. + +The ri_total checks for SET/REPLACE operations are hardcoded to 3, +but xfs_attri_item_size() only emits a value iovec when value_len > 0, +so ri_total is 2 when value_len == 0. + +For PPTR_SET/PPTR_REMOVE/PPTR_REPLACE, value_len is validated by +xfs_attri_validate() to be exactly sizeof(struct xfs_parent_rec) and +is never zero, so their hardcoded checks remain correct. + +This problem may cause log recovery failures. The following script can be +used to reproduce the problem: + + #!/bin/bash + mkfs.xfs -f /dev/sda + mount /dev/sda /mnt/test/ + touch /mnt/test/file + for i in {1..200}; do + attr -s "user.attr_$i" -V "value_$i" /mnt/test/file > /dev/null + done + echo 1 > /sys/fs/xfs/debug/larp + echo 1 > /sys/fs/xfs/sda/errortag/larp + attr -s "user.zero" -V "" /mnt/test/file + echo 0 > /sys/fs/xfs/sda/errortag/larp + umount /mnt/test + mount /dev/sda /mnt/test/ # mount failed + +Fix this by deriving the expected count dynamically as "2 + !!value_len" +for SET/REPLACE operations. + +Cc: stable@vger.kernel.org # v6.9 +Fixes: ad206ae50eca ("xfs: check opcode and iovec count match in xlog_recover_attri_commit_pass2") +Reviewed-by: Darrick J. Wong +Signed-off-by: Long Li +Reviewed-by: Christoph Hellwig +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/xfs_attr_item.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/xfs/xfs_attr_item.c ++++ b/fs/xfs/xfs_attr_item.c +@@ -1052,8 +1052,8 @@ xlog_recover_attri_commit_pass2( + break; + case XFS_ATTRI_OP_FLAGS_SET: + case XFS_ATTRI_OP_FLAGS_REPLACE: +- /* Log item, attr name, attr value */ +- if (item->ri_total != 3) { ++ /* Log item, attr name, optional attr value */ ++ if (item->ri_total != 2 + !!attri_formatp->alfi_value_len) { + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, + attri_formatp, len); + return -EFSCORRUPTED; diff --git a/queue-6.12/xfs-remove-file_path-tracepoint-data.patch b/queue-6.12/xfs-remove-file_path-tracepoint-data.patch new file mode 100644 index 0000000000..afeb4f5baf --- /dev/null +++ b/queue-6.12/xfs-remove-file_path-tracepoint-data.patch @@ -0,0 +1,91 @@ +From e31c53a8060e134111ed095783fee0aa0c43b080 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Mon, 23 Mar 2026 14:04:33 -0700 +Subject: xfs: remove file_path tracepoint data + +From: Darrick J. Wong + +commit e31c53a8060e134111ed095783fee0aa0c43b080 upstream. + +The xfile/xmbuf shmem file descriptions are no longer as detailed as +they were when online fsck was first merged, because moving to static +strings in commit 60382993a2e180 ("xfs: get rid of the +xchk_xfile_*_descr calls") removed a memory allocation and hence a +source of failure. + +However this makes encoding the description in the tracepoints sort of a +waste of memory. David Laight also points out that file_path doesn't +zero the whole buffer which causes exposure of stale trace bytes, and +Steven Rostedt wonders why we're not using a dynamic array for the file +path. + +I don't think this is worth fixing, so let's just rip it out. + +Cc: rostedt@goodmis.org +Cc: david.laight.linux@gmail.com +Link: https://lore.kernel.org/linux-xfs/20260323172204.work.979-kees@kernel.org/ +Cc: stable@vger.kernel.org # v6.11 +Fixes: 19ebc8f84ea12e ("xfs: fix file_path handling in tracepoints") +Signed-off-by: Darrick J. Wong +Reviewed-by: Carlos Maiolino +Reviewed-by: Christoph Hellwig +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/scrub/trace.h | 12 ++---------- + fs/xfs/xfs_trace.h | 11 ++--------- + 2 files changed, 4 insertions(+), 19 deletions(-) + +--- a/fs/xfs/scrub/trace.h ++++ b/fs/xfs/scrub/trace.h +@@ -959,20 +959,12 @@ TRACE_EVENT(xfile_create, + TP_STRUCT__entry( + __field(dev_t, dev) + __field(unsigned long, ino) +- __array(char, pathname, MAXNAMELEN) + ), + TP_fast_assign( +- char *path; +- + __entry->ino = file_inode(xf->file)->i_ino; +- path = file_path(xf->file, __entry->pathname, MAXNAMELEN); +- if (IS_ERR(path)) +- strncpy(__entry->pathname, "(unknown)", +- sizeof(__entry->pathname)); + ), +- TP_printk("xfino 0x%lx path '%s'", +- __entry->ino, +- __entry->pathname) ++ TP_printk("xfino 0x%lx", ++ __entry->ino) + ); + + TRACE_EVENT(xfile_destroy, +--- a/fs/xfs/xfs_trace.h ++++ b/fs/xfs/xfs_trace.h +@@ -4710,23 +4710,16 @@ TRACE_EVENT(xmbuf_create, + TP_STRUCT__entry( + __field(dev_t, dev) + __field(unsigned long, ino) +- __array(char, pathname, MAXNAMELEN) + ), + TP_fast_assign( +- char *path; + struct file *file = btp->bt_file; + + __entry->dev = btp->bt_mount->m_super->s_dev; + __entry->ino = file_inode(file)->i_ino; +- path = file_path(file, __entry->pathname, MAXNAMELEN); +- if (IS_ERR(path)) +- strncpy(__entry->pathname, "(unknown)", +- sizeof(__entry->pathname)); + ), +- TP_printk("dev %d:%d xmino 0x%lx path '%s'", ++ TP_printk("dev %d:%d xmino 0x%lx", + MAJOR(__entry->dev), MINOR(__entry->dev), +- __entry->ino, +- __entry->pathname) ++ __entry->ino) + ); + + TRACE_EVENT(xmbuf_free, diff --git a/queue-6.12/xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch b/queue-6.12/xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch new file mode 100644 index 0000000000..61d7bca7bc --- /dev/null +++ b/queue-6.12/xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch @@ -0,0 +1,98 @@ +From 394d70b86fae9fe865e7e6d9540b7696f73aa9b6 Mon Sep 17 00:00:00 2001 +From: Yuto Ohnuki +Date: Tue, 10 Mar 2026 18:38:39 +0000 +Subject: xfs: save ailp before dropping the AIL lock in push callbacks + +From: Yuto Ohnuki + +commit 394d70b86fae9fe865e7e6d9540b7696f73aa9b6 upstream. + +In xfs_inode_item_push() and xfs_qm_dquot_logitem_push(), the AIL lock +is dropped to perform buffer IO. Once the cluster buffer no longer +protects the log item from reclaim, the log item may be freed by +background reclaim or the dquot shrinker. The subsequent spin_lock() +call dereferences lip->li_ailp, which is a use-after-free. + +Fix this by saving the ailp pointer in a local variable while the AIL +lock is held and the log item is guaranteed to be valid. + +Reported-by: syzbot+652af2b3c5569c4ab63c@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=652af2b3c5569c4ab63c +Fixes: 90c60e164012 ("xfs: xfs_iflush() is no longer necessary") +Cc: stable@vger.kernel.org # v5.9 +Reviewed-by: Darrick J. Wong +Reviewed-by: Dave Chinner +Signed-off-by: Yuto Ohnuki +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/xfs_dquot_item.c | 9 +++++++-- + fs/xfs/xfs_inode_item.c | 9 +++++++-- + 2 files changed, 14 insertions(+), 4 deletions(-) + +--- a/fs/xfs/xfs_dquot_item.c ++++ b/fs/xfs/xfs_dquot_item.c +@@ -126,6 +126,7 @@ xfs_qm_dquot_logitem_push( + struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip); + struct xfs_dquot *dqp = qlip->qli_dquot; + struct xfs_buf *bp; ++ struct xfs_ail *ailp = lip->li_ailp; + uint rval = XFS_ITEM_SUCCESS; + int error; + +@@ -154,7 +155,7 @@ xfs_qm_dquot_logitem_push( + goto out_unlock; + } + +- spin_unlock(&lip->li_ailp->ail_lock); ++ spin_unlock(&ailp->ail_lock); + + error = xfs_dquot_use_attached_buf(dqp, &bp); + if (error == -EAGAIN) { +@@ -173,9 +174,13 @@ xfs_qm_dquot_logitem_push( + rval = XFS_ITEM_FLUSHING; + } + xfs_buf_relse(bp); ++ /* ++ * The buffer no longer protects the log item from reclaim, so ++ * do not reference lip after this point. ++ */ + + out_relock_ail: +- spin_lock(&lip->li_ailp->ail_lock); ++ spin_lock(&ailp->ail_lock); + out_unlock: + xfs_dqunlock(dqp); + return rval; +--- a/fs/xfs/xfs_inode_item.c ++++ b/fs/xfs/xfs_inode_item.c +@@ -726,6 +726,7 @@ xfs_inode_item_push( + struct xfs_inode_log_item *iip = INODE_ITEM(lip); + struct xfs_inode *ip = iip->ili_inode; + struct xfs_buf *bp = lip->li_buf; ++ struct xfs_ail *ailp = lip->li_ailp; + uint rval = XFS_ITEM_SUCCESS; + int error; + +@@ -748,7 +749,7 @@ xfs_inode_item_push( + if (!xfs_buf_trylock(bp)) + return XFS_ITEM_LOCKED; + +- spin_unlock(&lip->li_ailp->ail_lock); ++ spin_unlock(&ailp->ail_lock); + + /* + * We need to hold a reference for flushing the cluster buffer as it may +@@ -772,7 +773,11 @@ xfs_inode_item_push( + rval = XFS_ITEM_LOCKED; + } + +- spin_lock(&lip->li_ailp->ail_lock); ++ /* ++ * The buffer no longer protects the log item from reclaim, so ++ * do not reference lip after this point. ++ */ ++ spin_lock(&ailp->ail_lock); + return rval; + } + diff --git a/queue-6.12/xfs-scrub-unlock-dquot-before-early-return-in-quota-scrub.patch b/queue-6.12/xfs-scrub-unlock-dquot-before-early-return-in-quota-scrub.patch new file mode 100644 index 0000000000..077f7ad9e9 --- /dev/null +++ b/queue-6.12/xfs-scrub-unlock-dquot-before-early-return-in-quota-scrub.patch @@ -0,0 +1,40 @@ +From 268378b6ad20569af0d1957992de1c8b16c6e900 Mon Sep 17 00:00:00 2001 +From: hongao +Date: Thu, 12 Mar 2026 20:10:26 +0800 +Subject: xfs: scrub: unlock dquot before early return in quota scrub + +From: hongao + +commit 268378b6ad20569af0d1957992de1c8b16c6e900 upstream. + +xchk_quota_item can return early after calling xchk_fblock_process_error. +When that helper returns false, the function returned immediately without +dropping dq->q_qlock, which can leave the dquot lock held and risk lock +leaks or deadlocks in later quota operations. + +Fix this by unlocking dq->q_qlock before the early return. + +Signed-off-by: hongao +Fixes: 7d1f0e167a067e ("xfs: check the ondisk space mapping behind a dquot") +Cc: # v6.8 +Reviewed-by: Darrick J. Wong +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/scrub/quota.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/fs/xfs/scrub/quota.c ++++ b/fs/xfs/scrub/quota.c +@@ -174,8 +174,10 @@ xchk_quota_item( + + error = xchk_quota_item_bmap(sc, dq, offset); + xchk_iunlock(sc, XFS_ILOCK_SHARED); +- if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, offset, &error)) ++ if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, offset, &error)) { ++ mutex_unlock(&dq->q_qlock); + return error; ++ } + + /* + * Warn if the hard limits are larger than the fs. diff --git a/queue-6.12/xfs-stop-reclaim-before-pushing-ail-during-unmount.patch b/queue-6.12/xfs-stop-reclaim-before-pushing-ail-during-unmount.patch new file mode 100644 index 0000000000..1fc10acbdf --- /dev/null +++ b/queue-6.12/xfs-stop-reclaim-before-pushing-ail-during-unmount.patch @@ -0,0 +1,58 @@ +From 4f24a767e3d64a5f58c595b5c29b6063a201f1e3 Mon Sep 17 00:00:00 2001 +From: Yuto Ohnuki +Date: Tue, 10 Mar 2026 18:38:37 +0000 +Subject: xfs: stop reclaim before pushing AIL during unmount + +From: Yuto Ohnuki + +commit 4f24a767e3d64a5f58c595b5c29b6063a201f1e3 upstream. + +The unmount sequence in xfs_unmount_flush_inodes() pushed the AIL while +background reclaim and inodegc are still running. This is broken +independently of any use-after-free issues - background reclaim and +inodegc should not be running while the AIL is being pushed during +unmount, as inodegc can dirty and insert inodes into the AIL during the +flush, and background reclaim can race to abort and free dirty inodes. + +Reorder xfs_unmount_flush_inodes() to stop inodegc and cancel background +reclaim before pushing the AIL. Stop inodegc before cancelling +m_reclaim_work because the inodegc worker can re-queue m_reclaim_work +via xfs_inodegc_set_reclaimable. + +Reported-by: syzbot+652af2b3c5569c4ab63c@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=652af2b3c5569c4ab63c +Fixes: 90c60e164012 ("xfs: xfs_iflush() is no longer necessary") +Cc: stable@vger.kernel.org # v5.9 +Signed-off-by: Yuto Ohnuki +Reviewed-by: Darrick J. Wong +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/xfs_mount.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/fs/xfs/xfs_mount.c ++++ b/fs/xfs/xfs_mount.c +@@ -588,8 +588,9 @@ xfs_unmount_check( + * have been retrying in the background. This will prevent never-ending + * retries in AIL pushing from hanging the unmount. + * +- * Finally, we can push the AIL to clean all the remaining dirty objects, then +- * reclaim the remaining inodes that are still in memory at this point in time. ++ * Stop inodegc and background reclaim before pushing the AIL so that they ++ * are not running while the AIL is being flushed. Then push the AIL to ++ * clean all the remaining dirty objects and reclaim the remaining inodes. + */ + static void + xfs_unmount_flush_inodes( +@@ -601,9 +602,9 @@ xfs_unmount_flush_inodes( + + xfs_set_unmounting(mp); + +- xfs_ail_push_all_sync(mp->m_ail); + xfs_inodegc_stop(mp); + cancel_delayed_work_sync(&mp->m_reclaim_work); ++ xfs_ail_push_all_sync(mp->m_ail); + xfs_reclaim_inodes(mp); + xfs_health_unmount(mp); + }