]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.13-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 5 Feb 2025 12:24:55 +0000 (13:24 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 5 Feb 2025 12:24:55 +0000 (13:24 +0100)
added patches:
asoc-da7213-initialize-the-mutex.patch
btrfs-do-proper-folio-cleanup-when-cow_file_range-failed.patch
btrfs-do-proper-folio-cleanup-when-run_delalloc_nocow-failed.patch
drm-amd-display-add-hubp-cache-reset-when-powergating.patch
kvm-x86-plumb-in-the-vcpu-to-kvm_x86_ops.hwapic_isr_update.patch
loongarch-change-8-to-14-for-loongarch_max_-brp-wrp.patch
memcg-fix-soft-lockup-in-the-oom-process.patch
pwm-ensure-callbacks-exist-before-calling-them.patch
s390-add-std-gnu11-to-decompressor-and-purgatory-cflags.patch
selftests-mm-build-with-o2.patch

queue-6.13/asoc-da7213-initialize-the-mutex.patch [new file with mode: 0644]
queue-6.13/btrfs-do-proper-folio-cleanup-when-cow_file_range-failed.patch [new file with mode: 0644]
queue-6.13/btrfs-do-proper-folio-cleanup-when-run_delalloc_nocow-failed.patch [new file with mode: 0644]
queue-6.13/drm-amd-display-add-hubp-cache-reset-when-powergating.patch [new file with mode: 0644]
queue-6.13/kvm-x86-plumb-in-the-vcpu-to-kvm_x86_ops.hwapic_isr_update.patch [new file with mode: 0644]
queue-6.13/loongarch-change-8-to-14-for-loongarch_max_-brp-wrp.patch [new file with mode: 0644]
queue-6.13/memcg-fix-soft-lockup-in-the-oom-process.patch [new file with mode: 0644]
queue-6.13/pwm-ensure-callbacks-exist-before-calling-them.patch [new file with mode: 0644]
queue-6.13/s390-add-std-gnu11-to-decompressor-and-purgatory-cflags.patch [new file with mode: 0644]
queue-6.13/selftests-mm-build-with-o2.patch [new file with mode: 0644]
queue-6.13/series

diff --git a/queue-6.13/asoc-da7213-initialize-the-mutex.patch b/queue-6.13/asoc-da7213-initialize-the-mutex.patch
new file mode 100644 (file)
index 0000000..a6b3b2a
--- /dev/null
@@ -0,0 +1,71 @@
+From 4a32a38cb68f55ff9e100df348ddb3d4b3e50643 Mon Sep 17 00:00:00 2001
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Date: Thu, 23 Jan 2025 14:10:36 +0200
+Subject: ASoC: da7213: Initialize the mutex
+
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+
+commit 4a32a38cb68f55ff9e100df348ddb3d4b3e50643 upstream.
+
+Initialize the struct da7213_priv::ctrl_lock mutex. Without it the
+following stack trace is displayed when rebooting and lockdep is enabled:
+
+DEBUG_LOCKS_WARN_ON(lock->magic != lock)
+WARNING: CPU: 0 PID: 180 at kernel/locking/mutex.c:564 __mutex_lock+0x254/0x4e4
+CPU: 0 UID: 0 PID: 180 Comm: alsactl Not tainted 6.13.0-next-20250123-arm64-renesas-00002-g132083a22d3d #30
+Hardware name: Renesas SMARC EVK version 2 based on r9a08g045s33 (DT)
+pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+pc : __mutex_lock+0x254/0x4e4
+lr : __mutex_lock+0x254/0x4e4
+sp : ffff800082c13c00
+x29: ffff800082c13c00 x28: ffff00001002b500 x27: 0000000000000000
+x26: 0000000000000000 x25: ffff800080b30db4 x24: 0000000000000002
+x23: ffff800082c13c70 x22: 0000ffffc2a68a70 x21: ffff000010348000
+x20: 0000000000000000 x19: ffff00000be2e488 x18: 0000000000000000
+x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
+x14: 00000000000003c1 x13: 00000000000003c1 x12: 0000000000000000
+x11: 0000000000000011 x10: 0000000000001420 x9 : ffff800082c13a70
+x8 : 0000000000000001 x7 : ffff800082c13a50 x6 : ffff800082c139e0
+x5 : ffff800082c14000 x4 : ffff800082c13a50 x3 : 0000000000000000
+x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff00001002b500
+Call trace:
+  __mutex_lock+0x254/0x4e4 (P)
+  mutex_lock_nested+0x20/0x28
+  da7213_volsw_locked_get+0x34/0x60
+  snd_ctl_elem_read+0xbc/0x114
+  snd_ctl_ioctl+0x878/0xa70
+  __arm64_sys_ioctl+0x94/0xc8
+  invoke_syscall+0x44/0x104
+  el0_svc_common.constprop.0+0xb4/0xd4
+  do_el0_svc+0x18/0x20
+  el0_svc+0x3c/0xf0
+  el0t_64_sync_handler+0xc0/0xc4
+  el0t_64_sync+0x154/0x158
+ irq event stamp: 7713
+ hardirqs last  enabled at (7713): [<ffff800080170d94>] ktime_get_coarse_real_ts64+0xf0/0x10c
+ hardirqs last disabled at (7712): [<ffff800080170d58>] ktime_get_coarse_real_ts64+0xb4/0x10c
+ softirqs last  enabled at (7550): [<ffff8000800179d4>] fpsimd_restore_current_state+0x30/0xb8
+ softirqs last disabled at (7548): [<ffff8000800179a8>] fpsimd_restore_current_state+0x4/0xb8
+ ---[ end trace 0000000000000000 ]---
+
+Fixes: 64c3259b5f86 ("ASoC: da7213: Add new kcontrol for tonegen")
+Cc: stable@vger.kernel.org
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Link: https://patch.msgid.link/20250123121036.70406-1-claudiu.beznea.uj@bp.renesas.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/codecs/da7213.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/sound/soc/codecs/da7213.c
++++ b/sound/soc/codecs/da7213.c
+@@ -2203,6 +2203,8 @@ static int da7213_i2c_probe(struct i2c_c
+               return ret;
+       }
++      mutex_init(&da7213->ctrl_lock);
++
+       pm_runtime_set_autosuspend_delay(&i2c->dev, 100);
+       pm_runtime_use_autosuspend(&i2c->dev);
+       pm_runtime_set_active(&i2c->dev);
diff --git a/queue-6.13/btrfs-do-proper-folio-cleanup-when-cow_file_range-failed.patch b/queue-6.13/btrfs-do-proper-folio-cleanup-when-cow_file_range-failed.patch
new file mode 100644 (file)
index 0000000..f94ac50
--- /dev/null
@@ -0,0 +1,251 @@
+From 06f364284794f149d2abc167c11d556cf20c954b Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Thu, 12 Dec 2024 16:43:58 +1030
+Subject: btrfs: do proper folio cleanup when cow_file_range() failed
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit 06f364284794f149d2abc167c11d556cf20c954b upstream.
+
+[BUG]
+When testing with COW fixup marked as BUG_ON() (this is involved with the
+new pin_user_pages*() change, which should not result new out-of-band
+dirty pages), I hit a crash triggered by the BUG_ON() from hitting COW
+fixup path.
+
+This BUG_ON() happens just after a failed btrfs_run_delalloc_range():
+
+  BTRFS error (device dm-2): failed to run delalloc range, root 348 ino 405 folio 65536 submit_bitmap 6-15 start 90112 len 106496: -28
+  ------------[ cut here ]------------
+  kernel BUG at fs/btrfs/extent_io.c:1444!
+  Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
+  CPU: 0 UID: 0 PID: 434621 Comm: kworker/u24:8 Tainted: G           OE      6.12.0-rc7-custom+ #86
+  Hardware name: QEMU KVM Virtual Machine, BIOS unknown 2/2/2022
+  Workqueue: events_unbound btrfs_async_reclaim_data_space [btrfs]
+  pc : extent_writepage_io+0x2d4/0x308 [btrfs]
+  lr : extent_writepage_io+0x2d4/0x308 [btrfs]
+  Call trace:
+   extent_writepage_io+0x2d4/0x308 [btrfs]
+   extent_writepage+0x218/0x330 [btrfs]
+   extent_write_cache_pages+0x1d4/0x4b0 [btrfs]
+   btrfs_writepages+0x94/0x150 [btrfs]
+   do_writepages+0x74/0x190
+   filemap_fdatawrite_wbc+0x88/0xc8
+   start_delalloc_inodes+0x180/0x3b0 [btrfs]
+   btrfs_start_delalloc_roots+0x174/0x280 [btrfs]
+   shrink_delalloc+0x114/0x280 [btrfs]
+   flush_space+0x250/0x2f8 [btrfs]
+   btrfs_async_reclaim_data_space+0x180/0x228 [btrfs]
+   process_one_work+0x164/0x408
+   worker_thread+0x25c/0x388
+   kthread+0x100/0x118
+   ret_from_fork+0x10/0x20
+  Code: aa1403e1 9402f3ef aa1403e0 9402f36f (d4210000)
+  ---[ end trace 0000000000000000 ]---
+
+[CAUSE]
+That failure is mostly from cow_file_range(), where we can hit -ENOSPC.
+
+Although the -ENOSPC is already a bug related to our space reservation
+code, let's just focus on the error handling.
+
+For example, we have the following dirty range [0, 64K) of an inode,
+with 4K sector size and 4K page size:
+
+   0        16K        32K       48K       64K
+   |///////////////////////////////////////|
+   |#######################################|
+
+Where |///| means page are still dirty, and |###| means the extent io
+tree has EXTENT_DELALLOC flag.
+
+- Enter extent_writepage() for page 0
+
+- Enter btrfs_run_delalloc_range() for range [0, 64K)
+
+- Enter cow_file_range() for range [0, 64K)
+
+- Function btrfs_reserve_extent() only reserved one 16K extent
+  So we created extent map and ordered extent for range [0, 16K)
+
+   0        16K        32K       48K       64K
+   |////////|//////////////////////////////|
+   |<- OE ->|##############################|
+
+   And range [0, 16K) has its delalloc flag cleared.
+   But since we haven't yet submit any bio, involved 4 pages are still
+   dirty.
+
+- Function btrfs_reserve_extent() returns with -ENOSPC
+  Now we have to run error cleanup, which will clear all
+  EXTENT_DELALLOC* flags and clear the dirty flags for the remaining
+  ranges:
+
+   0        16K        32K       48K       64K
+   |////////|                              |
+   |        |                              |
+
+  Note that range [0, 16K) still has its pages dirty.
+
+- Some time later, writeback is triggered again for the range [0, 16K)
+  since the page range still has dirty flags.
+
+- btrfs_run_delalloc_range() will do nothing because there is no
+  EXTENT_DELALLOC flag.
+
+- extent_writepage_io() finds page 0 has no ordered flag
+  Which falls into the COW fixup path, triggering the BUG_ON().
+
+Unfortunately this error handling bug dates back to the introduction of
+btrfs.  Thankfully with the abuse of COW fixup, at least it won't crash
+the kernel.
+
+[FIX]
+Instead of immediately unlocking the extent and folios, we keep the extent
+and folios locked until either erroring out or the whole delalloc range
+finished.
+
+When the whole delalloc range finished without error, we just unlock the
+whole range with PAGE_SET_ORDERED (and PAGE_UNLOCK for !keep_locked
+cases), with EXTENT_DELALLOC and EXTENT_LOCKED cleared.
+And the involved folios will be properly submitted, with their dirty
+flags cleared during submission.
+
+For the error path, it will be a little more complex:
+
+- The range with ordered extent allocated (range (1))
+  We only clear the EXTENT_DELALLOC and EXTENT_LOCKED, as the remaining
+  flags are cleaned up by
+  btrfs_mark_ordered_io_finished()->btrfs_finish_one_ordered().
+
+  For folios we finish the IO (clear dirty, start writeback and
+  immediately finish the writeback) and unlock the folios.
+
+- The range with reserved extent but no ordered extent (range(2))
+- The range we never touched (range(3))
+  For both range (2) and range(3) the behavior is not changed.
+
+Now even if cow_file_range() failed halfway with some successfully
+reserved extents/ordered extents, we will keep all folios clean, so
+there will be no future writeback triggered on them.
+
+CC: stable@vger.kernel.org
+Reviewed-by: Boris Burkov <boris@bur.io>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/inode.c |   63 ++++++++++++++++++++++++++-----------------------------
+ 1 file changed, 30 insertions(+), 33 deletions(-)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -1373,6 +1373,17 @@ static noinline int cow_file_range(struc
+       alloc_hint = btrfs_get_extent_allocation_hint(inode, start, num_bytes);
+       /*
++       * We're not doing compressed IO, don't unlock the first page (which
++       * the caller expects to stay locked), don't clear any dirty bits and
++       * don't set any writeback bits.
++       *
++       * Do set the Ordered (Private2) bit so we know this page was properly
++       * setup for writepage.
++       */
++      page_ops = (keep_locked ? 0 : PAGE_UNLOCK);
++      page_ops |= PAGE_SET_ORDERED;
++
++      /*
+        * Relocation relies on the relocated extents to have exactly the same
+        * size as the original extents. Normally writeback for relocation data
+        * extents follows a NOCOW path because relocation preallocates the
+@@ -1431,6 +1442,10 @@ static noinline int cow_file_range(struc
+               file_extent.offset = 0;
+               file_extent.compression = BTRFS_COMPRESS_NONE;
++              /*
++               * Locked range will be released either during error clean up or
++               * after the whole range is finished.
++               */
+               lock_extent(&inode->io_tree, start, start + cur_alloc_size - 1,
+                           &cached);
+@@ -1476,21 +1491,6 @@ static noinline int cow_file_range(struc
+               btrfs_dec_block_group_reservations(fs_info, ins.objectid);
+-              /*
+-               * We're not doing compressed IO, don't unlock the first page
+-               * (which the caller expects to stay locked), don't clear any
+-               * dirty bits and don't set any writeback bits
+-               *
+-               * Do set the Ordered flag so we know this page was
+-               * properly setup for writepage.
+-               */
+-              page_ops = (keep_locked ? 0 : PAGE_UNLOCK);
+-              page_ops |= PAGE_SET_ORDERED;
+-
+-              extent_clear_unlock_delalloc(inode, start, start + cur_alloc_size - 1,
+-                                           locked_folio, &cached,
+-                                           EXTENT_LOCKED | EXTENT_DELALLOC,
+-                                           page_ops);
+               if (num_bytes < cur_alloc_size)
+                       num_bytes = 0;
+               else
+@@ -1507,6 +1507,8 @@ static noinline int cow_file_range(struc
+               if (ret)
+                       goto out_unlock;
+       }
++      extent_clear_unlock_delalloc(inode, orig_start, end, locked_folio, &cached,
++                                   EXTENT_LOCKED | EXTENT_DELALLOC, page_ops);
+ done:
+       if (done_offset)
+               *done_offset = end;
+@@ -1527,35 +1529,30 @@ out_unlock:
+        * We process each region below.
+        */
+-      clear_bits = EXTENT_LOCKED | EXTENT_DELALLOC | EXTENT_DELALLOC_NEW |
+-              EXTENT_DEFRAG | EXTENT_CLEAR_META_RESV;
+-      page_ops = PAGE_UNLOCK | PAGE_START_WRITEBACK | PAGE_END_WRITEBACK;
+-
+       /*
+        * For the range (1). We have already instantiated the ordered extents
+        * for this region. They are cleaned up by
+        * btrfs_cleanup_ordered_extents() in e.g,
+-       * btrfs_run_delalloc_range(). EXTENT_LOCKED | EXTENT_DELALLOC are
+-       * already cleared in the above loop. And, EXTENT_DELALLOC_NEW |
+-       * EXTENT_DEFRAG | EXTENT_CLEAR_META_RESV are handled by the cleanup
+-       * function.
++       * btrfs_run_delalloc_range().
++       * EXTENT_DELALLOC_NEW | EXTENT_DEFRAG | EXTENT_CLEAR_META_RESV
++       * are also handled by the cleanup function.
+        *
+-       * However, in case of @keep_locked, we still need to unlock the pages
+-       * (except @locked_folio) to ensure all the pages are unlocked.
++       * So here we only clear EXTENT_LOCKED and EXTENT_DELALLOC flag, and
++       * finish the writeback of the involved folios, which will be never submitted.
+        */
+-      if (keep_locked && orig_start < start) {
++      if (orig_start < start) {
++              clear_bits = EXTENT_LOCKED | EXTENT_DELALLOC;
++              page_ops = PAGE_UNLOCK | PAGE_START_WRITEBACK | PAGE_END_WRITEBACK;
++
+               if (!locked_folio)
+                       mapping_set_error(inode->vfs_inode.i_mapping, ret);
+               extent_clear_unlock_delalloc(inode, orig_start, start - 1,
+-                                           locked_folio, NULL, 0, page_ops);
++                                           locked_folio, NULL, clear_bits, page_ops);
+       }
+-      /*
+-       * At this point we're unlocked, we want to make sure we're only
+-       * clearing these flags under the extent lock, so lock the rest of the
+-       * range and clear everything up.
+-       */
+-      lock_extent(&inode->io_tree, start, end, NULL);
++      clear_bits = EXTENT_LOCKED | EXTENT_DELALLOC | EXTENT_DELALLOC_NEW |
++                   EXTENT_DEFRAG | EXTENT_CLEAR_META_RESV;
++      page_ops = PAGE_UNLOCK | PAGE_START_WRITEBACK | PAGE_END_WRITEBACK;
+       /*
+        * For the range (2). If we reserved an extent for our delalloc range
diff --git a/queue-6.13/btrfs-do-proper-folio-cleanup-when-run_delalloc_nocow-failed.patch b/queue-6.13/btrfs-do-proper-folio-cleanup-when-run_delalloc_nocow-failed.patch
new file mode 100644 (file)
index 0000000..874f678
--- /dev/null
@@ -0,0 +1,274 @@
+From c2b47df81c8e20a8e8cd94f0d7df211137ae94ed Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Thu, 12 Dec 2024 16:43:59 +1030
+Subject: btrfs: do proper folio cleanup when run_delalloc_nocow() failed
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit c2b47df81c8e20a8e8cd94f0d7df211137ae94ed upstream.
+
+[BUG]
+With CONFIG_DEBUG_VM set, test case generic/476 has some chance to crash
+with the following VM_BUG_ON_FOLIO():
+
+  BTRFS error (device dm-3): cow_file_range failed, start 1146880 end 1253375 len 106496 ret -28
+  BTRFS error (device dm-3): run_delalloc_nocow failed, start 1146880 end 1253375 len 106496 ret -28
+  page: refcount:4 mapcount:0 mapping:00000000592787cc index:0x12 pfn:0x10664
+  aops:btrfs_aops [btrfs] ino:101 dentry name(?):"f1774"
+  flags: 0x2fffff80004028(uptodate|lru|private|node=0|zone=2|lastcpupid=0xfffff)
+  page dumped because: VM_BUG_ON_FOLIO(!folio_test_locked(folio))
+  ------------[ cut here ]------------
+  kernel BUG at mm/page-writeback.c:2992!
+  Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
+  CPU: 2 UID: 0 PID: 3943513 Comm: kworker/u24:15 Tainted: G           OE      6.12.0-rc7-custom+ #87
+  Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
+  Hardware name: QEMU KVM Virtual Machine, BIOS unknown 2/2/2022
+  Workqueue: events_unbound btrfs_async_reclaim_data_space [btrfs]
+  pc : folio_clear_dirty_for_io+0x128/0x258
+  lr : folio_clear_dirty_for_io+0x128/0x258
+  Call trace:
+   folio_clear_dirty_for_io+0x128/0x258
+   btrfs_folio_clamp_clear_dirty+0x80/0xd0 [btrfs]
+   __process_folios_contig+0x154/0x268 [btrfs]
+   extent_clear_unlock_delalloc+0x5c/0x80 [btrfs]
+   run_delalloc_nocow+0x5f8/0x760 [btrfs]
+   btrfs_run_delalloc_range+0xa8/0x220 [btrfs]
+   writepage_delalloc+0x230/0x4c8 [btrfs]
+   extent_writepage+0xb8/0x358 [btrfs]
+   extent_write_cache_pages+0x21c/0x4e8 [btrfs]
+   btrfs_writepages+0x94/0x150 [btrfs]
+   do_writepages+0x74/0x190
+   filemap_fdatawrite_wbc+0x88/0xc8
+   start_delalloc_inodes+0x178/0x3a8 [btrfs]
+   btrfs_start_delalloc_roots+0x174/0x280 [btrfs]
+   shrink_delalloc+0x114/0x280 [btrfs]
+   flush_space+0x250/0x2f8 [btrfs]
+   btrfs_async_reclaim_data_space+0x180/0x228 [btrfs]
+   process_one_work+0x164/0x408
+   worker_thread+0x25c/0x388
+   kthread+0x100/0x118
+   ret_from_fork+0x10/0x20
+  Code: 910a8021 a90363f7 a9046bf9 94012379 (d4210000)
+  ---[ end trace 0000000000000000 ]---
+
+[CAUSE]
+The first two lines of extra debug messages show the problem is caused
+by the error handling of run_delalloc_nocow().
+
+E.g. we have the following dirtied range (4K blocksize 4K page size):
+
+    0                 16K                  32K
+    |//////////////////////////////////////|
+    |  Pre-allocated  |
+
+And the range [0, 16K) has a preallocated extent.
+
+- Enter run_delalloc_nocow() for range [0, 16K)
+  Which found range [0, 16K) is preallocated, can do the proper NOCOW
+  write.
+
+- Enter fallback_to_fow() for range [16K, 32K)
+  Since the range [16K, 32K) is not backed by preallocated extent, we
+  have to go COW.
+
+- cow_file_range() failed for range [16K, 32K)
+  So cow_file_range() will do the clean up by clearing folio dirty,
+  unlock the folios.
+
+  Now the folios in range [16K, 32K) is unlocked.
+
+- Enter extent_clear_unlock_delalloc() from run_delalloc_nocow()
+  Which is called with PAGE_START_WRITEBACK to start page writeback.
+  But folios can only be marked writeback when it's properly locked,
+  thus this triggered the VM_BUG_ON_FOLIO().
+
+Furthermore there is another hidden but common bug that
+run_delalloc_nocow() is not clearing the folio dirty flags in its error
+handling path.
+This is the common bug shared between run_delalloc_nocow() and
+cow_file_range().
+
+[FIX]
+- Clear folio dirty for range [@start, @cur_offset)
+  Introduce a helper, cleanup_dirty_folios(), which
+  will find and lock the folio in the range, clear the dirty flag and
+  start/end the writeback, with the extra handling for the
+  @locked_folio.
+
+- Introduce a helper to clear folio dirty, start and end writeback
+
+- Introduce a helper to record the last failed COW range end
+  This is to trace which range we should skip, to avoid double
+  unlocking.
+
+- Skip the failed COW range for the error handling
+
+CC: stable@vger.kernel.org
+Reviewed-by: Boris Burkov <boris@bur.io>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/inode.c   |   95 +++++++++++++++++++++++++++++++++++++++++++++++++----
+ fs/btrfs/subpage.h |   13 +++++++
+ 2 files changed, 102 insertions(+), 6 deletions(-)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -1968,6 +1968,53 @@ static int can_nocow_file_extent(struct
+ }
+ /*
++ * Cleanup the dirty folios which will never be submitted due to error.
++ *
++ * When running a delalloc range, we may need to split the ranges (due to
++ * fragmentation or NOCOW). If we hit an error in the later part, we will error
++ * out and previously successfully executed range will never be submitted, thus
++ * we have to cleanup those folios by clearing their dirty flag, starting and
++ * finishing the writeback.
++ */
++static void cleanup_dirty_folios(struct btrfs_inode *inode,
++                               struct folio *locked_folio,
++                               u64 start, u64 end, int error)
++{
++      struct btrfs_fs_info *fs_info = inode->root->fs_info;
++      struct address_space *mapping = inode->vfs_inode.i_mapping;
++      pgoff_t start_index = start >> PAGE_SHIFT;
++      pgoff_t end_index = end >> PAGE_SHIFT;
++      u32 len;
++
++      ASSERT(end + 1 - start < U32_MAX);
++      ASSERT(IS_ALIGNED(start, fs_info->sectorsize) &&
++             IS_ALIGNED(end + 1, fs_info->sectorsize));
++      len = end + 1 - start;
++
++      /*
++       * Handle the locked folio first.
++       * The btrfs_folio_clamp_*() helpers can handle range out of the folio case.
++       */
++      btrfs_folio_clamp_finish_io(fs_info, locked_folio, start, len);
++
++      for (pgoff_t index = start_index; index <= end_index; index++) {
++              struct folio *folio;
++
++              /* Already handled at the beginning. */
++              if (index == locked_folio->index)
++                      continue;
++              folio = __filemap_get_folio(mapping, index, FGP_LOCK, GFP_NOFS);
++              /* Cache already dropped, no need to do any cleanup. */
++              if (IS_ERR(folio))
++                      continue;
++              btrfs_folio_clamp_finish_io(fs_info, locked_folio, start, len);
++              folio_unlock(folio);
++              folio_put(folio);
++      }
++      mapping_set_error(mapping, error);
++}
++
++/*
+  * when nowcow writeback call back.  This checks for snapshots or COW copies
+  * of the extents that exist in the file, and COWs the file as required.
+  *
+@@ -1982,6 +2029,11 @@ static noinline int run_delalloc_nocow(s
+       struct btrfs_root *root = inode->root;
+       struct btrfs_path *path;
+       u64 cow_start = (u64)-1;
++      /*
++       * If not 0, represents the inclusive end of the last fallback_to_cow()
++       * range. Only for error handling.
++       */
++      u64 cow_end = 0;
+       u64 cur_offset = start;
+       int ret;
+       bool check_prev = true;
+@@ -2142,6 +2194,7 @@ must_cow:
+                                             found_key.offset - 1);
+                       cow_start = (u64)-1;
+                       if (ret) {
++                              cow_end = found_key.offset - 1;
+                               btrfs_dec_nocow_writers(nocow_bg);
+                               goto error;
+                       }
+@@ -2215,11 +2268,12 @@ must_cow:
+               cow_start = cur_offset;
+       if (cow_start != (u64)-1) {
+-              cur_offset = end;
+               ret = fallback_to_cow(inode, locked_folio, cow_start, end);
+               cow_start = (u64)-1;
+-              if (ret)
++              if (ret) {
++                      cow_end = end;
+                       goto error;
++              }
+       }
+       btrfs_free_path(path);
+@@ -2227,12 +2281,41 @@ must_cow:
+ error:
+       /*
++       * There are several error cases:
++       *
++       * 1) Failed without falling back to COW
++       *    start         cur_offset             end
++       *    |/////////////|                      |
++       *
++       *    For range [start, cur_offset) the folios are already unlocked (except
++       *    @locked_folio), EXTENT_DELALLOC already removed.
++       *    Only need to clear the dirty flag as they will never be submitted.
++       *    Ordered extent and extent maps are handled by
++       *    btrfs_mark_ordered_io_finished() inside run_delalloc_range().
++       *
++       * 2) Failed with error from fallback_to_cow()
++       *    start         cur_offset  cow_end    end
++       *    |/////////////|-----------|          |
++       *
++       *    For range [start, cur_offset) it's the same as case 1).
++       *    But for range [cur_offset, cow_end), the folios have dirty flag
++       *    cleared and unlocked, EXTENT_DEALLLOC cleared by cow_file_range().
++       *
++       *    Thus we should not call extent_clear_unlock_delalloc() on range
++       *    [cur_offset, cow_end), as the folios are already unlocked.
++       *
++       * So clear the folio dirty flags for [start, cur_offset) first.
++       */
++      if (cur_offset > start)
++              cleanup_dirty_folios(inode, locked_folio, start, cur_offset - 1, ret);
++
++      /*
+        * If an error happened while a COW region is outstanding, cur_offset
+-       * needs to be reset to cow_start to ensure the COW region is unlocked
+-       * as well.
++       * needs to be reset to @cow_end + 1 to skip the COW range, as
++       * cow_file_range() will do the proper cleanup at error.
+        */
+-      if (cow_start != (u64)-1)
+-              cur_offset = cow_start;
++      if (cow_end)
++              cur_offset = cow_end + 1;
+       /*
+        * We need to lock the extent here because we're clearing DELALLOC and
+--- a/fs/btrfs/subpage.h
++++ b/fs/btrfs/subpage.h
+@@ -137,6 +137,19 @@ DECLARE_BTRFS_SUBPAGE_OPS(writeback);
+ DECLARE_BTRFS_SUBPAGE_OPS(ordered);
+ DECLARE_BTRFS_SUBPAGE_OPS(checked);
++/*
++ * Helper for error cleanup, where a folio will have its dirty flag cleared,
++ * with writeback started and finished.
++ */
++static inline void btrfs_folio_clamp_finish_io(struct btrfs_fs_info *fs_info,
++                                             struct folio *locked_folio,
++                                             u64 start, u32 len)
++{
++      btrfs_folio_clamp_clear_dirty(fs_info, locked_folio, start, len);
++      btrfs_folio_clamp_set_writeback(fs_info, locked_folio, start, len);
++      btrfs_folio_clamp_clear_writeback(fs_info, locked_folio, start, len);
++}
++
+ bool btrfs_subpage_clear_and_test_dirty(const struct btrfs_fs_info *fs_info,
+                                       struct folio *folio, u64 start, u32 len);
diff --git a/queue-6.13/drm-amd-display-add-hubp-cache-reset-when-powergating.patch b/queue-6.13/drm-amd-display-add-hubp-cache-reset-when-powergating.patch
new file mode 100644 (file)
index 0000000..c112e43
--- /dev/null
@@ -0,0 +1,256 @@
+From 01130f5260e5868fb6b15ab8c00dbc894139f48e Mon Sep 17 00:00:00 2001
+From: Aric Cyr <Aric.Cyr@amd.com>
+Date: Thu, 9 Jan 2025 15:03:48 -0500
+Subject: drm/amd/display: Add hubp cache reset when powergating
+
+From: Aric Cyr <Aric.Cyr@amd.com>
+
+commit 01130f5260e5868fb6b15ab8c00dbc894139f48e upstream.
+
+[Why]
+When HUBP is power gated, the SW state can get out of sync with the
+hardware state causing cursor to not be programmed correctly.
+
+[How]
+Similar to DPP, add a HUBP reset function which is called wherever
+HUBP is initialized or powergated.  This function will clear the cursor
+position and attribute cache allowing for proper programming when the
+HUBP is brought back up.
+
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Sung Lee <sung.lee@amd.com>
+Signed-off-by: Aric Cyr <Aric.Cyr@amd.com>
+Signed-off-by: Wayne Lin <wayne.lin@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/dc/dpp/dcn10/dcn10_dpp.c     |    3 +++
+ drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c   |   10 +++++++++-
+ drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.h   |    2 ++
+ drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c   |    1 +
+ drivers/gpu/drm/amd/display/dc/hubp/dcn201/dcn201_hubp.c |    1 +
+ drivers/gpu/drm/amd/display/dc/hubp/dcn21/dcn21_hubp.c   |    3 +++
+ drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c   |    3 +++
+ drivers/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.c   |    1 +
+ drivers/gpu/drm/amd/display/dc/hubp/dcn32/dcn32_hubp.c   |    1 +
+ drivers/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.c   |    1 +
+ drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c |    3 ++-
+ drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c  |    2 ++
+ drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c  |    2 ++
+ drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h             |    2 ++
+ 14 files changed, 33 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/dc/dpp/dcn10/dcn10_dpp.c
++++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn10/dcn10_dpp.c
+@@ -194,6 +194,9 @@ void dpp_reset(struct dpp *dpp_base)
+       dpp->filter_h = NULL;
+       dpp->filter_v = NULL;
++      memset(&dpp_base->pos, 0, sizeof(dpp_base->pos));
++      memset(&dpp_base->att, 0, sizeof(dpp_base->att));
++
+       memset(&dpp->scl_data, 0, sizeof(dpp->scl_data));
+       memset(&dpp->pwl_data, 0, sizeof(dpp->pwl_data));
+ }
+--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c
++++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c
+@@ -532,6 +532,12 @@ void hubp1_dcc_control(struct hubp *hubp
+                       SECONDARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk);
+ }
++void hubp_reset(struct hubp *hubp)
++{
++      memset(&hubp->pos, 0, sizeof(hubp->pos));
++      memset(&hubp->att, 0, sizeof(hubp->att));
++}
++
+ void hubp1_program_surface_config(
+       struct hubp *hubp,
+       enum surface_pixel_format format,
+@@ -1337,8 +1343,9 @@ static void hubp1_wait_pipe_read_start(s
+ void hubp1_init(struct hubp *hubp)
+ {
+-      //do nothing
++      hubp_reset(hubp);
+ }
++
+ static const struct hubp_funcs dcn10_hubp_funcs = {
+       .hubp_program_surface_flip_and_addr =
+                       hubp1_program_surface_flip_and_addr,
+@@ -1351,6 +1358,7 @@ static const struct hubp_funcs dcn10_hub
+       .hubp_set_vm_context0_settings = hubp1_set_vm_context0_settings,
+       .set_blank = hubp1_set_blank,
+       .dcc_control = hubp1_dcc_control,
++      .hubp_reset = hubp_reset,
+       .mem_program_viewport = min_set_viewport,
+       .set_hubp_blank_en = hubp1_set_hubp_blank_en,
+       .set_cursor_attributes  = hubp1_cursor_set_attributes,
+--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.h
++++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.h
+@@ -746,6 +746,8 @@ void hubp1_dcc_control(struct hubp *hubp
+               bool enable,
+               enum hubp_ind_block_size independent_64b_blks);
++void hubp_reset(struct hubp *hubp);
++
+ bool hubp1_program_surface_flip_and_addr(
+       struct hubp *hubp,
+       const struct dc_plane_address *address,
+--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c
++++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c
+@@ -1660,6 +1660,7 @@ static struct hubp_funcs dcn20_hubp_func
+       .set_blank = hubp2_set_blank,
+       .set_blank_regs = hubp2_set_blank_regs,
+       .dcc_control = hubp2_dcc_control,
++      .hubp_reset = hubp_reset,
+       .mem_program_viewport = min_set_viewport,
+       .set_cursor_attributes  = hubp2_cursor_set_attributes,
+       .set_cursor_position    = hubp2_cursor_set_position,
+--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn201/dcn201_hubp.c
++++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn201/dcn201_hubp.c
+@@ -121,6 +121,7 @@ static struct hubp_funcs dcn201_hubp_fun
+       .set_cursor_position    = hubp1_cursor_set_position,
+       .set_blank = hubp1_set_blank,
+       .dcc_control = hubp1_dcc_control,
++      .hubp_reset = hubp_reset,
+       .mem_program_viewport = min_set_viewport,
+       .hubp_clk_cntl = hubp1_clk_cntl,
+       .hubp_vtg_sel = hubp1_vtg_sel,
+--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn21/dcn21_hubp.c
++++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn21/dcn21_hubp.c
+@@ -811,6 +811,8 @@ static void hubp21_init(struct hubp *hub
+       struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp);
+       //hubp[i].HUBPREQ_DEBUG.HUBPREQ_DEBUG[26] = 1;
+       REG_WRITE(HUBPREQ_DEBUG, 1 << 26);
++
++      hubp_reset(hubp);
+ }
+ static struct hubp_funcs dcn21_hubp_funcs = {
+       .hubp_enable_tripleBuffer = hubp2_enable_triplebuffer,
+@@ -823,6 +825,7 @@ static struct hubp_funcs dcn21_hubp_func
+       .hubp_set_vm_system_aperture_settings = hubp21_set_vm_system_aperture_settings,
+       .set_blank = hubp1_set_blank,
+       .dcc_control = hubp1_dcc_control,
++      .hubp_reset = hubp_reset,
+       .mem_program_viewport = hubp21_set_viewport,
+       .set_cursor_attributes  = hubp2_cursor_set_attributes,
+       .set_cursor_position    = hubp1_cursor_set_position,
+--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c
++++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c
+@@ -483,6 +483,8 @@ void hubp3_init(struct hubp *hubp)
+       struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+       //hubp[i].HUBPREQ_DEBUG.HUBPREQ_DEBUG[26] = 1;
+       REG_WRITE(HUBPREQ_DEBUG, 1 << 26);
++
++      hubp_reset(hubp);
+ }
+ static struct hubp_funcs dcn30_hubp_funcs = {
+@@ -497,6 +499,7 @@ static struct hubp_funcs dcn30_hubp_func
+       .set_blank = hubp2_set_blank,
+       .set_blank_regs = hubp2_set_blank_regs,
+       .dcc_control = hubp3_dcc_control,
++      .hubp_reset = hubp_reset,
+       .mem_program_viewport = min_set_viewport,
+       .set_cursor_attributes  = hubp2_cursor_set_attributes,
+       .set_cursor_position    = hubp2_cursor_set_position,
+--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.c
++++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.c
+@@ -79,6 +79,7 @@ static struct hubp_funcs dcn31_hubp_func
+       .hubp_set_vm_system_aperture_settings = hubp3_set_vm_system_aperture_settings,
+       .set_blank = hubp2_set_blank,
+       .dcc_control = hubp3_dcc_control,
++      .hubp_reset = hubp_reset,
+       .mem_program_viewport = min_set_viewport,
+       .set_cursor_attributes  = hubp2_cursor_set_attributes,
+       .set_cursor_position    = hubp2_cursor_set_position,
+--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn32/dcn32_hubp.c
++++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn32/dcn32_hubp.c
+@@ -181,6 +181,7 @@ static struct hubp_funcs dcn32_hubp_func
+       .set_blank = hubp2_set_blank,
+       .set_blank_regs = hubp2_set_blank_regs,
+       .dcc_control = hubp3_dcc_control,
++      .hubp_reset = hubp_reset,
+       .mem_program_viewport = min_set_viewport,
+       .set_cursor_attributes  = hubp32_cursor_set_attributes,
+       .set_cursor_position    = hubp2_cursor_set_position,
+--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.c
++++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.c
+@@ -199,6 +199,7 @@ static struct hubp_funcs dcn35_hubp_func
+       .hubp_set_vm_system_aperture_settings = hubp3_set_vm_system_aperture_settings,
+       .set_blank = hubp2_set_blank,
+       .dcc_control = hubp3_dcc_control,
++      .hubp_reset = hubp_reset,
+       .mem_program_viewport = min_set_viewport,
+       .set_cursor_attributes  = hubp2_cursor_set_attributes,
+       .set_cursor_position    = hubp2_cursor_set_position,
+--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
++++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
+@@ -141,7 +141,7 @@ void hubp401_update_mall_sel(struct hubp
+ void hubp401_init(struct hubp *hubp)
+ {
+-      //For now nothing to do, HUBPREQ_DEBUG_DB register is removed on DCN4x.
++      hubp_reset(hubp);
+ }
+ void hubp401_vready_at_or_After_vsync(struct hubp *hubp,
+@@ -974,6 +974,7 @@ static struct hubp_funcs dcn401_hubp_fun
+       .hubp_set_vm_system_aperture_settings = hubp3_set_vm_system_aperture_settings,
+       .set_blank = hubp2_set_blank,
+       .set_blank_regs = hubp2_set_blank_regs,
++      .hubp_reset = hubp_reset,
+       .mem_program_viewport = hubp401_set_viewport,
+       .set_cursor_attributes  = hubp32_cursor_set_attributes,
+       .set_cursor_position    = hubp401_cursor_set_position,
+--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
+@@ -1286,6 +1286,7 @@ void dcn10_plane_atomic_power_down(struc
+               if (hws->funcs.hubp_pg_control)
+                       hws->funcs.hubp_pg_control(hws, hubp->inst, false);
++              hubp->funcs->hubp_reset(hubp);
+               dpp->funcs->dpp_reset(dpp);
+               REG_SET(DC_IP_REQUEST_CNTL, 0,
+@@ -1447,6 +1448,7 @@ void dcn10_init_pipes(struct dc *dc, str
+               /* Disable on the current state so the new one isn't cleared. */
+               pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
++              hubp->funcs->hubp_reset(hubp);
+               dpp->funcs->dpp_reset(dpp);
+               pipe_ctx->stream_res.tg = tg;
+--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
+@@ -788,6 +788,7 @@ void dcn35_init_pipes(struct dc *dc, str
+               /* Disable on the current state so the new one isn't cleared. */
+               pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
++              hubp->funcs->hubp_reset(hubp);
+               dpp->funcs->dpp_reset(dpp);
+               pipe_ctx->stream_res.tg = tg;
+@@ -944,6 +945,7 @@ void dcn35_plane_atomic_disable(struct d
+ /*to do, need to support both case*/
+       hubp->power_gated = true;
++      hubp->funcs->hubp_reset(hubp);
+       dpp->funcs->dpp_reset(dpp);
+       pipe_ctx->stream = NULL;
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
+@@ -152,6 +152,8 @@ struct hubp_funcs {
+       void (*dcc_control)(struct hubp *hubp, bool enable,
+                       enum hubp_ind_block_size blk_size);
++      void (*hubp_reset)(struct hubp *hubp);
++
+       void (*mem_program_viewport)(
+                       struct hubp *hubp,
+                       const struct rect *viewport,
diff --git a/queue-6.13/kvm-x86-plumb-in-the-vcpu-to-kvm_x86_ops.hwapic_isr_update.patch b/queue-6.13/kvm-x86-plumb-in-the-vcpu-to-kvm_x86_ops.hwapic_isr_update.patch
new file mode 100644 (file)
index 0000000..bea8c64
--- /dev/null
@@ -0,0 +1,108 @@
+From 76bce9f10162cd4b36ac0b7889649b22baf70ebd Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Wed, 27 Nov 2024 16:00:09 -0800
+Subject: KVM: x86: Plumb in the vCPU to kvm_x86_ops.hwapic_isr_update()
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit 76bce9f10162cd4b36ac0b7889649b22baf70ebd upstream.
+
+Pass the target vCPU to the hwapic_isr_update() vendor hook so that VMX
+can defer the update until after nested VM-Exit if an EOI for L1's vAPIC
+occurs while L2 is active.
+
+Note, commit d39850f57d21 ("KVM: x86: Drop @vcpu parameter from
+kvm_x86_ops.hwapic_isr_update()") removed the parameter with the
+justification that doing so "allows for a decent amount of (future)
+cleanup in the APIC code", but it's not at all clear what cleanup was
+intended, or if it was ever realized.
+
+No functional change intended.
+
+Cc: stable@vger.kernel.org
+Reviewed-by: Chao Gao <chao.gao@intel.com>
+Tested-by: Chao Gao <chao.gao@intel.com>
+Link: https://lore.kernel.org/r/20241128000010.4051275-2-seanjc@google.com
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/include/asm/kvm_host.h |    2 +-
+ arch/x86/kvm/lapic.c            |   11 +++++------
+ arch/x86/kvm/vmx/vmx.c          |    2 +-
+ arch/x86/kvm/vmx/x86_ops.h      |    2 +-
+ 4 files changed, 8 insertions(+), 9 deletions(-)
+
+--- a/arch/x86/include/asm/kvm_host.h
++++ b/arch/x86/include/asm/kvm_host.h
+@@ -1735,7 +1735,7 @@ struct kvm_x86_ops {
+       bool allow_apicv_in_x2apic_without_x2apic_virtualization;
+       void (*refresh_apicv_exec_ctrl)(struct kvm_vcpu *vcpu);
+       void (*hwapic_irr_update)(struct kvm_vcpu *vcpu, int max_irr);
+-      void (*hwapic_isr_update)(int isr);
++      void (*hwapic_isr_update)(struct kvm_vcpu *vcpu, int isr);
+       void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
+       void (*set_virtual_apic_mode)(struct kvm_vcpu *vcpu);
+       void (*set_apic_access_page_addr)(struct kvm_vcpu *vcpu);
+--- a/arch/x86/kvm/lapic.c
++++ b/arch/x86/kvm/lapic.c
+@@ -763,7 +763,7 @@ static inline void apic_set_isr(int vec,
+        * just set SVI.
+        */
+       if (unlikely(apic->apicv_active))
+-              kvm_x86_call(hwapic_isr_update)(vec);
++              kvm_x86_call(hwapic_isr_update)(apic->vcpu, vec);
+       else {
+               ++apic->isr_count;
+               BUG_ON(apic->isr_count > MAX_APIC_VECTOR);
+@@ -808,7 +808,7 @@ static inline void apic_clear_isr(int ve
+        * and must be left alone.
+        */
+       if (unlikely(apic->apicv_active))
+-              kvm_x86_call(hwapic_isr_update)(apic_find_highest_isr(apic));
++              kvm_x86_call(hwapic_isr_update)(apic->vcpu, apic_find_highest_isr(apic));
+       else {
+               --apic->isr_count;
+               BUG_ON(apic->isr_count < 0);
+@@ -2806,7 +2806,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vc
+       if (apic->apicv_active) {
+               kvm_x86_call(apicv_post_state_restore)(vcpu);
+               kvm_x86_call(hwapic_irr_update)(vcpu, -1);
+-              kvm_x86_call(hwapic_isr_update)(-1);
++              kvm_x86_call(hwapic_isr_update)(vcpu, -1);
+       }
+       vcpu->arch.apic_arb_prio = 0;
+@@ -3121,9 +3121,8 @@ int kvm_apic_set_state(struct kvm_vcpu *
+       kvm_apic_update_apicv(vcpu);
+       if (apic->apicv_active) {
+               kvm_x86_call(apicv_post_state_restore)(vcpu);
+-              kvm_x86_call(hwapic_irr_update)(vcpu,
+-                                              apic_find_highest_irr(apic));
+-              kvm_x86_call(hwapic_isr_update)(apic_find_highest_isr(apic));
++              kvm_x86_call(hwapic_irr_update)(vcpu, apic_find_highest_irr(apic));
++              kvm_x86_call(hwapic_isr_update)(vcpu, apic_find_highest_isr(apic));
+       }
+       kvm_make_request(KVM_REQ_EVENT, vcpu);
+       if (ioapic_in_kernel(vcpu->kvm))
+--- a/arch/x86/kvm/vmx/vmx.c
++++ b/arch/x86/kvm/vmx/vmx.c
+@@ -6862,7 +6862,7 @@ void vmx_set_apic_access_page_addr(struc
+       read_unlock(&vcpu->kvm->mmu_lock);
+ }
+-void vmx_hwapic_isr_update(int max_isr)
++void vmx_hwapic_isr_update(struct kvm_vcpu *vcpu, int max_isr)
+ {
+       u16 status;
+       u8 old;
+--- a/arch/x86/kvm/vmx/x86_ops.h
++++ b/arch/x86/kvm/vmx/x86_ops.h
+@@ -48,7 +48,7 @@ void vmx_migrate_timers(struct kvm_vcpu
+ void vmx_set_virtual_apic_mode(struct kvm_vcpu *vcpu);
+ void vmx_apicv_pre_state_restore(struct kvm_vcpu *vcpu);
+ void vmx_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr);
+-void vmx_hwapic_isr_update(int max_isr);
++void vmx_hwapic_isr_update(struct kvm_vcpu *vcpu, int max_isr);
+ int vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu);
+ void vmx_deliver_interrupt(struct kvm_lapic *apic, int delivery_mode,
+                          int trig_mode, int vector);
diff --git a/queue-6.13/loongarch-change-8-to-14-for-loongarch_max_-brp-wrp.patch b/queue-6.13/loongarch-change-8-to-14-for-loongarch_max_-brp-wrp.patch
new file mode 100644 (file)
index 0000000..82902b5
--- /dev/null
@@ -0,0 +1,147 @@
+From f502ea618bf16d615d7dc6138c8988d3118fe750 Mon Sep 17 00:00:00 2001
+From: Tiezhu Yang <yangtiezhu@loongson.cn>
+Date: Sun, 26 Jan 2025 21:49:59 +0800
+Subject: LoongArch: Change 8 to 14 for LOONGARCH_MAX_{BRP,WRP}
+
+From: Tiezhu Yang <yangtiezhu@loongson.cn>
+
+commit f502ea618bf16d615d7dc6138c8988d3118fe750 upstream.
+
+The maximum number of load/store watchpoints and fetch instruction
+watchpoints is 14 each according to LoongArch Reference Manual, so
+change 8 to 14 for the related code.
+
+Link: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#control-and-status-registers-related-to-watchpoints
+Cc: stable@vger.kernel.org
+Fixes: edffa33c7bb5 ("LoongArch: Add hardware breakpoints/watchpoints support")
+Reviewed-by: WANG Xuerui <git@xen0n.name>
+Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/loongarch/include/asm/hw_breakpoint.h |    4 -
+ arch/loongarch/include/asm/loongarch.h     |   60 +++++++++++++++++++++++++++++
+ arch/loongarch/kernel/hw_breakpoint.c      |   16 ++++++-
+ 3 files changed, 76 insertions(+), 4 deletions(-)
+
+--- a/arch/loongarch/include/asm/hw_breakpoint.h
++++ b/arch/loongarch/include/asm/hw_breakpoint.h
+@@ -38,8 +38,8 @@ struct arch_hw_breakpoint {
+  * Limits.
+  * Changing these will require modifications to the register accessors.
+  */
+-#define LOONGARCH_MAX_BRP             8
+-#define LOONGARCH_MAX_WRP             8
++#define LOONGARCH_MAX_BRP             14
++#define LOONGARCH_MAX_WRP             14
+ /* Virtual debug register bases. */
+ #define CSR_CFG_ADDR  0
+--- a/arch/loongarch/include/asm/loongarch.h
++++ b/arch/loongarch/include/asm/loongarch.h
+@@ -959,6 +959,36 @@
+ #define LOONGARCH_CSR_DB7CTRL         0x34a   /* data breakpoint 7 control */
+ #define LOONGARCH_CSR_DB7ASID         0x34b   /* data breakpoint 7 asid */
++#define LOONGARCH_CSR_DB8ADDR         0x350   /* data breakpoint 8 address */
++#define LOONGARCH_CSR_DB8MASK         0x351   /* data breakpoint 8 mask */
++#define LOONGARCH_CSR_DB8CTRL         0x352   /* data breakpoint 8 control */
++#define LOONGARCH_CSR_DB8ASID         0x353   /* data breakpoint 8 asid */
++
++#define LOONGARCH_CSR_DB9ADDR         0x358   /* data breakpoint 9 address */
++#define LOONGARCH_CSR_DB9MASK         0x359   /* data breakpoint 9 mask */
++#define LOONGARCH_CSR_DB9CTRL         0x35a   /* data breakpoint 9 control */
++#define LOONGARCH_CSR_DB9ASID         0x35b   /* data breakpoint 9 asid */
++
++#define LOONGARCH_CSR_DB10ADDR                0x360   /* data breakpoint 10 address */
++#define LOONGARCH_CSR_DB10MASK                0x361   /* data breakpoint 10 mask */
++#define LOONGARCH_CSR_DB10CTRL                0x362   /* data breakpoint 10 control */
++#define LOONGARCH_CSR_DB10ASID                0x363   /* data breakpoint 10 asid */
++
++#define LOONGARCH_CSR_DB11ADDR                0x368   /* data breakpoint 11 address */
++#define LOONGARCH_CSR_DB11MASK                0x369   /* data breakpoint 11 mask */
++#define LOONGARCH_CSR_DB11CTRL                0x36a   /* data breakpoint 11 control */
++#define LOONGARCH_CSR_DB11ASID                0x36b   /* data breakpoint 11 asid */
++
++#define LOONGARCH_CSR_DB12ADDR                0x370   /* data breakpoint 12 address */
++#define LOONGARCH_CSR_DB12MASK                0x371   /* data breakpoint 12 mask */
++#define LOONGARCH_CSR_DB12CTRL                0x372   /* data breakpoint 12 control */
++#define LOONGARCH_CSR_DB12ASID                0x373   /* data breakpoint 12 asid */
++
++#define LOONGARCH_CSR_DB13ADDR                0x378   /* data breakpoint 13 address */
++#define LOONGARCH_CSR_DB13MASK                0x379   /* data breakpoint 13 mask */
++#define LOONGARCH_CSR_DB13CTRL                0x37a   /* data breakpoint 13 control */
++#define LOONGARCH_CSR_DB13ASID                0x37b   /* data breakpoint 13 asid */
++
+ #define LOONGARCH_CSR_FWPC            0x380   /* instruction breakpoint config */
+ #define LOONGARCH_CSR_FWPS            0x381   /* instruction breakpoint status */
+@@ -1002,6 +1032,36 @@
+ #define LOONGARCH_CSR_IB7CTRL         0x3ca   /* inst breakpoint 7 control */
+ #define LOONGARCH_CSR_IB7ASID         0x3cb   /* inst breakpoint 7 asid */
++#define LOONGARCH_CSR_IB8ADDR         0x3d0   /* inst breakpoint 8 address */
++#define LOONGARCH_CSR_IB8MASK         0x3d1   /* inst breakpoint 8 mask */
++#define LOONGARCH_CSR_IB8CTRL         0x3d2   /* inst breakpoint 8 control */
++#define LOONGARCH_CSR_IB8ASID         0x3d3   /* inst breakpoint 8 asid */
++
++#define LOONGARCH_CSR_IB9ADDR         0x3d8   /* inst breakpoint 9 address */
++#define LOONGARCH_CSR_IB9MASK         0x3d9   /* inst breakpoint 9 mask */
++#define LOONGARCH_CSR_IB9CTRL         0x3da   /* inst breakpoint 9 control */
++#define LOONGARCH_CSR_IB9ASID         0x3db   /* inst breakpoint 9 asid */
++
++#define LOONGARCH_CSR_IB10ADDR                0x3e0   /* inst breakpoint 10 address */
++#define LOONGARCH_CSR_IB10MASK                0x3e1   /* inst breakpoint 10 mask */
++#define LOONGARCH_CSR_IB10CTRL                0x3e2   /* inst breakpoint 10 control */
++#define LOONGARCH_CSR_IB10ASID                0x3e3   /* inst breakpoint 10 asid */
++
++#define LOONGARCH_CSR_IB11ADDR                0x3e8   /* inst breakpoint 11 address */
++#define LOONGARCH_CSR_IB11MASK                0x3e9   /* inst breakpoint 11 mask */
++#define LOONGARCH_CSR_IB11CTRL                0x3ea   /* inst breakpoint 11 control */
++#define LOONGARCH_CSR_IB11ASID                0x3eb   /* inst breakpoint 11 asid */
++
++#define LOONGARCH_CSR_IB12ADDR                0x3f0   /* inst breakpoint 12 address */
++#define LOONGARCH_CSR_IB12MASK                0x3f1   /* inst breakpoint 12 mask */
++#define LOONGARCH_CSR_IB12CTRL                0x3f2   /* inst breakpoint 12 control */
++#define LOONGARCH_CSR_IB12ASID                0x3f3   /* inst breakpoint 12 asid */
++
++#define LOONGARCH_CSR_IB13ADDR                0x3f8   /* inst breakpoint 13 address */
++#define LOONGARCH_CSR_IB13MASK                0x3f9   /* inst breakpoint 13 mask */
++#define LOONGARCH_CSR_IB13CTRL                0x3fa   /* inst breakpoint 13 control */
++#define LOONGARCH_CSR_IB13ASID                0x3fb   /* inst breakpoint 13 asid */
++
+ #define LOONGARCH_CSR_DEBUG           0x500   /* debug config */
+ #define LOONGARCH_CSR_DERA            0x501   /* debug era */
+ #define LOONGARCH_CSR_DESAVE          0x502   /* debug save */
+--- a/arch/loongarch/kernel/hw_breakpoint.c
++++ b/arch/loongarch/kernel/hw_breakpoint.c
+@@ -51,7 +51,13 @@ int hw_breakpoint_slots(int type)
+       READ_WB_REG_CASE(OFF, 4, REG, T, VAL);          \
+       READ_WB_REG_CASE(OFF, 5, REG, T, VAL);          \
+       READ_WB_REG_CASE(OFF, 6, REG, T, VAL);          \
+-      READ_WB_REG_CASE(OFF, 7, REG, T, VAL);
++      READ_WB_REG_CASE(OFF, 7, REG, T, VAL);          \
++      READ_WB_REG_CASE(OFF, 8, REG, T, VAL);          \
++      READ_WB_REG_CASE(OFF, 9, REG, T, VAL);          \
++      READ_WB_REG_CASE(OFF, 10, REG, T, VAL);         \
++      READ_WB_REG_CASE(OFF, 11, REG, T, VAL);         \
++      READ_WB_REG_CASE(OFF, 12, REG, T, VAL);         \
++      READ_WB_REG_CASE(OFF, 13, REG, T, VAL);
+ #define GEN_WRITE_WB_REG_CASES(OFF, REG, T, VAL)      \
+       WRITE_WB_REG_CASE(OFF, 0, REG, T, VAL);         \
+@@ -61,7 +67,13 @@ int hw_breakpoint_slots(int type)
+       WRITE_WB_REG_CASE(OFF, 4, REG, T, VAL);         \
+       WRITE_WB_REG_CASE(OFF, 5, REG, T, VAL);         \
+       WRITE_WB_REG_CASE(OFF, 6, REG, T, VAL);         \
+-      WRITE_WB_REG_CASE(OFF, 7, REG, T, VAL);
++      WRITE_WB_REG_CASE(OFF, 7, REG, T, VAL);         \
++      WRITE_WB_REG_CASE(OFF, 8, REG, T, VAL);         \
++      WRITE_WB_REG_CASE(OFF, 9, REG, T, VAL);         \
++      WRITE_WB_REG_CASE(OFF, 10, REG, T, VAL);        \
++      WRITE_WB_REG_CASE(OFF, 11, REG, T, VAL);        \
++      WRITE_WB_REG_CASE(OFF, 12, REG, T, VAL);        \
++      WRITE_WB_REG_CASE(OFF, 13, REG, T, VAL);
+ static u64 read_wb_reg(int reg, int n, int t)
+ {
diff --git a/queue-6.13/memcg-fix-soft-lockup-in-the-oom-process.patch b/queue-6.13/memcg-fix-soft-lockup-in-the-oom-process.patch
new file mode 100644 (file)
index 0000000..a747d19
--- /dev/null
@@ -0,0 +1,121 @@
+From ade81479c7dda1ce3eedb215c78bc615bbd04f06 Mon Sep 17 00:00:00 2001
+From: Chen Ridong <chenridong@huawei.com>
+Date: Tue, 24 Dec 2024 02:52:38 +0000
+Subject: memcg: fix soft lockup in the OOM process
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Chen Ridong <chenridong@huawei.com>
+
+commit ade81479c7dda1ce3eedb215c78bc615bbd04f06 upstream.
+
+A soft lockup issue was found in the product with about 56,000 tasks were
+in the OOM cgroup, it was traversing them when the soft lockup was
+triggered.
+
+watchdog: BUG: soft lockup - CPU#2 stuck for 23s! [VM Thread:1503066]
+CPU: 2 PID: 1503066 Comm: VM Thread Kdump: loaded Tainted: G
+Hardware name: Huawei Cloud OpenStack Nova, BIOS
+RIP: 0010:console_unlock+0x343/0x540
+RSP: 0000:ffffb751447db9a0 EFLAGS: 00000247 ORIG_RAX: ffffffffffffff13
+RAX: 0000000000000001 RBX: 0000000000000000 RCX: 00000000ffffffff
+RDX: 0000000000000000 RSI: 0000000000000004 RDI: 0000000000000247
+RBP: ffffffffafc71f90 R08: 0000000000000000 R09: 0000000000000040
+R10: 0000000000000080 R11: 0000000000000000 R12: ffffffffafc74bd0
+R13: ffffffffaf60a220 R14: 0000000000000247 R15: 0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007f2fe6ad91f0 CR3: 00000004b2076003 CR4: 0000000000360ee0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ vprintk_emit+0x193/0x280
+ printk+0x52/0x6e
+ dump_task+0x114/0x130
+ mem_cgroup_scan_tasks+0x76/0x100
+ dump_header+0x1fe/0x210
+ oom_kill_process+0xd1/0x100
+ out_of_memory+0x125/0x570
+ mem_cgroup_out_of_memory+0xb5/0xd0
+ try_charge+0x720/0x770
+ mem_cgroup_try_charge+0x86/0x180
+ mem_cgroup_try_charge_delay+0x1c/0x40
+ do_anonymous_page+0xb5/0x390
+ handle_mm_fault+0xc4/0x1f0
+
+This is because thousands of processes are in the OOM cgroup, it takes a
+long time to traverse all of them.  As a result, this lead to soft lockup
+in the OOM process.
+
+To fix this issue, call 'cond_resched' in the 'mem_cgroup_scan_tasks'
+function per 1000 iterations.  For global OOM, call
+'touch_softlockup_watchdog' per 1000 iterations to avoid this issue.
+
+Link: https://lkml.kernel.org/r/20241224025238.3768787-1-chenridong@huaweicloud.com
+Fixes: 9cbb78bb3143 ("mm, memcg: introduce own oom handler to iterate only over its own threads")
+Signed-off-by: Chen Ridong <chenridong@huawei.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Cc: Roman Gushchin <roman.gushchin@linux.dev>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Shakeel Butt <shakeelb@google.com>
+Cc: Muchun Song <songmuchun@bytedance.com>
+Cc: Michal Koutný <mkoutny@suse.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/memcontrol.c |    7 ++++++-
+ mm/oom_kill.c   |    8 +++++++-
+ 2 files changed, 13 insertions(+), 2 deletions(-)
+
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -1161,6 +1161,7 @@ void mem_cgroup_scan_tasks(struct mem_cg
+ {
+       struct mem_cgroup *iter;
+       int ret = 0;
++      int i = 0;
+       BUG_ON(mem_cgroup_is_root(memcg));
+@@ -1169,8 +1170,12 @@ void mem_cgroup_scan_tasks(struct mem_cg
+               struct task_struct *task;
+               css_task_iter_start(&iter->css, CSS_TASK_ITER_PROCS, &it);
+-              while (!ret && (task = css_task_iter_next(&it)))
++              while (!ret && (task = css_task_iter_next(&it))) {
++                      /* Avoid potential softlockup warning */
++                      if ((++i & 1023) == 0)
++                              cond_resched();
+                       ret = fn(task, arg);
++              }
+               css_task_iter_end(&it);
+               if (ret) {
+                       mem_cgroup_iter_break(memcg, iter);
+--- a/mm/oom_kill.c
++++ b/mm/oom_kill.c
+@@ -44,6 +44,7 @@
+ #include <linux/init.h>
+ #include <linux/mmu_notifier.h>
+ #include <linux/cred.h>
++#include <linux/nmi.h>
+ #include <asm/tlb.h>
+ #include "internal.h"
+@@ -430,10 +431,15 @@ static void dump_tasks(struct oom_contro
+               mem_cgroup_scan_tasks(oc->memcg, dump_task, oc);
+       else {
+               struct task_struct *p;
++              int i = 0;
+               rcu_read_lock();
+-              for_each_process(p)
++              for_each_process(p) {
++                      /* Avoid potential softlockup warning */
++                      if ((++i & 1023) == 0)
++                              touch_softlockup_watchdog();
+                       dump_task(p, oc);
++              }
+               rcu_read_unlock();
+       }
+ }
diff --git a/queue-6.13/pwm-ensure-callbacks-exist-before-calling-them.patch b/queue-6.13/pwm-ensure-callbacks-exist-before-calling-them.patch
new file mode 100644 (file)
index 0000000..cd72848
--- /dev/null
@@ -0,0 +1,111 @@
+From da6b353786997c0ffa67127355ad1d54ed3324c2 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@baylibre.com>
+Date: Thu, 23 Jan 2025 18:27:07 +0100
+Subject: pwm: Ensure callbacks exist before calling them
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+
+commit da6b353786997c0ffa67127355ad1d54ed3324c2 upstream.
+
+If one of the waveform functions is called for a chip that only supports
+.apply(), we want that an error code is returned and not a NULL pointer
+exception.
+
+Fixes: 6c5126c6406d ("pwm: Provide new consumer API functions for waveforms")
+Cc: stable@vger.kernel.org
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+Tested-by: Trevor Gamblin <tgamblin@baylibre.com>
+Link: https://lore.kernel.org/r/20250123172709.391349-2-u.kleine-koenig@baylibre.com
+Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pwm/core.c  | 13 +++++++++++--
+ include/linux/pwm.h | 17 +++++++++++++++++
+ 2 files changed, 28 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
+index 9c733877e98e..1a36ee3cab91 100644
+--- a/drivers/pwm/core.c
++++ b/drivers/pwm/core.c
+@@ -242,6 +242,9 @@ int pwm_round_waveform_might_sleep(struct pwm_device *pwm, struct pwm_waveform *
+       BUG_ON(WFHWSIZE < ops->sizeof_wfhw);
++      if (!pwmchip_supports_waveform(chip))
++              return -EOPNOTSUPP;
++
+       if (!pwm_wf_valid(wf))
+               return -EINVAL;
+@@ -294,6 +297,9 @@ int pwm_get_waveform_might_sleep(struct pwm_device *pwm, struct pwm_waveform *wf
+       BUG_ON(WFHWSIZE < ops->sizeof_wfhw);
++      if (!pwmchip_supports_waveform(chip) || !ops->read_waveform)
++              return -EOPNOTSUPP;
++
+       guard(pwmchip)(chip);
+       if (!chip->operational)
+@@ -320,6 +326,9 @@ static int __pwm_set_waveform(struct pwm_device *pwm,
+       BUG_ON(WFHWSIZE < ops->sizeof_wfhw);
++      if (!pwmchip_supports_waveform(chip))
++              return -EOPNOTSUPP;
++
+       if (!pwm_wf_valid(wf))
+               return -EINVAL;
+@@ -592,7 +601,7 @@ static int __pwm_apply(struct pwm_device *pwm, const struct pwm_state *state)
+           state->usage_power == pwm->state.usage_power)
+               return 0;
+-      if (ops->write_waveform) {
++      if (pwmchip_supports_waveform(chip)) {
+               struct pwm_waveform wf;
+               char wfhw[WFHWSIZE];
+@@ -746,7 +755,7 @@ int pwm_get_state_hw(struct pwm_device *pwm, struct pwm_state *state)
+       if (!chip->operational)
+               return -ENODEV;
+-      if (ops->read_waveform) {
++      if (pwmchip_supports_waveform(chip) && ops->read_waveform) {
+               char wfhw[WFHWSIZE];
+               struct pwm_waveform wf;
+diff --git a/include/linux/pwm.h b/include/linux/pwm.h
+index 78827f312407..b8d78009e779 100644
+--- a/include/linux/pwm.h
++++ b/include/linux/pwm.h
+@@ -347,6 +347,23 @@ struct pwm_chip {
+       struct pwm_device pwms[] __counted_by(npwm);
+ };
++/**
++ * pwmchip_supports_waveform() - checks if the given chip supports waveform callbacks
++ * @chip: The pwm_chip to test
++ *
++ * Returns true iff the pwm chip support the waveform functions like
++ * pwm_set_waveform_might_sleep() and pwm_round_waveform_might_sleep()
++ */
++static inline bool pwmchip_supports_waveform(struct pwm_chip *chip)
++{
++      /*
++       * only check for .write_waveform(). If that is available,
++       * .round_waveform_tohw() and .round_waveform_fromhw() asserted to be
++       * available, too, in pwmchip_add().
++       */
++      return chip->ops->write_waveform != NULL;
++}
++
+ static inline struct device *pwmchip_parent(const struct pwm_chip *chip)
+ {
+       return chip->dev.parent;
+-- 
+2.48.1
+
diff --git a/queue-6.13/s390-add-std-gnu11-to-decompressor-and-purgatory-cflags.patch b/queue-6.13/s390-add-std-gnu11-to-decompressor-and-purgatory-cflags.patch
new file mode 100644 (file)
index 0000000..6dc6233
--- /dev/null
@@ -0,0 +1,63 @@
+From 3b8b80e993766dc96d1a1c01c62f5d15fafc79b9 Mon Sep 17 00:00:00 2001
+From: Nathan Chancellor <nathan@kernel.org>
+Date: Wed, 22 Jan 2025 19:54:27 -0700
+Subject: s390: Add '-std=gnu11' to decompressor and purgatory CFLAGS
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+commit 3b8b80e993766dc96d1a1c01c62f5d15fafc79b9 upstream.
+
+GCC changed the default C standard dialect from gnu17 to gnu23,
+which should not have impacted the kernel because it explicitly requests
+the gnu11 standard in the main Makefile. However, there are certain
+places in the s390 code that use their own CFLAGS without a '-std='
+value, which break with this dialect change because of the kernel's own
+definitions of bool, false, and true conflicting with the C23 reserved
+keywords.
+
+  include/linux/stddef.h:11:9: error: cannot use keyword 'false' as enumeration constant
+     11 |         false   = 0,
+        |         ^~~~~
+  include/linux/stddef.h:11:9: note: 'false' is a keyword with '-std=c23' onwards
+  include/linux/types.h:35:33: error: 'bool' cannot be defined via 'typedef'
+     35 | typedef _Bool                   bool;
+        |                                 ^~~~
+  include/linux/types.h:35:33: note: 'bool' is a keyword with '-std=c23' onwards
+
+Add '-std=gnu11' to the decompressor and purgatory CFLAGS to eliminate
+these errors and make the C standard version of these areas match the
+rest of the kernel.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Tested-by: Heiko Carstens <hca@linux.ibm.com>
+Link: https://lore.kernel.org/r/20250122-s390-fix-std-for-gcc-15-v1-1-8b00cadee083@kernel.org
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/Makefile           |    2 +-
+ arch/s390/purgatory/Makefile |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/s390/Makefile
++++ b/arch/s390/Makefile
+@@ -22,7 +22,7 @@ KBUILD_AFLAGS_DECOMPRESSOR := $(CLANG_FL
+ ifndef CONFIG_AS_IS_LLVM
+ KBUILD_AFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO),$(aflags_dwarf))
+ endif
+-KBUILD_CFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -O2 -mpacked-stack
++KBUILD_CFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -O2 -mpacked-stack -std=gnu11
+ KBUILD_CFLAGS_DECOMPRESSOR += -DDISABLE_BRANCH_PROFILING -D__NO_FORTIFY
+ KBUILD_CFLAGS_DECOMPRESSOR += -D__DECOMPRESSOR
+ KBUILD_CFLAGS_DECOMPRESSOR += -fno-delete-null-pointer-checks -msoft-float -mbackchain
+--- a/arch/s390/purgatory/Makefile
++++ b/arch/s390/purgatory/Makefile
+@@ -13,7 +13,7 @@ CFLAGS_sha256.o := -D__DISABLE_EXPORTS -
+ $(obj)/mem.o: $(srctree)/arch/s390/lib/mem.S FORCE
+       $(call if_changed_rule,as_o_S)
+-KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes
++KBUILD_CFLAGS := -std=gnu11 -fno-strict-aliasing -Wall -Wstrict-prototypes
+ KBUILD_CFLAGS += -Wno-pointer-sign -Wno-sign-compare
+ KBUILD_CFLAGS += -fno-zero-initialized-in-bss -fno-builtin -ffreestanding
+ KBUILD_CFLAGS += -Os -m64 -msoft-float -fno-common
diff --git a/queue-6.13/selftests-mm-build-with-o2.patch b/queue-6.13/selftests-mm-build-with-o2.patch
new file mode 100644 (file)
index 0000000..3da784c
--- /dev/null
@@ -0,0 +1,51 @@
+From 46036188ea1f5266df23a6149dea0df1c77cd1c7 Mon Sep 17 00:00:00 2001
+From: Kevin Brodsky <kevin.brodsky@arm.com>
+Date: Mon, 9 Dec 2024 09:50:10 +0000
+Subject: selftests/mm: build with -O2
+
+From: Kevin Brodsky <kevin.brodsky@arm.com>
+
+commit 46036188ea1f5266df23a6149dea0df1c77cd1c7 upstream.
+
+The mm kselftests are currently built with no optimisation (-O0).  It's
+unclear why, and besides being obviously suboptimal, this also prevents
+the pkeys tests from working as intended.  Let's build all the tests with
+-O2.
+
+[kevin.brodsky@arm.com: silence unused-result warnings]
+  Link: https://lkml.kernel.org/r/20250107170110.2819685-1-kevin.brodsky@arm.com
+Link: https://lkml.kernel.org/r/20241209095019.1732120-6-kevin.brodsky@arm.com
+Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
+Cc: Aruna Ramakrishna <aruna.ramakrishna@oracle.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: Joey Gouly <joey.gouly@arm.com>
+Cc: Keith Lucas <keith.lucas@oracle.com>
+Cc: Ryan Roberts <ryan.roberts@arm.com>
+Cc: Shuah Khan <shuah@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/mm/Makefile |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/tools/testing/selftests/mm/Makefile
++++ b/tools/testing/selftests/mm/Makefile
+@@ -33,9 +33,16 @@ endif
+ # LDLIBS.
+ MAKEFLAGS += --no-builtin-rules
+-CFLAGS = -Wall -I $(top_srcdir) $(EXTRA_CFLAGS) $(KHDR_INCLUDES) $(TOOLS_INCLUDES)
++CFLAGS = -Wall -O2 -I $(top_srcdir) $(EXTRA_CFLAGS) $(KHDR_INCLUDES) $(TOOLS_INCLUDES)
+ LDLIBS = -lrt -lpthread -lm
++# Some distributions (such as Ubuntu) configure GCC so that _FORTIFY_SOURCE is
++# automatically enabled at -O1 or above. This triggers various unused-result
++# warnings where functions such as read() or write() are called and their
++# return value is not checked. Disable _FORTIFY_SOURCE to silence those
++# warnings.
++CFLAGS += -U_FORTIFY_SOURCE
++
+ KDIR ?= /lib/modules/$(shell uname -r)/build
+ ifneq (,$(wildcard $(KDIR)/Module.symvers))
+ ifneq (,$(wildcard $(KDIR)/include/linux/page_frag_cache.h))
index e4ee6a4a522d5ffb7823c0c8a26af66e2ae1b336..c168d10577e079807b42d1407ec64ff72f3dc4ee 100644 (file)
@@ -611,3 +611,13 @@ media-imx-jpeg-fix-potential-error-pointer-dereference-in-detach_pm.patch
 powerpc-pseries-iommu-don-t-unset-window-if-it-was-never-set.patch
 md-md-bitmap-synchronize-bitmap_get_stats-with-bitmap-lifetime.patch
 btrfs-output-the-reason-for-open_ctree-failure.patch
+selftests-mm-build-with-o2.patch
+asoc-da7213-initialize-the-mutex.patch
+s390-add-std-gnu11-to-decompressor-and-purgatory-cflags.patch
+drm-amd-display-add-hubp-cache-reset-when-powergating.patch
+kvm-x86-plumb-in-the-vcpu-to-kvm_x86_ops.hwapic_isr_update.patch
+memcg-fix-soft-lockup-in-the-oom-process.patch
+pwm-ensure-callbacks-exist-before-calling-them.patch
+loongarch-change-8-to-14-for-loongarch_max_-brp-wrp.patch
+btrfs-do-proper-folio-cleanup-when-cow_file_range-failed.patch
+btrfs-do-proper-folio-cleanup-when-run_delalloc_nocow-failed.patch