]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 30 Mar 2026 10:05:32 +0000 (12:05 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 30 Mar 2026 10:05:32 +0000 (12:05 +0200)
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-amd-display-check-if-ext_caps-is-valid-in-bl-setup.patch
drm-amd-display-fix-dce-lvds-handling.patch
drm-amd-display-fix-drm_edid-leak-in-amdgpu_dm.patch
drm-amd-pm-return-eopnotsupp-for-unsupported-od_mclk-on-smu_v13_0_6.patch
drm-amdgpu-fix-strsep-corrupting-lockup_timeout-on-multi-gpu-v3.patch
drm-amdgpu-prevent-immediate-pasid-reuse-case.patch
drm-i915-dp_tunnel-fix-error-handling-when-clearing-stream-bw-in-atomic-state.patch
drm-i915-order-op-vs.-timeout-correctly-in-__wait_for.patch
drm-i915-unlink-nv12-planes-earlier.patch
futex-clear-stale-exiting-pointer-in-futex_lock_pi-retry-path.patch
i2c-designware-amdisp-fix-resume-probe-race-condition-issue.patch
i2c-imx-ensure-no-clock-is-generated-after-last-read.patch
i2c-imx-fix-i2c-issue-when-reading-multiple-messages.patch
iomap-fix-invalid-folio-access-when-i_blkbits-differs-from-i-o-granularity.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
kvm-x86-mmu-only-warn-in-direct-mmus-when-overwriting-shadow-present-spte.patch
loongarch-fix-missing-null-checks-for-kstrdup.patch
loongarch-kvm-fix-base-address-calculation-in-kvm_eiointc_regs_access.patch
loongarch-kvm-handle-the-case-that-eiointc-s-coremap-is-empty.patch
loongarch-kvm-make-kvm_get_vcpu_by_cpuid-more-robust.patch
loongarch-vdso-emit-gnu_eh_frame-correctly.patch
loongarch-workaround-ls2k-ls7a-gpu-dma-hang-bug.patch
mm-damon-sysfs-check-contexts-nr-before-accessing-contexts_arr.patch
mm-damon-sysfs-check-contexts-nr-in-repeat_call_fn.patch
mm-damon-sysfs-fix-param_ctx-leak-on-damon_sysfs_new_test_ctx-failure.patch
mm-huge_memory-fix-folio-isn-t-locked-in-softleaf_to_folio.patch
mm-memory-fix-pmd-pud-checks-in-follow_pfnmap_start.patch
mm-mseal-update-vma-end-correctly-on-merge.patch
mm-pagewalk-fix-race-between-concurrent-split-and-refault.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
ovl-make-fsync-after-metadata-copy-up-opt-in-mount-option.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
writeback-don-t-block-sync-for-filesystems-with-no-data-integrity-guarantees.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
x86-fred-fix-early-boot-failures-on-sev-es-snp-guests.patch
xfs-avoid-dereferencing-log-items-after-push-callbacks.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

55 files changed:
queue-6.19/alarmtimer-fix-argument-order-in-alarm_timer_forward.patch [new file with mode: 0644]
queue-6.19/dmaengine-fsl-edma-fix-channel-parameter-config-for-fixed-channel-requests.patch [new file with mode: 0644]
queue-6.19/dmaengine-sh-rz-dmac-move-chctrl-updates-under-spinlock.patch [new file with mode: 0644]
queue-6.19/dmaengine-sh-rz-dmac-protect-the-driver-specific-lists.patch [new file with mode: 0644]
queue-6.19/drm-amd-display-check-if-ext_caps-is-valid-in-bl-setup.patch [new file with mode: 0644]
queue-6.19/drm-amd-display-fix-dce-lvds-handling.patch [new file with mode: 0644]
queue-6.19/drm-amd-display-fix-drm_edid-leak-in-amdgpu_dm.patch [new file with mode: 0644]
queue-6.19/drm-amd-pm-return-eopnotsupp-for-unsupported-od_mclk-on-smu_v13_0_6.patch [new file with mode: 0644]
queue-6.19/drm-amdgpu-fix-strsep-corrupting-lockup_timeout-on-multi-gpu-v3.patch [new file with mode: 0644]
queue-6.19/drm-amdgpu-prevent-immediate-pasid-reuse-case.patch [new file with mode: 0644]
queue-6.19/drm-i915-dp_tunnel-fix-error-handling-when-clearing-stream-bw-in-atomic-state.patch [new file with mode: 0644]
queue-6.19/drm-i915-order-op-vs.-timeout-correctly-in-__wait_for.patch [new file with mode: 0644]
queue-6.19/drm-i915-unlink-nv12-planes-earlier.patch [new file with mode: 0644]
queue-6.19/futex-clear-stale-exiting-pointer-in-futex_lock_pi-retry-path.patch [new file with mode: 0644]
queue-6.19/i2c-designware-amdisp-fix-resume-probe-race-condition-issue.patch [new file with mode: 0644]
queue-6.19/i2c-imx-ensure-no-clock-is-generated-after-last-read.patch [new file with mode: 0644]
queue-6.19/i2c-imx-fix-i2c-issue-when-reading-multiple-messages.patch [new file with mode: 0644]
queue-6.19/iomap-fix-invalid-folio-access-when-i_blkbits-differs-from-i-o-granularity.patch [new file with mode: 0644]
queue-6.19/irqchip-qcom-mpm-add-missing-mailbox-tx-done-acknowledgment.patch [new file with mode: 0644]
queue-6.19/jbd2-gracefully-abort-on-checkpointing-state-corruptions.patch [new file with mode: 0644]
queue-6.19/kvm-x86-mmu-drop-zap-existing-present-spte-even-when-creating-an-mmio-spte.patch [new file with mode: 0644]
queue-6.19/kvm-x86-mmu-only-warn-in-direct-mmus-when-overwriting-shadow-present-spte.patch [new file with mode: 0644]
queue-6.19/loongarch-fix-missing-null-checks-for-kstrdup.patch [new file with mode: 0644]
queue-6.19/loongarch-kvm-fix-base-address-calculation-in-kvm_eiointc_regs_access.patch [new file with mode: 0644]
queue-6.19/loongarch-kvm-handle-the-case-that-eiointc-s-coremap-is-empty.patch [new file with mode: 0644]
queue-6.19/loongarch-kvm-make-kvm_get_vcpu_by_cpuid-more-robust.patch [new file with mode: 0644]
queue-6.19/loongarch-vdso-emit-gnu_eh_frame-correctly.patch [new file with mode: 0644]
queue-6.19/loongarch-workaround-ls2k-ls7a-gpu-dma-hang-bug.patch [new file with mode: 0644]
queue-6.19/mm-damon-sysfs-check-contexts-nr-before-accessing-contexts_arr.patch [new file with mode: 0644]
queue-6.19/mm-damon-sysfs-check-contexts-nr-in-repeat_call_fn.patch [new file with mode: 0644]
queue-6.19/mm-damon-sysfs-fix-param_ctx-leak-on-damon_sysfs_new_test_ctx-failure.patch [new file with mode: 0644]
queue-6.19/mm-huge_memory-fix-folio-isn-t-locked-in-softleaf_to_folio.patch [new file with mode: 0644]
queue-6.19/mm-memory-fix-pmd-pud-checks-in-follow_pfnmap_start.patch [new file with mode: 0644]
queue-6.19/mm-mseal-update-vma-end-correctly-on-merge.patch [new file with mode: 0644]
queue-6.19/mm-pagewalk-fix-race-between-concurrent-split-and-refault.patch [new file with mode: 0644]
queue-6.19/net-macb-move-devm_-free-request-_irq-out-of-spin-lock-area.patch [new file with mode: 0644]
queue-6.19/net-macb-protect-access-to-net_device-ip_ptr-with-rcu-lock.patch [new file with mode: 0644]
queue-6.19/net-macb-use-dev_consume_skb_any-to-free-tx-skbs.patch [new file with mode: 0644]
queue-6.19/ovl-fix-wrong-detection-of-32bit-inode-numbers.patch [new file with mode: 0644]
queue-6.19/ovl-make-fsync-after-metadata-copy-up-opt-in-mount-option.patch [new file with mode: 0644]
queue-6.19/phy-qcom-qmp-ufs-fix-sm8650-pcs-table-for-gear-4.patch [new file with mode: 0644]
queue-6.19/scsi-ibmvfc-fix-oob-access-in-ibmvfc_discover_targets_done.patch [new file with mode: 0644]
queue-6.19/scsi-ses-handle-positive-scsi-error-from-ses_recv_diag.patch [new file with mode: 0644]
queue-6.19/series
queue-6.19/writeback-don-t-block-sync-for-filesystems-with-no-data-integrity-guarantees.patch [new file with mode: 0644]
queue-6.19/x86-cpu-enable-fsgsbase-early-in-cpu_init_exception_handling.patch [new file with mode: 0644]
queue-6.19/x86-cpu-remove-x86_cr4_fred-from-the-cr4-pinned-bits-mask.patch [new file with mode: 0644]
queue-6.19/x86-fred-fix-early-boot-failures-on-sev-es-snp-guests.patch [new file with mode: 0644]
queue-6.19/xfs-avoid-dereferencing-log-items-after-push-callbacks.patch [new file with mode: 0644]
queue-6.19/xfs-don-t-irele-after-failing-to-iget-in-xfs_attri_recover_work.patch [new file with mode: 0644]
queue-6.19/xfs-fix-ri_total-validation-in-xlog_recover_attri_commit_pass2.patch [new file with mode: 0644]
queue-6.19/xfs-remove-file_path-tracepoint-data.patch [new file with mode: 0644]
queue-6.19/xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch [new file with mode: 0644]
queue-6.19/xfs-scrub-unlock-dquot-before-early-return-in-quota-scrub.patch [new file with mode: 0644]
queue-6.19/xfs-stop-reclaim-before-pushing-ail-during-unmount.patch [new file with mode: 0644]

diff --git a/queue-6.19/alarmtimer-fix-argument-order-in-alarm_timer_forward.patch b/queue-6.19/alarmtimer-fix-argument-order-in-alarm_timer_forward.patch
new file mode 100644 (file)
index 0000000..17e7892
--- /dev/null
@@ -0,0 +1,51 @@
+From 5d16467ae56343b9205caedf85e3a131e0914ad8 Mon Sep 17 00:00:00 2001
+From: Zhan Xusheng <zhanxusheng1024@gmail.com>
+Date: Mon, 23 Mar 2026 14:11:30 +0800
+Subject: alarmtimer: Fix argument order in alarm_timer_forward()
+
+From: Zhan Xusheng <zhanxusheng1024@gmail.com>
+
+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 <zhanxusheng@xiaomi.com>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260323061130.29991-1-zhanxusheng@xiaomi.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/time/alarmtimer.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/time/alarmtimer.c
++++ b/kernel/time/alarmtimer.c
+@@ -540,7 +540,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.19/dmaengine-fsl-edma-fix-channel-parameter-config-for-fixed-channel-requests.patch b/queue-6.19/dmaengine-fsl-edma-fix-channel-parameter-config-for-fixed-channel-requests.patch
new file mode 100644 (file)
index 0000000..dd4eb7a
--- /dev/null
@@ -0,0 +1,75 @@
+From 2e7b5cf72e51c9cf9c8b75190189c757df31ddd9 Mon Sep 17 00:00:00 2001
+From: Joy Zou <joy.zou@nxp.com>
+Date: Wed, 17 Sep 2025 17:53:42 +0800
+Subject: dmaengine: fsl-edma: fix channel parameter config for fixed channel requests
+
+From: Joy Zou <joy.zou@nxp.com>
+
+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 <joy.zou@nxp.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20250917-b4-edma-chanconf-v1-1-886486e02e91@nxp.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -317,10 +317,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;
+@@ -328,17 +326,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.19/dmaengine-sh-rz-dmac-move-chctrl-updates-under-spinlock.patch b/queue-6.19/dmaengine-sh-rz-dmac-move-chctrl-updates-under-spinlock.patch
new file mode 100644 (file)
index 0000000..d564fdf
--- /dev/null
@@ -0,0 +1,67 @@
+From 89a8567d84bde88cb7cdbbac2ab2299c4f991490 Mon Sep 17 00:00:00 2001
+From: Claudiu Beznea <claudiu.beznea@tuxon.dev>
+Date: Mon, 16 Mar 2026 15:32:46 +0200
+Subject: dmaengine: sh: rz-dmac: Move CHCTRL updates under spinlock
+
+From: Claudiu Beznea <claudiu.beznea@tuxon.dev>
+
+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 <biju.das.jz@bp.renesas.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Link: https://patch.msgid.link/20260316133252.240348-3-claudiu.beznea.uj@bp.renesas.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -298,13 +298,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)
+@@ -569,8 +566,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;
+@@ -707,7 +704,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.19/dmaengine-sh-rz-dmac-protect-the-driver-specific-lists.patch b/queue-6.19/dmaengine-sh-rz-dmac-protect-the-driver-specific-lists.patch
new file mode 100644 (file)
index 0000000..5365af9
--- /dev/null
@@ -0,0 +1,126 @@
+From abb863e6213dc41a58ef8bb3289b7e77460dabf3 Mon Sep 17 00:00:00 2001
+From: Claudiu Beznea <claudiu.beznea@tuxon.dev>
+Date: Mon, 16 Mar 2026 15:32:45 +0200
+Subject: dmaengine: sh: rz-dmac: Protect the driver specific lists
+
+From: Claudiu Beznea <claudiu.beznea@tuxon.dev>
+
+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 <Frank.Li@nxp.com>
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Link: https://patch.msgid.link/20260316133252.240348-2-claudiu.beznea.uj@bp.renesas.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 <linux/bitfield.h>
++#include <linux/cleanup.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/dmaengine.h>
+ #include <linux/interrupt.h>
+@@ -448,6 +449,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++;
+       }
+@@ -503,18 +505,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);
+ }
+@@ -530,27 +535,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.19/drm-amd-display-check-if-ext_caps-is-valid-in-bl-setup.patch b/queue-6.19/drm-amd-display-check-if-ext_caps-is-valid-in-bl-setup.patch
new file mode 100644 (file)
index 0000000..d1b0154
--- /dev/null
@@ -0,0 +1,35 @@
+From 9da4f9964abcaeb6e19797d5e3b10faad338a786 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Fri, 20 Mar 2026 12:33:48 -0400
+Subject: drm/amd/display: check if ext_caps is valid in BL setup
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 9da4f9964abcaeb6e19797d5e3b10faad338a786 upstream.
+
+LVDS connectors don't have extended backlight caps so check
+if the pointer is valid before accessing it.
+
+Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/5012
+Fixes: 1454642960b0 ("drm/amd: Re-introduce property to control adaptive backlight modulation")
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 3f797396d7f4eb9bb6eded184bbc6f033628a6f6)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -5406,7 +5406,7 @@ static void setup_backlight_device(struc
+       caps = &dm->backlight_caps[aconnector->bl_idx];
+       /* Only offer ABM property when non-OLED and user didn't turn off by module parameter */
+-      if (!caps->ext_caps->bits.oled && amdgpu_dm_abm_level < 0)
++      if (caps->ext_caps && !caps->ext_caps->bits.oled && amdgpu_dm_abm_level < 0)
+               drm_object_attach_property(&aconnector->base.base,
+                                          dm->adev->mode_info.abm_level_property,
+                                          ABM_SYSFS_CONTROL);
diff --git a/queue-6.19/drm-amd-display-fix-dce-lvds-handling.patch b/queue-6.19/drm-amd-display-fix-dce-lvds-handling.patch
new file mode 100644 (file)
index 0000000..a122a8f
--- /dev/null
@@ -0,0 +1,165 @@
+From 90d239cc53723c1a3f89ce08eac17bf3a9e9f2d4 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Thu, 26 Feb 2026 17:12:08 -0500
+Subject: drm/amd/display: Fix DCE LVDS handling
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 90d239cc53723c1a3f89ce08eac17bf3a9e9f2d4 upstream.
+
+LVDS does not use an HPD pin so it may be invalid.  Handle
+this case correctly in link encoder creation.
+
+Fixes: 7c8fb3b8e9ba ("drm/amd/display: Add hpd_source index check for DCE60/80/100/110/112/120 link encoders")
+Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/5012
+Cc: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Cc: Roman Li <roman.li@amd.com>
+Reviewed-by: Roman Li <roman.li@amd.com>
+Reviewed-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 3b5620f7ee688177fcf65cf61588c5435bce1872)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c |    6 +---
+ drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c |    5 ++-
+ drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c |    5 ++-
+ drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c |    5 ++-
+ drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c   |   14 ++++------
+ drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c   |    6 +---
+ 6 files changed, 19 insertions(+), 22 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
+@@ -651,9 +651,6 @@ static struct link_encoder *dce100_link_
+               return &enc110->base;
+       }
+-      if (enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs))
+-              return NULL;
+-
+       link_regs_id =
+               map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
+@@ -662,7 +659,8 @@ static struct link_encoder *dce100_link_
+                                     &link_enc_feature,
+                                     &link_enc_regs[link_regs_id],
+                                     &link_enc_aux_regs[enc_init_data->channel - 1],
+-                                    &link_enc_hpd_regs[enc_init_data->hpd_source]);
++                                    enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ?
++                                    NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]);
+       return &enc110->base;
+ }
+--- a/drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c
+@@ -672,7 +672,7 @@ static struct link_encoder *dce110_link_
+               kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
+       int link_regs_id;
+-      if (!enc110 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs))
++      if (!enc110)
+               return NULL;
+       link_regs_id =
+@@ -683,7 +683,8 @@ static struct link_encoder *dce110_link_
+                                     &link_enc_feature,
+                                     &link_enc_regs[link_regs_id],
+                                     &link_enc_aux_regs[enc_init_data->channel - 1],
+-                                    &link_enc_hpd_regs[enc_init_data->hpd_source]);
++                                    enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ?
++                                    NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]);
+       return &enc110->base;
+ }
+--- a/drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c
+@@ -633,7 +633,7 @@ static struct link_encoder *dce112_link_
+               kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
+       int link_regs_id;
+-      if (!enc110 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs))
++      if (!enc110)
+               return NULL;
+       link_regs_id =
+@@ -644,7 +644,8 @@ static struct link_encoder *dce112_link_
+                                     &link_enc_feature,
+                                     &link_enc_regs[link_regs_id],
+                                     &link_enc_aux_regs[enc_init_data->channel - 1],
+-                                    &link_enc_hpd_regs[enc_init_data->hpd_source]);
++                                    enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ?
++                                    NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]);
+       return &enc110->base;
+ }
+--- a/drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c
+@@ -717,7 +717,7 @@ static struct link_encoder *dce120_link_
+               kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
+       int link_regs_id;
+-      if (!enc110 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs))
++      if (!enc110)
+               return NULL;
+       link_regs_id =
+@@ -728,7 +728,8 @@ static struct link_encoder *dce120_link_
+                                     &link_enc_feature,
+                                     &link_enc_regs[link_regs_id],
+                                     &link_enc_aux_regs[enc_init_data->channel - 1],
+-                                    &link_enc_hpd_regs[enc_init_data->hpd_source]);
++                                    enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ?
++                                    NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]);
+       return &enc110->base;
+ }
+--- a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
+@@ -747,18 +747,16 @@ static struct link_encoder *dce60_link_e
+               return &enc110->base;
+       }
+-      if (enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs))
+-              return NULL;
+-
+       link_regs_id =
+               map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
+       dce60_link_encoder_construct(enc110,
+-                                    enc_init_data,
+-                                    &link_enc_feature,
+-                                    &link_enc_regs[link_regs_id],
+-                                    &link_enc_aux_regs[enc_init_data->channel - 1],
+-                                    &link_enc_hpd_regs[enc_init_data->hpd_source]);
++                                   enc_init_data,
++                                   &link_enc_feature,
++                                   &link_enc_regs[link_regs_id],
++                                   &link_enc_aux_regs[enc_init_data->channel - 1],
++                                   enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ?
++                                   NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]);
+       return &enc110->base;
+ }
+--- a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c
+@@ -753,9 +753,6 @@ static struct link_encoder *dce80_link_e
+               return &enc110->base;
+       }
+-      if (enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs))
+-              return NULL;
+-
+       link_regs_id =
+               map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
+@@ -764,7 +761,8 @@ static struct link_encoder *dce80_link_e
+                                     &link_enc_feature,
+                                     &link_enc_regs[link_regs_id],
+                                     &link_enc_aux_regs[enc_init_data->channel - 1],
+-                                    &link_enc_hpd_regs[enc_init_data->hpd_source]);
++                                    enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ?
++                                    NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]);
+       return &enc110->base;
+ }
diff --git a/queue-6.19/drm-amd-display-fix-drm_edid-leak-in-amdgpu_dm.patch b/queue-6.19/drm-amd-display-fix-drm_edid-leak-in-amdgpu_dm.patch
new file mode 100644 (file)
index 0000000..7f47cd8
--- /dev/null
@@ -0,0 +1,40 @@
+From 37c2caa167b0b8aca4f74c32404c5288b876a2a3 Mon Sep 17 00:00:00 2001
+From: Alex Hung <alex.hung@amd.com>
+Date: Mon, 9 Mar 2026 11:16:08 -0600
+Subject: drm/amd/display: Fix drm_edid leak in amdgpu_dm
+
+From: Alex Hung <alex.hung@amd.com>
+
+commit 37c2caa167b0b8aca4f74c32404c5288b876a2a3 upstream.
+
+[WHAT]
+When a sink is connected, aconnector->drm_edid was overwritten without
+freeing the previous allocation, causing a memory leak on resume.
+
+[HOW]
+Free the previous drm_edid before updating it.
+
+Reviewed-by: Roman Li <roman.li@amd.com>
+Signed-off-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Chuanyu Tseng <chuanyu.tseng@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 52024a94e7111366141cfc5d888b2ef011f879e5)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -3891,8 +3891,9 @@ void amdgpu_dm_update_connector_after_de
+               aconnector->dc_sink = sink;
+               dc_sink_retain(aconnector->dc_sink);
++              drm_edid_free(aconnector->drm_edid);
++              aconnector->drm_edid = NULL;
+               if (sink->dc_edid.length == 0) {
+-                      aconnector->drm_edid = NULL;
+                       hdmi_cec_unset_edid(aconnector);
+                       if (aconnector->dc_link->aux_mode) {
+                               drm_dp_cec_unset_edid(&aconnector->dm_dp_aux.aux);
diff --git a/queue-6.19/drm-amd-pm-return-eopnotsupp-for-unsupported-od_mclk-on-smu_v13_0_6.patch b/queue-6.19/drm-amd-pm-return-eopnotsupp-for-unsupported-od_mclk-on-smu_v13_0_6.patch
new file mode 100644 (file)
index 0000000..8093175
--- /dev/null
@@ -0,0 +1,35 @@
+From 2f0e491faee43181b6a86e90f34016b256042fe1 Mon Sep 17 00:00:00 2001
+From: Asad Kamal <asad.kamal@amd.com>
+Date: Wed, 18 Mar 2026 13:52:57 +0800
+Subject: drm/amd/pm: Return -EOPNOTSUPP for unsupported OD_MCLK on smu_v13_0_6
+
+From: Asad Kamal <asad.kamal@amd.com>
+
+commit 2f0e491faee43181b6a86e90f34016b256042fe1 upstream.
+
+When SET_UCLK_MAX capability is absent, return -EOPNOTSUPP from
+smu_v13_0_6_emit_clk_levels() for OD_MCLK instead of 0. This makes
+unsupported OD_MCLK reporting consistent with other clock types
+and allows callers to skip the entry cleanly.
+
+Signed-off-by: Asad Kamal <asad.kamal@amd.com>
+Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit d82e0a72d9189e8acd353988e1a57f85ce479e37)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
+@@ -1520,7 +1520,7 @@ static int smu_v13_0_6_print_clk_levels(
+       case SMU_OD_MCLK:
+               if (!smu_v13_0_6_cap_supported(smu, SMU_CAP(SET_UCLK_MAX)))
+-                      return 0;
++                      return -EOPNOTSUPP;
+               size += sysfs_emit_at(buf, size, "%s:\n", "OD_MCLK");
+               size += sysfs_emit_at(buf, size, "0: %uMhz\n1: %uMhz\n",
diff --git a/queue-6.19/drm-amdgpu-fix-strsep-corrupting-lockup_timeout-on-multi-gpu-v3.patch b/queue-6.19/drm-amdgpu-fix-strsep-corrupting-lockup_timeout-on-multi-gpu-v3.patch
new file mode 100644 (file)
index 0000000..e37a97b
--- /dev/null
@@ -0,0 +1,79 @@
+From 2d300ebfc411205fa31ba7741c5821d381912381 Mon Sep 17 00:00:00 2001
+From: Ruijing Dong <ruijing.dong@amd.com>
+Date: Tue, 17 Mar 2026 13:54:11 -0400
+Subject: drm/amdgpu: fix strsep() corrupting lockup_timeout on multi-GPU (v3)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ruijing Dong <ruijing.dong@amd.com>
+
+commit 2d300ebfc411205fa31ba7741c5821d381912381 upstream.
+
+amdgpu_device_get_job_timeout_settings() passes a pointer directly
+to the global amdgpu_lockup_timeout[] buffer into strsep().
+strsep() destructively replaces delimiter characters with '\0'
+in-place.
+
+On multi-GPU systems, this function is called once per device.
+When a multi-value setting like "0,0,0,-1" is used, the first
+GPU's call transforms the global buffer into "0\00\00\0-1". The
+second GPU then sees only "0" (terminated at the first '\0'),
+parses a single value, hits the single-value fallthrough
+(index == 1), and applies timeout=0 to all rings â€” causing
+immediate false job timeouts.
+
+Fix this by copying into a stack-local array before calling
+strsep(), so the global module parameter buffer remains intact
+across calls. The buffer is AMDGPU_MAX_TIMEOUT_PARAM_LENGTH
+(256) bytes, which is safe for the stack.
+
+v2: wrap commit message to 72 columns, add Assisted-by tag.
+v3: use stack array with strscpy() instead of kstrdup()/kfree()
+    to avoid unnecessary heap allocation (Christian).
+
+This patch was developed with assistance from Claude (claude-opus-4-6).
+
+Assisted-by: Claude:claude-opus-4-6
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Ruijing Dong <ruijing.dong@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 94d79f51efecb74be1d88dde66bdc8bfcca17935)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |   13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -4361,7 +4361,8 @@ fail:
+ static int amdgpu_device_get_job_timeout_settings(struct amdgpu_device *adev)
+ {
+-      char *input = amdgpu_lockup_timeout;
++      char buf[AMDGPU_MAX_TIMEOUT_PARAM_LENGTH];
++      char *input = buf;
+       char *timeout_setting = NULL;
+       int index = 0;
+       long timeout;
+@@ -4371,9 +4372,17 @@ static int amdgpu_device_get_job_timeout
+       adev->gfx_timeout = adev->compute_timeout = adev->sdma_timeout =
+               adev->video_timeout = msecs_to_jiffies(2000);
+-      if (!strnlen(input, AMDGPU_MAX_TIMEOUT_PARAM_LENGTH))
++      if (!strnlen(amdgpu_lockup_timeout, AMDGPU_MAX_TIMEOUT_PARAM_LENGTH))
+               return 0;
++      /*
++       * strsep() destructively modifies its input by replacing delimiters
++       * with '\0'. Use a stack copy so the global module parameter buffer
++       * remains intact for multi-GPU systems where this function is called
++       * once per device.
++       */
++      strscpy(buf, amdgpu_lockup_timeout, sizeof(buf));
++
+       while ((timeout_setting = strsep(&input, ",")) &&
+              strnlen(timeout_setting, AMDGPU_MAX_TIMEOUT_PARAM_LENGTH)) {
+               ret = kstrtol(timeout_setting, 0, &timeout);
diff --git a/queue-6.19/drm-amdgpu-prevent-immediate-pasid-reuse-case.patch b/queue-6.19/drm-amdgpu-prevent-immediate-pasid-reuse-case.patch
new file mode 100644 (file)
index 0000000..396c4b2
--- /dev/null
@@ -0,0 +1,132 @@
+From 14b81abe7bdc25f8097906fc2f91276ffedb2d26 Mon Sep 17 00:00:00 2001
+From: Eric Huang <jinhuieric.huang@amd.com>
+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 <jinhuieric.huang@amd.com>
+
+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 <jinhuieric.huang@amd.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 8f1de51f49be692de137c8525106e0fce2d1912d)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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,
+@@ -616,3 +623,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
+@@ -74,6 +74,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
+@@ -2898,6 +2898,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.19/drm-i915-dp_tunnel-fix-error-handling-when-clearing-stream-bw-in-atomic-state.patch b/queue-6.19/drm-i915-dp_tunnel-fix-error-handling-when-clearing-stream-bw-in-atomic-state.patch
new file mode 100644 (file)
index 0000000..e4946db
--- /dev/null
@@ -0,0 +1,131 @@
+From 77fcf58df15edcf3f5b5421f24814fb72796def9 Mon Sep 17 00:00:00 2001
+From: Imre Deak <imre.deak@intel.com>
+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 <imre.deak@intel.com>
+
+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 <uma.shankar@intel.com>
+Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Cc: <stable@vger.kernel.org> # 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 <michal.grzelak@intel.com>
+Reviewed-by: Uma Shankar <uma.shankar@intel.com>
+Signed-off-by: Imre Deak <imre.deak@intel.com>
+Link: https://patch.msgid.link/20260320092900.13210-1-imre.deak@intel.com
+(cherry picked from commit fb69d0076e687421188bc8103ab0e8e5825b1df1)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -4578,6 +4578,7 @@ intel_crtc_prepare_cleared_state(struct
+       struct intel_crtc_state *crtc_state =
+               intel_atomic_get_new_crtc_state(state, crtc);
+       struct intel_crtc_state *saved_state;
++      int err;
+       saved_state = intel_crtc_state_alloc(crtc);
+       if (!saved_state)
+@@ -4586,7 +4587,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
+@@ -40,8 +40,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);
+@@ -88,9 +88,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.19/drm-i915-order-op-vs.-timeout-correctly-in-__wait_for.patch b/queue-6.19/drm-i915-order-op-vs.-timeout-correctly-in-__wait_for.patch
new file mode 100644 (file)
index 0000000..c17a013
--- /dev/null
@@ -0,0 +1,53 @@
+From 6ad2a661ff0d3d94884947d2a593311ba46d34c2 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
+Date: Fri, 13 Mar 2026 13:07:40 +0200
+Subject: drm/i915: Order OP vs. timeout correctly in __wait_for()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+
+commit 6ad2a661ff0d3d94884947d2a593311ba46d34c2 upstream.
+
+Put the barrier() before the OP so that anything we read out in
+OP and check in COND will actually be read out after the timeout
+has been evaluated.
+
+Currently the only place where we use OP is __intel_wait_for_register(),
+but the use there is precisely susceptible to this reordering, assuming
+the ktime_*() stuff itself doesn't act as a sufficient barrier:
+
+__intel_wait_for_register(...)
+{
+       ...
+       ret = __wait_for(reg_value = intel_uncore_read_notrace(...),
+                        (reg_value & mask) == value, ...);
+       ...
+}
+
+Cc: stable@vger.kernel.org
+Fixes: 1c3c1dc66a96 ("drm/i915: Add compiler barrier to wait_for")
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Link: https://patch.msgid.link/20260313110740.24620-1-ville.syrjala@linux.intel.com
+Reviewed-by: Jani Nikula <jani.nikula@intel.com>
+(cherry picked from commit a464bace0482aa9a83e9aa7beefbaf44cd58e6cf)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i915/i915_wait_util.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i915/i915_wait_util.h
++++ b/drivers/gpu/drm/i915/i915_wait_util.h
+@@ -25,9 +25,9 @@
+       might_sleep();                                                  \
+       for (;;) {                                                      \
+               const bool expired__ = ktime_after(ktime_get_raw(), end__); \
+-              OP;                                                     \
+               /* Guarantee COND check prior to timeout */             \
+               barrier();                                              \
++              OP;                                                     \
+               if (COND) {                                             \
+                       ret__ = 0;                                      \
+                       break;                                          \
diff --git a/queue-6.19/drm-i915-unlink-nv12-planes-earlier.patch b/queue-6.19/drm-i915-unlink-nv12-planes-earlier.patch
new file mode 100644 (file)
index 0000000..7050191
--- /dev/null
@@ -0,0 +1,85 @@
+From bfa71b7a9dc6b5b8af157686e03308291141d00c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
+Date: Mon, 16 Mar 2026 18:39:51 +0200
+Subject: drm/i915: Unlink NV12 planes earlier
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+
+commit bfa71b7a9dc6b5b8af157686e03308291141d00c upstream.
+
+unlink_nv12_plane() will clobber parts of the plane state
+potentially already set up by plane_atomic_check(), so we
+must make sure not to call the two in the wrong order.
+The problem happens when a plane previously selected as
+a Y plane is now configured as a normal plane by user space.
+plane_atomic_check() will first compute the proper plane
+state based on the userspace request, and unlink_nv12_plane()
+later clears some of the state.
+
+This used to work on account of unlink_nv12_plane() skipping
+the state clearing based on the plane visibility. But I removed
+that check, thinking it was an impossible situation. Now when
+that situation happens unlink_nv12_plane() will just WARN
+and proceed to clobber the state.
+
+Rather than reverting to the old way of doing things, I think
+it's more clear if we unlink the NV12 planes before we even
+compute the new plane state.
+
+Cc: stable@vger.kernel.org
+Reported-by: Khaled Almahallawy <khaled.almahallawy@intel.com>
+Closes: https://lore.kernel.org/intel-gfx/20260212004852.1920270-1-khaled.almahallawy@intel.com/
+Tested-by: Khaled Almahallawy <khaled.almahallawy@intel.com>
+Fixes: 6a01df2f1b2a ("drm/i915: Remove pointless visible check in unlink_nv12_plane()")
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Link: https://patch.msgid.link/20260316163953.12905-2-ville.syrjala@linux.intel.com
+Reviewed-by: Uma Shankar <uma.shankar@intel.com>
+(cherry picked from commit 017ecd04985573eeeb0745fa2c23896fb22ee0cc)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i915/display/intel_plane.c |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/i915/display/intel_plane.c
++++ b/drivers/gpu/drm/i915/display/intel_plane.c
+@@ -433,11 +433,16 @@ void intel_plane_copy_hw_state(struct in
+               drm_framebuffer_get(plane_state->hw.fb);
+ }
++static void unlink_nv12_plane(struct intel_crtc_state *crtc_state,
++                            struct intel_plane_state *plane_state);
++
+ void intel_plane_set_invisible(struct intel_crtc_state *crtc_state,
+                              struct intel_plane_state *plane_state)
+ {
+       struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
++      unlink_nv12_plane(crtc_state, plane_state);
++
+       crtc_state->active_planes &= ~BIT(plane->id);
+       crtc_state->scaled_planes &= ~BIT(plane->id);
+       crtc_state->nv12_planes &= ~BIT(plane->id);
+@@ -1511,6 +1516,9 @@ static void unlink_nv12_plane(struct int
+       struct intel_display *display = to_intel_display(plane_state);
+       struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
++      if (!plane_state->planar_linked_plane)
++              return;
++
+       plane_state->planar_linked_plane = NULL;
+       if (!plane_state->is_y_plane)
+@@ -1548,8 +1556,7 @@ static int icl_check_nv12_planes(struct
+               if (plane->pipe != crtc->pipe)
+                       continue;
+-              if (plane_state->planar_linked_plane)
+-                      unlink_nv12_plane(crtc_state, plane_state);
++              unlink_nv12_plane(crtc_state, plane_state);
+       }
+       if (!crtc_state->nv12_planes)
diff --git a/queue-6.19/futex-clear-stale-exiting-pointer-in-futex_lock_pi-retry-path.patch b/queue-6.19/futex-clear-stale-exiting-pointer-in-futex_lock_pi-retry-path.patch
new file mode 100644 (file)
index 0000000..ce31817
--- /dev/null
@@ -0,0 +1,76 @@
+From 210d36d892de5195e6766c45519dfb1e65f3eb83 Mon Sep 17 00:00:00 2001
+From: Davidlohr Bueso <dave@stgolabs.net>
+Date: Wed, 25 Mar 2026 17:17:59 -0700
+Subject: futex: Clear stale exiting pointer in futex_lock_pi() retry path
+
+From: Davidlohr Bueso <dave@stgolabs.net>
+
+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 <dave@stgolabs.net>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260326001759.4129680-1-dave@stgolabs.net
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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_q q = futex_q_init;
+       DEFINE_WAKE_Q(wake_q);
+@@ -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.19/i2c-designware-amdisp-fix-resume-probe-race-condition-issue.patch b/queue-6.19/i2c-designware-amdisp-fix-resume-probe-race-condition-issue.patch
new file mode 100644 (file)
index 0000000..744292b
--- /dev/null
@@ -0,0 +1,78 @@
+From e2f1ada8e089dd5a331bcd8b88125ae2af8d188f Mon Sep 17 00:00:00 2001
+From: Pratap Nirujogi <pratap.nirujogi@amd.com>
+Date: Fri, 20 Mar 2026 16:12:22 -0400
+Subject: i2c: designware: amdisp: Fix resume-probe race condition issue
+
+From: Pratap Nirujogi <pratap.nirujogi@amd.com>
+
+commit e2f1ada8e089dd5a331bcd8b88125ae2af8d188f upstream.
+
+Identified resume-probe race condition in kernel v7.0 with the commit
+38fa29b01a6a ("i2c: designware: Combine the init functions"),but this
+issue existed from the beginning though not detected.
+
+The amdisp i2c device requires ISP to be in power-on state for probe
+to succeed. To meet this requirement, this device is added to genpd
+to control ISP power using runtime PM. The pm_runtime_get_sync() called
+before i2c_dw_probe() triggers PM resume, which powers on ISP and also
+invokes the amdisp i2c runtime resume before the probe completes resulting
+in this race condition and a NULL dereferencing issue in v7.0
+
+Fix this race condition by using the genpd APIs directly during probe:
+  - Call dev_pm_genpd_resume() to Power ON ISP before probe
+  - Call dev_pm_genpd_suspend() to Power OFF ISP after probe
+  - Set the device to suspended state with pm_runtime_set_suspended()
+  - Enable runtime PM only after the device is fully initialized
+
+Fixes: d6263c468a761 ("i2c: amd-isp: Add ISP i2c-designware driver")
+Co-developed-by: Bin Du <bin.du@amd.com>
+Signed-off-by: Bin Du <bin.du@amd.com>
+Signed-off-by: Pratap Nirujogi <pratap.nirujogi@amd.com>
+Cc: <stable@vger.kernel.org> # v6.16+
+Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
+Link: https://lore.kernel.org/r/20260320201302.3490570-1-pratap.nirujogi@amd.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/i2c/busses/i2c-designware-amdisp.c |   11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-designware-amdisp.c
++++ b/drivers/i2c/busses/i2c-designware-amdisp.c
+@@ -7,6 +7,7 @@
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
++#include <linux/pm_domain.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/soc/amd/isp4_misc.h>
+@@ -82,22 +83,20 @@ static int amd_isp_dw_i2c_plat_probe(str
+       if (isp_i2c_dev->shared_with_punit)
+               pm_runtime_get_noresume(&pdev->dev);
+-      pm_runtime_enable(&pdev->dev);
+-      pm_runtime_get_sync(&pdev->dev);
+-
++      dev_pm_genpd_resume(&pdev->dev);
+       ret = i2c_dw_probe(isp_i2c_dev);
+       if (ret) {
+               dev_err_probe(&pdev->dev, ret, "i2c_dw_probe failed\n");
+               goto error_release_rpm;
+       }
+-
+-      pm_runtime_put_sync(&pdev->dev);
++      dev_pm_genpd_suspend(&pdev->dev);
++      pm_runtime_set_suspended(&pdev->dev);
++      pm_runtime_enable(&pdev->dev);
+       return 0;
+ error_release_rpm:
+       amd_isp_dw_i2c_plat_pm_cleanup(isp_i2c_dev);
+-      pm_runtime_put_sync(&pdev->dev);
+       return ret;
+ }
diff --git a/queue-6.19/i2c-imx-ensure-no-clock-is-generated-after-last-read.patch b/queue-6.19/i2c-imx-ensure-no-clock-is-generated-after-last-read.patch
new file mode 100644 (file)
index 0000000..e4dbf89
--- /dev/null
@@ -0,0 +1,131 @@
+From 13101db735bdb29c5f60e95fb578690bd178b30f Mon Sep 17 00:00:00 2001
+From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
+Date: Wed, 18 Feb 2026 16:08:50 +0100
+Subject: i2c: imx: ensure no clock is generated after last read
+
+From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
+
+commit 13101db735bdb29c5f60e95fb578690bd178b30f upstream.
+
+When reading from the I2DR register, right after releasing the bus by
+clearing MSTA and MTX, the I2C controller might still generate an
+additional clock cycle which can cause devices to misbehave. Ensure to
+only read from I2DR after the bus is not busy anymore. Because this
+requires polling, the read of the last byte is moved outside of the
+interrupt handler.
+
+An example for such a failing transfer is this:
+i2ctransfer -y -a 0 w1@0x00 0x02 r1
+Error: Sending messages failed: Connection timed out
+It does not happen with every device because not all devices react to
+the additional clock cycle.
+
+Fixes: 5f5c2d4579ca ("i2c: imx: prevent rescheduling in non dma mode")
+Cc: stable@vger.kernel.org # v6.13+
+Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
+Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
+Link: https://lore.kernel.org/r/20260218150940.131354-3-eichest@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/i2c/busses/i2c-imx.c |   51 ++++++++++++++++++++++++++-----------------
+ 1 file changed, 32 insertions(+), 19 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-imx.c
++++ b/drivers/i2c/busses/i2c-imx.c
+@@ -1018,8 +1018,9 @@ static inline int i2c_imx_isr_read(struc
+       return 0;
+ }
+-static inline void i2c_imx_isr_read_continue(struct imx_i2c_struct *i2c_imx)
++static inline enum imx_i2c_state i2c_imx_isr_read_continue(struct imx_i2c_struct *i2c_imx)
+ {
++      enum imx_i2c_state next_state = IMX_I2C_STATE_READ_CONTINUE;
+       unsigned int temp;
+       if ((i2c_imx->msg->len - 1) == i2c_imx->msg_buf_idx) {
+@@ -1033,18 +1034,20 @@ static inline void i2c_imx_isr_read_cont
+                               i2c_imx->stopped =  1;
+                       temp &= ~(I2CR_MSTA | I2CR_MTX);
+                       imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
+-              } else {
+-                      /*
+-                       * For i2c master receiver repeat restart operation like:
+-                       * read -> repeat MSTA -> read/write
+-                       * The controller must set MTX before read the last byte in
+-                       * the first read operation, otherwise the first read cost
+-                       * one extra clock cycle.
+-                       */
+-                      temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
+-                      temp |= I2CR_MTX;
+-                      imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
++
++                      return IMX_I2C_STATE_DONE;
+               }
++              /*
++               * For i2c master receiver repeat restart operation like:
++               * read -> repeat MSTA -> read/write
++               * The controller must set MTX before read the last byte in
++               * the first read operation, otherwise the first read cost
++               * one extra clock cycle.
++               */
++              temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
++              temp |= I2CR_MTX;
++              imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
++              next_state = IMX_I2C_STATE_DONE;
+       } else if (i2c_imx->msg_buf_idx == (i2c_imx->msg->len - 2)) {
+               temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
+               temp |= I2CR_TXAK;
+@@ -1052,6 +1055,7 @@ static inline void i2c_imx_isr_read_cont
+       }
+       i2c_imx->msg->buf[i2c_imx->msg_buf_idx++] = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
++      return next_state;
+ }
+ static inline void i2c_imx_isr_read_block_data_len(struct imx_i2c_struct *i2c_imx)
+@@ -1088,11 +1092,9 @@ static irqreturn_t i2c_imx_master_isr(st
+               break;
+       case IMX_I2C_STATE_READ_CONTINUE:
+-              i2c_imx_isr_read_continue(i2c_imx);
+-              if (i2c_imx->msg_buf_idx == i2c_imx->msg->len) {
+-                      i2c_imx->state = IMX_I2C_STATE_DONE;
++              i2c_imx->state = i2c_imx_isr_read_continue(i2c_imx);
++              if (i2c_imx->state == IMX_I2C_STATE_DONE)
+                       wake_up(&i2c_imx->queue);
+-              }
+               break;
+       case IMX_I2C_STATE_READ_BLOCK_DATA:
+@@ -1490,6 +1492,7 @@ static int i2c_imx_read(struct imx_i2c_s
+                       bool is_lastmsg)
+ {
+       int block_data = msgs->flags & I2C_M_RECV_LEN;
++      int ret = 0;
+       dev_dbg(&i2c_imx->adapter.dev,
+               "<%s> write slave address: addr=0x%x\n",
+@@ -1522,10 +1525,20 @@ static int i2c_imx_read(struct imx_i2c_s
+               dev_err(&i2c_imx->adapter.dev, "<%s> read timedout\n", __func__);
+               return -ETIMEDOUT;
+       }
+-      if (i2c_imx->is_lastmsg && !i2c_imx->stopped)
+-              return i2c_imx_bus_busy(i2c_imx, 0, false);
++      if (i2c_imx->is_lastmsg) {
++              if (!i2c_imx->stopped)
++                      ret = i2c_imx_bus_busy(i2c_imx, 0, false);
++              /*
++               * Only read the last byte of the last message after the bus is
++               * not busy. Else the controller generates another clock which
++               * might confuse devices.
++               */
++              if (!ret)
++                      i2c_imx->msg->buf[i2c_imx->msg_buf_idx++] = imx_i2c_read_reg(i2c_imx,
++                                                                                   IMX_I2C_I2DR);
++      }
+-      return 0;
++      return ret;
+ }
+ static int i2c_imx_xfer_common(struct i2c_adapter *adapter,
diff --git a/queue-6.19/i2c-imx-fix-i2c-issue-when-reading-multiple-messages.patch b/queue-6.19/i2c-imx-fix-i2c-issue-when-reading-multiple-messages.patch
new file mode 100644 (file)
index 0000000..54b6d6f
--- /dev/null
@@ -0,0 +1,39 @@
+From f88e2e748a1fc3cb4b8d163a9be790812f578850 Mon Sep 17 00:00:00 2001
+From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
+Date: Wed, 18 Feb 2026 16:08:49 +0100
+Subject: i2c: imx: fix i2c issue when reading multiple messages
+
+From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
+
+commit f88e2e748a1fc3cb4b8d163a9be790812f578850 upstream.
+
+When reading multiple messages, meaning a repeated start is required,
+polling the bus busy bit must be avoided. This must only be done for
+the last message. Otherwise, the driver will timeout.
+
+Here an example of such a sequence that fails with an error:
+i2ctransfer -y -a 0 w1@0x00 0x02 r1 w1@0x00 0x02 r1
+Error: Sending messages failed: Connection timed out
+
+Fixes: 5f5c2d4579ca ("i2c: imx: prevent rescheduling in non dma mode")
+Cc: stable@vger.kernel.org # v6.13+
+Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
+Link: https://lore.kernel.org/r/20260218150940.131354-2-eichest@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/i2c/busses/i2c-imx.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/i2c/busses/i2c-imx.c
++++ b/drivers/i2c/busses/i2c-imx.c
+@@ -1522,7 +1522,7 @@ static int i2c_imx_read(struct imx_i2c_s
+               dev_err(&i2c_imx->adapter.dev, "<%s> read timedout\n", __func__);
+               return -ETIMEDOUT;
+       }
+-      if (!i2c_imx->stopped)
++      if (i2c_imx->is_lastmsg && !i2c_imx->stopped)
+               return i2c_imx_bus_busy(i2c_imx, 0, false);
+       return 0;
diff --git a/queue-6.19/iomap-fix-invalid-folio-access-when-i_blkbits-differs-from-i-o-granularity.patch b/queue-6.19/iomap-fix-invalid-folio-access-when-i_blkbits-differs-from-i-o-granularity.patch
new file mode 100644 (file)
index 0000000..802d0f0
--- /dev/null
@@ -0,0 +1,81 @@
+From bd71fb3fea9945987053968f028a948997cba8cc Mon Sep 17 00:00:00 2001
+From: Joanne Koong <joannelkoong@gmail.com>
+Date: Tue, 17 Mar 2026 13:39:35 -0700
+Subject: iomap: fix invalid folio access when i_blkbits differs from I/O granularity
+
+From: Joanne Koong <joannelkoong@gmail.com>
+
+commit bd71fb3fea9945987053968f028a948997cba8cc upstream.
+
+Commit aa35dd5cbc06 ("iomap: fix invalid folio access after
+folio_end_read()") partially addressed invalid folio access for folios
+without an ifs attached, but it did not handle the case where
+1 << inode->i_blkbits matches the folio size but is different from the
+granularity used for the IO, which means IO can be submitted for less
+than the full folio for the !ifs case.
+
+In this case, the condition:
+
+  if (*bytes_submitted == folio_len)
+    ctx->cur_folio = NULL;
+
+in iomap_read_folio_iter() will not invalidate ctx->cur_folio, and
+iomap_read_end() will still be called on the folio even though the IO
+helper owns it and will finish the read on it.
+
+Fix this by unconditionally invalidating ctx->cur_folio for the !ifs
+case.
+
+Reported-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Tested-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Link: https://lore.kernel.org/linux-fsdevel/b3dfe271-4e3d-4922-b618-e73731242bca@wdc.com/
+Fixes: b2f35ac4146d ("iomap: add caller-provided callbacks for read and readahead")
+Cc: stable@vger.kernel.org
+Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
+Link: https://patch.msgid.link/20260317203935.830549-1-joannelkoong@gmail.com
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/iomap/buffered-io.c |   15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+--- a/fs/iomap/buffered-io.c
++++ b/fs/iomap/buffered-io.c
+@@ -506,6 +506,7 @@ static int iomap_read_folio_iter(struct
+       loff_t length = iomap_length(iter);
+       struct folio *folio = ctx->cur_folio;
+       size_t folio_len = folio_size(folio);
++      struct iomap_folio_state *ifs;
+       size_t poff, plen;
+       loff_t pos_diff;
+       int ret;
+@@ -517,7 +518,7 @@ static int iomap_read_folio_iter(struct
+               return iomap_iter_advance(iter, length);
+       }
+-      ifs_alloc(iter->inode, folio, iter->flags);
++      ifs = ifs_alloc(iter->inode, folio, iter->flags);
+       length = min_t(loff_t, length, folio_len - offset_in_folio(folio, pos));
+       while (length) {
+@@ -548,11 +549,15 @@ static int iomap_read_folio_iter(struct
+                       *bytes_submitted += plen;
+                       /*
+-                       * If the entire folio has been read in by the IO
+-                       * helper, then the helper owns the folio and will end
+-                       * the read on it.
++                       * Hand off folio ownership to the IO helper when:
++                       * 1) The entire folio has been submitted for IO, or
++                       * 2) There is no ifs attached to the folio
++                       *
++                       * Case (2) occurs when 1 << i_blkbits matches the folio
++                       * size but the underlying filesystem or block device
++                       * uses a smaller granularity for IO.
+                        */
+-                      if (*bytes_submitted == folio_len)
++                      if (*bytes_submitted == folio_len || !ifs)
+                               ctx->cur_folio = NULL;
+               }
diff --git a/queue-6.19/irqchip-qcom-mpm-add-missing-mailbox-tx-done-acknowledgment.patch b/queue-6.19/irqchip-qcom-mpm-add-missing-mailbox-tx-done-acknowledgment.patch
new file mode 100644 (file)
index 0000000..e8eccd2
--- /dev/null
@@ -0,0 +1,46 @@
+From cfe02147e86307a17057ee4e3604f5f5919571d2 Mon Sep 17 00:00:00 2001
+From: Jassi Brar <jassisinghbrar@gmail.com>
+Date: Sun, 22 Mar 2026 12:15:33 -0500
+Subject: irqchip/qcom-mpm: Add missing mailbox TX done acknowledgment
+
+From: Jassi Brar <jassisinghbrar@gmail.com>
+
+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 <jassisinghbrar@gmail.com>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260322171533.608436-1-jassisinghbrar@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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_probe(struct platfor
+       }
+       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.19/jbd2-gracefully-abort-on-checkpointing-state-corruptions.patch b/queue-6.19/jbd2-gracefully-abort-on-checkpointing-state-corruptions.patch
new file mode 100644 (file)
index 0000000..536ba14
--- /dev/null
@@ -0,0 +1,66 @@
+From bac3190a8e79beff6ed221975e0c9b1b5f2a21da Mon Sep 17 00:00:00 2001
+From: Milos Nikic <nikic.milos@gmail.com>
+Date: Tue, 10 Mar 2026 21:15:48 -0700
+Subject: jbd2: gracefully abort on checkpointing state corruptions
+
+From: Milos Nikic <nikic.milos@gmail.com>
+
+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 <nikic.milos@gmail.com>
+Reviewed-by: Andreas Dilger <adilger@dilger.ca>
+Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Baokun Li <libaokun@linux.alibaba.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://patch.msgid.link/20260311041548.159424-1-nikic.milos@gmail.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.19/kvm-x86-mmu-drop-zap-existing-present-spte-even-when-creating-an-mmio-spte.patch b/queue-6.19/kvm-x86-mmu-drop-zap-existing-present-spte-even-when-creating-an-mmio-spte.patch
new file mode 100644 (file)
index 0000000..5d813f0
--- /dev/null
@@ -0,0 +1,83 @@
+From aad885e774966e97b675dfe928da164214a71605 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+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 <seanjc@google.com>
+
+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:
+   <TASK>
+   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
+   </TASK>
+  ---[ end trace 0000000000000000 ]---
+
+Reported-by: Alexander Bulekov <bkov@amazon.com>
+Debugged-by: Alexander Bulekov <bkov@amazon.com>
+Suggested-by: Fred Griffoul <fgriffo@amazon.co.uk>
+Fixes: a54aa15c6bda3 ("KVM: x86/mmu: Handle MMIO SPTEs directly in mmu_set_spte()")
+Cc: stable@vger.kernel.org
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -3044,12 +3044,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 (prefetch && is_last_spte(*sptep, level) &&
+                   pfn == spte_to_pfn(*sptep))
+@@ -3073,6 +3067,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,
+                          false, host_writable, &spte);
diff --git a/queue-6.19/kvm-x86-mmu-only-warn-in-direct-mmus-when-overwriting-shadow-present-spte.patch b/queue-6.19/kvm-x86-mmu-only-warn-in-direct-mmus-when-overwriting-shadow-present-spte.patch
new file mode 100644 (file)
index 0000000..93da6e9
--- /dev/null
@@ -0,0 +1,57 @@
+From df83746075778958954aa0460cca55f4b3fc9c02 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Thu, 5 Mar 2026 17:42:14 -0800
+Subject: KVM: x86/mmu: Only WARN in direct MMUs when overwriting shadow-present SPTE
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit df83746075778958954aa0460cca55f4b3fc9c02 upstream.
+
+Adjust KVM's sanity check against overwriting a shadow-present SPTE with a
+another SPTE with a different target PFN to only apply to direct MMUs,
+i.e. only to MMUs without shadowed gPTEs.  While it's impossible for KVM
+to overwrite a shadow-present SPTE in response to a guest write, writes
+from outside the scope of KVM, e.g. from host userspace, aren't detected
+by KVM's write tracking and so can break KVM's shadow paging rules.
+
+  ------------[ cut here ]------------
+  pfn != spte_to_pfn(*sptep)
+  WARNING: arch/x86/kvm/mmu/mmu.c:3069 at mmu_set_spte+0x1e4/0x440 [kvm], CPU#0: vmx_ept_stale_r/872
+  Modules linked in: kvm_intel kvm irqbypass
+  CPU: 0 UID: 1000 PID: 872 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:mmu_set_spte+0x1e4/0x440 [kvm]
+  Call Trace:
+   <TASK>
+   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
+   </TASK>
+  ---[ end trace 0000000000000000 ]---
+
+Fixes: 11d45175111d ("KVM: x86/mmu: Warn if PFN changes on shadow-present SPTE in shadow MMU")
+Cc: stable@vger.kernel.org
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/mmu/mmu.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/kvm/mmu/mmu.c
++++ b/arch/x86/kvm/mmu/mmu.c
+@@ -3060,7 +3060,8 @@ static int mmu_set_spte(struct kvm_vcpu
+                       child = spte_to_child_sp(pte);
+                       drop_parent_pte(vcpu->kvm, child, sptep);
+                       flush = true;
+-              } else if (WARN_ON_ONCE(pfn != spte_to_pfn(*sptep))) {
++              } else if (pfn != spte_to_pfn(*sptep)) {
++                      WARN_ON_ONCE(vcpu->arch.mmu->root_role.direct);
+                       drop_spte(vcpu->kvm, sptep);
+                       flush = true;
+               } else
diff --git a/queue-6.19/loongarch-fix-missing-null-checks-for-kstrdup.patch b/queue-6.19/loongarch-fix-missing-null-checks-for-kstrdup.patch
new file mode 100644 (file)
index 0000000..6f7601e
--- /dev/null
@@ -0,0 +1,45 @@
+From 3a28daa9b7d7c2ddf2c722e9e95d7e0928bf0cd1 Mon Sep 17 00:00:00 2001
+From: Li Jun <lijun01@kylinos.cn>
+Date: Thu, 26 Mar 2026 14:29:08 +0800
+Subject: LoongArch: Fix missing NULL checks for kstrdup()
+
+From: Li Jun <lijun01@kylinos.cn>
+
+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 <lijun01@kylinos.cn>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.19/loongarch-kvm-fix-base-address-calculation-in-kvm_eiointc_regs_access.patch b/queue-6.19/loongarch-kvm-fix-base-address-calculation-in-kvm_eiointc_regs_access.patch
new file mode 100644 (file)
index 0000000..ce25adc
--- /dev/null
@@ -0,0 +1,70 @@
+From 6bcfb7f46d667b04bd1a1169ccedf5fb699c60df Mon Sep 17 00:00:00 2001
+From: Bibo Mao <maobibo@loongson.cn>
+Date: Thu, 26 Mar 2026 14:29:09 +0800
+Subject: LoongArch: KVM: Fix base address calculation in kvm_eiointc_regs_access()
+
+From: Bibo Mao <maobibo@loongson.cn>
+
+commit 6bcfb7f46d667b04bd1a1169ccedf5fb699c60df upstream.
+
+In function kvm_eiointc_regs_access(), the register base address is
+caculated from array base address plus offset, the offset is absolute
+value from the base address. The data type of array base address is
+u64, it should be converted into the "void *" type and then plus the
+offset.
+
+Cc: <stable@vger.kernel.org>
+Fixes: d3e43a1f34ac ("LoongArch: KVM: Use 64-bit register definition for EIOINTC").
+Reported-by: Aurelien Jarno <aurel32@debian.org>
+Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1131431
+Signed-off-by: Bibo Mao <maobibo@loongson.cn>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/loongarch/kvm/intc/eiointc.c |   14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/arch/loongarch/kvm/intc/eiointc.c
++++ b/arch/loongarch/kvm/intc/eiointc.c
+@@ -481,34 +481,34 @@ static int kvm_eiointc_regs_access(struc
+       switch (addr) {
+       case EIOINTC_NODETYPE_START ... EIOINTC_NODETYPE_END:
+               offset = (addr - EIOINTC_NODETYPE_START) / 4;
+-              p = s->nodetype + offset * 4;
++              p = (void *)s->nodetype + offset * 4;
+               break;
+       case EIOINTC_IPMAP_START ... EIOINTC_IPMAP_END:
+               offset = (addr - EIOINTC_IPMAP_START) / 4;
+-              p = &s->ipmap + offset * 4;
++              p = (void *)&s->ipmap + offset * 4;
+               break;
+       case EIOINTC_ENABLE_START ... EIOINTC_ENABLE_END:
+               offset = (addr - EIOINTC_ENABLE_START) / 4;
+-              p = s->enable + offset * 4;
++              p = (void *)s->enable + offset * 4;
+               break;
+       case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END:
+               offset = (addr - EIOINTC_BOUNCE_START) / 4;
+-              p = s->bounce + offset * 4;
++              p = (void *)s->bounce + offset * 4;
+               break;
+       case EIOINTC_ISR_START ... EIOINTC_ISR_END:
+               offset = (addr - EIOINTC_ISR_START) / 4;
+-              p = s->isr + offset * 4;
++              p = (void *)s->isr + offset * 4;
+               break;
+       case EIOINTC_COREISR_START ... EIOINTC_COREISR_END:
+               if (cpu >= s->num_cpu)
+                       return -EINVAL;
+               offset = (addr - EIOINTC_COREISR_START) / 4;
+-              p = s->coreisr[cpu] + offset * 4;
++              p = (void *)s->coreisr[cpu] + offset * 4;
+               break;
+       case EIOINTC_COREMAP_START ... EIOINTC_COREMAP_END:
+               offset = (addr - EIOINTC_COREMAP_START) / 4;
+-              p = s->coremap + offset * 4;
++              p = (void *)s->coremap + offset * 4;
+               break;
+       default:
+               kvm_err("%s: unknown eiointc register, addr = %d\n", __func__, addr);
diff --git a/queue-6.19/loongarch-kvm-handle-the-case-that-eiointc-s-coremap-is-empty.patch b/queue-6.19/loongarch-kvm-handle-the-case-that-eiointc-s-coremap-is-empty.patch
new file mode 100644 (file)
index 0000000..3070e41
--- /dev/null
@@ -0,0 +1,36 @@
+From b97bd69eb0f67b5f961b304d28e9ba45e202d841 Mon Sep 17 00:00:00 2001
+From: Huacai Chen <chenhuacai@loongson.cn>
+Date: Thu, 26 Mar 2026 14:29:09 +0800
+Subject: LoongArch: KVM: Handle the case that EIOINTC's coremap is empty
+
+From: Huacai Chen <chenhuacai@loongson.cn>
+
+commit b97bd69eb0f67b5f961b304d28e9ba45e202d841 upstream.
+
+EIOINTC's coremap in eiointc_update_sw_coremap() can be empty, currently
+we get a cpuid with -1 in this case, but we actually need 0 because it's
+similar as the case that cpuid >= 4.
+
+This fix an out-of-bounds access to kvm_arch::phyid_map::phys_map[].
+
+Cc: <stable@vger.kernel.org>
+Fixes: 3956a52bc05bd81 ("LoongArch: KVM: Add EIOINTC read and write functions")
+Reported-by: Aurelien Jarno <aurel32@debian.org>
+Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1131431
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/loongarch/kvm/intc/eiointc.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/loongarch/kvm/intc/eiointc.c
++++ b/arch/loongarch/kvm/intc/eiointc.c
+@@ -83,7 +83,7 @@ static inline void eiointc_update_sw_cor
+               if (!(s->status & BIT(EIOINTC_ENABLE_CPU_ENCODE))) {
+                       cpuid = ffs(cpuid) - 1;
+-                      cpuid = (cpuid >= 4) ? 0 : cpuid;
++                      cpuid = ((cpuid < 0) || (cpuid >= 4)) ? 0 : cpuid;
+               }
+               vcpu = kvm_get_vcpu_by_cpuid(s->kvm, cpuid);
diff --git a/queue-6.19/loongarch-kvm-make-kvm_get_vcpu_by_cpuid-more-robust.patch b/queue-6.19/loongarch-kvm-make-kvm_get_vcpu_by_cpuid-more-robust.patch
new file mode 100644 (file)
index 0000000..1a858f1
--- /dev/null
@@ -0,0 +1,37 @@
+From 2db06c15d8c7a0ccb6108524e16cd9163753f354 Mon Sep 17 00:00:00 2001
+From: Huacai Chen <chenhuacai@loongson.cn>
+Date: Thu, 26 Mar 2026 14:29:09 +0800
+Subject: LoongArch: KVM: Make kvm_get_vcpu_by_cpuid() more robust
+
+From: Huacai Chen <chenhuacai@loongson.cn>
+
+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: <stable@vger.kernel.org>
+Fixes: 73516e9da512adc ("LoongArch: KVM: Add vcpu mapping from physical cpuid")
+Reported-by: Aurelien Jarno <aurel32@debian.org>
+Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1131431
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/loongarch/kvm/vcpu.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/arch/loongarch/kvm/vcpu.c
++++ b/arch/loongarch/kvm/vcpu.c
+@@ -562,6 +562,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.19/loongarch-vdso-emit-gnu_eh_frame-correctly.patch b/queue-6.19/loongarch-vdso-emit-gnu_eh_frame-correctly.patch
new file mode 100644 (file)
index 0000000..b1930a2
--- /dev/null
@@ -0,0 +1,208 @@
+From e4878c37f6679fdea91b27a0f4e60a871f0b7bad Mon Sep 17 00:00:00 2001
+From: Xi Ruoyao <xry111@xry111.site>
+Date: Thu, 26 Mar 2026 14:29:09 +0800
+Subject: LoongArch: vDSO: Emit GNU_EH_FRAME correctly
+
+From: Xi Ruoyao <xry111@xry111.site>
+
+commit e4878c37f6679fdea91b27a0f4e60a871f0b7bad upstream.
+
+With -fno-asynchronous-unwind-tables and --no-eh-frame-hdr (the default
+of the linker), the GNU_EH_FRAME segment (specified by vdso.lds.S) is
+empty.  This is not valid, as the current DWARF specification mandates
+the first byte of the EH frame to be the version number 1.  It causes
+some unwinders to complain, for example the ClickHouse query profiler
+spams the log with messages:
+
+    clickhouse-server[365854]: libunwind: unsupported .eh_frame_hdr
+    version: 127 at 7ffffffb0000
+
+Here "127" is just the byte located at the p_vaddr (0, i.e. the
+beginning of the vDSO) of the empty GNU_EH_FRAME segment. Cross-
+checking with /proc/365854/maps has also proven 7ffffffb0000 is the
+start of vDSO in the process VM image.
+
+In LoongArch the -fno-asynchronous-unwind-tables option seems just a
+MIPS legacy, and MIPS only uses this option to satisfy the MIPS-specific
+"genvdso" program, per the commit cfd75c2db17e ("MIPS: VDSO: Explicitly
+use -fno-asynchronous-unwind-tables").  IIRC it indicates some inherent
+limitation of the MIPS ELF ABI and has nothing to do with LoongArch.  So
+we can simply flip it over to -fasynchronous-unwind-tables and pass
+--eh-frame-hdr for linking the vDSO, allowing the profilers to unwind the
+stack for statistics even if the sample point is taken when the PC is in
+the vDSO.
+
+However simply adjusting the options above would exploit an issue: when
+the libgcc unwinder saw the invalid GNU_EH_FRAME segment, it silently
+falled back to a machine-specific routine to match the code pattern of
+rt_sigreturn() and extract the registers saved in the sigframe if the
+code pattern is matched.  As unwinding from signal handlers is vital for
+libgcc to support pthread cancellation etc., the fall-back routine had
+been silently keeping the LoongArch Linux systems functioning since
+Linux 5.19.  But when we start to emit GNU_EH_FRAME with the correct
+format, fall-back routine will no longer be used and libgcc will fail
+to unwind the sigframe, and unwinding from signal handlers will no
+longer work, causing dozens of glibc test failures.  To make it possible
+to unwind from signal handlers again, it's necessary to code the unwind
+info in __vdso_rt_sigreturn via .cfi_* directives.
+
+The offsets in the .cfi_* directives depend on the layout of struct
+sigframe, notably the offset of sigcontext in the sigframe.  To use the
+offset in the assembly file, factor out struct sigframe into a header to
+allow asm-offsets.c to output the offset for assembly.
+
+To work around a long-term issue in the libgcc unwinder (the pc is
+unconditionally substracted by 1: doing so is technically incorrect for
+a signal frame), a nop instruction is included with the two real
+instructions in __vdso_rt_sigreturn in the same FDE PC range.  The same
+hack has been used on x86 for a long time.
+
+Cc: stable@vger.kernel.org
+Fixes: c6b99bed6b8f ("LoongArch: Add VDSO and VSYSCALL support")
+Signed-off-by: Xi Ruoyao <xry111@xry111.site>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/loongarch/include/asm/linkage.h  |   36 ++++++++++++++++++++++++++++++++++
+ arch/loongarch/include/asm/sigframe.h |    9 ++++++++
+ arch/loongarch/kernel/asm-offsets.c   |    2 +
+ arch/loongarch/kernel/signal.c        |    6 -----
+ arch/loongarch/vdso/Makefile          |    4 +--
+ arch/loongarch/vdso/sigreturn.S       |    6 ++---
+ 6 files changed, 53 insertions(+), 10 deletions(-)
+ create mode 100644 arch/loongarch/include/asm/sigframe.h
+
+--- a/arch/loongarch/include/asm/linkage.h
++++ b/arch/loongarch/include/asm/linkage.h
+@@ -41,4 +41,40 @@
+       .cfi_endproc;                                   \
+       SYM_END(name, SYM_T_NONE)
++/*
++ * This is for the signal handler trampoline, which is used as the return
++ * address of the signal handlers in userspace instead of called normally.
++ * The long standing libgcc bug https://gcc.gnu.org/PR124050 requires a
++ * nop between .cfi_startproc and the actual address of the trampoline, so
++ * we cannot simply use SYM_FUNC_START.
++ *
++ * This wrapper also contains all the .cfi_* directives for recovering
++ * the content of the GPRs and the "return address" (where the rt_sigreturn
++ * syscall will jump to), assuming there is a struct rt_sigframe (where
++ * a struct sigcontext containing those information we need to recover) at
++ * $sp.  The "DWARF for the LoongArch(TM) Architecture" manual states
++ * column 0 is for $zero, but it does not make too much sense to
++ * save/restore the hardware zero register.  Repurpose this column here
++ * for the return address (here it's not the content of $ra we cannot use
++ * the default column 3).
++ */
++#define SYM_SIGFUNC_START(name)                               \
++      .cfi_startproc;                                 \
++      .cfi_signal_frame;                              \
++      .cfi_def_cfa 3, RT_SIGFRAME_SC;                 \
++      .cfi_return_column 0;                           \
++      .cfi_offset 0, SC_PC;                           \
++                                                      \
++      .irp num, 1,  2,  3,  4,  5,  6,  7,  8,        \
++                9,  10, 11, 12, 13, 14, 15, 16,       \
++                17, 18, 19, 20, 21, 22, 23, 24,       \
++                25, 26, 27, 28, 29, 30, 31;           \
++      .cfi_offset \num, SC_REGS + \num * SZREG;       \
++      .endr;                                          \
++                                                      \
++      nop;                                            \
++      SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)
++
++#define SYM_SIGFUNC_END(name) SYM_FUNC_END(name)
++
+ #endif
+--- /dev/null
++++ b/arch/loongarch/include/asm/sigframe.h
+@@ -0,0 +1,9 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
++
++#include <asm/siginfo.h>
++#include <asm/ucontext.h>
++
++struct rt_sigframe {
++      struct siginfo rs_info;
++      struct ucontext rs_uctx;
++};
+--- a/arch/loongarch/kernel/asm-offsets.c
++++ b/arch/loongarch/kernel/asm-offsets.c
+@@ -16,6 +16,7 @@
+ #include <asm/ptrace.h>
+ #include <asm/processor.h>
+ #include <asm/ftrace.h>
++#include <asm/sigframe.h>
+ #include <vdso/datapage.h>
+ static void __used output_ptreg_defines(void)
+@@ -220,6 +221,7 @@ static void __used output_sc_defines(voi
+       COMMENT("Linux sigcontext offsets.");
+       OFFSET(SC_REGS, sigcontext, sc_regs);
+       OFFSET(SC_PC, sigcontext, sc_pc);
++      OFFSET(RT_SIGFRAME_SC, rt_sigframe, rs_uctx.uc_mcontext);
+       BLANK();
+ }
+--- a/arch/loongarch/kernel/signal.c
++++ b/arch/loongarch/kernel/signal.c
+@@ -35,6 +35,7 @@
+ #include <asm/cpu-features.h>
+ #include <asm/fpu.h>
+ #include <asm/lbt.h>
++#include <asm/sigframe.h>
+ #include <asm/ucontext.h>
+ #include <asm/vdso.h>
+@@ -51,11 +52,6 @@
+ #define lock_lbt_owner()      ({ preempt_disable(); pagefault_disable(); })
+ #define unlock_lbt_owner()    ({ pagefault_enable(); preempt_enable(); })
+-struct rt_sigframe {
+-      struct siginfo rs_info;
+-      struct ucontext rs_uctx;
+-};
+-
+ struct _ctx_layout {
+       struct sctx_info *addr;
+       unsigned int size;
+--- a/arch/loongarch/vdso/Makefile
++++ b/arch/loongarch/vdso/Makefile
+@@ -26,7 +26,7 @@ cflags-vdso := $(ccflags-vdso) \
+       $(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \
+       -std=gnu11 -fms-extensions -O2 -g -fno-strict-aliasing -fno-common -fno-builtin \
+       -fno-stack-protector -fno-jump-tables -DDISABLE_BRANCH_PROFILING \
+-      $(call cc-option, -fno-asynchronous-unwind-tables) \
++      $(call cc-option, -fasynchronous-unwind-tables) \
+       $(call cc-option, -fno-stack-protector)
+ aflags-vdso := $(ccflags-vdso) \
+       -D__ASSEMBLY__ -Wa,-gdwarf-2
+@@ -41,7 +41,7 @@ endif
+ # VDSO linker flags.
+ ldflags-y := -Bsymbolic --no-undefined -soname=linux-vdso.so.1 \
+-      $(filter -E%,$(KBUILD_CFLAGS)) -shared --build-id -T
++      $(filter -E%,$(KBUILD_CFLAGS)) -shared --build-id --eh-frame-hdr -T
+ #
+ # Shared build commands.
+--- a/arch/loongarch/vdso/sigreturn.S
++++ b/arch/loongarch/vdso/sigreturn.S
+@@ -12,13 +12,13 @@
+ #include <asm/regdef.h>
+ #include <asm/asm.h>
++#include <asm/asm-offsets.h>
+       .section        .text
+-      .cfi_sections   .debug_frame
+-SYM_FUNC_START(__vdso_rt_sigreturn)
++SYM_SIGFUNC_START(__vdso_rt_sigreturn)
+       li.w    a7, __NR_rt_sigreturn
+       syscall 0
+-SYM_FUNC_END(__vdso_rt_sigreturn)
++SYM_SIGFUNC_END(__vdso_rt_sigreturn)
diff --git a/queue-6.19/loongarch-workaround-ls2k-ls7a-gpu-dma-hang-bug.patch b/queue-6.19/loongarch-workaround-ls2k-ls7a-gpu-dma-hang-bug.patch
new file mode 100644 (file)
index 0000000..7c7cc8b
--- /dev/null
@@ -0,0 +1,131 @@
+From 95db0c9f526d583634cddb2e5914718570fbac87 Mon Sep 17 00:00:00 2001
+From: Huacai Chen <chenhuacai@loongson.cn>
+Date: Thu, 26 Mar 2026 14:29:09 +0800
+Subject: LoongArch: Workaround LS2K/LS7A GPU DMA hang bug
+
+From: Huacai Chen <chenhuacai@loongson.cn>
+
+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 <wuqianhai@loongson.cn>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/loongarch/pci/pci.c |   80 +++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 80 insertions(+)
+
+--- a/arch/loongarch/pci/pci.c
++++ b/arch/loongarch/pci/pci.c
+@@ -5,9 +5,11 @@
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/acpi.h>
++#include <linux/delay.h>
+ #include <linux/types.h>
+ #include <linux/pci.h>
+ #include <linux/vgaarb.h>
++#include <linux/io-64-nonatomic-lo-hi.h>
+ #include <asm/cacheflush.h>
+ #include <asm/loongson.h>
+@@ -15,6 +17,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)
+@@ -99,3 +104,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.19/mm-damon-sysfs-check-contexts-nr-before-accessing-contexts_arr.patch b/queue-6.19/mm-damon-sysfs-check-contexts-nr-before-accessing-contexts_arr.patch
new file mode 100644 (file)
index 0000000..7a2fa5a
--- /dev/null
@@ -0,0 +1,58 @@
+From 1bfe9fb5ed2667fb075682408b776b5273162615 Mon Sep 17 00:00:00 2001
+From: Josh Law <objecting@objecting.org>
+Date: Sat, 21 Mar 2026 10:54:25 -0700
+Subject: mm/damon/sysfs: check contexts->nr before accessing contexts_arr[0]
+
+From: Josh Law <objecting@objecting.org>
+
+commit 1bfe9fb5ed2667fb075682408b776b5273162615 upstream.
+
+Multiple sysfs command paths dereference contexts_arr[0] without first
+verifying that kdamond->contexts->nr == 1.  A user can set nr_contexts to
+0 via sysfs while DAMON is running, causing NULL pointer dereferences.
+
+In more detail, the issue can be triggered by privileged users like
+below.
+
+First, start DAMON and make contexts directory empty
+(kdamond->contexts->nr == 0).
+
+    # damo start
+    # cd /sys/kernel/mm/damon/admin/kdamonds/0
+    # echo 0 > contexts/nr_contexts
+
+Then, each of below commands will cause the NULL pointer dereference.
+
+    # echo update_schemes_stats > state
+    # echo update_schemes_tried_regions > state
+    # echo update_schemes_tried_bytes > state
+    # echo update_schemes_effective_quotas > state
+    # echo update_tuned_intervals > state
+
+Guard all commands (except OFF) at the entry point of
+damon_sysfs_handle_cmd().
+
+Link: https://lkml.kernel.org/r/20260321175427.86000-3-sj@kernel.org
+Fixes: 0ac32b8affb5 ("mm/damon/sysfs: support DAMOS stats")
+Signed-off-by: Josh Law <objecting@objecting.org>
+Reviewed-by: SeongJae Park <sj@kernel.org>
+Signed-off-by: SeongJae Park <sj@kernel.org>
+Cc: <stable@vger.kernel.org>   [5.18+]
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/damon/sysfs.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/mm/damon/sysfs.c
++++ b/mm/damon/sysfs.c
+@@ -1752,6 +1752,9 @@ static int damon_sysfs_update_schemes_tr
+ static int damon_sysfs_handle_cmd(enum damon_sysfs_cmd cmd,
+               struct damon_sysfs_kdamond *kdamond)
+ {
++      if (cmd != DAMON_SYSFS_CMD_OFF && kdamond->contexts->nr != 1)
++              return -EINVAL;
++
+       switch (cmd) {
+       case DAMON_SYSFS_CMD_ON:
+               return damon_sysfs_turn_damon_on(kdamond);
diff --git a/queue-6.19/mm-damon-sysfs-check-contexts-nr-in-repeat_call_fn.patch b/queue-6.19/mm-damon-sysfs-check-contexts-nr-in-repeat_call_fn.patch
new file mode 100644 (file)
index 0000000..09e4583
--- /dev/null
@@ -0,0 +1,52 @@
+From 6557004a8b59c7701e695f02be03c7e20ed1cc15 Mon Sep 17 00:00:00 2001
+From: Josh Law <objecting@objecting.org>
+Date: Sat, 21 Mar 2026 10:54:26 -0700
+Subject: mm/damon/sysfs: check contexts->nr in repeat_call_fn
+
+From: Josh Law <objecting@objecting.org>
+
+commit 6557004a8b59c7701e695f02be03c7e20ed1cc15 upstream.
+
+damon_sysfs_repeat_call_fn() calls damon_sysfs_upd_tuned_intervals(),
+damon_sysfs_upd_schemes_stats(), and
+damon_sysfs_upd_schemes_effective_quotas() without checking contexts->nr.
+If nr_contexts is set to 0 via sysfs while DAMON is running, these
+functions dereference contexts_arr[0] and cause a NULL pointer
+dereference.  Add the missing check.
+
+For example, the issue can be reproduced using DAMON sysfs interface and
+DAMON user-space tool (damo) [1] like below.
+
+    $ sudo damo start --refresh_interval 1s
+    $ echo 0 | sudo tee \
+            /sys/kernel/mm/damon/admin/kdamonds/0/contexts/nr_contexts
+
+Link: https://patch.msgid.link/20260320163559.178101-3-objecting@objecting.org
+Link: https://lkml.kernel.org/r/20260321175427.86000-4-sj@kernel.org
+Link: https://github.com/damonitor/damo [1]
+Fixes: d809a7c64ba8 ("mm/damon/sysfs: implement refresh_ms file internal work")
+Signed-off-by: Josh Law <objecting@objecting.org>
+Reviewed-by: SeongJae Park <sj@kernel.org>
+Signed-off-by: SeongJae Park <sj@kernel.org>
+Cc: <stable@vger.kernel.org>   [6.17+]
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/damon/sysfs.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/mm/damon/sysfs.c
++++ b/mm/damon/sysfs.c
+@@ -1622,9 +1622,12 @@ static int damon_sysfs_repeat_call_fn(vo
+       if (!mutex_trylock(&damon_sysfs_lock))
+               return 0;
++      if (sysfs_kdamond->contexts->nr != 1)
++              goto out;
+       damon_sysfs_upd_tuned_intervals(sysfs_kdamond);
+       damon_sysfs_upd_schemes_stats(sysfs_kdamond);
+       damon_sysfs_upd_schemes_effective_quotas(sysfs_kdamond);
++out:
+       mutex_unlock(&damon_sysfs_lock);
+       return 0;
+ }
diff --git a/queue-6.19/mm-damon-sysfs-fix-param_ctx-leak-on-damon_sysfs_new_test_ctx-failure.patch b/queue-6.19/mm-damon-sysfs-fix-param_ctx-leak-on-damon_sysfs_new_test_ctx-failure.patch
new file mode 100644 (file)
index 0000000..049f0dd
--- /dev/null
@@ -0,0 +1,50 @@
+From 7fe000eb32904758a85e62f6ea9483f89d5dabfc Mon Sep 17 00:00:00 2001
+From: Josh Law <objecting@objecting.org>
+Date: Sat, 21 Mar 2026 10:54:24 -0700
+Subject: mm/damon/sysfs: fix param_ctx leak on damon_sysfs_new_test_ctx() failure
+
+From: Josh Law <objecting@objecting.org>
+
+commit 7fe000eb32904758a85e62f6ea9483f89d5dabfc upstream.
+
+Patch series "mm/damon/sysfs: fix memory leak and NULL dereference
+issues", v4.
+
+DAMON_SYSFS can leak memory under allocation failure, and do NULL pointer
+dereference when a privileged user make wrong sequences of control.  Fix
+those.
+
+
+This patch (of 3):
+
+When damon_sysfs_new_test_ctx() fails in damon_sysfs_commit_input(),
+param_ctx is leaked because the early return skips the cleanup at the out
+label.  Destroy param_ctx before returning.
+
+Link: https://lkml.kernel.org/r/20260321175427.86000-1-sj@kernel.org
+Link: https://lkml.kernel.org/r/20260321175427.86000-2-sj@kernel.org
+Fixes: f0c5118ebb0e ("mm/damon/sysfs: catch commit test ctx alloc failure")
+Signed-off-by: Josh Law <objecting@objecting.org>
+Reviewed-by: SeongJae Park <sj@kernel.org>
+Signed-off-by: SeongJae Park <sj@kernel.org>
+Cc: <stable@vger.kernel.org>   [6.18+]
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/damon/sysfs.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/mm/damon/sysfs.c
++++ b/mm/damon/sysfs.c
+@@ -1526,8 +1526,10 @@ static int damon_sysfs_commit_input(void
+       if (IS_ERR(param_ctx))
+               return PTR_ERR(param_ctx);
+       test_ctx = damon_sysfs_new_test_ctx(kdamond->damon_ctx);
+-      if (!test_ctx)
++      if (!test_ctx) {
++              damon_destroy_ctx(param_ctx);
+               return -ENOMEM;
++      }
+       err = damon_commit_ctx(test_ctx, param_ctx);
+       if (err)
+               goto out;
diff --git a/queue-6.19/mm-huge_memory-fix-folio-isn-t-locked-in-softleaf_to_folio.patch b/queue-6.19/mm-huge_memory-fix-folio-isn-t-locked-in-softleaf_to_folio.patch
new file mode 100644 (file)
index 0000000..3cb1be8
--- /dev/null
@@ -0,0 +1,122 @@
+From 4c5e7f0fcd592801c9cc18f29f80fbee84eb8669 Mon Sep 17 00:00:00 2001
+From: Jinjiang Tu <tujinjiang@huawei.com>
+Date: Thu, 19 Mar 2026 09:25:41 +0800
+Subject: mm/huge_memory: fix folio isn't locked in softleaf_to_folio()
+
+From: Jinjiang Tu <tujinjiang@huawei.com>
+
+commit 4c5e7f0fcd592801c9cc18f29f80fbee84eb8669 upstream.
+
+On arm64 server, we found folio that get from migration entry isn't locked
+in softleaf_to_folio().  This issue triggers when mTHP splitting and
+zap_nonpresent_ptes() races, and the root cause is lack of memory barrier
+in softleaf_to_folio().  The race is as follows:
+
+       CPU0                                             CPU1
+
+deferred_split_scan()                              zap_nonpresent_ptes()
+  lock folio
+  split_folio()
+    unmap_folio()
+      change ptes to migration entries
+    __split_folio_to_order()                         softleaf_to_folio()
+      set flags(including PG_locked) for tail pages    folio = pfn_folio(softleaf_to_pfn(entry))
+      smp_wmb()                                        VM_WARN_ON_ONCE(!folio_test_locked(folio))
+      prep_compound_page() for tail pages
+
+In __split_folio_to_order(), smp_wmb() guarantees page flags of tail pages
+are visible before the tail page becomes non-compound.  smp_wmb() should
+be paired with smp_rmb() in softleaf_to_folio(), which is missed.  As a
+result, if zap_nonpresent_ptes() accesses migration entry that stores tail
+pfn, softleaf_to_folio() may see the updated compound_head of tail page
+before page->flags.
+
+This issue will trigger VM_WARN_ON_ONCE() in pfn_swap_entry_folio()
+because of the race between folio split and zap_nonpresent_ptes()
+leading to a folio incorrectly undergoing modification without a folio
+lock being held.
+
+This is a BUG_ON() before commit 93976a20345b ("mm: eliminate further
+swapops predicates"), which in merged in v6.19-rc1.
+
+To fix it, add missing smp_rmb() if the softleaf entry is migration entry
+in softleaf_to_folio() and softleaf_to_page().
+
+[tujinjiang@huawei.com: update function name and comments]
+  Link: https://lkml.kernel.org/r/20260321075214.3305564-1-tujinjiang@huawei.com
+Link: https://lkml.kernel.org/r/20260319012541.4158561-1-tujinjiang@huawei.com
+Fixes: e9b61f19858a ("thp: reintroduce split_huge_page()")
+Signed-off-by: Jinjiang Tu <tujinjiang@huawei.com>
+Acked-by: David Hildenbrand (Arm) <david@kernel.org>
+Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
+Cc: Barry Song <baohua@kernel.org>
+Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
+Cc: Liam Howlett <liam.howlett@oracle.com>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Nanyong Sun <sunnanyong@huawei.com>
+Cc: Ryan Roberts <ryan.roberts@arm.com>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/leafops.h |   32 +++++++++++++++++++++-----------
+ 1 file changed, 21 insertions(+), 11 deletions(-)
+
+--- a/include/linux/leafops.h
++++ b/include/linux/leafops.h
+@@ -363,6 +363,23 @@ static inline unsigned long softleaf_to_
+       return swp_offset(entry) & SWP_PFN_MASK;
+ }
++static inline void softleaf_migration_sync(softleaf_t entry,
++              struct folio *folio)
++{
++      /*
++       * Ensure we do not race with split, which might alter tail pages into new
++       * folios and thus result in observing an unlocked folio.
++       * This matches the write barrier in __split_folio_to_order().
++       */
++      smp_rmb();
++
++      /*
++       * Any use of migration entries may only occur while the
++       * corresponding page is locked
++       */
++      VM_WARN_ON_ONCE(!folio_test_locked(folio));
++}
++
+ /**
+  * softleaf_to_page() - Obtains struct page for PFN encoded within leaf entry.
+  * @entry: Leaf entry, softleaf_has_pfn(@entry) must return true.
+@@ -374,11 +391,8 @@ static inline struct page *softleaf_to_p
+       struct page *page = pfn_to_page(softleaf_to_pfn(entry));
+       VM_WARN_ON_ONCE(!softleaf_has_pfn(entry));
+-      /*
+-       * Any use of migration entries may only occur while the
+-       * corresponding page is locked
+-       */
+-      VM_WARN_ON_ONCE(softleaf_is_migration(entry) && !PageLocked(page));
++      if (softleaf_is_migration(entry))
++              softleaf_migration_sync(entry, page_folio(page));
+       return page;
+ }
+@@ -394,12 +408,8 @@ static inline struct folio *softleaf_to_
+       struct folio *folio = pfn_folio(softleaf_to_pfn(entry));
+       VM_WARN_ON_ONCE(!softleaf_has_pfn(entry));
+-      /*
+-       * Any use of migration entries may only occur while the
+-       * corresponding folio is locked.
+-       */
+-      VM_WARN_ON_ONCE(softleaf_is_migration(entry) &&
+-                      !folio_test_locked(folio));
++      if (softleaf_is_migration(entry))
++              softleaf_migration_sync(entry, folio);
+       return folio;
+ }
diff --git a/queue-6.19/mm-memory-fix-pmd-pud-checks-in-follow_pfnmap_start.patch b/queue-6.19/mm-memory-fix-pmd-pud-checks-in-follow_pfnmap_start.patch
new file mode 100644 (file)
index 0000000..f3f8f22
--- /dev/null
@@ -0,0 +1,99 @@
+From ffef67b93aa352b34e6aeba3d52c19a63885409a Mon Sep 17 00:00:00 2001
+From: "David Hildenbrand (Arm)" <david@kernel.org>
+Date: Mon, 23 Mar 2026 21:20:18 +0100
+Subject: mm/memory: fix PMD/PUD checks in follow_pfnmap_start()
+
+From: David Hildenbrand (Arm) <david@kernel.org>
+
+commit ffef67b93aa352b34e6aeba3d52c19a63885409a upstream.
+
+follow_pfnmap_start() suffers from two problems:
+
+(1) We are not re-fetching the pmd/pud after taking the PTL
+
+Therefore, we are not properly stabilizing what the lock actually
+protects.  If there is concurrent zapping, we would indicate to the
+caller that we found an entry, however, that entry might already have
+been invalidated, or contain a different PFN after taking the lock.
+
+Properly use pmdp_get() / pudp_get() after taking the lock.
+
+(2) pmd_leaf() / pud_leaf() are not well defined on non-present entries
+
+pmd_leaf()/pud_leaf() could wrongly trigger on non-present entries.
+
+There is no real guarantee that pmd_leaf()/pud_leaf() returns something
+reasonable on non-present entries.  Most architectures indeed either
+perform a present check or make it work by smart use of flags.
+
+However, for example loongarch checks the _PAGE_HUGE flag in pmd_leaf(),
+and always sets the _PAGE_HUGE flag in __swp_entry_to_pmd().  Whereby
+pmd_trans_huge() explicitly checks pmd_present(), pmd_leaf() does not do
+that.
+
+Let's check pmd_present()/pud_present() before assuming "the is a present
+PMD leaf" when spotting pmd_leaf()/pud_leaf(), like other page table
+handling code that traverses user page tables does.
+
+Given that non-present PMD entries are likely rare in VM_IO|VM_PFNMAP, (1)
+is likely more relevant than (2).  It is questionable how often (1) would
+actually trigger, but let's CC stable to be sure.
+
+This was found by code inspection.
+
+Link: https://lkml.kernel.org/r/20260323-follow_pfnmap_fix-v1-1-5b0ec10872b3@kernel.org
+Fixes: 6da8e9634bb7 ("mm: new follow_pfnmap API")
+Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
+Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
+Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
+Cc: Liam Howlett <liam.howlett@oracle.com>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/memory.c |   18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -6775,11 +6775,16 @@ retry:
+       pudp = pud_offset(p4dp, address);
+       pud = pudp_get(pudp);
+-      if (pud_none(pud))
++      if (!pud_present(pud))
+               goto out;
+       if (pud_leaf(pud)) {
+               lock = pud_lock(mm, pudp);
+-              if (!unlikely(pud_leaf(pud))) {
++              pud = pudp_get(pudp);
++
++              if (unlikely(!pud_present(pud))) {
++                      spin_unlock(lock);
++                      goto out;
++              } else if (unlikely(!pud_leaf(pud))) {
+                       spin_unlock(lock);
+                       goto retry;
+               }
+@@ -6791,9 +6796,16 @@ retry:
+       pmdp = pmd_offset(pudp, address);
+       pmd = pmdp_get_lockless(pmdp);
++      if (!pmd_present(pmd))
++              goto out;
+       if (pmd_leaf(pmd)) {
+               lock = pmd_lock(mm, pmdp);
+-              if (!unlikely(pmd_leaf(pmd))) {
++              pmd = pmdp_get(pmdp);
++
++              if (unlikely(!pmd_present(pmd))) {
++                      spin_unlock(lock);
++                      goto out;
++              } else if (unlikely(!pmd_leaf(pmd))) {
+                       spin_unlock(lock);
+                       goto retry;
+               }
diff --git a/queue-6.19/mm-mseal-update-vma-end-correctly-on-merge.patch b/queue-6.19/mm-mseal-update-vma-end-correctly-on-merge.patch
new file mode 100644 (file)
index 0000000..d8f42ba
--- /dev/null
@@ -0,0 +1,70 @@
+From 2697dd8ae721db4f6a53d4f4cbd438212a80f8dc Mon Sep 17 00:00:00 2001
+From: "Lorenzo Stoakes (Oracle)" <ljs@kernel.org>
+Date: Fri, 27 Mar 2026 17:31:04 +0000
+Subject: mm/mseal: update VMA end correctly on merge
+
+From: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
+
+commit 2697dd8ae721db4f6a53d4f4cbd438212a80f8dc upstream.
+
+Previously we stored the end of the current VMA in curr_end, and then upon
+iterating to the next VMA updated curr_start to curr_end to advance to the
+next VMA.
+
+However, this doesn't take into account the fact that a VMA might be
+updated due to a merge by vma_modify_flags(), which can result in curr_end
+being stale and thus, upon setting curr_start to curr_end, ending up with
+an incorrect curr_start on the next iteration.
+
+Resolve the issue by setting curr_end to vma->vm_end unconditionally to
+ensure this value remains updated should this occur.
+
+While we're here, eliminate this entire class of bug by simply setting
+const curr_[start/end] to be clamped to the input range and VMAs, which
+also happens to simplify the logic.
+
+Link: https://lkml.kernel.org/r/20260327173104.322405-1-ljs@kernel.org
+Fixes: 6c2da14ae1e0 ("mm/mseal: rework mseal apply logic")
+Signed-off-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
+Reported-by: Antonius <antonius@bluedragonsec.com>
+Closes: https://lore.kernel.org/linux-mm/CAK8a0jwWGj9-SgFk0yKFh7i8jMkwKm5b0ao9=kmXWjO54veX2g@mail.gmail.com/
+Suggested-by: David Hildenbrand (ARM) <david@kernel.org>
+Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
+Reviewed-by: Pedro Falcato <pfalcato@suse.de>
+Acked-by: David Hildenbrand (Arm) <david@kernel.org>
+Cc: Jann Horn <jannh@google.com>
+Cc: Jeff Xu <jeffxu@chromium.org>
+Cc: Liam Howlett <liam.howlett@oracle.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/mseal.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/mm/mseal.c
++++ b/mm/mseal.c
+@@ -56,7 +56,6 @@ static int mseal_apply(struct mm_struct
+               unsigned long start, unsigned long end)
+ {
+       struct vm_area_struct *vma, *prev;
+-      unsigned long curr_start = start;
+       VMA_ITERATOR(vmi, mm, start);
+       /* We know there are no gaps so this will be non-NULL. */
+@@ -66,6 +65,7 @@ static int mseal_apply(struct mm_struct
+               prev = vma;
+       for_each_vma_range(vmi, vma, end) {
++              const unsigned long curr_start = MAX(vma->vm_start, start);
+               const unsigned long curr_end = MIN(vma->vm_end, end);
+               if (!(vma->vm_flags & VM_SEALED)) {
+@@ -79,7 +79,6 @@ static int mseal_apply(struct mm_struct
+               }
+               prev = vma;
+-              curr_start = curr_end;
+       }
+       return 0;
diff --git a/queue-6.19/mm-pagewalk-fix-race-between-concurrent-split-and-refault.patch b/queue-6.19/mm-pagewalk-fix-race-between-concurrent-split-and-refault.patch
new file mode 100644 (file)
index 0000000..e7f7910
--- /dev/null
@@ -0,0 +1,151 @@
+From 3b89863c3fa482912911cd65a12a3aeef662c250 Mon Sep 17 00:00:00 2001
+From: Max Boone <mboone@akamai.com>
+Date: Wed, 25 Mar 2026 10:59:16 +0100
+Subject: mm/pagewalk: fix race between concurrent split and refault
+
+From: Max Boone <mboone@akamai.com>
+
+commit 3b89863c3fa482912911cd65a12a3aeef662c250 upstream.
+
+The splitting of a PUD entry in walk_pud_range() can race with a
+concurrent thread refaulting the PUD leaf entry causing it to try walking
+a PMD range that has disappeared.
+
+An example and reproduction of this is to try reading numa_maps of a
+process while VFIO-PCI is setting up DMA (specifically the
+vfio_pin_pages_remote call) on a large BAR for that process.
+
+This will trigger a kernel BUG:
+vfio-pci 0000:03:00.0: enabling device (0000 -> 0002)
+BUG: unable to handle page fault for address: ffffa23980000000
+PGD 0 P4D 0
+Oops: Oops: 0000 [#1] SMP NOPTI
+...
+RIP: 0010:walk_pgd_range+0x3b5/0x7a0
+Code: 8d 43 ff 48 89 44 24 28 4d 89 ce 4d 8d a7 00 00 20 00 48 8b 4c 24
+28 49 81 e4 00 00 e0 ff 49 8d 44 24 ff 48 39 c8 4c 0f 43 e3 <49> f7 06
+   9f ff ff ff 75 3b 48 8b 44 24 20 48 8b 40 28 48 85 c0 74
+RSP: 0018:ffffac23e1ecf808 EFLAGS: 00010287
+RAX: 00007f44c01fffff RBX: 00007f4500000000 RCX: 00007f44ffffffff
+RDX: 0000000000000000 RSI: 000ffffffffff000 RDI: ffffffff93378fe0
+RBP: ffffac23e1ecf918 R08: 0000000000000004 R09: ffffa23980000000
+R10: 0000000000000020 R11: 0000000000000004 R12: 00007f44c0200000
+R13: 00007f44c0000000 R14: ffffa23980000000 R15: 00007f44c0000000
+FS:  00007fe884739580(0000) GS:ffff9b7d7a9c0000(0000)
+knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: ffffa23980000000 CR3: 000000c0650e2005 CR4: 0000000000770ef0
+PKRU: 55555554
+Call Trace:
+ <TASK>
+ __walk_page_range+0x195/0x1b0
+ walk_page_vma+0x62/0xc0
+ show_numa_map+0x12b/0x3b0
+ seq_read_iter+0x297/0x440
+ seq_read+0x11d/0x140
+ vfs_read+0xc2/0x340
+ ksys_read+0x5f/0xe0
+ do_syscall_64+0x68/0x130
+ ? get_page_from_freelist+0x5c2/0x17e0
+ ? mas_store_prealloc+0x17e/0x360
+ ? vma_set_page_prot+0x4c/0xa0
+ ? __alloc_pages_noprof+0x14e/0x2d0
+ ? __mod_memcg_lruvec_state+0x8d/0x140
+ ? __lruvec_stat_mod_folio+0x76/0xb0
+ ? __folio_mod_stat+0x26/0x80
+ ? do_anonymous_page+0x705/0x900
+ ? __handle_mm_fault+0xa8d/0x1000
+ ? __count_memcg_events+0x53/0xf0
+ ? handle_mm_fault+0xa5/0x360
+ ? do_user_addr_fault+0x342/0x640
+ ? arch_exit_to_user_mode_prepare.constprop.0+0x16/0xa0
+ ? irqentry_exit_to_user_mode+0x24/0x100
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+RIP: 0033:0x7fe88464f47e
+Code: c0 e9 b6 fe ff ff 50 48 8d 3d be 07 0b 00 e8 69 01 02 00 66 0f 1f
+84 00 00 00 00 00 64 8b 04 25 18 00 00 00 85 c0 75 14 0f 05 <48> 3d 00
+   f0 ff ff 77 5a c3 66 0f 1f 84 00 00 00 00 00 48 83 ec 28
+RSP: 002b:00007ffe6cd9a9b8 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
+RAX: ffffffffffffffda RBX: 0000000000020000 RCX: 00007fe88464f47e
+RDX: 0000000000020000 RSI: 00007fe884543000 RDI: 0000000000000003
+RBP: 00007fe884543000 R08: 00007fe884542010 R09: 0000000000000000
+R10: fffffffffffffbc5 R11: 0000000000000246 R12: 0000000000000000
+R13: 0000000000000003 R14: 0000000000020000 R15: 0000000000020000
+ </TASK>
+
+Fix this by validating the PUD entry in walk_pmd_range() using a stable
+snapshot (pudp_get()).  If the PUD is not present or is a leaf, retry the
+walk via ACTION_AGAIN instead of descending further.  This mirrors the
+retry logic in walk_pte_range(), which lets walk_pmd_range() retry if the
+PTE is not being got by pte_offset_map_lock().
+
+Link: https://lkml.kernel.org/r/20260325-pagewalk-check-pmd-refault-v2-1-707bff33bc60@akamai.com
+Fixes: f9e54c3a2f5b ("vfio/pci: implement huge_fault support")
+Co-developed-by: David Hildenbrand (Arm) <david@kernel.org>
+Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
+Signed-off-by: Max Boone <mboone@akamai.com>
+Acked-by: David Hildenbrand (Arm) <david@kernel.org>
+Cc: Liam Howlett <liam.howlett@oracle.com>
+Cc: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/pagewalk.c |   25 ++++++++++++++++++++++---
+ 1 file changed, 22 insertions(+), 3 deletions(-)
+
+--- a/mm/pagewalk.c
++++ b/mm/pagewalk.c
+@@ -97,6 +97,7 @@ static int walk_pte_range(pmd_t *pmd, un
+ static int walk_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
+                         struct mm_walk *walk)
+ {
++      pud_t pudval = pudp_get(pud);
+       pmd_t *pmd;
+       unsigned long next;
+       const struct mm_walk_ops *ops = walk->ops;
+@@ -105,6 +106,24 @@ static int walk_pmd_range(pud_t *pud, un
+       int err = 0;
+       int depth = real_depth(3);
++      /*
++       * For PTE handling, pte_offset_map_lock() takes care of checking
++       * whether there actually is a page table. But it also has to be
++       * very careful about concurrent page table reclaim.
++       *
++       * Similarly, we have to be careful here - a PUD entry that points
++       * to a PMD table cannot go away, so we can just walk it. But if
++       * it's something else, we need to ensure we didn't race something,
++       * so need to retry.
++       *
++       * A pertinent example of this is a PUD refault after PUD split -
++       * we will need to split again or risk accessing invalid memory.
++       */
++      if (!pud_present(pudval) || pud_leaf(pudval)) {
++              walk->action = ACTION_AGAIN;
++              return 0;
++      }
++
+       pmd = pmd_offset(pud, addr);
+       do {
+ again:
+@@ -218,12 +237,12 @@ static int walk_pud_range(p4d_t *p4d, un
+               else if (pud_leaf(*pud) || !pud_present(*pud))
+                       continue; /* Nothing to do. */
+-              if (pud_none(*pud))
+-                      goto again;
+-
+               err = walk_pmd_range(pud, addr, next, walk);
+               if (err)
+                       break;
++
++              if (walk->action == ACTION_AGAIN)
++                      goto again;
+       } while (pud++, addr = next, addr != end);
+       return err;
diff --git a/queue-6.19/net-macb-move-devm_-free-request-_irq-out-of-spin-lock-area.patch b/queue-6.19/net-macb-move-devm_-free-request-_irq-out-of-spin-lock-area.patch
new file mode 100644 (file)
index 0000000..5a15376
--- /dev/null
@@ -0,0 +1,144 @@
+From 317e49358ebbf6390fa439ef3c142f9239dd25fb Mon Sep 17 00:00:00 2001
+From: Kevin Hao <haokexin@gmail.com>
+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 <haokexin@gmail.com>
+
+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): [<ffff8000813c7d7c>] _raw_spin_unlock_irqrestore+0x44/0x88
+  hardirqs last disabled at (8682): [<ffff8000813c7b58>] _raw_spin_lock_irqsave+0x38/0x98
+  softirqs last  enabled at (7322): [<ffff8000800f1b4c>] handle_softirqs+0x52c/0x588
+  softirqs last disabled at (7317): [<ffff800080010310>] __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 <theo.lebrun@bootlin.com>
+Signed-off-by: Kevin Hao <haokexin@gmail.com>
+Link: https://patch.msgid.link/20260318-macb-irq-v2-1-f1179768ab24@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -5832,6 +5832,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
+@@ -5844,11 +5845,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);
+@@ -5856,13 +5858,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);
+       }
+@@ -5929,6 +5931,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,
+@@ -5937,10 +5941,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.19/net-macb-protect-access-to-net_device-ip_ptr-with-rcu-lock.patch b/queue-6.19/net-macb-protect-access-to-net_device-ip_ptr-with-rcu-lock.patch
new file mode 100644 (file)
index 0000000..2a74b59
--- /dev/null
@@ -0,0 +1,125 @@
+From baa35a698cea26930679a20a7550bbb4c8319725 Mon Sep 17 00:00:00 2001
+From: Kevin Hao <haokexin@gmail.com>
+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 <haokexin@gmail.com>
+
+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 <haokexin@gmail.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Théo Lebrun <theo.lebrun@bootlin.com>
+Link: https://patch.msgid.link/20260318-macb-irq-v2-2-f1179768ab24@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -5773,9 +5773,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->phy);
+@@ -5784,14 +5784,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,
+@@ -5830,7 +5837,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.19/net-macb-use-dev_consume_skb_any-to-free-tx-skbs.patch b/queue-6.19/net-macb-use-dev_consume_skb_any-to-free-tx-skbs.patch
new file mode 100644 (file)
index 0000000..fe6773c
--- /dev/null
@@ -0,0 +1,73 @@
+From 647b8a2fe474474704110db6bd07f7a139e621eb Mon Sep 17 00:00:00 2001
+From: Kevin Hao <haokexin@gmail.com>
+Date: Sat, 21 Mar 2026 22:04:41 +0800
+Subject: net: macb: Use dev_consume_skb_any() to free TX SKBs
+
+From: Kevin Hao <haokexin@gmail.com>
+
+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): [<ffff8000813be184>] _raw_spin_unlock_irqrestore+0x44/0x88
+   hardirqs last disabled at (29751): [<ffff8000813bdf60>] _raw_spin_lock_irqsave+0x38/0x98
+   softirqs last  enabled at (29150): [<ffff8000800f1aec>] handle_softirqs+0x504/0x560
+   softirqs last disabled at (29153): [<ffff8000800f2fec>] run_ksoftirqd+0x44/0x80
+
+Fixes: 6bc8a5098bf4 ("net: macb: Fix tx_ptr_lock locking")
+Signed-off-by: Kevin Hao <haokexin@gmail.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260321-macb-tx-v1-1-b383a58dd4e6@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -1071,7 +1071,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.19/ovl-fix-wrong-detection-of-32bit-inode-numbers.patch b/queue-6.19/ovl-fix-wrong-detection-of-32bit-inode-numbers.patch
new file mode 100644 (file)
index 0000000..cc2e71c
--- /dev/null
@@ -0,0 +1,43 @@
+From 53a7c171e9dd833f0a96b545adcb89bd57387239 Mon Sep 17 00:00:00 2001
+From: Amir Goldstein <amir73il@gmail.com>
+Date: Sun, 8 Mar 2026 12:02:21 +0100
+Subject: ovl: fix wrong detection of 32bit inode numbers
+
+From: Amir Goldstein <amir73il@gmail.com>
+
+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 <amir73il@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/overlayfs/util.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/fs/overlayfs/util.c
++++ b/fs/overlayfs/util.c
+@@ -85,7 +85,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.19/ovl-make-fsync-after-metadata-copy-up-opt-in-mount-option.patch b/queue-6.19/ovl-make-fsync-after-metadata-copy-up-opt-in-mount-option.patch
new file mode 100644 (file)
index 0000000..f5e0c95
--- /dev/null
@@ -0,0 +1,285 @@
+From 1f6ee9be92f8df85a8c9a5a78c20fd39c0c21a95 Mon Sep 17 00:00:00 2001
+From: Fei Lv <feilv@asrmicro.com>
+Date: Mon, 22 Jul 2024 18:14:43 +0800
+Subject: ovl: make fsync after metadata copy-up opt-in mount option
+
+From: Fei Lv <feilv@asrmicro.com>
+
+commit 1f6ee9be92f8df85a8c9a5a78c20fd39c0c21a95 upstream.
+
+Commit 7d6899fb69d25 ("ovl: fsync after metadata copy-up") was done to
+fix durability of overlayfs copy up on an upper filesystem which does
+not enforce ordering on storing of metadata changes (e.g. ubifs).
+
+In an earlier revision of the regressing commit by Lei Lv, the metadata
+fsync behavior was opt-in via a new "fsync=strict" mount option.
+We were hoping that the opt-in mount option could be avoided, so the
+change was only made to depend on metacopy=off, in the hope of not
+hurting performance of metadata heavy workloads, which are more likely
+to be using metacopy=on.
+
+This hope was proven wrong by a performance regression report from Google
+COS workload after upgrade to kernel 6.12.
+
+This is an adaptation of Lei's original "fsync=strict" mount option
+to the existing upstream code.
+
+The new mount option is mutually exclusive with the "volatile" mount
+option, so the latter is now an alias to the "fsync=volatile" mount
+option.
+
+Reported-by: Chenglong Tang <chenglongtang@google.com>
+Closes: https://lore.kernel.org/linux-unionfs/CAOdxtTadAFH01Vui1FvWfcmQ8jH1O45owTzUcpYbNvBxnLeM7Q@mail.gmail.com/
+Link: https://lore.kernel.org/linux-unionfs/CAOQ4uxgKC1SgjMWre=fUb00v8rxtd6sQi-S+dxR8oDzAuiGu8g@mail.gmail.com/
+Fixes: 7d6899fb69d25 ("ovl: fsync after metadata copy-up")
+Depends: 50e638beb67e0 ("ovl: Use str_on_off() helper in ovl_show_options()")
+Cc: stable@vger.kernel.org # v6.12+
+Signed-off-by: Fei Lv <feilv@asrmicro.com>
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/filesystems/overlayfs.rst |   50 ++++++++++++++++++++++++++++++++
+ fs/overlayfs/copy_up.c                  |    6 +--
+ fs/overlayfs/overlayfs.h                |   21 +++++++++++++
+ fs/overlayfs/ovl_entry.h                |    7 ----
+ fs/overlayfs/params.c                   |   33 +++++++++++++++++----
+ fs/overlayfs/super.c                    |    2 -
+ 6 files changed, 104 insertions(+), 15 deletions(-)
+
+--- a/Documentation/filesystems/overlayfs.rst
++++ b/Documentation/filesystems/overlayfs.rst
+@@ -783,6 +783,56 @@ controlled by the "uuid" mount option, w
+     mounted with "uuid=on".
++Durability and copy up
++----------------------
++
++The fsync(2) system call ensures that the data and metadata of a file
++are safely written to the backing storage, which is expected to
++guarantee the existence of the information post system crash.
++
++Without an fsync(2) call, there is no guarantee that the observed
++data after a system crash will be either the old or the new data, but
++in practice, the observed data after crash is often the old or new data
++or a mix of both.
++
++When an overlayfs file is modified for the first time, copy up will
++create a copy of the lower file and its parent directories in the upper
++layer.  Since the Linux filesystem API does not enforce any particular
++ordering on storing changes without explicit fsync(2) calls, in case
++of a system crash, the upper file could end up with no data at all
++(i.e. zeros), which would be an unusual outcome.  To avoid this
++experience, overlayfs calls fsync(2) on the upper file before completing
++data copy up with rename(2) or link(2) to make the copy up "atomic".
++
++By default, overlayfs does not explicitly call fsync(2) on copied up
++directories or on metadata-only copy up, so it provides no guarantee to
++persist the user's modification unless the user calls fsync(2).
++The fsync during copy up only guarantees that if a copy up is observed
++after a crash, the observed data is not zeroes or intermediate values
++from the copy up staging area.
++
++On traditional local filesystems with a single journal (e.g. ext4, xfs),
++fsync on a file also persists the parent directory changes, because they
++are usually modified in the same transaction, so metadata durability during
++data copy up effectively comes for free.  Overlayfs further limits risk by
++disallowing network filesystems as upper layer.
++
++Overlayfs can be tuned to prefer performance or durability when storing
++to the underlying upper layer.  This is controlled by the "fsync" mount
++option, which supports these values:
++
++- "auto": (default)
++    Call fsync(2) on upper file before completion of data copy up.
++    No explicit fsync(2) on directory or metadata-only copy up.
++- "strict":
++    Call fsync(2) on upper file and directories before completion of any
++    copy up.
++- "volatile": [*]
++    Prefer performance over durability (see `Volatile mount`_)
++
++[*] The mount option "volatile" is an alias to "fsync=volatile".
++
++
+ Volatile mount
+ --------------
+--- a/fs/overlayfs/copy_up.c
++++ b/fs/overlayfs/copy_up.c
+@@ -1146,15 +1146,15 @@ static int ovl_copy_up_one(struct dentry
+               return -EOVERFLOW;
+       /*
+-       * With metacopy disabled, we fsync after final metadata copyup, for
++       * With "fsync=strict", we fsync after final metadata copyup, for
+        * both regular files and directories to get atomic copyup semantics
+        * on filesystems that do not use strict metadata ordering (e.g. ubifs).
+        *
+-       * With metacopy enabled we want to avoid fsync on all meta copyup
++       * By default, we want to avoid fsync on all meta copyup, because
+        * that will hurt performance of workloads such as chown -R, so we
+        * only fsync on data copyup as legacy behavior.
+        */
+-      ctx.metadata_fsync = !OVL_FS(dentry->d_sb)->config.metacopy &&
++      ctx.metadata_fsync = ovl_should_sync_metadata(OVL_FS(dentry->d_sb)) &&
+                            (S_ISREG(ctx.stat.mode) || S_ISDIR(ctx.stat.mode));
+       ctx.metacopy = ovl_need_meta_copy_up(dentry, ctx.stat.mode, flags);
+--- a/fs/overlayfs/overlayfs.h
++++ b/fs/overlayfs/overlayfs.h
+@@ -99,6 +99,12 @@ enum {
+       OVL_VERITY_REQUIRE,
+ };
++enum {
++      OVL_FSYNC_VOLATILE,
++      OVL_FSYNC_AUTO,
++      OVL_FSYNC_STRICT,
++};
++
+ /*
+  * The tuple (fh,uuid) is a universal unique identifier for a copy up origin,
+  * where:
+@@ -656,6 +662,21 @@ static inline bool ovl_xino_warn(struct
+       return ofs->config.xino == OVL_XINO_ON;
+ }
++static inline bool ovl_should_sync(struct ovl_fs *ofs)
++{
++      return ofs->config.fsync_mode != OVL_FSYNC_VOLATILE;
++}
++
++static inline bool ovl_should_sync_metadata(struct ovl_fs *ofs)
++{
++      return ofs->config.fsync_mode == OVL_FSYNC_STRICT;
++}
++
++static inline bool ovl_is_volatile(struct ovl_config *config)
++{
++      return config->fsync_mode == OVL_FSYNC_VOLATILE;
++}
++
+ /*
+  * To avoid regressions in existing setups with overlay lower offline changes,
+  * we allow lower changes only if none of the new features are used.
+--- a/fs/overlayfs/ovl_entry.h
++++ b/fs/overlayfs/ovl_entry.h
+@@ -18,7 +18,7 @@ struct ovl_config {
+       int xino;
+       bool metacopy;
+       bool userxattr;
+-      bool ovl_volatile;
++      int fsync_mode;
+ };
+ struct ovl_sb {
+@@ -120,11 +120,6 @@ static inline struct ovl_fs *OVL_FS(stru
+       return (struct ovl_fs *)sb->s_fs_info;
+ }
+-static inline bool ovl_should_sync(struct ovl_fs *ofs)
+-{
+-      return !ofs->config.ovl_volatile;
+-}
+-
+ static inline unsigned int ovl_numlower(struct ovl_entry *oe)
+ {
+       return oe ? oe->__numlower : 0;
+--- a/fs/overlayfs/params.c
++++ b/fs/overlayfs/params.c
+@@ -58,6 +58,7 @@ enum ovl_opt {
+       Opt_xino,
+       Opt_metacopy,
+       Opt_verity,
++      Opt_fsync,
+       Opt_volatile,
+       Opt_override_creds,
+ };
+@@ -140,6 +141,23 @@ static int ovl_verity_mode_def(void)
+       return OVL_VERITY_OFF;
+ }
++static const struct constant_table ovl_parameter_fsync[] = {
++      { "volatile",   OVL_FSYNC_VOLATILE },
++      { "auto",       OVL_FSYNC_AUTO     },
++      { "strict",     OVL_FSYNC_STRICT   },
++      {}
++};
++
++static const char *ovl_fsync_mode(struct ovl_config *config)
++{
++      return ovl_parameter_fsync[config->fsync_mode].name;
++}
++
++static int ovl_fsync_mode_def(void)
++{
++      return OVL_FSYNC_AUTO;
++}
++
+ const struct fs_parameter_spec ovl_parameter_spec[] = {
+       fsparam_string_empty("lowerdir",    Opt_lowerdir),
+       fsparam_file_or_string("lowerdir+", Opt_lowerdir_add),
+@@ -155,6 +173,7 @@ const struct fs_parameter_spec ovl_param
+       fsparam_enum("xino",                Opt_xino, ovl_parameter_xino),
+       fsparam_enum("metacopy",            Opt_metacopy, ovl_parameter_bool),
+       fsparam_enum("verity",              Opt_verity, ovl_parameter_verity),
++      fsparam_enum("fsync",               Opt_fsync, ovl_parameter_fsync),
+       fsparam_flag("volatile",            Opt_volatile),
+       fsparam_flag_no("override_creds",   Opt_override_creds),
+       {}
+@@ -665,8 +684,11 @@ static int ovl_parse_param(struct fs_con
+       case Opt_verity:
+               config->verity_mode = result.uint_32;
+               break;
++      case Opt_fsync:
++              config->fsync_mode = result.uint_32;
++              break;
+       case Opt_volatile:
+-              config->ovl_volatile = true;
++              config->fsync_mode = OVL_FSYNC_VOLATILE;
+               break;
+       case Opt_userxattr:
+               config->userxattr = true;
+@@ -800,6 +822,7 @@ int ovl_init_fs_context(struct fs_contex
+       ofs->config.nfs_export          = ovl_nfs_export_def;
+       ofs->config.xino                = ovl_xino_def();
+       ofs->config.metacopy            = ovl_metacopy_def;
++      ofs->config.fsync_mode          = ovl_fsync_mode_def();
+       fc->s_fs_info           = ofs;
+       fc->fs_private          = ctx;
+@@ -870,9 +893,9 @@ int ovl_fs_params_verify(const struct ov
+               config->index = false;
+       }
+-      if (!config->upperdir && config->ovl_volatile) {
++      if (!config->upperdir && ovl_is_volatile(config)) {
+               pr_info("option \"volatile\" is meaningless in a non-upper mount, ignoring it.\n");
+-              config->ovl_volatile = false;
++              config->fsync_mode = ovl_fsync_mode_def();
+       }
+       if (!config->upperdir && config->uuid == OVL_UUID_ON) {
+@@ -1070,8 +1093,8 @@ int ovl_show_options(struct seq_file *m,
+               seq_printf(m, ",xino=%s", ovl_xino_mode(&ofs->config));
+       if (ofs->config.metacopy != ovl_metacopy_def)
+               seq_printf(m, ",metacopy=%s", str_on_off(ofs->config.metacopy));
+-      if (ofs->config.ovl_volatile)
+-              seq_puts(m, ",volatile");
++      if (ofs->config.fsync_mode != ovl_fsync_mode_def())
++              seq_printf(m, ",fsync=%s", ovl_fsync_mode(&ofs->config));
+       if (ofs->config.userxattr)
+               seq_puts(m, ",userxattr");
+       if (ofs->config.verity_mode != ovl_verity_mode_def())
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -776,7 +776,7 @@ static int ovl_make_workdir(struct super
+        * For volatile mount, create a incompat/volatile/dirty file to keep
+        * track of it.
+        */
+-      if (ofs->config.ovl_volatile) {
++      if (ovl_is_volatile(&ofs->config)) {
+               err = ovl_create_volatile_dirty(ofs);
+               if (err < 0) {
+                       pr_err("Failed to create volatile/dirty file.\n");
diff --git a/queue-6.19/phy-qcom-qmp-ufs-fix-sm8650-pcs-table-for-gear-4.patch b/queue-6.19/phy-qcom-qmp-ufs-fix-sm8650-pcs-table-for-gear-4.patch
new file mode 100644 (file)
index 0000000..d2d3cbd
--- /dev/null
@@ -0,0 +1,59 @@
+From 81af9e40e2e4e1aa95f09fb34811760be6742c58 Mon Sep 17 00:00:00 2001
+From: Abel Vesa <abel.vesa@oss.qualcomm.com>
+Date: Thu, 19 Feb 2026 13:11:48 +0200
+Subject: phy: qcom: qmp-ufs: Fix SM8650 PCS table for Gear 4
+
+From: Abel Vesa <abel.vesa@oss.qualcomm.com>
+
+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 <nitin.rawat@oss.qualcomm.com>
+Signed-off-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # 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 <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -928,6 +928,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),
+@@ -937,13 +938,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.19/scsi-ibmvfc-fix-oob-access-in-ibmvfc_discover_targets_done.patch b/queue-6.19/scsi-ibmvfc-fix-oob-access-in-ibmvfc_discover_targets_done.patch
new file mode 100644 (file)
index 0000000..72dda4f
--- /dev/null
@@ -0,0 +1,45 @@
+From 61d099ac4a7a8fb11ebdb6e2ec8d77f38e77362f Mon Sep 17 00:00:00 2001
+From: Tyllis Xu <livelycarpet87@gmail.com>
+Date: Sat, 14 Mar 2026 12:01:50 -0500
+Subject: scsi: ibmvfc: Fix OOB access in ibmvfc_discover_targets_done()
+
+From: Tyllis Xu <livelycarpet87@gmail.com>
+
+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 <danisjiang@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Tyllis Xu <LivelyCarpet87@gmail.com>
+Reviewed-by: Dave Marquardt <davemarq@linux.ibm.com>
+Acked-by: Tyrel Datwyler <tyreld@linux.ibm.com>
+Link: https://patch.msgid.link/20260314170151.548614-1-LivelyCarpet87@gmail.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -4965,7 +4965,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.19/scsi-ses-handle-positive-scsi-error-from-ses_recv_diag.patch b/queue-6.19/scsi-ses-handle-positive-scsi-error-from-ses_recv_diag.patch
new file mode 100644 (file)
index 0000000..9f47cea
--- /dev/null
@@ -0,0 +1,36 @@
+From 7a9f448d44127217fabc4065c5ba070d4e0b5d37 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Mon, 23 Feb 2026 16:44:59 +0100
+Subject: scsi: ses: Handle positive SCSI error from ses_recv_diag()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+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 <James.Bottomley@HansenPartnership.com>
+Cc: Martin K. Petersen <martin.petersen@oracle.com>
+Cc: stable <stable@kernel.org>
+Assisted-by: gkh_clanker_2000
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Link: https://patch.msgid.link/2026022301-bony-overstock-a07f@gregkh
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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) {
index bbb1bb7773eea6e382a00a3ce990fc5073ca5652..0b4ed579c7e8015cfe91f04350a9cd0df903edce 100644 (file)
@@ -233,3 +233,57 @@ virt-tdx-guest-fix-handling-of-host-controlled-quote-buffer-length.patch
 virtio_net-fix-uaf-on-dst_ops-when-iff_xmit_dst_release-is-cleared-and-napi_tx-is-false.patch
 vfio-pci-fix-double-free-in-dma-buf-feature.patch
 erofs-add-gfp_noio-in-the-bio-completion-if-needed.patch
+alarmtimer-fix-argument-order-in-alarm_timer_forward.patch
+mm-huge_memory-fix-folio-isn-t-locked-in-softleaf_to_folio.patch
+writeback-don-t-block-sync-for-filesystems-with-no-data-integrity-guarantees.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
+x86-fred-fix-early-boot-failures-on-sev-es-snp-guests.patch
+phy-qcom-qmp-ufs-fix-sm8650-pcs-table-for-gear-4.patch
+ovl-make-fsync-after-metadata-copy-up-opt-in-mount-option.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
+kvm-x86-mmu-only-warn-in-direct-mmus-when-overwriting-shadow-present-spte.patch
+jbd2-gracefully-abort-on-checkpointing-state-corruptions.patch
+irqchip-qcom-mpm-add-missing-mailbox-tx-done-acknowledgment.patch
+iomap-fix-invalid-folio-access-when-i_blkbits-differs-from-i-o-granularity.patch
+i2c-designware-amdisp-fix-resume-probe-race-condition-issue.patch
+futex-clear-stale-exiting-pointer-in-futex_lock_pi-retry-path.patch
+i2c-imx-fix-i2c-issue-when-reading-multiple-messages.patch
+i2c-imx-ensure-no-clock-is-generated-after-last-read.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-amdgpu-fix-strsep-corrupting-lockup_timeout-on-multi-gpu-v3.patch
+drm-amd-display-fix-dce-lvds-handling.patch
+drm-amd-display-fix-drm_edid-leak-in-amdgpu_dm.patch
+drm-amd-display-check-if-ext_caps-is-valid-in-bl-setup.patch
+drm-i915-dp_tunnel-fix-error-handling-when-clearing-stream-bw-in-atomic-state.patch
+drm-i915-order-op-vs.-timeout-correctly-in-__wait_for.patch
+drm-i915-unlink-nv12-planes-earlier.patch
+loongarch-fix-missing-null-checks-for-kstrdup.patch
+loongarch-vdso-emit-gnu_eh_frame-correctly.patch
+loongarch-workaround-ls2k-ls7a-gpu-dma-hang-bug.patch
+loongarch-kvm-make-kvm_get_vcpu_by_cpuid-more-robust.patch
+loongarch-kvm-fix-base-address-calculation-in-kvm_eiointc_regs_access.patch
+loongarch-kvm-handle-the-case-that-eiointc-s-coremap-is-empty.patch
+drm-amd-pm-return-eopnotsupp-for-unsupported-od_mclk-on-smu_v13_0_6.patch
+mm-memory-fix-pmd-pud-checks-in-follow_pfnmap_start.patch
+mm-mseal-update-vma-end-correctly-on-merge.patch
+mm-damon-sysfs-fix-param_ctx-leak-on-damon_sysfs_new_test_ctx-failure.patch
+mm-damon-sysfs-check-contexts-nr-before-accessing-contexts_arr.patch
+mm-damon-sysfs-check-contexts-nr-in-repeat_call_fn.patch
+mm-pagewalk-fix-race-between-concurrent-split-and-refault.patch
+xfs-stop-reclaim-before-pushing-ail-during-unmount.patch
+xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch
+xfs-avoid-dereferencing-log-items-after-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.19/writeback-don-t-block-sync-for-filesystems-with-no-data-integrity-guarantees.patch b/queue-6.19/writeback-don-t-block-sync-for-filesystems-with-no-data-integrity-guarantees.patch
new file mode 100644 (file)
index 0000000..b8c2de8
--- /dev/null
@@ -0,0 +1,173 @@
+From 76f9377cd2ab7a9220c25d33940d9ca20d368172 Mon Sep 17 00:00:00 2001
+From: Joanne Koong <joannelkoong@gmail.com>
+Date: Thu, 19 Mar 2026 17:51:45 -0700
+Subject: writeback: don't block sync for filesystems with no data integrity guarantees
+
+From: Joanne Koong <joannelkoong@gmail.com>
+
+commit 76f9377cd2ab7a9220c25d33940d9ca20d368172 upstream.
+
+Add a SB_I_NO_DATA_INTEGRITY superblock flag for filesystems that cannot
+guarantee data persistence on sync (eg fuse). For superblocks with this
+flag set, sync kicks off writeback of dirty inodes but does not wait
+for the flusher threads to complete the writeback.
+
+This replaces the per-inode AS_NO_DATA_INTEGRITY mapping flag added in
+commit f9a49aa302a0 ("fs/writeback: skip AS_NO_DATA_INTEGRITY mappings
+in wait_sb_inodes()"). The flag belongs at the superblock level because
+data integrity is a filesystem-wide property, not a per-inode one.
+Having this flag at the superblock level also allows us to skip having
+to iterate every dirty inode in wait_sb_inodes() only to skip each inode
+individually.
+
+Prior to this commit, mappings with no data integrity guarantees skipped
+waiting on writeback completion but still waited on the flusher threads
+to finish initiating the writeback. Waiting on the flusher threads is
+unnecessary. This commit kicks off writeback but does not wait on the
+flusher threads. This change properly addresses a recent report [1] for
+a suspend-to-RAM hang seen on fuse-overlayfs that was caused by waiting
+on the flusher threads to finish:
+
+Workqueue: pm_fs_sync pm_fs_sync_work_fn
+Call Trace:
+ <TASK>
+ __schedule+0x457/0x1720
+ schedule+0x27/0xd0
+ wb_wait_for_completion+0x97/0xe0
+ sync_inodes_sb+0xf8/0x2e0
+ __iterate_supers+0xdc/0x160
+ ksys_sync+0x43/0xb0
+ pm_fs_sync_work_fn+0x17/0xa0
+ process_one_work+0x193/0x350
+ worker_thread+0x1a1/0x310
+ kthread+0xfc/0x240
+ ret_from_fork+0x243/0x280
+ ret_from_fork_asm+0x1a/0x30
+ </TASK>
+
+On fuse this is problematic because there are paths that may cause the
+flusher thread to block (eg if systemd freezes the user session cgroups
+first, which freezes the fuse daemon, before invoking the kernel
+suspend. The kernel suspend triggers ->write_node() which on fuse issues
+a synchronous setattr request, which cannot be processed since the
+daemon is frozen. Or if the daemon is buggy and cannot properly complete
+writeback, initiating writeback on a dirty folio already under writeback
+leads to writeback_get_folio() -> folio_prepare_writeback() ->
+unconditional wait on writeback to finish, which will cause a hang).
+This commit restores fuse to its prior behavior before tmp folios were
+removed, where sync was essentially a no-op.
+
+[1] https://lore.kernel.org/linux-fsdevel/CAJnrk1a-asuvfrbKXbEwwDSctvemF+6zfhdnuzO65Pt8HsFSRw@mail.gmail.com/T/#m632c4648e9cafc4239299887109ebd880ac6c5c1
+
+Fixes: 0c58a97f919c ("fuse: remove tmp folio for writebacks and internal rb tree")
+Reported-by: John <therealgraysky@proton.me>
+Cc: stable@vger.kernel.org
+Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
+Link: https://patch.msgid.link/20260320005145.2483161-2-joannelkoong@gmail.com
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/fs-writeback.c              |   18 ++++++++++++------
+ fs/fuse/file.c                 |    4 +---
+ fs/fuse/inode.c                |    1 +
+ include/linux/fs/super_types.h |    1 +
+ include/linux/pagemap.h        |   11 -----------
+ 5 files changed, 15 insertions(+), 20 deletions(-)
+
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -2759,13 +2759,8 @@ static void wait_sb_inodes(struct super_
+                * The mapping can appear untagged while still on-list since we
+                * do not have the mapping lock. Skip it here, wb completion
+                * will remove it.
+-               *
+-               * If the mapping does not have data integrity semantics,
+-               * there's no need to wait for the writeout to complete, as the
+-               * mapping cannot guarantee that data is persistently stored.
+                */
+-              if (!mapping_tagged(mapping, PAGECACHE_TAG_WRITEBACK) ||
+-                  mapping_no_data_integrity(mapping))
++              if (!mapping_tagged(mapping, PAGECACHE_TAG_WRITEBACK))
+                       continue;
+               spin_unlock_irq(&sb->s_inode_wblist_lock);
+@@ -2900,6 +2895,17 @@ void sync_inodes_sb(struct super_block *
+        */
+       if (bdi == &noop_backing_dev_info)
+               return;
++
++      /*
++       * If the superblock has SB_I_NO_DATA_INTEGRITY set, there's no need to
++       * wait for the writeout to complete, as the filesystem cannot guarantee
++       * data persistence on sync. Just kick off writeback and return.
++       */
++      if (sb->s_iflags & SB_I_NO_DATA_INTEGRITY) {
++              wakeup_flusher_threads_bdi(bdi, WB_REASON_SYNC);
++              return;
++      }
++
+       WARN_ON(!rwsem_is_locked(&sb->s_umount));
+       /* protect against inode wb switch, see inode_switch_wbs_work_fn() */
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -3200,10 +3200,8 @@ void fuse_init_file_inode(struct inode *
+       inode->i_fop = &fuse_file_operations;
+       inode->i_data.a_ops = &fuse_file_aops;
+-      if (fc->writeback_cache) {
++      if (fc->writeback_cache)
+               mapping_set_writeback_may_deadlock_on_reclaim(&inode->i_data);
+-              mapping_set_no_data_integrity(&inode->i_data);
+-      }
+       INIT_LIST_HEAD(&fi->write_files);
+       INIT_LIST_HEAD(&fi->queued_writes);
+--- a/fs/fuse/inode.c
++++ b/fs/fuse/inode.c
+@@ -1709,6 +1709,7 @@ static void fuse_sb_defaults(struct supe
+       sb->s_export_op = &fuse_export_operations;
+       sb->s_iflags |= SB_I_IMA_UNVERIFIABLE_SIGNATURE;
+       sb->s_iflags |= SB_I_NOIDMAP;
++      sb->s_iflags |= SB_I_NO_DATA_INTEGRITY;
+       if (sb->s_user_ns != &init_user_ns)
+               sb->s_iflags |= SB_I_UNTRUSTED_MOUNTER;
+       sb->s_flags &= ~(SB_NOSEC | SB_I_VERSION);
+--- a/include/linux/fs/super_types.h
++++ b/include/linux/fs/super_types.h
+@@ -332,5 +332,6 @@ struct super_block {
+ #define SB_I_NOUMASK  0x00001000      /* VFS does not apply umask */
+ #define SB_I_NOIDMAP  0x00002000      /* No idmapped mounts on this superblock */
+ #define SB_I_ALLOW_HSM        0x00004000      /* Allow HSM events on this superblock */
++#define SB_I_NO_DATA_INTEGRITY        0x00008000 /* fs cannot guarantee data persistence on sync */
+ #endif /* _LINUX_FS_SUPER_TYPES_H */
+--- a/include/linux/pagemap.h
++++ b/include/linux/pagemap.h
+@@ -210,7 +210,6 @@ enum mapping_flags {
+       AS_WRITEBACK_MAY_DEADLOCK_ON_RECLAIM = 9,
+       AS_KERNEL_FILE = 10,    /* mapping for a fake kernel file that shouldn't
+                                  account usage to user cgroups */
+-      AS_NO_DATA_INTEGRITY = 11, /* no data integrity guarantees */
+       /* Bits 16-25 are used for FOLIO_ORDER */
+       AS_FOLIO_ORDER_BITS = 5,
+       AS_FOLIO_ORDER_MIN = 16,
+@@ -346,16 +345,6 @@ static inline bool mapping_writeback_may
+       return test_bit(AS_WRITEBACK_MAY_DEADLOCK_ON_RECLAIM, &mapping->flags);
+ }
+-static inline void mapping_set_no_data_integrity(struct address_space *mapping)
+-{
+-      set_bit(AS_NO_DATA_INTEGRITY, &mapping->flags);
+-}
+-
+-static inline bool mapping_no_data_integrity(const struct address_space *mapping)
+-{
+-      return test_bit(AS_NO_DATA_INTEGRITY, &mapping->flags);
+-}
+-
+ static inline gfp_t mapping_gfp_mask(const struct address_space *mapping)
+ {
+       return mapping->gfp_mask;
diff --git a/queue-6.19/x86-cpu-enable-fsgsbase-early-in-cpu_init_exception_handling.patch b/queue-6.19/x86-cpu-enable-fsgsbase-early-in-cpu_init_exception_handling.patch
new file mode 100644 (file)
index 0000000..314a325
--- /dev/null
@@ -0,0 +1,137 @@
+From 05243d490bb7852a8acca7b5b5658019c7797a52 Mon Sep 17 00:00:00 2001
+From: Nikunj A Dadhania <nikunj@amd.com>
+Date: Wed, 18 Mar 2026 07:56:52 +0000
+Subject: x86/cpu: Enable FSGSBASE early in cpu_init_exception_handling()
+
+From: Nikunj A Dadhania <nikunj@amd.com>
+
+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 <bp@alien8.de>
+Suggested-by: Sohil Mehta <sohil.mehta@intel.com>
+Signed-off-by: Nikunj A Dadhania <nikunj@amd.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Reviewed-by: Sohil Mehta <sohil.mehta@intel.com>
+Cc: <stable@kernel.org>
+Link: https://patch.msgid.link/20260318075654.1792916-2-nikunj@amd.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -2042,12 +2042,6 @@ static void identify_cpu(struct cpuinfo_
+       setup_umip(c);
+       setup_lass(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."
+@@ -2408,6 +2402,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.19/x86-cpu-remove-x86_cr4_fred-from-the-cr4-pinned-bits-mask.patch b/queue-6.19/x86-cpu-remove-x86_cr4_fred-from-the-cr4-pinned-bits-mask.patch
new file mode 100644 (file)
index 0000000..7ae8376
--- /dev/null
@@ -0,0 +1,63 @@
+From 411df123c017169922cc767affce76282b8e6c85 Mon Sep 17 00:00:00 2001
+From: "Borislav Petkov (AMD)" <bp@alien8.de>
+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) <bp@alien8.de>
+
+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 <dave.hansen@linux.intel.com>
+Suggested-by: Peter Zijlstra <peterz@infradead.org>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Cc: <stable@kernel.org> # 6.12+
+Link: https://lore.kernel.org/r/177385987098.1647592.3381141860481415647.tip-bot2@tip-bot2
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -433,7 +433,7 @@ static __always_inline void setup_lass(s
+ /* 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.19/x86-fred-fix-early-boot-failures-on-sev-es-snp-guests.patch b/queue-6.19/x86-fred-fix-early-boot-failures-on-sev-es-snp-guests.patch
new file mode 100644 (file)
index 0000000..d28befa
--- /dev/null
@@ -0,0 +1,89 @@
+From 3645eb7e3915990a149460c151a00894cb586253 Mon Sep 17 00:00:00 2001
+From: Nikunj A Dadhania <nikunj@amd.com>
+Date: Wed, 18 Mar 2026 07:56:54 +0000
+Subject: x86/fred: Fix early boot failures on SEV-ES/SNP guests
+
+From: Nikunj A Dadhania <nikunj@amd.com>
+
+commit 3645eb7e3915990a149460c151a00894cb586253 upstream.
+
+FRED-enabled SEV-(ES,SNP) guests fail to boot due to the following issues
+in the early boot sequence:
+
+* FRED does not have a #VC exception handler in the dispatch logic
+
+* Early FRED #VC exceptions attempt to use uninitialized per-CPU GHCBs
+  instead of boot_ghcb
+
+Add X86_TRAP_VC case to fred_hwexc() with a new exc_vmm_communication()
+function that provides the unified entry point FRED requires, dispatching
+to existing user/kernel handlers based on privilege level. The function is
+already declared via DECLARE_IDTENTRY_VC().
+
+Fix early GHCB access by falling back to boot_ghcb in
+__sev_{get,put}_ghcb() when per-CPU GHCBs are not yet initialized.
+
+Fixes: 14619d912b65 ("x86/fred: FRED entry/exit and dispatch code")
+Signed-off-by: Nikunj A Dadhania <nikunj@amd.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
+Cc: <stable@kernel.org>  # 6.12+
+Link: https://patch.msgid.link/20260318075654.1792916-4-nikunj@amd.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/coco/sev/noinstr.c |    6 ++++++
+ arch/x86/entry/entry_fred.c |   14 ++++++++++++++
+ 2 files changed, 20 insertions(+)
+
+--- a/arch/x86/coco/sev/noinstr.c
++++ b/arch/x86/coco/sev/noinstr.c
+@@ -120,6 +120,9 @@ noinstr struct ghcb *__sev_get_ghcb(stru
+       WARN_ON(!irqs_disabled());
++      if (!sev_cfg.ghcbs_initialized)
++              return boot_ghcb;
++
+       data = this_cpu_read(runtime_data);
+       ghcb = &data->ghcb_page;
+@@ -163,6 +166,9 @@ noinstr void __sev_put_ghcb(struct ghcb_
+       WARN_ON(!irqs_disabled());
++      if (!sev_cfg.ghcbs_initialized)
++              return;
++
+       data = this_cpu_read(runtime_data);
+       ghcb = &data->ghcb_page;
+--- a/arch/x86/entry/entry_fred.c
++++ b/arch/x86/entry/entry_fred.c
+@@ -176,6 +176,16 @@ static noinstr void fred_extint(struct p
+       }
+ }
++#ifdef CONFIG_AMD_MEM_ENCRYPT
++noinstr void exc_vmm_communication(struct pt_regs *regs, unsigned long error_code)
++{
++      if (user_mode(regs))
++              return user_exc_vmm_communication(regs, error_code);
++      else
++              return kernel_exc_vmm_communication(regs, error_code);
++}
++#endif
++
+ static noinstr void fred_hwexc(struct pt_regs *regs, unsigned long error_code)
+ {
+       /* Optimize for #PF. That's the only exception which matters performance wise */
+@@ -206,6 +216,10 @@ static noinstr void fred_hwexc(struct pt
+ #ifdef CONFIG_X86_CET
+       case X86_TRAP_CP: return exc_control_protection(regs, error_code);
+ #endif
++#ifdef CONFIG_AMD_MEM_ENCRYPT
++      case X86_TRAP_VC: return exc_vmm_communication(regs, error_code);
++#endif
++
+       default: return fred_bad_type(regs, error_code);
+       }
diff --git a/queue-6.19/xfs-avoid-dereferencing-log-items-after-push-callbacks.patch b/queue-6.19/xfs-avoid-dereferencing-log-items-after-push-callbacks.patch
new file mode 100644 (file)
index 0000000..9bc3b00
--- /dev/null
@@ -0,0 +1,165 @@
+From 79ef34ec0554ec04bdbafafbc9836423734e1bd6 Mon Sep 17 00:00:00 2001
+From: Yuto Ohnuki <ytohnuki@amazon.com>
+Date: Tue, 10 Mar 2026 18:38:38 +0000
+Subject: xfs: avoid dereferencing log items after push callbacks
+
+From: Yuto Ohnuki <ytohnuki@amazon.com>
+
+commit 79ef34ec0554ec04bdbafafbc9836423734e1bd6 upstream.
+
+After xfsaild_push_item() calls iop_push(), the log item may have been
+freed if the AIL lock was dropped during the push. Background inode
+reclaim or the dquot shrinker can free the log item while the AIL lock
+is not held, and the tracepoints in the switch statement dereference
+the log item after iop_push() returns.
+
+Fix this by capturing the log item type, flags, and LSN before calling
+xfsaild_push_item(), and introducing a new xfs_ail_push_class trace
+event class that takes these pre-captured values and the ailp pointer
+instead of the log item pointer.
+
+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 <ytohnuki@amazon.com>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Carlos Maiolino <cem@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/xfs_trace.h     |   36 ++++++++++++++++++++++++++++++++----
+ fs/xfs/xfs_trans_ail.c |   26 +++++++++++++++++++-------
+ 2 files changed, 51 insertions(+), 11 deletions(-)
+
+--- a/fs/xfs/xfs_trace.h
++++ b/fs/xfs/xfs_trace.h
+@@ -56,6 +56,7 @@
+ #include <linux/tracepoint.h>
+ struct xfs_agf;
++struct xfs_ail;
+ struct xfs_alloc_arg;
+ struct xfs_attr_list_context;
+ struct xfs_buf_log_item;
+@@ -1647,16 +1648,43 @@ TRACE_EVENT(xfs_log_force,
+ DEFINE_EVENT(xfs_log_item_class, name, \
+       TP_PROTO(struct xfs_log_item *lip), \
+       TP_ARGS(lip))
+-DEFINE_LOG_ITEM_EVENT(xfs_ail_push);
+-DEFINE_LOG_ITEM_EVENT(xfs_ail_pinned);
+-DEFINE_LOG_ITEM_EVENT(xfs_ail_locked);
+-DEFINE_LOG_ITEM_EVENT(xfs_ail_flushing);
+ DEFINE_LOG_ITEM_EVENT(xfs_cil_whiteout_mark);
+ DEFINE_LOG_ITEM_EVENT(xfs_cil_whiteout_skip);
+ DEFINE_LOG_ITEM_EVENT(xfs_cil_whiteout_unpin);
+ DEFINE_LOG_ITEM_EVENT(xlog_ail_insert_abort);
+ DEFINE_LOG_ITEM_EVENT(xfs_trans_free_abort);
++DECLARE_EVENT_CLASS(xfs_ail_push_class,
++      TP_PROTO(struct xfs_ail *ailp, uint type, unsigned long flags, xfs_lsn_t lsn),
++      TP_ARGS(ailp, type, flags, lsn),
++      TP_STRUCT__entry(
++              __field(dev_t, dev)
++              __field(uint, type)
++              __field(unsigned long, flags)
++              __field(xfs_lsn_t, lsn)
++      ),
++      TP_fast_assign(
++              __entry->dev = ailp->ail_log->l_mp->m_super->s_dev;
++              __entry->type = type;
++              __entry->flags = flags;
++              __entry->lsn = lsn;
++      ),
++      TP_printk("dev %d:%d lsn %d/%d type %s flags %s",
++                MAJOR(__entry->dev), MINOR(__entry->dev),
++                CYCLE_LSN(__entry->lsn), BLOCK_LSN(__entry->lsn),
++                __print_symbolic(__entry->type, XFS_LI_TYPE_DESC),
++                __print_flags(__entry->flags, "|", XFS_LI_FLAGS))
++)
++
++#define DEFINE_AIL_PUSH_EVENT(name) \
++DEFINE_EVENT(xfs_ail_push_class, name, \
++      TP_PROTO(struct xfs_ail *ailp, uint type, unsigned long flags, xfs_lsn_t lsn), \
++      TP_ARGS(ailp, type, flags, lsn))
++DEFINE_AIL_PUSH_EVENT(xfs_ail_push);
++DEFINE_AIL_PUSH_EVENT(xfs_ail_pinned);
++DEFINE_AIL_PUSH_EVENT(xfs_ail_locked);
++DEFINE_AIL_PUSH_EVENT(xfs_ail_flushing);
++
+ DECLARE_EVENT_CLASS(xfs_ail_class,
+       TP_PROTO(struct xfs_log_item *lip, xfs_lsn_t old_lsn, xfs_lsn_t new_lsn),
+       TP_ARGS(lip, old_lsn, new_lsn),
+--- a/fs/xfs/xfs_trans_ail.c
++++ b/fs/xfs/xfs_trans_ail.c
+@@ -365,6 +365,12 @@ xfsaild_resubmit_item(
+       return XFS_ITEM_SUCCESS;
+ }
++/*
++ * Push a single log item from the AIL.
++ *
++ * @lip may have been released and freed by the time this function returns,
++ * so callers must not dereference the log item afterwards.
++ */
+ static inline uint
+ xfsaild_push_item(
+       struct xfs_ail          *ailp,
+@@ -505,7 +511,10 @@ xfsaild_push(
+       lsn = lip->li_lsn;
+       while ((XFS_LSN_CMP(lip->li_lsn, ailp->ail_target) <= 0)) {
+-              int     lock_result;
++              int             lock_result;
++              uint            type = lip->li_type;
++              unsigned long   flags = lip->li_flags;
++              xfs_lsn_t       item_lsn = lip->li_lsn;
+               if (test_bit(XFS_LI_FLUSHING, &lip->li_flags))
+                       goto next_item;
+@@ -514,14 +523,17 @@ xfsaild_push(
+                * Note that iop_push may unlock and reacquire the AIL lock.  We
+                * rely on the AIL cursor implementation to be able to deal with
+                * the dropped lock.
++               *
++               * The log item may have been freed by the push, so it must not
++               * be accessed or dereferenced below this line.
+                */
+               lock_result = xfsaild_push_item(ailp, lip);
+               switch (lock_result) {
+               case XFS_ITEM_SUCCESS:
+                       XFS_STATS_INC(mp, xs_push_ail_success);
+-                      trace_xfs_ail_push(lip);
++                      trace_xfs_ail_push(ailp, type, flags, item_lsn);
+-                      ailp->ail_last_pushed_lsn = lsn;
++                      ailp->ail_last_pushed_lsn = item_lsn;
+                       break;
+               case XFS_ITEM_FLUSHING:
+@@ -537,22 +549,22 @@ xfsaild_push(
+                        * AIL is being flushed.
+                        */
+                       XFS_STATS_INC(mp, xs_push_ail_flushing);
+-                      trace_xfs_ail_flushing(lip);
++                      trace_xfs_ail_flushing(ailp, type, flags, item_lsn);
+                       flushing++;
+-                      ailp->ail_last_pushed_lsn = lsn;
++                      ailp->ail_last_pushed_lsn = item_lsn;
+                       break;
+               case XFS_ITEM_PINNED:
+                       XFS_STATS_INC(mp, xs_push_ail_pinned);
+-                      trace_xfs_ail_pinned(lip);
++                      trace_xfs_ail_pinned(ailp, type, flags, item_lsn);
+                       stuck++;
+                       ailp->ail_log_flush++;
+                       break;
+               case XFS_ITEM_LOCKED:
+                       XFS_STATS_INC(mp, xs_push_ail_locked);
+-                      trace_xfs_ail_locked(lip);
++                      trace_xfs_ail_locked(ailp, type, flags, item_lsn);
+                       stuck++;
+                       break;
diff --git a/queue-6.19/xfs-don-t-irele-after-failing-to-iget-in-xfs_attri_recover_work.patch b/queue-6.19/xfs-don-t-irele-after-failing-to-iget-in-xfs_attri_recover_work.patch
new file mode 100644 (file)
index 0000000..15b08b3
--- /dev/null
@@ -0,0 +1,34 @@
+From 70685c291ef82269180758130394ecdc4496b52c Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <djwong@kernel.org>
+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 <djwong@kernel.org>
+
+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 <djwong@kernel.org>
+Reviewed-by: Long Li <leo.lilong@huawei.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
+Signed-off-by: Carlos Maiolino <cem@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -656,7 +656,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.19/xfs-fix-ri_total-validation-in-xlog_recover_attri_commit_pass2.patch b/queue-6.19/xfs-fix-ri_total-validation-in-xlog_recover_attri_commit_pass2.patch
new file mode 100644 (file)
index 0000000..4a7c074
--- /dev/null
@@ -0,0 +1,61 @@
+From d72f2084e30966097c8eae762e31986a33c3c0ae Mon Sep 17 00:00:00 2001
+From: Long Li <leo.lilong@huawei.com>
+Date: Fri, 20 Mar 2026 10:11:29 +0800
+Subject: xfs: fix ri_total validation in xlog_recover_attri_commit_pass2
+
+From: Long Li <leo.lilong@huawei.com>
+
+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 <djwong@kernel.org>
+Signed-off-by: Long Li <leo.lilong@huawei.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Carlos Maiolino <cem@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -1050,8 +1050,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.19/xfs-remove-file_path-tracepoint-data.patch b/queue-6.19/xfs-remove-file_path-tracepoint-data.patch
new file mode 100644 (file)
index 0000000..82a5653
--- /dev/null
@@ -0,0 +1,91 @@
+From e31c53a8060e134111ed095783fee0aa0c43b080 Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <djwong@kernel.org>
+Date: Mon, 23 Mar 2026 14:04:33 -0700
+Subject: xfs: remove file_path tracepoint data
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+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 <djwong@kernel.org>
+Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Carlos Maiolino <cem@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -972,20 +972,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
+@@ -5115,23 +5115,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.19/xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch b/queue-6.19/xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch
new file mode 100644 (file)
index 0000000..35339e2
--- /dev/null
@@ -0,0 +1,98 @@
+From 394d70b86fae9fe865e7e6d9540b7696f73aa9b6 Mon Sep 17 00:00:00 2001
+From: Yuto Ohnuki <ytohnuki@amazon.com>
+Date: Tue, 10 Mar 2026 18:38:39 +0000
+Subject: xfs: save ailp before dropping the AIL lock in push callbacks
+
+From: Yuto Ohnuki <ytohnuki@amazon.com>
+
+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 <djwong@kernel.org>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Signed-off-by: Yuto Ohnuki <ytohnuki@amazon.com>
+Signed-off-by: Carlos Maiolino <cem@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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:
+       mutex_unlock(&dqp->q_qlock);
+       return rval;
+--- a/fs/xfs/xfs_inode_item.c
++++ b/fs/xfs/xfs_inode_item.c
+@@ -749,6 +749,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;
+@@ -774,7 +775,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
+@@ -798,7 +799,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.19/xfs-scrub-unlock-dquot-before-early-return-in-quota-scrub.patch b/queue-6.19/xfs-scrub-unlock-dquot-before-early-return-in-quota-scrub.patch
new file mode 100644 (file)
index 0000000..8bd83c3
--- /dev/null
@@ -0,0 +1,40 @@
+From 268378b6ad20569af0d1957992de1c8b16c6e900 Mon Sep 17 00:00:00 2001
+From: hongao <hongao@uniontech.com>
+Date: Thu, 12 Mar 2026 20:10:26 +0800
+Subject: xfs: scrub: unlock dquot before early return in quota scrub
+
+From: hongao <hongao@uniontech.com>
+
+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 <hongao@uniontech.com>
+Fixes: 7d1f0e167a067e ("xfs: check the ondisk space mapping behind a dquot")
+Cc: <stable@vger.kernel.org> # v6.8
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Carlos Maiolino <cem@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -171,8 +171,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.19/xfs-stop-reclaim-before-pushing-ail-during-unmount.patch b/queue-6.19/xfs-stop-reclaim-before-pushing-ail-during-unmount.patch
new file mode 100644 (file)
index 0000000..09a0c48
--- /dev/null
@@ -0,0 +1,58 @@
+From 4f24a767e3d64a5f58c595b5c29b6063a201f1e3 Mon Sep 17 00:00:00 2001
+From: Yuto Ohnuki <ytohnuki@amazon.com>
+Date: Tue, 10 Mar 2026 18:38:37 +0000
+Subject: xfs: stop reclaim before pushing AIL during unmount
+
+From: Yuto Ohnuki <ytohnuki@amazon.com>
+
+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 <ytohnuki@amazon.com>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Carlos Maiolino <cem@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -607,8 +607,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(
+@@ -620,9 +621,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);
+ }