]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.1
authorSasha Levin <sashal@kernel.org>
Fri, 27 Jun 2025 14:02:14 +0000 (10:02 -0400)
committerSasha Levin <sashal@kernel.org>
Fri, 27 Jun 2025 14:02:14 +0000 (10:02 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
71 files changed:
queue-6.1/af_unix-don-t-call-skb_get-for-oob-skb.patch [new file with mode: 0644]
queue-6.1/af_unix-don-t-leave-consecutive-consumed-oob-skbs.patch [new file with mode: 0644]
queue-6.1/alsa-hda-add-new-pci-id-for-amd-gpu-display-hd-audio.patch [new file with mode: 0644]
queue-6.1/alsa-hda-ignore-unsol-events-for-cards-being-shut-do.patch [new file with mode: 0644]
queue-6.1/alsa-usb-audio-add-a-quirk-for-lenovo-thinkpad-thund.patch [new file with mode: 0644]
queue-6.1/amd-amdkfd-fix-a-kfd_process-ref-leak.patch [new file with mode: 0644]
queue-6.1/asoc-codec-wcd9335-convert-to-gpio-descriptors.patch [new file with mode: 0644]
queue-6.1/asoc-codecs-wcd9335-fix-missing-free-of-regulator-su.patch [new file with mode: 0644]
queue-6.1/asoc-codecs-wcd9335-handle-nicer-probe-deferral-and-.patch [new file with mode: 0644]
queue-6.1/bcache-fix-null-pointer-in-cache_set_flush.patch [new file with mode: 0644]
queue-6.1/btrfs-handle-csum-tree-error-with-rescue-ibadroots-c.patch [new file with mode: 0644]
queue-6.1/ceph-fix-possible-integer-overflow-in-ceph_zero_obje.patch [new file with mode: 0644]
queue-6.1/cifs-correctly-set-smb1-sessionkey-field-in-session-.patch [new file with mode: 0644]
queue-6.1/cifs-fix-cifs_query_path_info-for-windows-nt-servers.patch [new file with mode: 0644]
queue-6.1/coresight-only-check-bottom-two-claim-bits.patch [new file with mode: 0644]
queue-6.1/dmaengine-xilinx_dma-set-dma_device-directions.patch [new file with mode: 0644]
queue-6.1/drivers-hv-allocate-interrupt-and-monitor-pages-alig.patch [new file with mode: 0644]
queue-6.1/drivers-hv-change-hv_free_hyperv_page-to-take-void-a.patch [new file with mode: 0644]
queue-6.1/drivers-hv-hyperv_fb-untangle-and-refactor-hyper-v-p.patch [new file with mode: 0644]
queue-6.1/drivers-hv-move-panic-report-code-from-vmbus-to-hv-e.patch [new file with mode: 0644]
queue-6.1/drivers-hv-vmbus-add-utility-function-for-querying-r.patch [new file with mode: 0644]
queue-6.1/drivers-hv-vmbus-leak-pages-if-set_memory_encrypted-.patch [new file with mode: 0644]
queue-6.1/drivers-hv-vmbus-remove-second-mapping-of-vmbus-moni.patch [new file with mode: 0644]
queue-6.1/drm-i915-gem-allow-exec_capture-on-recoverable-conte.patch [new file with mode: 0644]
queue-6.1/dummycon-trigger-redraw-when-switching-consoles-with.patch [new file with mode: 0644]
queue-6.1/f2fs-don-t-over-report-free-space-or-inodes-in-statv.patch [new file with mode: 0644]
queue-6.1/fbdev-fix-do_register_framebuffer-to-prevent-null-pt.patch [new file with mode: 0644]
queue-6.1/fs-jfs-consolidate-sanity-checking-in-dbmount.patch [new file with mode: 0644]
queue-6.1/hwmon-pmbus-max34440-fix-support-for-max34451.patch [new file with mode: 0644]
queue-6.1/iio-adc-ad_sigma_delta-fix-use-of-uninitialized-stat.patch [new file with mode: 0644]
queue-6.1/iio-pressure-zpa2326-use-aligned_s64-for-the-timesta.patch [new file with mode: 0644]
queue-6.1/jfs-validate-ag-parameters-in-dbmount-to-prevent-cra.patch [new file with mode: 0644]
queue-6.1/ksmbd-allow-a-filename-to-contain-special-characters.patch [new file with mode: 0644]
queue-6.1/leds-multicolor-fix-intensity-setting-while-sw-blink.patch [new file with mode: 0644]
queue-6.1/mailbox-not-protect-module_put-with-spin_lock_irqsav.patch [new file with mode: 0644]
queue-6.1/md-md-bitmap-fix-dm-raid-max_write_behind-setting.patch [new file with mode: 0644]
queue-6.1/media-imx-jpeg-add-a-timeout-mechanism-for-each-fram.patch [new file with mode: 0644]
queue-6.1/media-imx-jpeg-cleanup-after-an-allocation-error.patch [new file with mode: 0644]
queue-6.1/media-imx-jpeg-move-mxc_jpeg_free_slot_data-ahead.patch [new file with mode: 0644]
queue-6.1/media-imx-jpeg-remove-unnecessary-memset-after-dma_a.patch [new file with mode: 0644]
queue-6.1/media-imx-jpeg-reset-slot-data-pointers-when-freed.patch [new file with mode: 0644]
queue-6.1/media-imx-jpeg-support-to-assign-slot-for-encoder-de.patch [new file with mode: 0644]
queue-6.1/mfd-max14577-fix-wakeup-source-leaks-on-device-unbin.patch [new file with mode: 0644]
queue-6.1/nfsv4-always-set-nlink-even-if-the-server-doesn-t-su.patch [new file with mode: 0644]
queue-6.1/nfsv4-xattr-handlers-should-check-for-absent-nfs-fil.patch [new file with mode: 0644]
queue-6.1/nfsv4.2-fix-listxattr-to-return-selinux-security-lab.patch [new file with mode: 0644]
queue-6.1/ovl-check-for-null-d_inode-in-ovl_dentry_upper.patch [new file with mode: 0644]
queue-6.1/pci-apple-fix-missing-of-node-reference-in-apple_pci.patch [new file with mode: 0644]
queue-6.1/pci-apple-set-only-available-ports-up.patch [new file with mode: 0644]
queue-6.1/pci-apple-use-helper-function-for_each_child_of_node.patch [new file with mode: 0644]
queue-6.1/revert-drm-i915-gem-allow-exec_capture-on-recoverabl.patch [new file with mode: 0644]
queue-6.1/revert-iommu-amd-prevent-binding-other-pci-drivers-t.patch [new file with mode: 0644]
queue-6.1/rust-module-place-cleanup_module-in-.exit.text-secti.patch [new file with mode: 0644]
queue-6.1/series [new file with mode: 0644]
queue-6.1/tty-serial-uartlite-register-uart-driver-in-init.patch [new file with mode: 0644]
queue-6.1/tty-vt-make-consw-con_switch-return-a-bool.patch [new file with mode: 0644]
queue-6.1/tty-vt-make-init-parameter-of-consw-con_init-a-bool.patch [new file with mode: 0644]
queue-6.1/tty-vt-sanitize-arguments-of-consw-con_clear.patch [new file with mode: 0644]
queue-6.1/uio_hv_generic-align-ring-size-to-system-page.patch [new file with mode: 0644]
queue-6.1/uio_hv_generic-query-the-ringbuffer-size-for-device.patch [new file with mode: 0644]
queue-6.1/um-add-cmpxchg8b_emu-and-checksum-functions-to-asm-p.patch [new file with mode: 0644]
queue-6.1/um-use-proper-care-when-taking-mmap-lock-during-segf.patch [new file with mode: 0644]
queue-6.1/usb-add-checks-for-snprintf-calls-in-usb_alloc_dev.patch [new file with mode: 0644]
queue-6.1/usb-cdc-wdm-avoid-setting-wdm_read-for-zlp-s.patch [new file with mode: 0644]
queue-6.1/usb-common-usb-conn-gpio-use-a-unique-name-for-usb-c.patch [new file with mode: 0644]
queue-6.1/usb-dwc2-also-exit-clock_gating-when-stopping-udc-wh.patch [new file with mode: 0644]
queue-6.1/usb-potential-integer-overflow-in-usbg_make_tpg.patch [new file with mode: 0644]
queue-6.1/usb-typec-displayport-receive-dp-status-update-nak-r.patch [new file with mode: 0644]
queue-6.1/usb-typec-mux-do-not-return-on-eopnotsupp-in-mux-swi.patch [new file with mode: 0644]
queue-6.1/vgacon-remove-unneeded-forward-declarations.patch [new file with mode: 0644]
queue-6.1/vgacon-switch-vgacon_scrolldelta-and-vgacon_restore_.patch [new file with mode: 0644]

diff --git a/queue-6.1/af_unix-don-t-call-skb_get-for-oob-skb.patch b/queue-6.1/af_unix-don-t-call-skb_get-for-oob-skb.patch
new file mode 100644 (file)
index 0000000..fba7522
--- /dev/null
@@ -0,0 +1,163 @@
+From b62b799a9d16603f259104460e835c859d6686c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Aug 2024 16:39:21 -0700
+Subject: af_unix: Don't call skb_get() for OOB skb.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 8594d9b85c07f05e431bd07e895c2a3ad9b85d6f ]
+
+Since introduced, OOB skb holds an additional reference count with no
+special reason and caused many issues.
+
+Also, kfree_skb() and consume_skb() are used to decrement the count,
+which is confusing.
+
+Let's drop the unnecessary skb_get() in queue_oob() and corresponding
+kfree_skb(), consume_skb(), and skb_unref().
+
+Now unix_sk(sk)->oob_skb is just a pointer to skb in the receive queue,
+so special handing is no longer needed in GC.
+
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://patch.msgid.link/20240816233921.57800-1-kuniyu@amazon.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 32ca245464e1 ("af_unix: Don't leave consecutive consumed OOB skbs.")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/unix/af_unix.c | 27 +++++----------------------
+ net/unix/garbage.c | 24 +++---------------------
+ 2 files changed, 8 insertions(+), 43 deletions(-)
+
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index 79b783a70c87d..9ef6011a055b1 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -604,10 +604,7 @@ static void unix_release_sock(struct sock *sk, int embrion)
+       unix_state_unlock(sk);
+ #if IS_ENABLED(CONFIG_AF_UNIX_OOB)
+-      if (u->oob_skb) {
+-              kfree_skb(u->oob_skb);
+-              u->oob_skb = NULL;
+-      }
++      u->oob_skb = NULL;
+ #endif
+       wake_up_interruptible_all(&u->peer_wait);
+@@ -2133,13 +2130,9 @@ static int queue_oob(struct socket *sock, struct msghdr *msg, struct sock *other
+       }
+       maybe_add_creds(skb, sock, other);
+-      skb_get(skb);
+-
+       scm_stat_add(other, skb);
+       spin_lock(&other->sk_receive_queue.lock);
+-      if (ousk->oob_skb)
+-              consume_skb(ousk->oob_skb);
+       WRITE_ONCE(ousk->oob_skb, skb);
+       __skb_queue_tail(&other->sk_receive_queue, skb);
+       spin_unlock(&other->sk_receive_queue.lock);
+@@ -2640,8 +2633,6 @@ static int unix_stream_recv_urg(struct unix_stream_read_state *state)
+       if (!(state->flags & MSG_PEEK))
+               WRITE_ONCE(u->oob_skb, NULL);
+-      else
+-              skb_get(oob_skb);
+       spin_unlock(&sk->sk_receive_queue.lock);
+       unix_state_unlock(sk);
+@@ -2651,8 +2642,6 @@ static int unix_stream_recv_urg(struct unix_stream_read_state *state)
+       if (!(state->flags & MSG_PEEK))
+               UNIXCB(oob_skb).consumed += 1;
+-      consume_skb(oob_skb);
+-
+       mutex_unlock(&u->iolock);
+       if (chunk < 0)
+@@ -2680,12 +2669,10 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
+                       if (copied) {
+                               skb = NULL;
+                       } else if (!(flags & MSG_PEEK)) {
+-                              if (sock_flag(sk, SOCK_URGINLINE)) {
+-                                      WRITE_ONCE(u->oob_skb, NULL);
+-                                      consume_skb(skb);
+-                              } else {
++                              WRITE_ONCE(u->oob_skb, NULL);
++
++                              if (!sock_flag(sk, SOCK_URGINLINE)) {
+                                       __skb_unlink(skb, &sk->sk_receive_queue);
+-                                      WRITE_ONCE(u->oob_skb, NULL);
+                                       unlinked_skb = skb;
+                                       skb = skb_peek(&sk->sk_receive_queue);
+                               }
+@@ -2696,10 +2683,7 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
+               spin_unlock(&sk->sk_receive_queue.lock);
+-              if (unlinked_skb) {
+-                      WARN_ON_ONCE(skb_unref(unlinked_skb));
+-                      kfree_skb(unlinked_skb);
+-              }
++              kfree_skb(unlinked_skb);
+       }
+       return skb;
+ }
+@@ -2742,7 +2726,6 @@ static int unix_stream_read_skb(struct sock *sk, skb_read_actor_t recv_actor)
+               unix_state_unlock(sk);
+               if (drop) {
+-                      WARN_ON_ONCE(skb_unref(skb));
+                       kfree_skb(skb);
+                       return -EAGAIN;
+               }
+diff --git a/net/unix/garbage.c b/net/unix/garbage.c
+index 23efb78fe9ef4..0068e758be4dd 100644
+--- a/net/unix/garbage.c
++++ b/net/unix/garbage.c
+@@ -337,23 +337,6 @@ static bool unix_vertex_dead(struct unix_vertex *vertex)
+       return true;
+ }
+-enum unix_recv_queue_lock_class {
+-      U_RECVQ_LOCK_NORMAL,
+-      U_RECVQ_LOCK_EMBRYO,
+-};
+-
+-static void unix_collect_queue(struct unix_sock *u, struct sk_buff_head *hitlist)
+-{
+-      skb_queue_splice_init(&u->sk.sk_receive_queue, hitlist);
+-
+-#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
+-      if (u->oob_skb) {
+-              WARN_ON_ONCE(skb_unref(u->oob_skb));
+-              u->oob_skb = NULL;
+-      }
+-#endif
+-}
+-
+ static void unix_collect_skb(struct list_head *scc, struct sk_buff_head *hitlist)
+ {
+       struct unix_vertex *vertex;
+@@ -375,13 +358,12 @@ static void unix_collect_skb(struct list_head *scc, struct sk_buff_head *hitlist
+                       skb_queue_walk(queue, skb) {
+                               struct sk_buff_head *embryo_queue = &skb->sk->sk_receive_queue;
+-                              /* listener -> embryo order, the inversion never happens. */
+-                              spin_lock_nested(&embryo_queue->lock, U_RECVQ_LOCK_EMBRYO);
+-                              unix_collect_queue(unix_sk(skb->sk), hitlist);
++                              spin_lock(&embryo_queue->lock);
++                              skb_queue_splice_init(embryo_queue, hitlist);
+                               spin_unlock(&embryo_queue->lock);
+                       }
+               } else {
+-                      unix_collect_queue(u, hitlist);
++                      skb_queue_splice_init(queue, hitlist);
+               }
+               spin_unlock(&queue->lock);
+-- 
+2.39.5
+
diff --git a/queue-6.1/af_unix-don-t-leave-consecutive-consumed-oob-skbs.patch b/queue-6.1/af_unix-don-t-leave-consecutive-consumed-oob-skbs.patch
new file mode 100644 (file)
index 0000000..8eb0957
--- /dev/null
@@ -0,0 +1,203 @@
+From 4258a01d2ae3218fe4f93ddb7d50b1cf5df1cc18 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jun 2025 21:13:55 -0700
+Subject: af_unix: Don't leave consecutive consumed OOB skbs.
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit 32ca245464e1479bfea8592b9db227fdc1641705 ]
+
+Jann Horn reported a use-after-free in unix_stream_read_generic().
+
+The following sequences reproduce the issue:
+
+  $ python3
+  from socket import *
+  s1, s2 = socketpair(AF_UNIX, SOCK_STREAM)
+  s1.send(b'x', MSG_OOB)
+  s2.recv(1, MSG_OOB)     # leave a consumed OOB skb
+  s1.send(b'y', MSG_OOB)
+  s2.recv(1, MSG_OOB)     # leave a consumed OOB skb
+  s1.send(b'z', MSG_OOB)
+  s2.recv(1)              # recv 'z' illegally
+  s2.recv(1, MSG_OOB)     # access 'z' skb (use-after-free)
+
+Even though a user reads OOB data, the skb holding the data stays on
+the recv queue to mark the OOB boundary and break the next recv().
+
+After the last send() in the scenario above, the sk2's recv queue has
+2 leading consumed OOB skbs and 1 real OOB skb.
+
+Then, the following happens during the next recv() without MSG_OOB
+
+  1. unix_stream_read_generic() peeks the first consumed OOB skb
+  2. manage_oob() returns the next consumed OOB skb
+  3. unix_stream_read_generic() fetches the next not-yet-consumed OOB skb
+  4. unix_stream_read_generic() reads and frees the OOB skb
+
+, and the last recv(MSG_OOB) triggers KASAN splat.
+
+The 3. above occurs because of the SO_PEEK_OFF code, which does not
+expect unix_skb_len(skb) to be 0, but this is true for such consumed
+OOB skbs.
+
+  while (skip >= unix_skb_len(skb)) {
+    skip -= unix_skb_len(skb);
+    skb = skb_peek_next(skb, &sk->sk_receive_queue);
+    ...
+  }
+
+In addition to this use-after-free, there is another issue that
+ioctl(SIOCATMARK) does not function properly with consecutive consumed
+OOB skbs.
+
+So, nothing good comes out of such a situation.
+
+Instead of complicating manage_oob(), ioctl() handling, and the next
+ECONNRESET fix by introducing a loop for consecutive consumed OOB skbs,
+let's not leave such consecutive OOB unnecessarily.
+
+Now, while receiving an OOB skb in unix_stream_recv_urg(), if its
+previous skb is a consumed OOB skb, it is freed.
+
+[0]:
+BUG: KASAN: slab-use-after-free in unix_stream_read_actor (net/unix/af_unix.c:3027)
+Read of size 4 at addr ffff888106ef2904 by task python3/315
+
+CPU: 2 UID: 0 PID: 315 Comm: python3 Not tainted 6.16.0-rc1-00407-gec315832f6f9 #8 PREEMPT(voluntary)
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-4.fc42 04/01/2014
+Call Trace:
+ <TASK>
+ dump_stack_lvl (lib/dump_stack.c:122)
+ print_report (mm/kasan/report.c:409 mm/kasan/report.c:521)
+ kasan_report (mm/kasan/report.c:636)
+ unix_stream_read_actor (net/unix/af_unix.c:3027)
+ unix_stream_read_generic (net/unix/af_unix.c:2708 net/unix/af_unix.c:2847)
+ unix_stream_recvmsg (net/unix/af_unix.c:3048)
+ sock_recvmsg (net/socket.c:1063 (discriminator 20) net/socket.c:1085 (discriminator 20))
+ __sys_recvfrom (net/socket.c:2278)
+ __x64_sys_recvfrom (net/socket.c:2291 (discriminator 1) net/socket.c:2287 (discriminator 1) net/socket.c:2287 (discriminator 1))
+ do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1))
+ entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
+RIP: 0033:0x7f8911fcea06
+Code: 5d e8 41 8b 93 08 03 00 00 59 5e 48 83 f8 fc 75 19 83 e2 39 83 fa 08 75 11 e8 26 ff ff ff 66 0f 1f 44 00 00 48 8b 45 10 0f 05 <48> 8b 5d f8 c9 c3 0f 1f 40 00 f3 0f 1e fa 55 48 89 e5 48 83 ec 08
+RSP: 002b:00007fffdb0dccb0 EFLAGS: 00000202 ORIG_RAX: 000000000000002d
+RAX: ffffffffffffffda RBX: 00007fffdb0dcdc8 RCX: 00007f8911fcea06
+RDX: 0000000000000001 RSI: 00007f8911a5e060 RDI: 0000000000000006
+RBP: 00007fffdb0dccd0 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000001 R11: 0000000000000202 R12: 00007f89119a7d20
+R13: ffffffffc4653600 R14: 0000000000000000 R15: 0000000000000000
+ </TASK>
+
+Allocated by task 315:
+ kasan_save_stack (mm/kasan/common.c:48)
+ kasan_save_track (mm/kasan/common.c:60 (discriminator 1) mm/kasan/common.c:69 (discriminator 1))
+ __kasan_slab_alloc (mm/kasan/common.c:348)
+ kmem_cache_alloc_node_noprof (./include/linux/kasan.h:250 mm/slub.c:4148 mm/slub.c:4197 mm/slub.c:4249)
+ __alloc_skb (net/core/skbuff.c:660 (discriminator 4))
+ alloc_skb_with_frags (./include/linux/skbuff.h:1336 net/core/skbuff.c:6668)
+ sock_alloc_send_pskb (net/core/sock.c:2993)
+ unix_stream_sendmsg (./include/net/sock.h:1847 net/unix/af_unix.c:2256 net/unix/af_unix.c:2418)
+ __sys_sendto (net/socket.c:712 (discriminator 20) net/socket.c:727 (discriminator 20) net/socket.c:2226 (discriminator 20))
+ __x64_sys_sendto (net/socket.c:2233 (discriminator 1) net/socket.c:2229 (discriminator 1) net/socket.c:2229 (discriminator 1))
+ do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1))
+ entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
+
+Freed by task 315:
+ kasan_save_stack (mm/kasan/common.c:48)
+ kasan_save_track (mm/kasan/common.c:60 (discriminator 1) mm/kasan/common.c:69 (discriminator 1))
+ kasan_save_free_info (mm/kasan/generic.c:579 (discriminator 1))
+ __kasan_slab_free (mm/kasan/common.c:271)
+ kmem_cache_free (mm/slub.c:4643 (discriminator 3) mm/slub.c:4745 (discriminator 3))
+ unix_stream_read_generic (net/unix/af_unix.c:3010)
+ unix_stream_recvmsg (net/unix/af_unix.c:3048)
+ sock_recvmsg (net/socket.c:1063 (discriminator 20) net/socket.c:1085 (discriminator 20))
+ __sys_recvfrom (net/socket.c:2278)
+ __x64_sys_recvfrom (net/socket.c:2291 (discriminator 1) net/socket.c:2287 (discriminator 1) net/socket.c:2287 (discriminator 1))
+ do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1))
+ entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
+
+The buggy address belongs to the object at ffff888106ef28c0
+ which belongs to the cache skbuff_head_cache of size 224
+The buggy address is located 68 bytes inside of
+ freed 224-byte region [ffff888106ef28c0, ffff888106ef29a0)
+
+The buggy address belongs to the physical page:
+page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff888106ef3cc0 pfn:0x106ef2
+head: order:1 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
+flags: 0x200000000000040(head|node=0|zone=2)
+page_type: f5(slab)
+raw: 0200000000000040 ffff8881001d28c0 ffffea000422fe00 0000000000000004
+raw: ffff888106ef3cc0 0000000080190010 00000000f5000000 0000000000000000
+head: 0200000000000040 ffff8881001d28c0 ffffea000422fe00 0000000000000004
+head: ffff888106ef3cc0 0000000080190010 00000000f5000000 0000000000000000
+head: 0200000000000001 ffffea00041bbc81 00000000ffffffff 00000000ffffffff
+head: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
+page dumped because: kasan: bad access detected
+
+Memory state around the buggy address:
+ ffff888106ef2800: 00 00 00 00 00 00 00 00 00 00 00 00 fc fc fc fc
+ ffff888106ef2880: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb
+>ffff888106ef2900: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+                   ^
+ ffff888106ef2980: fb fb fb fb fc fc fc fc fc fc fc fc fc fc fc fc
+ ffff888106ef2a00: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+
+Fixes: 314001f0bf92 ("af_unix: Add OOB support")
+Reported-by: Jann Horn <jannh@google.com>
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Jann Horn <jannh@google.com>
+Link: https://patch.msgid.link/20250619041457.1132791-2-kuni1840@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/unix/af_unix.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index 9ef6011a055b1..01de31a0f22fe 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -2612,11 +2612,11 @@ struct unix_stream_read_state {
+ #if IS_ENABLED(CONFIG_AF_UNIX_OOB)
+ static int unix_stream_recv_urg(struct unix_stream_read_state *state)
+ {
++      struct sk_buff *oob_skb, *read_skb = NULL;
+       struct socket *sock = state->socket;
+       struct sock *sk = sock->sk;
+       struct unix_sock *u = unix_sk(sk);
+       int chunk = 1;
+-      struct sk_buff *oob_skb;
+       mutex_lock(&u->iolock);
+       unix_state_lock(sk);
+@@ -2631,9 +2631,16 @@ static int unix_stream_recv_urg(struct unix_stream_read_state *state)
+       oob_skb = u->oob_skb;
+-      if (!(state->flags & MSG_PEEK))
++      if (!(state->flags & MSG_PEEK)) {
+               WRITE_ONCE(u->oob_skb, NULL);
++              if (oob_skb->prev != (struct sk_buff *)&sk->sk_receive_queue &&
++                  !unix_skb_len(oob_skb->prev)) {
++                      read_skb = oob_skb->prev;
++                      __skb_unlink(read_skb, &sk->sk_receive_queue);
++              }
++      }
++
+       spin_unlock(&sk->sk_receive_queue.lock);
+       unix_state_unlock(sk);
+@@ -2644,6 +2651,8 @@ static int unix_stream_recv_urg(struct unix_stream_read_state *state)
+       mutex_unlock(&u->iolock);
++      consume_skb(read_skb);
++
+       if (chunk < 0)
+               return -EFAULT;
+-- 
+2.39.5
+
diff --git a/queue-6.1/alsa-hda-add-new-pci-id-for-amd-gpu-display-hd-audio.patch b/queue-6.1/alsa-hda-add-new-pci-id-for-amd-gpu-display-hd-audio.patch
new file mode 100644 (file)
index 0000000..090dd69
--- /dev/null
@@ -0,0 +1,37 @@
+From 8cbe0c5c12b4b2e0ab8d0170a1d476249c21cd7f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 May 2025 11:08:13 +0530
+Subject: ALSA: hda: Add new pci id for AMD GPU display HD audio controller
+
+From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+
+[ Upstream commit ab72bfce7647522e01a181e3600c3d14ff5c143e ]
+
+Add new pci id for AMD GPU display HD audio controller(device id- 0xab40).
+
+Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Link: https://patch.msgid.link/20250529053838.2350071-1-Vijendar.Mukunda@amd.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/hda_intel.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index d1639d8c22985..1bb315c175f67 100644
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -2793,6 +2793,9 @@ static const struct pci_device_id azx_ids[] = {
+       { PCI_DEVICE(0x1002, 0xab38),
+         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
+         AZX_DCAPS_PM_RUNTIME },
++      { PCI_VDEVICE(ATI, 0xab40),
++        .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
++        AZX_DCAPS_PM_RUNTIME },
+       /* GLENFLY */
+       { PCI_DEVICE(PCI_VENDOR_ID_GLENFLY, PCI_ANY_ID),
+         .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
+-- 
+2.39.5
+
diff --git a/queue-6.1/alsa-hda-ignore-unsol-events-for-cards-being-shut-do.patch b/queue-6.1/alsa-hda-ignore-unsol-events-for-cards-being-shut-do.patch
new file mode 100644 (file)
index 0000000..f33f478
--- /dev/null
@@ -0,0 +1,48 @@
+From ca2434bb757cc1cc11e826d751a1927ddeb07950 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 May 2025 16:13:09 +0200
+Subject: ALSA: hda: Ignore unsol events for cards being shut down
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cezary Rojewski <cezary.rojewski@intel.com>
+
+[ Upstream commit 3f100f524e75586537e337b34d18c8d604b398e7 ]
+
+For the classic snd_hda_intel driver, codec->card and bus->card point to
+the exact same thing. When snd_card_diconnect() fires, bus->shutdown is
+set thanks to azx_dev_disconnect(). card->shutdown is already set when
+that happens but both provide basically the same functionality.
+
+For the DSP snd_soc_avs driver where multiple codecs are located on
+multiple cards, bus->shutdown 'shortcut' is not sufficient. One codec
+card may be unregistered while other codecs are still operational.
+Proper check in form of card->shutdown must be used to verify whether
+the codec's card is being shut down.
+
+Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
+Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
+Link: https://patch.msgid.link/20250530141309.2943404-1-cezary.rojewski@intel.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/hda_bind.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c
+index 890c2f7c33fc2..4c7355a0814d1 100644
+--- a/sound/pci/hda/hda_bind.c
++++ b/sound/pci/hda/hda_bind.c
+@@ -45,7 +45,7 @@ static void hda_codec_unsol_event(struct hdac_device *dev, unsigned int ev)
+       struct hda_codec *codec = container_of(dev, struct hda_codec, core);
+       /* ignore unsol events during shutdown */
+-      if (codec->bus->shutdown)
++      if (codec->card->shutdown || codec->bus->shutdown)
+               return;
+       /* ignore unsol events during system suspend/resume */
+-- 
+2.39.5
+
diff --git a/queue-6.1/alsa-usb-audio-add-a-quirk-for-lenovo-thinkpad-thund.patch b/queue-6.1/alsa-usb-audio-add-a-quirk-for-lenovo-thinkpad-thund.patch
new file mode 100644 (file)
index 0000000..a87174a
--- /dev/null
@@ -0,0 +1,39 @@
+From e303c7a4635f58f39abd546b4d16d0f08207d57d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 May 2025 12:26:56 -0500
+Subject: ALSA: usb-audio: Add a quirk for Lenovo Thinkpad Thunderbolt 3 dock
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit 4919353c7789b8047e06a9b2b943f775a8f72883 ]
+
+The audio controller in the Lenovo Thinkpad Thunderbolt 3 dock doesn't
+support reading the sampling rate.
+
+Add a quirk for it.
+
+Suggested-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Link: https://patch.msgid.link/20250527172657.1972565-1-superm1@kernel.org
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/quirks.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index b2a612c5b299a..ac43bdf6e9ca6 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -2180,6 +2180,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
+                  QUIRK_FLAG_DISABLE_AUTOSUSPEND),
+       DEVICE_FLG(0x17aa, 0x104d, /* Lenovo ThinkStation P620 Internal Speaker + Front Headset */
+                  QUIRK_FLAG_DISABLE_AUTOSUSPEND),
++      DEVICE_FLG(0x17ef, 0x3083, /* Lenovo TBT3 dock */
++                 QUIRK_FLAG_GET_SAMPLE_RATE),
+       DEVICE_FLG(0x1852, 0x5062, /* Luxman D-08u */
+                  QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY),
+       DEVICE_FLG(0x1852, 0x5065, /* Luxman DA-06 */
+-- 
+2.39.5
+
diff --git a/queue-6.1/amd-amdkfd-fix-a-kfd_process-ref-leak.patch b/queue-6.1/amd-amdkfd-fix-a-kfd_process-ref-leak.patch
new file mode 100644 (file)
index 0000000..0afd4f4
--- /dev/null
@@ -0,0 +1,34 @@
+From 0a503068666ea91a5b0fee5037e9c212780788b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 May 2025 18:06:28 +0800
+Subject: amd/amdkfd: fix a kfd_process ref leak
+
+From: Yifan Zhang <yifan1.zhang@amd.com>
+
+[ Upstream commit 90237b16ec1d7afa16e2173cc9a664377214cdd9 ]
+
+This patch is to fix a kfd_prcess ref leak.
+
+Signed-off-by: Yifan Zhang <yifan1.zhang@amd.com>
+Reviewed-by: Philip Yang <Philip.Yang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_events.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+index 2880ed96ac2e3..80d567ba94846 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+@@ -1340,6 +1340,7 @@ void kfd_signal_poison_consumed_event(struct kfd_dev *dev, u32 pasid)
+       user_gpu_id = kfd_process_get_user_gpu_id(p, dev->id);
+       if (unlikely(user_gpu_id == -EINVAL)) {
+               WARN_ONCE(1, "Could not get user_gpu_id from dev->id:%x\n", dev->id);
++              kfd_unref_process(p);
+               return;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.1/asoc-codec-wcd9335-convert-to-gpio-descriptors.patch b/queue-6.1/asoc-codec-wcd9335-convert-to-gpio-descriptors.patch
new file mode 100644 (file)
index 0000000..afe0ea5
--- /dev/null
@@ -0,0 +1,85 @@
+From 4a30d35cebf8ff3f75c9733c4a8cca8d4a68d180 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 19:51:29 +0800
+Subject: ASoC: codec: wcd9335: Convert to GPIO descriptors
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit d5099bc1b56417733f4cccf10c61ee74dadd5562 ]
+
+of_gpio.h is deprecated, update the driver to use GPIO descriptors.
+- Use dev_gpiod_get to get GPIO descriptor.
+- Use gpiod_set_value to configure output value.
+
+With legacy of_gpio API, the driver set gpio value 0 to assert reset,
+and 1 to deassert reset. And the reset-gpios use GPIO_ACTIVE_LOW flag in
+DTS, so set GPIOD_OUT_LOW when get GPIO descriptors, and set value 1 means
+output low, set value 0 means output high with gpiod API.
+
+The in-tree DTS files have the right polarity set up already so we can
+expect this to "just work"
+
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Link: https://patch.msgid.link/20250324-wcd-gpiod-v2-3-773f67ce3b56@nxp.com
+Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 9079db287fc3 ("ASoC: codecs: wcd9335: Fix missing free of regulator supplies")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/wcd9335.c | 15 +++++++--------
+ 1 file changed, 7 insertions(+), 8 deletions(-)
+
+diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c
+index 23f3c0253d9eb..7817dff99b6c6 100644
+--- a/sound/soc/codecs/wcd9335.c
++++ b/sound/soc/codecs/wcd9335.c
+@@ -16,7 +16,7 @@
+ #include <sound/soc.h>
+ #include <sound/pcm_params.h>
+ #include <sound/soc-dapm.h>
+-#include <linux/of_gpio.h>
++#include <linux/gpio/consumer.h>
+ #include <linux/of.h>
+ #include <linux/of_irq.h>
+ #include <sound/tlv.h>
+@@ -329,7 +329,7 @@ struct wcd9335_codec {
+       int comp_enabled[COMPANDER_MAX];
+       int intr1;
+-      int reset_gpio;
++      struct gpio_desc *reset_gpio;
+       struct regulator_bulk_data supplies[WCD9335_MAX_SUPPLY];
+       unsigned int rx_port_value[WCD9335_RX_MAX];
+@@ -5032,12 +5032,11 @@ static const struct regmap_irq_chip wcd9335_regmap_irq1_chip = {
+ static int wcd9335_parse_dt(struct wcd9335_codec *wcd)
+ {
+       struct device *dev = wcd->dev;
+-      struct device_node *np = dev->of_node;
+       int ret;
+-      wcd->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0);
+-      if (wcd->reset_gpio < 0)
+-              return dev_err_probe(dev, wcd->reset_gpio, "Reset GPIO missing from DT\n");
++      wcd->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
++      if (IS_ERR(wcd->reset_gpio))
++              return dev_err_probe(dev, PTR_ERR(wcd->reset_gpio), "Reset GPIO missing from DT\n");
+       wcd->mclk = devm_clk_get(dev, "mclk");
+       if (IS_ERR(wcd->mclk))
+@@ -5080,9 +5079,9 @@ static int wcd9335_power_on_reset(struct wcd9335_codec *wcd)
+        */
+       usleep_range(600, 650);
+-      gpio_direction_output(wcd->reset_gpio, 0);
++      gpiod_set_value(wcd->reset_gpio, 1);
+       msleep(20);
+-      gpio_set_value(wcd->reset_gpio, 1);
++      gpiod_set_value(wcd->reset_gpio, 0);
+       msleep(20);
+       return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.1/asoc-codecs-wcd9335-fix-missing-free-of-regulator-su.patch b/queue-6.1/asoc-codecs-wcd9335-fix-missing-free-of-regulator-su.patch
new file mode 100644 (file)
index 0000000..59a35c6
--- /dev/null
@@ -0,0 +1,88 @@
+From 4107c0989c5328da6147955e7dccb4d7b63ad1c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 May 2025 11:47:01 +0200
+Subject: ASoC: codecs: wcd9335: Fix missing free of regulator supplies
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 9079db287fc3e38e040b0edeb0a25770bb679c8e ]
+
+Driver gets and enables all regulator supplies in probe path
+(wcd9335_parse_dt() and wcd9335_power_on_reset()), but does not cleanup
+in final error paths and in unbind (missing remove() callback).  This
+leads to leaked memory and unbalanced regulator enable count during
+probe errors or unbind.
+
+Fix this by converting entire code into devm_regulator_bulk_get_enable()
+which also greatly simplifies the code.
+
+Fixes: 20aedafdf492 ("ASoC: wcd9335: add support to wcd9335 codec")
+Cc: stable@vger.kernel.org
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://patch.msgid.link/20250526-b4-b4-asoc-wcd9395-vdd-px-fixes-v1-1-0b8a2993b7d3@linaro.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/wcd9335.c | 25 +++++++------------------
+ 1 file changed, 7 insertions(+), 18 deletions(-)
+
+diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c
+index 7817dff99b6c6..99de81c489681 100644
+--- a/sound/soc/codecs/wcd9335.c
++++ b/sound/soc/codecs/wcd9335.c
+@@ -330,7 +330,6 @@ struct wcd9335_codec {
+       int intr1;
+       struct gpio_desc *reset_gpio;
+-      struct regulator_bulk_data supplies[WCD9335_MAX_SUPPLY];
+       unsigned int rx_port_value[WCD9335_RX_MAX];
+       unsigned int tx_port_value[WCD9335_TX_MAX];
+@@ -357,6 +356,10 @@ struct wcd9335_irq {
+       char *name;
+ };
++static const char * const wcd9335_supplies[] = {
++      "vdd-buck", "vdd-buck-sido", "vdd-tx", "vdd-rx", "vdd-io",
++};
++
+ static const struct wcd9335_slim_ch wcd9335_tx_chs[WCD9335_TX_MAX] = {
+       WCD9335_SLIM_TX_CH(0),
+       WCD9335_SLIM_TX_CH(1),
+@@ -5046,30 +5049,16 @@ static int wcd9335_parse_dt(struct wcd9335_codec *wcd)
+       if (IS_ERR(wcd->native_clk))
+               return dev_err_probe(dev, PTR_ERR(wcd->native_clk), "slimbus clock not found\n");
+-      wcd->supplies[0].supply = "vdd-buck";
+-      wcd->supplies[1].supply = "vdd-buck-sido";
+-      wcd->supplies[2].supply = "vdd-tx";
+-      wcd->supplies[3].supply = "vdd-rx";
+-      wcd->supplies[4].supply = "vdd-io";
+-
+-      ret = regulator_bulk_get(dev, WCD9335_MAX_SUPPLY, wcd->supplies);
++      ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(wcd9335_supplies),
++                                           wcd9335_supplies);
+       if (ret)
+-              return dev_err_probe(dev, ret, "Failed to get supplies\n");
++              return dev_err_probe(dev, ret, "Failed to get and enable supplies\n");
+       return 0;
+ }
+ static int wcd9335_power_on_reset(struct wcd9335_codec *wcd)
+ {
+-      struct device *dev = wcd->dev;
+-      int ret;
+-
+-      ret = regulator_bulk_enable(WCD9335_MAX_SUPPLY, wcd->supplies);
+-      if (ret) {
+-              dev_err(dev, "Failed to get supplies: err = %d\n", ret);
+-              return ret;
+-      }
+-
+       /*
+        * For WCD9335, it takes about 600us for the Vout_A and
+        * Vout_D to be ready after BUCK_SIDO is powered up.
+-- 
+2.39.5
+
diff --git a/queue-6.1/asoc-codecs-wcd9335-handle-nicer-probe-deferral-and-.patch b/queue-6.1/asoc-codecs-wcd9335-handle-nicer-probe-deferral-and-.patch
new file mode 100644 (file)
index 0000000..8e92d50
--- /dev/null
@@ -0,0 +1,85 @@
+From 26adeaccaf41165b8138fd17076e4bc831811684 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Jun 2024 18:15:17 +0200
+Subject: ASoC: codecs: wcd9335: Handle nicer probe deferral and simplify with
+ dev_err_probe()
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 4a03b5dbad466c902d522f3405daa4e5d80578c5 ]
+
+wcd9335_parse_dt() function is called only from probe(), so printing
+errors on resource acquisition is discouraged, because it can pollute
+dmesg.  Use dev_err_probe() to fix this and also make the code a bit
+simpler.
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://msgid.link/r/20240612-asoc-wcd9xxx-wide-cleanups-v1-4-0d15885b2a06@linaro.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 9079db287fc3 ("ASoC: codecs: wcd9335: Fix missing free of regulator supplies")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/wcd9335.c | 28 +++++++++-------------------
+ 1 file changed, 9 insertions(+), 19 deletions(-)
+
+diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c
+index d2548fdf9ae56..23f3c0253d9eb 100644
+--- a/sound/soc/codecs/wcd9335.c
++++ b/sound/soc/codecs/wcd9335.c
+@@ -5036,22 +5036,16 @@ static int wcd9335_parse_dt(struct wcd9335_codec *wcd)
+       int ret;
+       wcd->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0);
+-      if (wcd->reset_gpio < 0) {
+-              dev_err(dev, "Reset GPIO missing from DT\n");
+-              return wcd->reset_gpio;
+-      }
++      if (wcd->reset_gpio < 0)
++              return dev_err_probe(dev, wcd->reset_gpio, "Reset GPIO missing from DT\n");
+       wcd->mclk = devm_clk_get(dev, "mclk");
+-      if (IS_ERR(wcd->mclk)) {
+-              dev_err(dev, "mclk not found\n");
+-              return PTR_ERR(wcd->mclk);
+-      }
++      if (IS_ERR(wcd->mclk))
++              return dev_err_probe(dev, PTR_ERR(wcd->mclk), "mclk not found\n");
+       wcd->native_clk = devm_clk_get(dev, "slimbus");
+-      if (IS_ERR(wcd->native_clk)) {
+-              dev_err(dev, "slimbus clock not found\n");
+-              return PTR_ERR(wcd->native_clk);
+-      }
++      if (IS_ERR(wcd->native_clk))
++              return dev_err_probe(dev, PTR_ERR(wcd->native_clk), "slimbus clock not found\n");
+       wcd->supplies[0].supply = "vdd-buck";
+       wcd->supplies[1].supply = "vdd-buck-sido";
+@@ -5060,10 +5054,8 @@ static int wcd9335_parse_dt(struct wcd9335_codec *wcd)
+       wcd->supplies[4].supply = "vdd-io";
+       ret = regulator_bulk_get(dev, WCD9335_MAX_SUPPLY, wcd->supplies);
+-      if (ret) {
+-              dev_err(dev, "Failed to get supplies: err = %d\n", ret);
+-              return ret;
+-      }
++      if (ret)
++              return dev_err_probe(dev, ret, "Failed to get supplies\n");
+       return 0;
+ }
+@@ -5166,10 +5158,8 @@ static int wcd9335_slim_probe(struct slim_device *slim)
+       wcd->dev = dev;
+       ret = wcd9335_parse_dt(wcd);
+-      if (ret) {
+-              dev_err(dev, "Error parsing DT: %d\n", ret);
++      if (ret)
+               return ret;
+-      }
+       ret = wcd9335_power_on_reset(wcd);
+       if (ret)
+-- 
+2.39.5
+
diff --git a/queue-6.1/bcache-fix-null-pointer-in-cache_set_flush.patch b/queue-6.1/bcache-fix-null-pointer-in-cache_set_flush.patch
new file mode 100644 (file)
index 0000000..2ebc749
--- /dev/null
@@ -0,0 +1,151 @@
+From 61550af1fd70a1de3e5cb10132462532e4f33fce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 May 2025 13:15:59 +0800
+Subject: bcache: fix NULL pointer in cache_set_flush()
+
+From: Linggang Zeng <linggang.zeng@easystack.cn>
+
+[ Upstream commit 1e46ed947ec658f89f1a910d880cd05e42d3763e ]
+
+1. LINE#1794 - LINE#1887 is some codes about function of
+   bch_cache_set_alloc().
+2. LINE#2078 - LINE#2142 is some codes about function of
+   register_cache_set().
+3. register_cache_set() will call bch_cache_set_alloc() in LINE#2098.
+
+ 1794 struct cache_set *bch_cache_set_alloc(struct cache_sb *sb)
+ 1795 {
+ ...
+ 1860         if (!(c->devices = kcalloc(c->nr_uuids, sizeof(void *), GFP_KERNEL)) ||
+ 1861             mempool_init_slab_pool(&c->search, 32, bch_search_cache) ||
+ 1862             mempool_init_kmalloc_pool(&c->bio_meta, 2,
+ 1863                                 sizeof(struct bbio) + sizeof(struct bio_vec) *
+ 1864                                 bucket_pages(c)) ||
+ 1865             mempool_init_kmalloc_pool(&c->fill_iter, 1, iter_size) ||
+ 1866             bioset_init(&c->bio_split, 4, offsetof(struct bbio, bio),
+ 1867                         BIOSET_NEED_BVECS|BIOSET_NEED_RESCUER) ||
+ 1868             !(c->uuids = alloc_bucket_pages(GFP_KERNEL, c)) ||
+ 1869             !(c->moving_gc_wq = alloc_workqueue("bcache_gc",
+ 1870                                                 WQ_MEM_RECLAIM, 0)) ||
+ 1871             bch_journal_alloc(c) ||
+ 1872             bch_btree_cache_alloc(c) ||
+ 1873             bch_open_buckets_alloc(c) ||
+ 1874             bch_bset_sort_state_init(&c->sort, ilog2(c->btree_pages)))
+ 1875                 goto err;
+                      ^^^^^^^^
+ 1876
+ ...
+ 1883         return c;
+ 1884 err:
+ 1885         bch_cache_set_unregister(c);
+              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ 1886         return NULL;
+ 1887 }
+ ...
+ 2078 static const char *register_cache_set(struct cache *ca)
+ 2079 {
+ ...
+ 2098         c = bch_cache_set_alloc(&ca->sb);
+ 2099         if (!c)
+ 2100                 return err;
+                      ^^^^^^^^^^
+ ...
+ 2128         ca->set = c;
+ 2129         ca->set->cache[ca->sb.nr_this_dev] = ca;
+              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ ...
+ 2138         return NULL;
+ 2139 err:
+ 2140         bch_cache_set_unregister(c);
+ 2141         return err;
+ 2142 }
+
+(1) If LINE#1860 - LINE#1874 is true, then do 'goto err'(LINE#1875) and
+    call bch_cache_set_unregister()(LINE#1885).
+(2) As (1) return NULL(LINE#1886), LINE#2098 - LINE#2100 would return.
+(3) As (2) has returned, LINE#2128 - LINE#2129 would do *not* give the
+    value to c->cache[], it means that c->cache[] is NULL.
+
+LINE#1624 - LINE#1665 is some codes about function of cache_set_flush().
+As (1), in LINE#1885 call
+bch_cache_set_unregister()
+---> bch_cache_set_stop()
+     ---> closure_queue()
+          -.-> cache_set_flush() (as below LINE#1624)
+
+ 1624 static void cache_set_flush(struct closure *cl)
+ 1625 {
+ ...
+ 1654         for_each_cache(ca, c, i)
+ 1655                 if (ca->alloc_thread)
+                          ^^
+ 1656                         kthread_stop(ca->alloc_thread);
+ ...
+ 1665 }
+
+(4) In LINE#1655 ca is NULL(see (3)) in cache_set_flush() then the
+    kernel crash occurred as below:
+[  846.712887] bcache: register_cache() error drbd6: cannot allocate memory
+[  846.713242] bcache: register_bcache() error : failed to register device
+[  846.713336] bcache: cache_set_free() Cache set 2f84bdc1-498a-4f2f-98a7-01946bf54287 unregistered
+[  846.713768] BUG: unable to handle kernel NULL pointer dereference at 00000000000009f8
+[  846.714790] PGD 0 P4D 0
+[  846.715129] Oops: 0000 [#1] SMP PTI
+[  846.715472] CPU: 19 PID: 5057 Comm: kworker/19:16 Kdump: loaded Tainted: G           OE    --------- -  - 4.18.0-147.5.1.el8_1.5es.3.x86_64 #1
+[  846.716082] Hardware name: ESPAN GI-25212/X11DPL-i, BIOS 2.1 06/15/2018
+[  846.716451] Workqueue: events cache_set_flush [bcache]
+[  846.716808] RIP: 0010:cache_set_flush+0xc9/0x1b0 [bcache]
+[  846.717155] Code: 00 4c 89 a5 b0 03 00 00 48 8b 85 68 f6 ff ff a8 08 0f 84 88 00 00 00 31 db 66 83 bd 3c f7 ff ff 00 48 8b 85 48 ff ff ff 74 28 <48> 8b b8 f8 09 00 00 48 85 ff 74 05 e8 b6 58 a2 e1 0f b7 95 3c f7
+[  846.718026] RSP: 0018:ffffb56dcf85fe70 EFLAGS: 00010202
+[  846.718372] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
+[  846.718725] RDX: 0000000000000001 RSI: 0000000040000001 RDI: 0000000000000000
+[  846.719076] RBP: ffffa0ccc0f20df8 R08: ffffa0ce1fedb118 R09: 000073746e657665
+[  846.719428] R10: 8080808080808080 R11: 0000000000000000 R12: ffffa0ce1fee8700
+[  846.719779] R13: ffffa0ccc0f211a8 R14: ffffa0cd1b902840 R15: ffffa0ccc0f20e00
+[  846.720132] FS:  0000000000000000(0000) GS:ffffa0ce1fec0000(0000) knlGS:0000000000000000
+[  846.720726] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[  846.721073] CR2: 00000000000009f8 CR3: 00000008ba00a005 CR4: 00000000007606e0
+[  846.721426] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[  846.721778] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+[  846.722131] PKRU: 55555554
+[  846.722467] Call Trace:
+[  846.722814]  process_one_work+0x1a7/0x3b0
+[  846.723157]  worker_thread+0x30/0x390
+[  846.723501]  ? create_worker+0x1a0/0x1a0
+[  846.723844]  kthread+0x112/0x130
+[  846.724184]  ? kthread_flush_work_fn+0x10/0x10
+[  846.724535]  ret_from_fork+0x35/0x40
+
+Now, check whether that ca is NULL in LINE#1655 to fix the issue.
+
+Signed-off-by: Linggang Zeng <linggang.zeng@easystack.cn>
+Signed-off-by: Mingzhe Zou <mingzhe.zou@easystack.cn>
+Signed-off-by: Coly Li <colyli@kernel.org>
+Link: https://lore.kernel.org/r/20250527051601.74407-2-colyli@kernel.org
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/bcache/super.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
+index 1ddae5c972398..2c7b3c8673de2 100644
+--- a/drivers/md/bcache/super.c
++++ b/drivers/md/bcache/super.c
+@@ -1741,7 +1741,12 @@ static void cache_set_flush(struct closure *cl)
+                       mutex_unlock(&b->write_lock);
+               }
+-      if (ca->alloc_thread)
++      /*
++       * If the register_cache_set() call to bch_cache_set_alloc() failed,
++       * ca has not been assigned a value and return error.
++       * So we need check ca is not NULL during bch_cache_set_unregister().
++       */
++      if (ca && ca->alloc_thread)
+               kthread_stop(ca->alloc_thread);
+       if (c->journal.cur) {
+-- 
+2.39.5
+
diff --git a/queue-6.1/btrfs-handle-csum-tree-error-with-rescue-ibadroots-c.patch b/queue-6.1/btrfs-handle-csum-tree-error-with-rescue-ibadroots-c.patch
new file mode 100644 (file)
index 0000000..d8fcbcd
--- /dev/null
@@ -0,0 +1,117 @@
+From be3be775c11712090f6b032dfe43e2d64347e4f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 7 Jun 2025 09:18:43 +0930
+Subject: btrfs: handle csum tree error with rescue=ibadroots correctly
+
+From: Qu Wenruo <wqu@suse.com>
+
+[ Upstream commit 547e836661554dcfa15c212a3821664e85b4191a ]
+
+[BUG]
+There is syzbot based reproducer that can crash the kernel, with the
+following call trace: (With some debug output added)
+
+ DEBUG: rescue=ibadroots parsed
+ BTRFS: device fsid 14d642db-7b15-43e4-81e6-4b8fac6a25f8 devid 1 transid 8 /dev/loop0 (7:0) scanned by repro (1010)
+ BTRFS info (device loop0): first mount of filesystem 14d642db-7b15-43e4-81e6-4b8fac6a25f8
+ BTRFS info (device loop0): using blake2b (blake2b-256-generic) checksum algorithm
+ BTRFS info (device loop0): using free-space-tree
+ BTRFS warning (device loop0): checksum verify failed on logical 5312512 mirror 1 wanted 0xb043382657aede36608fd3386d6b001692ff406164733d94e2d9a180412c6003 found 0x810ceb2bacb7f0f9eb2bf3b2b15c02af867cb35ad450898169f3b1f0bd818651 level 0
+ DEBUG: read tree root path failed for tree csum, ret=-5
+ BTRFS warning (device loop0): checksum verify failed on logical 5328896 mirror 1 wanted 0x51be4e8b303da58e6340226815b70e3a93592dac3f30dd510c7517454de8567a found 0x51be4e8b303da58e634022a315b70e3a93592dac3f30dd510c7517454de8567a level 0
+ BTRFS warning (device loop0): checksum verify failed on logical 5292032 mirror 1 wanted 0x1924ccd683be9efc2fa98582ef58760e3848e9043db8649ee382681e220cdee4 found 0x0cb6184f6e8799d9f8cb335dccd1d1832da1071d12290dab3b85b587ecacca6e level 0
+ process 'repro' launched './file2' with NULL argv: empty string added
+ DEBUG: no csum root, idatacsums=0 ibadroots=134217728
+ Oops: general protection fault, probably for non-canonical address 0xdffffc0000000041: 0000 [#1] SMP KASAN NOPTI
+ KASAN: null-ptr-deref in range [0x0000000000000208-0x000000000000020f]
+ CPU: 5 UID: 0 PID: 1010 Comm: repro Tainted: G           OE       6.15.0-custom+ #249 PREEMPT(full)
+ Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS unknown 02/02/2022
+ RIP: 0010:btrfs_lookup_csum+0x93/0x3d0 [btrfs]
+ Call Trace:
+  <TASK>
+  btrfs_lookup_bio_sums+0x47a/0xdf0 [btrfs]
+  btrfs_submit_bbio+0x43e/0x1a80 [btrfs]
+  submit_one_bio+0xde/0x160 [btrfs]
+  btrfs_readahead+0x498/0x6a0 [btrfs]
+  read_pages+0x1c3/0xb20
+  page_cache_ra_order+0x4b5/0xc20
+  filemap_get_pages+0x2d3/0x19e0
+  filemap_read+0x314/0xde0
+  __kernel_read+0x35b/0x900
+  bprm_execve+0x62e/0x1140
+  do_execveat_common.isra.0+0x3fc/0x520
+  __x64_sys_execveat+0xdc/0x130
+  do_syscall_64+0x54/0x1d0
+  entry_SYSCALL_64_after_hwframe+0x76/0x7e
+ ---[ end trace 0000000000000000 ]---
+
+[CAUSE]
+Firstly the fs has a corrupted csum tree root, thus to mount the fs we
+have to go "ro,rescue=ibadroots" mount option.
+
+Normally with that mount option, a bad csum tree root should set
+BTRFS_FS_STATE_NO_DATA_CSUMS flag, so that any future data read will
+ignore csum search.
+
+But in this particular case, we have the following call trace that
+caused NULL csum root, but not setting BTRFS_FS_STATE_NO_DATA_CSUMS:
+
+load_global_roots_objectid():
+
+               ret = btrfs_search_slot();
+               /* Succeeded */
+               btrfs_item_key_to_cpu()
+               found = true;
+               /* We found the root item for csum tree. */
+               root = read_tree_root_path();
+               if (IS_ERR(root)) {
+                       if (!btrfs_test_opt(fs_info, IGNOREBADROOTS))
+                       /*
+                        * Since we have rescue=ibadroots mount option,
+                        * @ret is still 0.
+                        */
+                       break;
+       if (!found || ret) {
+               /* @found is true, @ret is 0, error handling for csum
+                * tree is skipped.
+                */
+       }
+
+This means we completely skipped to set BTRFS_FS_STATE_NO_DATA_CSUMS if
+the csum tree is corrupted, which results unexpected later csum lookup.
+
+[FIX]
+If read_tree_root_path() failed, always populate @ret to the error
+number.
+
+As at the end of the function, we need @ret to determine if we need to
+do the extra error handling for csum tree.
+
+Fixes: abed4aaae4f7 ("btrfs: track the csum, extent, and free space trees in a rb tree")
+Reported-by: Zhiyu Zhang <zhiyuzhang999@gmail.com>
+Reported-by: Longxing Li <coregee2000@gmail.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/disk-io.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
+index 8c0da0025bc71..76a261cbf39d6 100644
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -2481,8 +2481,7 @@ static int load_global_roots_objectid(struct btrfs_root *tree_root,
+               found = true;
+               root = read_tree_root_path(tree_root, path, &key);
+               if (IS_ERR(root)) {
+-                      if (!btrfs_test_opt(fs_info, IGNOREBADROOTS))
+-                              ret = PTR_ERR(root);
++                      ret = PTR_ERR(root);
+                       break;
+               }
+               set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state);
+-- 
+2.39.5
+
diff --git a/queue-6.1/ceph-fix-possible-integer-overflow-in-ceph_zero_obje.patch b/queue-6.1/ceph-fix-possible-integer-overflow-in-ceph_zero_obje.patch
new file mode 100644 (file)
index 0000000..1c97015
--- /dev/null
@@ -0,0 +1,40 @@
+From bc79a6e1f347f76c980c4866af630d9cc830a92c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Apr 2025 12:32:04 +0300
+Subject: ceph: fix possible integer overflow in ceph_zero_objects()
+
+From: Dmitry Kandybka <d.kandybka@gmail.com>
+
+[ Upstream commit 0abd87942e0c93964e93224836944712feba1d91 ]
+
+In 'ceph_zero_objects', promote 'object_size' to 'u64' to avoid possible
+integer overflow.
+
+Compile tested only.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Signed-off-by: Dmitry Kandybka <d.kandybka@gmail.com>
+Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ceph/file.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/ceph/file.c b/fs/ceph/file.c
+index 882eccfd67e84..3336647e64df3 100644
+--- a/fs/ceph/file.c
++++ b/fs/ceph/file.c
+@@ -2043,7 +2043,7 @@ static int ceph_zero_objects(struct inode *inode, loff_t offset, loff_t length)
+       s32 stripe_unit = ci->i_layout.stripe_unit;
+       s32 stripe_count = ci->i_layout.stripe_count;
+       s32 object_size = ci->i_layout.object_size;
+-      u64 object_set_size = object_size * stripe_count;
++      u64 object_set_size = (u64) object_size * stripe_count;
+       u64 nearly, t;
+       /* round offset up to next period boundary */
+-- 
+2.39.5
+
diff --git a/queue-6.1/cifs-correctly-set-smb1-sessionkey-field-in-session-.patch b/queue-6.1/cifs-correctly-set-smb1-sessionkey-field-in-session-.patch
new file mode 100644 (file)
index 0000000..de45739
--- /dev/null
@@ -0,0 +1,106 @@
+From 6894f13dccde7b51e28c19386d575bd7f73b6dc1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Nov 2024 17:58:31 +0100
+Subject: cifs: Correctly set SMB1 SessionKey field in Session Setup Request
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit 89381c72d52094988e11d23ef24a00066a0fa458 ]
+
+[MS-CIFS] specification in section 2.2.4.53.1 where is described
+SMB_COM_SESSION_SETUP_ANDX Request, for SessionKey field says:
+
+    The client MUST set this field to be equal to the SessionKey field in
+    the SMB_COM_NEGOTIATE Response for this SMB connection.
+
+Linux SMB client currently set this field to zero. This is working fine
+against Windows NT SMB servers thanks to [MS-CIFS] product behavior <94>:
+
+    Windows NT Server ignores the client's SessionKey.
+
+For compatibility with [MS-CIFS], set this SessionKey field in Session
+Setup Request to value retrieved from Negotiate response.
+
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/cifsglob.h | 1 +
+ fs/smb/client/cifspdu.h  | 6 +++---
+ fs/smb/client/cifssmb.c  | 1 +
+ fs/smb/client/sess.c     | 1 +
+ 4 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
+index 17fce0afb297f..9c5aa646b8cc8 100644
+--- a/fs/smb/client/cifsglob.h
++++ b/fs/smb/client/cifsglob.h
+@@ -675,6 +675,7 @@ struct TCP_Server_Info {
+       char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
+       __u32 sequence_number; /* for signing, protected by srv_mutex */
+       __u32 reconnect_instance; /* incremented on each reconnect */
++      __le32 session_key_id; /* retrieved from negotiate response and send in session setup request */
+       struct session_key session_key;
+       unsigned long lstrp; /* when we got last response from this server */
+       struct cifs_secmech secmech; /* crypto sec mech functs, descriptors */
+diff --git a/fs/smb/client/cifspdu.h b/fs/smb/client/cifspdu.h
+index 9cb4577063344..a682c50d7ace4 100644
+--- a/fs/smb/client/cifspdu.h
++++ b/fs/smb/client/cifspdu.h
+@@ -557,7 +557,7 @@ typedef union smb_com_session_setup_andx {
+               __le16 MaxBufferSize;
+               __le16 MaxMpxCount;
+               __le16 VcNumber;
+-              __u32 SessionKey;
++              __le32 SessionKey;
+               __le16 SecurityBlobLength;
+               __u32 Reserved;
+               __le32 Capabilities;    /* see below */
+@@ -576,7 +576,7 @@ typedef union smb_com_session_setup_andx {
+               __le16 MaxBufferSize;
+               __le16 MaxMpxCount;
+               __le16 VcNumber;
+-              __u32 SessionKey;
++              __le32 SessionKey;
+               __le16 CaseInsensitivePasswordLength; /* ASCII password len */
+               __le16 CaseSensitivePasswordLength; /* Unicode password length*/
+               __u32 Reserved; /* see below */
+@@ -614,7 +614,7 @@ typedef union smb_com_session_setup_andx {
+               __le16 MaxBufferSize;
+               __le16 MaxMpxCount;
+               __le16 VcNumber;
+-              __u32 SessionKey;
++              __le32 SessionKey;
+               __le16 PasswordLength;
+               __u32 Reserved; /* encrypt key len and offset */
+               __le16 ByteCount;
+diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
+index 6077fe1dcc9ce..0c6ade1968947 100644
+--- a/fs/smb/client/cifssmb.c
++++ b/fs/smb/client/cifssmb.c
+@@ -469,6 +469,7 @@ CIFSSMBNegotiate(const unsigned int xid,
+       server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
+       cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
+       server->capabilities = le32_to_cpu(pSMBr->Capabilities);
++      server->session_key_id = pSMBr->SessionKey;
+       server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
+       server->timeAdj *= 60;
+diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c
+index c8f7ae0a20064..883d1cb1fc8b0 100644
+--- a/fs/smb/client/sess.c
++++ b/fs/smb/client/sess.c
+@@ -605,6 +605,7 @@ static __u32 cifs_ssetup_hdr(struct cifs_ses *ses,
+                                       USHRT_MAX));
+       pSMB->req.MaxMpxCount = cpu_to_le16(server->maxReq);
+       pSMB->req.VcNumber = cpu_to_le16(1);
++      pSMB->req.SessionKey = server->session_key_id;
+       /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
+-- 
+2.39.5
+
diff --git a/queue-6.1/cifs-fix-cifs_query_path_info-for-windows-nt-servers.patch b/queue-6.1/cifs-fix-cifs_query_path_info-for-windows-nt-servers.patch
new file mode 100644 (file)
index 0000000..ee85500
--- /dev/null
@@ -0,0 +1,55 @@
+From 09e875bed00dc991cf41d1cb8d9c2995145b2729 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Dec 2024 16:06:22 +0100
+Subject: cifs: Fix cifs_query_path_info() for Windows NT servers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit a3e771afbb3bce91c8296828304903e7348003fe ]
+
+For TRANS2 QUERY_PATH_INFO request when the path does not exist, the
+Windows NT SMB server returns error response STATUS_OBJECT_NAME_NOT_FOUND
+or ERRDOS/ERRbadfile without the SMBFLG_RESPONSE flag set. Similarly it
+returns STATUS_DELETE_PENDING when the file is being deleted. And looks
+like that any error response from TRANS2 QUERY_PATH_INFO does not have
+SMBFLG_RESPONSE flag set.
+
+So relax check in check_smb_hdr() for detecting if the packet is response
+for this special case.
+
+This change fixes stat() operation against Windows NT SMB servers and also
+all operations which depends on -ENOENT result from stat like creat() or
+mkdir().
+
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/misc.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c
+index 3826f71766086..99a0a1fe66187 100644
+--- a/fs/smb/client/misc.c
++++ b/fs/smb/client/misc.c
+@@ -307,6 +307,14 @@ check_smb_hdr(struct smb_hdr *smb)
+       if (smb->Command == SMB_COM_LOCKING_ANDX)
+               return 0;
++      /*
++       * Windows NT server returns error resposne (e.g. STATUS_DELETE_PENDING
++       * or STATUS_OBJECT_NAME_NOT_FOUND or ERRDOS/ERRbadfile or any other)
++       * for some TRANS2 requests without the RESPONSE flag set in header.
++       */
++      if (smb->Command == SMB_COM_TRANSACTION2 && smb->Status.CifsError != 0)
++              return 0;
++
+       cifs_dbg(VFS, "Server sent request, not response. mid=%u\n",
+                get_mid(smb));
+       return 1;
+-- 
+2.39.5
+
diff --git a/queue-6.1/coresight-only-check-bottom-two-claim-bits.patch b/queue-6.1/coresight-only-check-bottom-two-claim-bits.patch
new file mode 100644 (file)
index 0000000..597c332
--- /dev/null
@@ -0,0 +1,55 @@
+From 67d3bf4826dbfb4b1b2e7dfefc87012a8aea9445 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Mar 2025 11:58:47 +0000
+Subject: coresight: Only check bottom two claim bits
+
+From: James Clark <james.clark@linaro.org>
+
+[ Upstream commit a4e65842e1142aa18ef36113fbd81d614eaefe5a ]
+
+The use of the whole register and == could break the claim mechanism if
+any of the other bits are used in the future. The referenced doc "PSCI -
+ARM DEN 0022D" also says to only read and clear the bottom two bits.
+
+Use FIELD_GET() to extract only the relevant part.
+
+Reviewed-by: Leo Yan <leo.yan@arm.com>
+Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
+Signed-off-by: James Clark <james.clark@linaro.org>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20250325-james-coresight-claim-tags-v4-2-dfbd3822b2e5@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/coresight/coresight-core.c | 3 ++-
+ drivers/hwtracing/coresight/coresight-priv.h | 1 +
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
+index 4477b1ab73577..6d836f10b3de6 100644
+--- a/drivers/hwtracing/coresight/coresight-core.c
++++ b/drivers/hwtracing/coresight/coresight-core.c
+@@ -189,7 +189,8 @@ static int coresight_find_link_outport(struct coresight_device *csdev,
+ static inline u32 coresight_read_claim_tags(struct coresight_device *csdev)
+ {
+-      return csdev_access_relaxed_read32(&csdev->access, CORESIGHT_CLAIMCLR);
++      return FIELD_GET(CORESIGHT_CLAIM_MASK,
++                       csdev_access_relaxed_read32(&csdev->access, CORESIGHT_CLAIMCLR));
+ }
+ static inline bool coresight_is_claimed_self_hosted(struct coresight_device *csdev)
+diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
+index 595ce58620567..3c78df0b60893 100644
+--- a/drivers/hwtracing/coresight/coresight-priv.h
++++ b/drivers/hwtracing/coresight/coresight-priv.h
+@@ -32,6 +32,7 @@
+  * Coresight device CLAIM protocol.
+  * See PSCI - ARM DEN 0022D, Section: 6.8.1 Debug and Trace save and restore.
+  */
++#define CORESIGHT_CLAIM_MASK          GENMASK(1, 0)
+ #define CORESIGHT_CLAIM_SELF_HOSTED   BIT(1)
+ #define TIMEOUT_US            100
+-- 
+2.39.5
+
diff --git a/queue-6.1/dmaengine-xilinx_dma-set-dma_device-directions.patch b/queue-6.1/dmaengine-xilinx_dma-set-dma_device-directions.patch
new file mode 100644 (file)
index 0000000..0dc0212
--- /dev/null
@@ -0,0 +1,40 @@
+From ec49cbd8771a4b6c7dae6614e73d0cfa88f2a4fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 May 2025 20:21:01 +0200
+Subject: dmaengine: xilinx_dma: Set dma_device directions
+
+From: Thomas Gessler <thomas.gessler@brueckmann-gmbh.de>
+
+[ Upstream commit 7e01511443c30a55a5ae78d3debd46d4d872517e ]
+
+Coalesce the direction bits from the enabled TX and/or RX channels into
+the directions bit mask of dma_device. Without this mask set,
+dma_get_slave_caps() in the DMAEngine fails, which prevents the driver
+from being used with an IIO DMAEngine buffer.
+
+Signed-off-by: Thomas Gessler <thomas.gessler@brueckmann-gmbh.de>
+Reviewed-by: Suraj Gupta <suraj.gupta2@amd.com>
+Tested-by: Folker Schwesinger <dev@folker-schwesinger.de>
+Link: https://lore.kernel.org/r/20250507182101.909010-1-thomas.gessler@brueckmann-gmbh.de
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/xilinx/xilinx_dma.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
+index 7660175704883..e2175651f9795 100644
+--- a/drivers/dma/xilinx/xilinx_dma.c
++++ b/drivers/dma/xilinx/xilinx_dma.c
+@@ -2859,6 +2859,8 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
+               return -EINVAL;
+       }
++      xdev->common.directions |= chan->direction;
++
+       /* Request the interrupt */
+       chan->irq = of_irq_get(node, chan->tdest);
+       if (chan->irq < 0)
+-- 
+2.39.5
+
diff --git a/queue-6.1/drivers-hv-allocate-interrupt-and-monitor-pages-alig.patch b/queue-6.1/drivers-hv-allocate-interrupt-and-monitor-pages-alig.patch
new file mode 100644 (file)
index 0000000..2d8b920
--- /dev/null
@@ -0,0 +1,96 @@
+From d11c03274d259be97eaa503045723953ecba4614 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 May 2025 17:56:33 -0700
+Subject: Drivers: hv: Allocate interrupt and monitor pages aligned to system
+ page boundary
+
+From: Long Li <longli@microsoft.com>
+
+[ Upstream commit 09eea7ad0b8e973dcf5ed49902838e5d68177f8e ]
+
+There are use cases that interrupt and monitor pages are mapped to
+user-mode through UIO, so they need to be system page aligned. Some
+Hyper-V allocation APIs introduced earlier broke those requirements.
+
+Fix this by using page allocation functions directly for interrupt
+and monitor pages.
+
+Cc: stable@vger.kernel.org
+Fixes: ca48739e59df ("Drivers: hv: vmbus: Move Hyper-V page allocator to arch neutral code")
+Signed-off-by: Long Li <longli@microsoft.com>
+Reviewed-by: Michael Kelley <mhklinux@outlook.com>
+Link: https://lore.kernel.org/r/1746492997-4599-2-git-send-email-longli@linuxonhyperv.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Message-ID: <1746492997-4599-2-git-send-email-longli@linuxonhyperv.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/connection.c | 23 +++++++++++++++++------
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
+index 744d2809acc3f..7bb94e0dd0f66 100644
+--- a/drivers/hv/connection.c
++++ b/drivers/hv/connection.c
+@@ -205,11 +205,20 @@ int vmbus_connect(void)
+       INIT_LIST_HEAD(&vmbus_connection.chn_list);
+       mutex_init(&vmbus_connection.channel_mutex);
++      /*
++       * The following Hyper-V interrupt and monitor pages can be used by
++       * UIO for mapping to user-space, so they should always be allocated on
++       * system page boundaries. The system page size must be >= the Hyper-V
++       * page size.
++       */
++      BUILD_BUG_ON(PAGE_SIZE < HV_HYP_PAGE_SIZE);
++
+       /*
+        * Setup the vmbus event connection for channel interrupt
+        * abstraction stuff
+        */
+-      vmbus_connection.int_page = hv_alloc_hyperv_zeroed_page();
++      vmbus_connection.int_page =
++              (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
+       if (vmbus_connection.int_page == NULL) {
+               ret = -ENOMEM;
+               goto cleanup;
+@@ -224,8 +233,8 @@ int vmbus_connect(void)
+        * Setup the monitor notification facility. The 1st page for
+        * parent->child and the 2nd page for child->parent
+        */
+-      vmbus_connection.monitor_pages[0] = hv_alloc_hyperv_page();
+-      vmbus_connection.monitor_pages[1] = hv_alloc_hyperv_page();
++      vmbus_connection.monitor_pages[0] = (void *)__get_free_page(GFP_KERNEL);
++      vmbus_connection.monitor_pages[1] = (void *)__get_free_page(GFP_KERNEL);
+       if ((vmbus_connection.monitor_pages[0] == NULL) ||
+           (vmbus_connection.monitor_pages[1] == NULL)) {
+               ret = -ENOMEM;
+@@ -341,21 +350,23 @@ void vmbus_disconnect(void)
+               destroy_workqueue(vmbus_connection.work_queue);
+       if (vmbus_connection.int_page) {
+-              hv_free_hyperv_page(vmbus_connection.int_page);
++              free_page((unsigned long)vmbus_connection.int_page);
+               vmbus_connection.int_page = NULL;
+       }
+       if (vmbus_connection.monitor_pages[0]) {
+               if (!set_memory_encrypted(
+                       (unsigned long)vmbus_connection.monitor_pages[0], 1))
+-                      hv_free_hyperv_page(vmbus_connection.monitor_pages[0]);
++                      free_page((unsigned long)
++                              vmbus_connection.monitor_pages[0]);
+               vmbus_connection.monitor_pages[0] = NULL;
+       }
+       if (vmbus_connection.monitor_pages[1]) {
+               if (!set_memory_encrypted(
+                       (unsigned long)vmbus_connection.monitor_pages[1], 1))
+-                      hv_free_hyperv_page(vmbus_connection.monitor_pages[1]);
++                      free_page((unsigned long)
++                              vmbus_connection.monitor_pages[1]);
+               vmbus_connection.monitor_pages[1] = NULL;
+       }
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.1/drivers-hv-change-hv_free_hyperv_page-to-take-void-a.patch b/queue-6.1/drivers-hv-change-hv_free_hyperv_page-to-take-void-a.patch
new file mode 100644 (file)
index 0000000..bb9cbd2
--- /dev/null
@@ -0,0 +1,129 @@
+From 6f635403871e09472c9616c303e0be40915f197d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Jun 2023 15:09:49 -0700
+Subject: Drivers: hv: Change hv_free_hyperv_page() to take void * argument
+
+From: Kameron Carr <kameroncarr@linux.microsoft.com>
+
+[ Upstream commit a6fe043880820981f6e4918240f967ea79bb063e ]
+
+Currently hv_free_hyperv_page() takes an unsigned long argument, which
+is inconsistent with the void * return value from the corresponding
+hv_alloc_hyperv_page() function and variants. This creates unnecessary
+extra casting.
+
+Change the hv_free_hyperv_page() argument type to void *.
+Also remove redundant casts from invocations of
+hv_alloc_hyperv_page() and variants.
+
+Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
+Reviewed-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
+Reviewed-by: Dexuan Cui <decui@microsoft.com>
+Link: https://lore.kernel.org/r/1687558189-19734-1-git-send-email-kameroncarr@linux.microsoft.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Stable-dep-of: 09eea7ad0b8e ("Drivers: hv: Allocate interrupt and monitor pages aligned to system page boundary")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/connection.c        | 13 ++++++-------
+ drivers/hv/hv_common.c         | 10 +++++-----
+ include/asm-generic/mshyperv.h |  2 +-
+ 3 files changed, 12 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
+index 5978e9dbc286f..ebf15f31d97e3 100644
+--- a/drivers/hv/connection.c
++++ b/drivers/hv/connection.c
+@@ -209,8 +209,7 @@ int vmbus_connect(void)
+        * Setup the vmbus event connection for channel interrupt
+        * abstraction stuff
+        */
+-      vmbus_connection.int_page =
+-      (void *)hv_alloc_hyperv_zeroed_page();
++      vmbus_connection.int_page = hv_alloc_hyperv_zeroed_page();
+       if (vmbus_connection.int_page == NULL) {
+               ret = -ENOMEM;
+               goto cleanup;
+@@ -225,8 +224,8 @@ int vmbus_connect(void)
+        * Setup the monitor notification facility. The 1st page for
+        * parent->child and the 2nd page for child->parent
+        */
+-      vmbus_connection.monitor_pages[0] = (void *)hv_alloc_hyperv_page();
+-      vmbus_connection.monitor_pages[1] = (void *)hv_alloc_hyperv_page();
++      vmbus_connection.monitor_pages[0] = hv_alloc_hyperv_page();
++      vmbus_connection.monitor_pages[1] = hv_alloc_hyperv_page();
+       if ((vmbus_connection.monitor_pages[0] == NULL) ||
+           (vmbus_connection.monitor_pages[1] == NULL)) {
+               ret = -ENOMEM;
+@@ -333,15 +332,15 @@ void vmbus_disconnect(void)
+               destroy_workqueue(vmbus_connection.work_queue);
+       if (vmbus_connection.int_page) {
+-              hv_free_hyperv_page((unsigned long)vmbus_connection.int_page);
++              hv_free_hyperv_page(vmbus_connection.int_page);
+               vmbus_connection.int_page = NULL;
+       }
+       set_memory_encrypted((unsigned long)vmbus_connection.monitor_pages[0], 1);
+       set_memory_encrypted((unsigned long)vmbus_connection.monitor_pages[1], 1);
+-      hv_free_hyperv_page((unsigned long)vmbus_connection.monitor_pages[0]);
+-      hv_free_hyperv_page((unsigned long)vmbus_connection.monitor_pages[1]);
++      hv_free_hyperv_page(vmbus_connection.monitor_pages[0]);
++      hv_free_hyperv_page(vmbus_connection.monitor_pages[1]);
+       vmbus_connection.monitor_pages[0] = NULL;
+       vmbus_connection.monitor_pages[1] = NULL;
+ }
+diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
+index 07338f6ec1e2c..2bc1aea070468 100644
+--- a/drivers/hv/hv_common.c
++++ b/drivers/hv/hv_common.c
+@@ -112,12 +112,12 @@ void *hv_alloc_hyperv_zeroed_page(void)
+ }
+ EXPORT_SYMBOL_GPL(hv_alloc_hyperv_zeroed_page);
+-void hv_free_hyperv_page(unsigned long addr)
++void hv_free_hyperv_page(void *addr)
+ {
+       if (PAGE_SIZE == HV_HYP_PAGE_SIZE)
+-              free_page(addr);
++              free_page((unsigned long)addr);
+       else
+-              kfree((void *)addr);
++              kfree(addr);
+ }
+ EXPORT_SYMBOL_GPL(hv_free_hyperv_page);
+@@ -250,7 +250,7 @@ static void hv_kmsg_dump_unregister(void)
+       atomic_notifier_chain_unregister(&panic_notifier_list,
+                                        &hyperv_panic_report_block);
+-      hv_free_hyperv_page((unsigned long)hv_panic_page);
++      hv_free_hyperv_page(hv_panic_page);
+       hv_panic_page = NULL;
+ }
+@@ -267,7 +267,7 @@ static void hv_kmsg_dump_register(void)
+       ret = kmsg_dump_register(&hv_kmsg_dumper);
+       if (ret) {
+               pr_err("Hyper-V: kmsg dump register error 0x%x\n", ret);
+-              hv_free_hyperv_page((unsigned long)hv_panic_page);
++              hv_free_hyperv_page(hv_panic_page);
+               hv_panic_page = NULL;
+       }
+ }
+diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
+index bfb9eb9d7215b..a9b52845335c0 100644
+--- a/include/asm-generic/mshyperv.h
++++ b/include/asm-generic/mshyperv.h
+@@ -187,7 +187,7 @@ int hv_common_cpu_die(unsigned int cpu);
+ void *hv_alloc_hyperv_page(void);
+ void *hv_alloc_hyperv_zeroed_page(void);
+-void hv_free_hyperv_page(unsigned long addr);
++void hv_free_hyperv_page(void *addr);
+ /**
+  * hv_cpu_number_to_vp_number() - Map CPU to VP.
+-- 
+2.39.5
+
diff --git a/queue-6.1/drivers-hv-hyperv_fb-untangle-and-refactor-hyper-v-p.patch b/queue-6.1/drivers-hv-hyperv_fb-untangle-and-refactor-hyper-v-p.patch
new file mode 100644 (file)
index 0000000..3f5135c
--- /dev/null
@@ -0,0 +1,250 @@
+From 123ce5247a672409de0f968486882483567f5211 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Aug 2022 19:17:30 -0300
+Subject: drivers: hv, hyperv_fb: Untangle and refactor Hyper-V panic notifiers
+
+From: Guilherme G. Piccoli <gpiccoli@igalia.com>
+
+[ Upstream commit d786e00d19f9fc80c2239a07643b08ea75b8b364 ]
+
+Currently Hyper-V guests are among the most relevant users of the panic
+infrastructure, like panic notifiers, kmsg dumpers, etc. The reasons rely
+both in cleaning-up procedures (closing hypervisor <-> guest connection,
+disabling some paravirtualized timer) as well as to data collection
+(sending panic information to the hypervisor) and framebuffer management.
+
+The thing is: some notifiers are related to others, ordering matters, some
+functionalities are duplicated and there are lots of conditionals behind
+sending panic information to the hypervisor. As part of an effort to
+clean-up the panic notifiers mechanism and better document things, we
+hereby address some of the issues/complexities of Hyper-V panic handling
+through the following changes:
+
+(a) We have die and panic notifiers on vmbus_drv.c and both have goals of
+sending panic information to the hypervisor, though the panic notifier is
+also responsible for a cleaning-up procedure.
+
+This commit clears the code by splitting the panic notifier in two, one
+for closing the vmbus connection whereas the other is only for sending
+panic info to hypervisor. With that, it was possible to merge the die and
+panic notifiers in a single/well-documented function, and clear some
+conditional complexities on sending such information to the hypervisor.
+
+(b) There is a Hyper-V framebuffer panic notifier, which relies in doing
+a vmbus operation that demands a valid connection. So, we must order this
+notifier with the panic notifier from vmbus_drv.c, to guarantee that the
+framebuffer code executes before the vmbus connection is unloaded.
+
+Also, this commit removes a useless header.
+
+Although there is code rework and re-ordering, we expect that this change
+has no functional regressions but instead optimize the path and increase
+panic reliability on Hyper-V. This was tested on Hyper-V with success.
+
+Cc: Andrea Parri (Microsoft) <parri.andrea@gmail.com>
+Cc: Dexuan Cui <decui@microsoft.com>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Cc: "K. Y. Srinivasan" <kys@microsoft.com>
+Cc: Petr Mladek <pmladek@suse.com>
+Cc: Stephen Hemminger <sthemmin@microsoft.com>
+Cc: Tianyu Lan <Tianyu.Lan@microsoft.com>
+Cc: Wei Liu <wei.liu@kernel.org>
+Reviewed-by: Michael Kelley <mikelley@microsoft.com>
+Tested-by: Fabio A M Martins <fabiomirmar@gmail.com>
+Signed-off-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
+Tested-by: Michael Kelley <mikelley@microsoft.com>
+Link: https://lore.kernel.org/r/20220819221731.480795-11-gpiccoli@igalia.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Stable-dep-of: 09eea7ad0b8e ("Drivers: hv: Allocate interrupt and monitor pages aligned to system page boundary")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/vmbus_drv.c          | 105 +++++++++++++++++++-------------
+ drivers/video/fbdev/hyperv_fb.c |   8 +++
+ 2 files changed, 72 insertions(+), 41 deletions(-)
+
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+index dfbfdbf9cbd72..5f6415214a1e4 100644
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -25,7 +25,6 @@
+ #include <linux/sched/task_stack.h>
+ #include <linux/delay.h>
+-#include <linux/notifier.h>
+ #include <linux/panic_notifier.h>
+ #include <linux/ptrace.h>
+ #include <linux/screen_info.h>
+@@ -68,53 +67,74 @@ static int hyperv_report_reg(void)
+       return !sysctl_record_panic_msg || !hv_panic_page;
+ }
+-static int hyperv_panic_event(struct notifier_block *nb, unsigned long val,
++/*
++ * The panic notifier below is responsible solely for unloading the
++ * vmbus connection, which is necessary in a panic event.
++ *
++ * Notice an intrincate relation of this notifier with Hyper-V
++ * framebuffer panic notifier exists - we need vmbus connection alive
++ * there in order to succeed, so we need to order both with each other
++ * [see hvfb_on_panic()] - this is done using notifiers' priorities.
++ */
++static int hv_panic_vmbus_unload(struct notifier_block *nb, unsigned long val,
+                             void *args)
+ {
+-      struct pt_regs *regs;
+-
+       vmbus_initiate_unload(true);
+-
+-      /*
+-       * Hyper-V should be notified only once about a panic.  If we will be
+-       * doing hv_kmsg_dump() with kmsg data later, don't do the notification
+-       * here.
+-       */
+-      if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE
+-          && hyperv_report_reg()) {
+-              regs = current_pt_regs();
+-              hyperv_report_panic(regs, val, false);
+-      }
+       return NOTIFY_DONE;
+ }
++static struct notifier_block hyperv_panic_vmbus_unload_block = {
++      .notifier_call  = hv_panic_vmbus_unload,
++      .priority       = INT_MIN + 1, /* almost the latest one to execute */
++};
++
++static int hv_die_panic_notify_crash(struct notifier_block *self,
++                                   unsigned long val, void *args);
++
++static struct notifier_block hyperv_die_report_block = {
++      .notifier_call = hv_die_panic_notify_crash,
++};
++static struct notifier_block hyperv_panic_report_block = {
++      .notifier_call = hv_die_panic_notify_crash,
++};
+-static int hyperv_die_event(struct notifier_block *nb, unsigned long val,
+-                          void *args)
++/*
++ * The following callback works both as die and panic notifier; its
++ * goal is to provide panic information to the hypervisor unless the
++ * kmsg dumper is used [see hv_kmsg_dump()], which provides more
++ * information but isn't always available.
++ *
++ * Notice that both the panic/die report notifiers are registered only
++ * if we have the capability HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE set.
++ */
++static int hv_die_panic_notify_crash(struct notifier_block *self,
++                                   unsigned long val, void *args)
+ {
+-      struct die_args *die = args;
+-      struct pt_regs *regs = die->regs;
++      struct pt_regs *regs;
++      bool is_die;
+-      /* Don't notify Hyper-V if the die event is other than oops */
+-      if (val != DIE_OOPS)
+-              return NOTIFY_DONE;
++      /* Don't notify Hyper-V unless we have a die oops event or panic. */
++      if (self == &hyperv_panic_report_block) {
++              is_die = false;
++              regs = current_pt_regs();
++      } else { /* die event */
++              if (val != DIE_OOPS)
++                      return NOTIFY_DONE;
++
++              is_die = true;
++              regs = ((struct die_args *)args)->regs;
++      }
+       /*
+-       * Hyper-V should be notified only once about a panic.  If we will be
+-       * doing hv_kmsg_dump() with kmsg data later, don't do the notification
+-       * here.
++       * Hyper-V should be notified only once about a panic/die. If we will
++       * be calling hv_kmsg_dump() later with kmsg data, don't do the
++       * notification here.
+        */
+       if (hyperv_report_reg())
+-              hyperv_report_panic(regs, val, true);
++              hyperv_report_panic(regs, val, is_die);
++
+       return NOTIFY_DONE;
+ }
+-static struct notifier_block hyperv_die_block = {
+-      .notifier_call = hyperv_die_event,
+-};
+-static struct notifier_block hyperv_panic_block = {
+-      .notifier_call = hyperv_panic_event,
+-};
+-
+ static const char *fb_mmio_name = "fb_range";
+ static struct resource *fb_mmio;
+ static struct resource *hyperv_mmio;
+@@ -1538,16 +1558,17 @@ static int vmbus_bus_init(void)
+               if (hyperv_crash_ctl & HV_CRASH_CTL_CRASH_NOTIFY_MSG)
+                       hv_kmsg_dump_register();
+-              register_die_notifier(&hyperv_die_block);
++              register_die_notifier(&hyperv_die_report_block);
++              atomic_notifier_chain_register(&panic_notifier_list,
++                                              &hyperv_panic_report_block);
+       }
+       /*
+-       * Always register the panic notifier because we need to unload
+-       * the VMbus channel connection to prevent any VMbus
+-       * activity after the VM panics.
++       * Always register the vmbus unload panic notifier because we
++       * need to shut the VMbus channel connection on panic.
+        */
+       atomic_notifier_chain_register(&panic_notifier_list,
+-                             &hyperv_panic_block);
++                             &hyperv_panic_vmbus_unload_block);
+       vmbus_request_offers();
+@@ -2814,15 +2835,17 @@ static void __exit vmbus_exit(void)
+       if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) {
+               kmsg_dump_unregister(&hv_kmsg_dumper);
+-              unregister_die_notifier(&hyperv_die_block);
++              unregister_die_notifier(&hyperv_die_report_block);
++              atomic_notifier_chain_unregister(&panic_notifier_list,
++                                              &hyperv_panic_report_block);
+       }
+       /*
+-       * The panic notifier is always registered, hence we should
++       * The vmbus panic notifier is always registered, hence we should
+        * also unconditionally unregister it here as well.
+        */
+       atomic_notifier_chain_unregister(&panic_notifier_list,
+-                                       &hyperv_panic_block);
++                                      &hyperv_panic_vmbus_unload_block);
+       free_page((unsigned long)hv_panic_page);
+       unregister_sysctl_table(hv_ctl_table_hdr);
+diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
+index 41c496ff55cc4..f3f30ee6cc95a 100644
+--- a/drivers/video/fbdev/hyperv_fb.c
++++ b/drivers/video/fbdev/hyperv_fb.c
+@@ -1209,7 +1209,15 @@ static int hvfb_probe(struct hv_device *hdev,
+       par->fb_ready = true;
+       par->synchronous_fb = false;
++
++      /*
++       * We need to be sure this panic notifier runs _before_ the
++       * vmbus disconnect, so order it by priority. It must execute
++       * before the function hv_panic_vmbus_unload() [drivers/hv/vmbus_drv.c],
++       * which is almost at the end of list, with priority = INT_MIN + 1.
++       */
+       par->hvfb_panic_nb.notifier_call = hvfb_on_panic;
++      par->hvfb_panic_nb.priority = INT_MIN + 10,
+       atomic_notifier_chain_register(&panic_notifier_list,
+                                      &par->hvfb_panic_nb);
+-- 
+2.39.5
+
diff --git a/queue-6.1/drivers-hv-move-panic-report-code-from-vmbus-to-hv-e.patch b/queue-6.1/drivers-hv-move-panic-report-code-from-vmbus-to-hv-e.patch
new file mode 100644 (file)
index 0000000..aa8830f
--- /dev/null
@@ -0,0 +1,625 @@
+From b486cba57a668d5f00e285f5b855ee76e0fe690c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Apr 2023 15:49:06 -0700
+Subject: Drivers: hv: move panic report code from vmbus to hv early init code
+
+From: Long Li <longli@microsoft.com>
+
+[ Upstream commit 9c318a1d9b5000c77527011f158a75c5483510f5 ]
+
+The panic reporting code was added in commit 81b18bce48af
+("Drivers: HV: Send one page worth of kmsg dump over Hyper-V during panic")
+
+It was added to the vmbus driver. The panic reporting has no dependence
+on vmbus, and can be enabled at an earlier boot time when Hyper-V is
+initialized.
+
+This patch moves the panic reporting code out of vmbus. There is no
+functionality changes. During moving, also refactored some cleanup
+functions into hv_kmsg_dump_unregister().
+
+Signed-off-by: Long Li <longli@microsoft.com>
+Reviewed-by: Michael Kelley <mikelley@microsoft.com>
+Link: https://lore.kernel.org/r/1682030946-6372-1-git-send-email-longli@linuxonhyperv.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Stable-dep-of: 09eea7ad0b8e ("Drivers: hv: Allocate interrupt and monitor pages aligned to system page boundary")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/hv.c        |  36 -------
+ drivers/hv/hv_common.c | 231 +++++++++++++++++++++++++++++++++++++++++
+ drivers/hv/vmbus_drv.c | 199 -----------------------------------
+ 3 files changed, 231 insertions(+), 235 deletions(-)
+
+diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
+index 4d6480d57546d..d1a3be24396f0 100644
+--- a/drivers/hv/hv.c
++++ b/drivers/hv/hv.c
+@@ -38,42 +38,6 @@ int hv_init(void)
+       return 0;
+ }
+-/*
+- * Functions for allocating and freeing memory with size and
+- * alignment HV_HYP_PAGE_SIZE. These functions are needed because
+- * the guest page size may not be the same as the Hyper-V page
+- * size. We depend upon kmalloc() aligning power-of-two size
+- * allocations to the allocation size boundary, so that the
+- * allocated memory appears to Hyper-V as a page of the size
+- * it expects.
+- */
+-
+-void *hv_alloc_hyperv_page(void)
+-{
+-      BUILD_BUG_ON(PAGE_SIZE <  HV_HYP_PAGE_SIZE);
+-
+-      if (PAGE_SIZE == HV_HYP_PAGE_SIZE)
+-              return (void *)__get_free_page(GFP_KERNEL);
+-      else
+-              return kmalloc(HV_HYP_PAGE_SIZE, GFP_KERNEL);
+-}
+-
+-void *hv_alloc_hyperv_zeroed_page(void)
+-{
+-      if (PAGE_SIZE == HV_HYP_PAGE_SIZE)
+-              return (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
+-      else
+-              return kzalloc(HV_HYP_PAGE_SIZE, GFP_KERNEL);
+-}
+-
+-void hv_free_hyperv_page(unsigned long addr)
+-{
+-      if (PAGE_SIZE == HV_HYP_PAGE_SIZE)
+-              free_page(addr);
+-      else
+-              kfree((void *)addr);
+-}
+-
+ /*
+  * hv_post_message - Post a message using the hypervisor message IPC.
+  *
+diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
+index ae68298c0dcac..07338f6ec1e2c 100644
+--- a/drivers/hv/hv_common.c
++++ b/drivers/hv/hv_common.c
+@@ -17,8 +17,11 @@
+ #include <linux/export.h>
+ #include <linux/bitfield.h>
+ #include <linux/cpumask.h>
++#include <linux/sched/task_stack.h>
+ #include <linux/panic_notifier.h>
+ #include <linux/ptrace.h>
++#include <linux/kdebug.h>
++#include <linux/kmsg_dump.h>
+ #include <linux/slab.h>
+ #include <linux/dma-map-ops.h>
+ #include <asm/hyperv-tlfs.h>
+@@ -51,6 +54,10 @@ EXPORT_SYMBOL_GPL(hyperv_pcpu_input_arg);
+ void * __percpu *hyperv_pcpu_output_arg;
+ EXPORT_SYMBOL_GPL(hyperv_pcpu_output_arg);
++static void hv_kmsg_dump_unregister(void);
++
++static struct ctl_table_header *hv_ctl_table_hdr;
++
+ /*
+  * Hyper-V specific initialization and shutdown code that is
+  * common across all architectures.  Called from architecture
+@@ -59,6 +66,12 @@ EXPORT_SYMBOL_GPL(hyperv_pcpu_output_arg);
+ void __init hv_common_free(void)
+ {
++      unregister_sysctl_table(hv_ctl_table_hdr);
++      hv_ctl_table_hdr = NULL;
++
++      if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE)
++              hv_kmsg_dump_unregister();
++
+       kfree(hv_vp_index);
+       hv_vp_index = NULL;
+@@ -69,10 +82,203 @@ void __init hv_common_free(void)
+       hyperv_pcpu_input_arg = NULL;
+ }
++/*
++ * Functions for allocating and freeing memory with size and
++ * alignment HV_HYP_PAGE_SIZE. These functions are needed because
++ * the guest page size may not be the same as the Hyper-V page
++ * size. We depend upon kmalloc() aligning power-of-two size
++ * allocations to the allocation size boundary, so that the
++ * allocated memory appears to Hyper-V as a page of the size
++ * it expects.
++ */
++
++void *hv_alloc_hyperv_page(void)
++{
++      BUILD_BUG_ON(PAGE_SIZE <  HV_HYP_PAGE_SIZE);
++
++      if (PAGE_SIZE == HV_HYP_PAGE_SIZE)
++              return (void *)__get_free_page(GFP_KERNEL);
++      else
++              return kmalloc(HV_HYP_PAGE_SIZE, GFP_KERNEL);
++}
++EXPORT_SYMBOL_GPL(hv_alloc_hyperv_page);
++
++void *hv_alloc_hyperv_zeroed_page(void)
++{
++      if (PAGE_SIZE == HV_HYP_PAGE_SIZE)
++              return (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
++      else
++              return kzalloc(HV_HYP_PAGE_SIZE, GFP_KERNEL);
++}
++EXPORT_SYMBOL_GPL(hv_alloc_hyperv_zeroed_page);
++
++void hv_free_hyperv_page(unsigned long addr)
++{
++      if (PAGE_SIZE == HV_HYP_PAGE_SIZE)
++              free_page(addr);
++      else
++              kfree((void *)addr);
++}
++EXPORT_SYMBOL_GPL(hv_free_hyperv_page);
++
++static void *hv_panic_page;
++
++/*
++ * Boolean to control whether to report panic messages over Hyper-V.
++ *
++ * It can be set via /proc/sys/kernel/hyperv_record_panic_msg
++ */
++static int sysctl_record_panic_msg = 1;
++
++/*
++ * sysctl option to allow the user to control whether kmsg data should be
++ * reported to Hyper-V on panic.
++ */
++static struct ctl_table hv_ctl_table[] = {
++      {
++              .procname       = "hyperv_record_panic_msg",
++              .data           = &sysctl_record_panic_msg,
++              .maxlen         = sizeof(int),
++              .mode           = 0644,
++              .proc_handler   = proc_dointvec_minmax,
++              .extra1         = SYSCTL_ZERO,
++              .extra2         = SYSCTL_ONE
++      },
++      {}
++};
++
++static int hv_die_panic_notify_crash(struct notifier_block *self,
++                                   unsigned long val, void *args);
++
++static struct notifier_block hyperv_die_report_block = {
++      .notifier_call = hv_die_panic_notify_crash,
++};
++
++static struct notifier_block hyperv_panic_report_block = {
++      .notifier_call = hv_die_panic_notify_crash,
++};
++
++/*
++ * The following callback works both as die and panic notifier; its
++ * goal is to provide panic information to the hypervisor unless the
++ * kmsg dumper is used [see hv_kmsg_dump()], which provides more
++ * information but isn't always available.
++ *
++ * Notice that both the panic/die report notifiers are registered only
++ * if we have the capability HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE set.
++ */
++static int hv_die_panic_notify_crash(struct notifier_block *self,
++                                   unsigned long val, void *args)
++{
++      struct pt_regs *regs;
++      bool is_die;
++
++      /* Don't notify Hyper-V unless we have a die oops event or panic. */
++      if (self == &hyperv_panic_report_block) {
++              is_die = false;
++              regs = current_pt_regs();
++      } else { /* die event */
++              if (val != DIE_OOPS)
++                      return NOTIFY_DONE;
++
++              is_die = true;
++              regs = ((struct die_args *)args)->regs;
++      }
++
++      /*
++       * Hyper-V should be notified only once about a panic/die. If we will
++       * be calling hv_kmsg_dump() later with kmsg data, don't do the
++       * notification here.
++       */
++      if (!sysctl_record_panic_msg || !hv_panic_page)
++              hyperv_report_panic(regs, val, is_die);
++
++      return NOTIFY_DONE;
++}
++
++/*
++ * Callback from kmsg_dump. Grab as much as possible from the end of the kmsg
++ * buffer and call into Hyper-V to transfer the data.
++ */
++static void hv_kmsg_dump(struct kmsg_dumper *dumper,
++                       enum kmsg_dump_reason reason)
++{
++      struct kmsg_dump_iter iter;
++      size_t bytes_written;
++
++      /* We are only interested in panics. */
++      if (reason != KMSG_DUMP_PANIC || !sysctl_record_panic_msg)
++              return;
++
++      /*
++       * Write dump contents to the page. No need to synchronize; panic should
++       * be single-threaded.
++       */
++      kmsg_dump_rewind(&iter);
++      kmsg_dump_get_buffer(&iter, false, hv_panic_page, HV_HYP_PAGE_SIZE,
++                           &bytes_written);
++      if (!bytes_written)
++              return;
++      /*
++       * P3 to contain the physical address of the panic page & P4 to
++       * contain the size of the panic data in that page. Rest of the
++       * registers are no-op when the NOTIFY_MSG flag is set.
++       */
++      hv_set_register(HV_REGISTER_CRASH_P0, 0);
++      hv_set_register(HV_REGISTER_CRASH_P1, 0);
++      hv_set_register(HV_REGISTER_CRASH_P2, 0);
++      hv_set_register(HV_REGISTER_CRASH_P3, virt_to_phys(hv_panic_page));
++      hv_set_register(HV_REGISTER_CRASH_P4, bytes_written);
++
++      /*
++       * Let Hyper-V know there is crash data available along with
++       * the panic message.
++       */
++      hv_set_register(HV_REGISTER_CRASH_CTL,
++                      (HV_CRASH_CTL_CRASH_NOTIFY |
++                       HV_CRASH_CTL_CRASH_NOTIFY_MSG));
++}
++
++static struct kmsg_dumper hv_kmsg_dumper = {
++      .dump = hv_kmsg_dump,
++};
++
++static void hv_kmsg_dump_unregister(void)
++{
++      kmsg_dump_unregister(&hv_kmsg_dumper);
++      unregister_die_notifier(&hyperv_die_report_block);
++      atomic_notifier_chain_unregister(&panic_notifier_list,
++                                       &hyperv_panic_report_block);
++
++      hv_free_hyperv_page((unsigned long)hv_panic_page);
++      hv_panic_page = NULL;
++}
++
++static void hv_kmsg_dump_register(void)
++{
++      int ret;
++
++      hv_panic_page = hv_alloc_hyperv_zeroed_page();
++      if (!hv_panic_page) {
++              pr_err("Hyper-V: panic message page memory allocation failed\n");
++              return;
++      }
++
++      ret = kmsg_dump_register(&hv_kmsg_dumper);
++      if (ret) {
++              pr_err("Hyper-V: kmsg dump register error 0x%x\n", ret);
++              hv_free_hyperv_page((unsigned long)hv_panic_page);
++              hv_panic_page = NULL;
++      }
++}
++
+ int __init hv_common_init(void)
+ {
+       int i;
++      if (hv_is_isolation_supported())
++              sysctl_record_panic_msg = 0;
++
+       /*
+        * Hyper-V expects to get crash register data or kmsg when
+        * crash enlightment is available and system crashes. Set
+@@ -81,8 +287,33 @@ int __init hv_common_init(void)
+        * kernel.
+        */
+       if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) {
++              u64 hyperv_crash_ctl;
++
+               crash_kexec_post_notifiers = true;
+               pr_info("Hyper-V: enabling crash_kexec_post_notifiers\n");
++
++              /*
++               * Panic message recording (sysctl_record_panic_msg)
++               * is enabled by default in non-isolated guests and
++               * disabled by default in isolated guests; the panic
++               * message recording won't be available in isolated
++               * guests should the following registration fail.
++               */
++              hv_ctl_table_hdr = register_sysctl("kernel", hv_ctl_table);
++              if (!hv_ctl_table_hdr)
++                      pr_err("Hyper-V: sysctl table register error");
++
++              /*
++               * Register for panic kmsg callback only if the right
++               * capability is supported by the hypervisor.
++               */
++              hyperv_crash_ctl = hv_get_register(HV_REGISTER_CRASH_CTL);
++              if (hyperv_crash_ctl & HV_CRASH_CTL_CRASH_NOTIFY_MSG)
++                      hv_kmsg_dump_register();
++
++              register_die_notifier(&hyperv_die_report_block);
++              atomic_notifier_chain_register(&panic_notifier_list,
++                                             &hyperv_panic_report_block);
+       }
+       /*
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+index 5f6415214a1e4..074168f34afd7 100644
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -28,7 +28,6 @@
+ #include <linux/panic_notifier.h>
+ #include <linux/ptrace.h>
+ #include <linux/screen_info.h>
+-#include <linux/kdebug.h>
+ #include <linux/efi.h>
+ #include <linux/random.h>
+ #include <linux/kernel.h>
+@@ -47,26 +46,12 @@ static struct acpi_device  *hv_acpi_dev;
+ static int hyperv_cpuhp_online;
+-static void *hv_panic_page;
+-
+ static long __percpu *vmbus_evt;
+ /* Values parsed from ACPI DSDT */
+ int vmbus_irq;
+ int vmbus_interrupt;
+-/*
+- * Boolean to control whether to report panic messages over Hyper-V.
+- *
+- * It can be set via /proc/sys/kernel/hyperv_record_panic_msg
+- */
+-static int sysctl_record_panic_msg = 1;
+-
+-static int hyperv_report_reg(void)
+-{
+-      return !sysctl_record_panic_msg || !hv_panic_page;
+-}
+-
+ /*
+  * The panic notifier below is responsible solely for unloading the
+  * vmbus connection, which is necessary in a panic event.
+@@ -87,54 +72,6 @@ static struct notifier_block hyperv_panic_vmbus_unload_block = {
+       .priority       = INT_MIN + 1, /* almost the latest one to execute */
+ };
+-static int hv_die_panic_notify_crash(struct notifier_block *self,
+-                                   unsigned long val, void *args);
+-
+-static struct notifier_block hyperv_die_report_block = {
+-      .notifier_call = hv_die_panic_notify_crash,
+-};
+-static struct notifier_block hyperv_panic_report_block = {
+-      .notifier_call = hv_die_panic_notify_crash,
+-};
+-
+-/*
+- * The following callback works both as die and panic notifier; its
+- * goal is to provide panic information to the hypervisor unless the
+- * kmsg dumper is used [see hv_kmsg_dump()], which provides more
+- * information but isn't always available.
+- *
+- * Notice that both the panic/die report notifiers are registered only
+- * if we have the capability HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE set.
+- */
+-static int hv_die_panic_notify_crash(struct notifier_block *self,
+-                                   unsigned long val, void *args)
+-{
+-      struct pt_regs *regs;
+-      bool is_die;
+-
+-      /* Don't notify Hyper-V unless we have a die oops event or panic. */
+-      if (self == &hyperv_panic_report_block) {
+-              is_die = false;
+-              regs = current_pt_regs();
+-      } else { /* die event */
+-              if (val != DIE_OOPS)
+-                      return NOTIFY_DONE;
+-
+-              is_die = true;
+-              regs = ((struct die_args *)args)->regs;
+-      }
+-
+-      /*
+-       * Hyper-V should be notified only once about a panic/die. If we will
+-       * be calling hv_kmsg_dump() later with kmsg data, don't do the
+-       * notification here.
+-       */
+-      if (hyperv_report_reg())
+-              hyperv_report_panic(regs, val, is_die);
+-
+-      return NOTIFY_DONE;
+-}
+-
+ static const char *fb_mmio_name = "fb_range";
+ static struct resource *fb_mmio;
+ static struct resource *hyperv_mmio;
+@@ -1376,98 +1313,6 @@ static irqreturn_t vmbus_percpu_isr(int irq, void *dev_id)
+       return IRQ_HANDLED;
+ }
+-/*
+- * Callback from kmsg_dump. Grab as much as possible from the end of the kmsg
+- * buffer and call into Hyper-V to transfer the data.
+- */
+-static void hv_kmsg_dump(struct kmsg_dumper *dumper,
+-                       enum kmsg_dump_reason reason)
+-{
+-      struct kmsg_dump_iter iter;
+-      size_t bytes_written;
+-
+-      /* We are only interested in panics. */
+-      if ((reason != KMSG_DUMP_PANIC) || (!sysctl_record_panic_msg))
+-              return;
+-
+-      /*
+-       * Write dump contents to the page. No need to synchronize; panic should
+-       * be single-threaded.
+-       */
+-      kmsg_dump_rewind(&iter);
+-      kmsg_dump_get_buffer(&iter, false, hv_panic_page, HV_HYP_PAGE_SIZE,
+-                           &bytes_written);
+-      if (!bytes_written)
+-              return;
+-      /*
+-       * P3 to contain the physical address of the panic page & P4 to
+-       * contain the size of the panic data in that page. Rest of the
+-       * registers are no-op when the NOTIFY_MSG flag is set.
+-       */
+-      hv_set_register(HV_REGISTER_CRASH_P0, 0);
+-      hv_set_register(HV_REGISTER_CRASH_P1, 0);
+-      hv_set_register(HV_REGISTER_CRASH_P2, 0);
+-      hv_set_register(HV_REGISTER_CRASH_P3, virt_to_phys(hv_panic_page));
+-      hv_set_register(HV_REGISTER_CRASH_P4, bytes_written);
+-
+-      /*
+-       * Let Hyper-V know there is crash data available along with
+-       * the panic message.
+-       */
+-      hv_set_register(HV_REGISTER_CRASH_CTL,
+-             (HV_CRASH_CTL_CRASH_NOTIFY | HV_CRASH_CTL_CRASH_NOTIFY_MSG));
+-}
+-
+-static struct kmsg_dumper hv_kmsg_dumper = {
+-      .dump = hv_kmsg_dump,
+-};
+-
+-static void hv_kmsg_dump_register(void)
+-{
+-      int ret;
+-
+-      hv_panic_page = hv_alloc_hyperv_zeroed_page();
+-      if (!hv_panic_page) {
+-              pr_err("Hyper-V: panic message page memory allocation failed\n");
+-              return;
+-      }
+-
+-      ret = kmsg_dump_register(&hv_kmsg_dumper);
+-      if (ret) {
+-              pr_err("Hyper-V: kmsg dump register error 0x%x\n", ret);
+-              hv_free_hyperv_page((unsigned long)hv_panic_page);
+-              hv_panic_page = NULL;
+-      }
+-}
+-
+-static struct ctl_table_header *hv_ctl_table_hdr;
+-
+-/*
+- * sysctl option to allow the user to control whether kmsg data should be
+- * reported to Hyper-V on panic.
+- */
+-static struct ctl_table hv_ctl_table[] = {
+-      {
+-              .procname       = "hyperv_record_panic_msg",
+-              .data           = &sysctl_record_panic_msg,
+-              .maxlen         = sizeof(int),
+-              .mode           = 0644,
+-              .proc_handler   = proc_dointvec_minmax,
+-              .extra1         = SYSCTL_ZERO,
+-              .extra2         = SYSCTL_ONE
+-      },
+-      {}
+-};
+-
+-static struct ctl_table hv_root_table[] = {
+-      {
+-              .procname       = "kernel",
+-              .mode           = 0555,
+-              .child          = hv_ctl_table
+-      },
+-      {}
+-};
+-
+ /*
+  * vmbus_bus_init -Main vmbus driver initialization routine.
+  *
+@@ -1531,38 +1376,6 @@ static int vmbus_bus_init(void)
+       if (ret)
+               goto err_connect;
+-      if (hv_is_isolation_supported())
+-              sysctl_record_panic_msg = 0;
+-
+-      /*
+-       * Only register if the crash MSRs are available
+-       */
+-      if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) {
+-              u64 hyperv_crash_ctl;
+-              /*
+-               * Panic message recording (sysctl_record_panic_msg)
+-               * is enabled by default in non-isolated guests and
+-               * disabled by default in isolated guests; the panic
+-               * message recording won't be available in isolated
+-               * guests should the following registration fail.
+-               */
+-              hv_ctl_table_hdr = register_sysctl_table(hv_root_table);
+-              if (!hv_ctl_table_hdr)
+-                      pr_err("Hyper-V: sysctl table register error");
+-
+-              /*
+-               * Register for panic kmsg callback only if the right
+-               * capability is supported by the hypervisor.
+-               */
+-              hyperv_crash_ctl = hv_get_register(HV_REGISTER_CRASH_CTL);
+-              if (hyperv_crash_ctl & HV_CRASH_CTL_CRASH_NOTIFY_MSG)
+-                      hv_kmsg_dump_register();
+-
+-              register_die_notifier(&hyperv_die_report_block);
+-              atomic_notifier_chain_register(&panic_notifier_list,
+-                                              &hyperv_panic_report_block);
+-      }
+-
+       /*
+        * Always register the vmbus unload panic notifier because we
+        * need to shut the VMbus channel connection on panic.
+@@ -1586,8 +1399,6 @@ static int vmbus_bus_init(void)
+       }
+ err_setup:
+       bus_unregister(&hv_bus);
+-      unregister_sysctl_table(hv_ctl_table_hdr);
+-      hv_ctl_table_hdr = NULL;
+       return ret;
+ }
+@@ -2833,13 +2644,6 @@ static void __exit vmbus_exit(void)
+       vmbus_free_channels();
+       kfree(vmbus_connection.channels);
+-      if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) {
+-              kmsg_dump_unregister(&hv_kmsg_dumper);
+-              unregister_die_notifier(&hyperv_die_report_block);
+-              atomic_notifier_chain_unregister(&panic_notifier_list,
+-                                              &hyperv_panic_report_block);
+-      }
+-
+       /*
+        * The vmbus panic notifier is always registered, hence we should
+        * also unconditionally unregister it here as well.
+@@ -2847,9 +2651,6 @@ static void __exit vmbus_exit(void)
+       atomic_notifier_chain_unregister(&panic_notifier_list,
+                                       &hyperv_panic_vmbus_unload_block);
+-      free_page((unsigned long)hv_panic_page);
+-      unregister_sysctl_table(hv_ctl_table_hdr);
+-      hv_ctl_table_hdr = NULL;
+       bus_unregister(&hv_bus);
+       cpuhp_remove_state(hyperv_cpuhp_online);
+-- 
+2.39.5
+
diff --git a/queue-6.1/drivers-hv-vmbus-add-utility-function-for-querying-r.patch b/queue-6.1/drivers-hv-vmbus-add-utility-function-for-querying-r.patch
new file mode 100644 (file)
index 0000000..d5358fc
--- /dev/null
@@ -0,0 +1,94 @@
+From 8c27055a51360031a58ec44fb2bf252bd5cd055f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 Mar 2024 01:51:57 -0700
+Subject: Drivers: hv: vmbus: Add utility function for querying ring size
+
+From: Saurabh Sengar <ssengar@linux.microsoft.com>
+
+[ Upstream commit e8c4bd6c6e6b7e7b416c42806981c2a81370001e ]
+
+Add a function to query for the preferred ring buffer size of VMBus
+device. This will allow the drivers (eg. UIO) to allocate the most
+optimized ring buffer size for devices.
+
+Signed-off-by: Saurabh Sengar <ssengar@linux.microsoft.com>
+Reviewed-by: Long Li <longli@microsoft.com>
+Link: https://lore.kernel.org/r/1711788723-8593-2-git-send-email-ssengar@linux.microsoft.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 0315fef2aff9 ("uio_hv_generic: Align ring size to system page")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/channel_mgmt.c | 15 ++++++++++++---
+ drivers/hv/hyperv_vmbus.h |  5 +++++
+ include/linux/hyperv.h    |  2 ++
+ 3 files changed, 19 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index d95e567a190d2..25e2958923af9 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -120,7 +120,9 @@ const struct vmbus_device vmbus_devs[] = {
+       },
+       /* File copy */
+-      { .dev_type = HV_FCOPY,
++      /* fcopy always uses 16KB ring buffer size and is working well for last many years */
++      { .pref_ring_size = 0x4000,
++        .dev_type = HV_FCOPY,
+         HV_FCOPY_GUID,
+         .perf_device = false,
+         .allowed_in_isolated = false,
+@@ -140,12 +142,19 @@ const struct vmbus_device vmbus_devs[] = {
+         .allowed_in_isolated = false,
+       },
+-      /* Unknown GUID */
+-      { .dev_type = HV_UNKNOWN,
++      /*
++       * Unknown GUID
++       * 64 KB ring buffer + 4 KB header should be sufficient size for any Hyper-V device apart
++       * from HV_NIC and HV_SCSI. This case avoid the fallback for unknown devices to allocate
++       * much bigger (2 MB) of ring size.
++       */
++      { .pref_ring_size = 0x11000,
++        .dev_type = HV_UNKNOWN,
+         .perf_device = false,
+         .allowed_in_isolated = false,
+       },
+ };
++EXPORT_SYMBOL_GPL(vmbus_devs);
+ static const struct {
+       guid_t guid;
+diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
+index 4cff3997c3ccd..f039b110e98ce 100644
+--- a/drivers/hv/hyperv_vmbus.h
++++ b/drivers/hv/hyperv_vmbus.h
+@@ -412,6 +412,11 @@ static inline bool hv_is_perf_channel(struct vmbus_channel *channel)
+       return vmbus_devs[channel->device_id].perf_device;
+ }
++static inline size_t hv_dev_ring_size(struct vmbus_channel *channel)
++{
++      return vmbus_devs[channel->device_id].pref_ring_size;
++}
++
+ static inline bool hv_is_allocated_cpu(unsigned int cpu)
+ {
+       struct vmbus_channel *channel, *sc;
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+index 80d876593caa9..43f778b6b9cda 100644
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -820,6 +820,8 @@ struct vmbus_requestor {
+ #define VMBUS_RQST_RESET (U64_MAX - 3)
+ struct vmbus_device {
++      /* preferred ring buffer size in KB, 0 means no preferred size for this device */
++      size_t pref_ring_size;
+       u16  dev_type;
+       guid_t guid;
+       bool perf_device;
+-- 
+2.39.5
+
diff --git a/queue-6.1/drivers-hv-vmbus-leak-pages-if-set_memory_encrypted-.patch b/queue-6.1/drivers-hv-vmbus-leak-pages-if-set_memory_encrypted-.patch
new file mode 100644 (file)
index 0000000..a8dc863
--- /dev/null
@@ -0,0 +1,84 @@
+From e4b216b69bde01026a2872446e6e97211b2d3e59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Mar 2024 09:15:54 -0700
+Subject: Drivers: hv: vmbus: Leak pages if set_memory_encrypted() fails
+
+From: Rick Edgecombe <rick.p.edgecombe@intel.com>
+
+[ Upstream commit 03f5a999adba062456c8c818a683beb1b498983a ]
+
+In CoCo VMs it is possible for the untrusted host to cause
+set_memory_encrypted() or set_memory_decrypted() to fail such that an
+error is returned and the resulting memory is shared. Callers need to
+take care to handle these errors to avoid returning decrypted (shared)
+memory to the page allocator, which could lead to functional or security
+issues.
+
+VMBus code could free decrypted pages if set_memory_encrypted()/decrypted()
+fails. Leak the pages if this happens.
+
+Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
+Signed-off-by: Michael Kelley <mhklinux@outlook.com>
+Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Link: https://lore.kernel.org/r/20240311161558.1310-2-mhklinux@outlook.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Message-ID: <20240311161558.1310-2-mhklinux@outlook.com>
+Stable-dep-of: 09eea7ad0b8e ("Drivers: hv: Allocate interrupt and monitor pages aligned to system page boundary")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/connection.c | 29 ++++++++++++++++++++++-------
+ 1 file changed, 22 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
+index ebf15f31d97e3..744d2809acc3f 100644
+--- a/drivers/hv/connection.c
++++ b/drivers/hv/connection.c
+@@ -236,8 +236,17 @@ int vmbus_connect(void)
+                               vmbus_connection.monitor_pages[0], 1);
+       ret |= set_memory_decrypted((unsigned long)
+                               vmbus_connection.monitor_pages[1], 1);
+-      if (ret)
++      if (ret) {
++              /*
++               * If set_memory_decrypted() fails, the encryption state
++               * of the memory is unknown. So leak the memory instead
++               * of risking returning decrypted memory to the free list.
++               * For simplicity, always handle both pages the same.
++               */
++              vmbus_connection.monitor_pages[0] = NULL;
++              vmbus_connection.monitor_pages[1] = NULL;
+               goto cleanup;
++      }
+       /*
+        * Set_memory_decrypted() will change the memory contents if
+@@ -336,13 +345,19 @@ void vmbus_disconnect(void)
+               vmbus_connection.int_page = NULL;
+       }
+-      set_memory_encrypted((unsigned long)vmbus_connection.monitor_pages[0], 1);
+-      set_memory_encrypted((unsigned long)vmbus_connection.monitor_pages[1], 1);
++      if (vmbus_connection.monitor_pages[0]) {
++              if (!set_memory_encrypted(
++                      (unsigned long)vmbus_connection.monitor_pages[0], 1))
++                      hv_free_hyperv_page(vmbus_connection.monitor_pages[0]);
++              vmbus_connection.monitor_pages[0] = NULL;
++      }
+-      hv_free_hyperv_page(vmbus_connection.monitor_pages[0]);
+-      hv_free_hyperv_page(vmbus_connection.monitor_pages[1]);
+-      vmbus_connection.monitor_pages[0] = NULL;
+-      vmbus_connection.monitor_pages[1] = NULL;
++      if (vmbus_connection.monitor_pages[1]) {
++              if (!set_memory_encrypted(
++                      (unsigned long)vmbus_connection.monitor_pages[1], 1))
++                      hv_free_hyperv_page(vmbus_connection.monitor_pages[1]);
++              vmbus_connection.monitor_pages[1] = NULL;
++      }
+ }
+ /*
+-- 
+2.39.5
+
diff --git a/queue-6.1/drivers-hv-vmbus-remove-second-mapping-of-vmbus-moni.patch b/queue-6.1/drivers-hv-vmbus-remove-second-mapping-of-vmbus-moni.patch
new file mode 100644 (file)
index 0000000..35104c8
--- /dev/null
@@ -0,0 +1,193 @@
+From 7dcf90097793ec1eb2b6935efadbd414c89249a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 26 Mar 2023 06:52:03 -0700
+Subject: Drivers: hv: vmbus: Remove second mapping of VMBus monitor pages
+
+From: Michael Kelley <mikelley@microsoft.com>
+
+[ Upstream commit a5ddb74588213c31ce993a8e9a09d1ffdc11a142 ]
+
+With changes to how Hyper-V guest VMs flip memory between private
+(encrypted) and shared (decrypted), creating a second kernel virtual
+mapping for shared memory is no longer necessary.  Everything needed
+for the transition to shared is handled by set_memory_decrypted().
+
+As such, remove the code to create and manage the second
+mapping for VMBus monitor pages. Because set_memory_decrypted()
+and set_memory_encrypted() are no-ops in normal VMs, it's
+not even necessary to test for being in a Confidential VM
+(a.k.a., "Isolation VM").
+
+Signed-off-by: Michael Kelley <mikelley@microsoft.com>
+Reviewed-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
+Link: https://lore.kernel.org/r/1679838727-87310-9-git-send-email-mikelley@microsoft.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Stable-dep-of: 09eea7ad0b8e ("Drivers: hv: Allocate interrupt and monitor pages aligned to system page boundary")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/connection.c   | 113 ++++++++++----------------------------
+ drivers/hv/hyperv_vmbus.h |   2 -
+ 2 files changed, 28 insertions(+), 87 deletions(-)
+
+diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
+index da51b50787dff..5978e9dbc286f 100644
+--- a/drivers/hv/connection.c
++++ b/drivers/hv/connection.c
+@@ -104,8 +104,14 @@ int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version)
+               vmbus_connection.msg_conn_id = VMBUS_MESSAGE_CONNECTION_ID;
+       }
+-      msg->monitor_page1 = vmbus_connection.monitor_pages_pa[0];
+-      msg->monitor_page2 = vmbus_connection.monitor_pages_pa[1];
++      /*
++       * shared_gpa_boundary is zero in non-SNP VMs, so it's safe to always
++       * bitwise OR it
++       */
++      msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]) |
++                              ms_hyperv.shared_gpa_boundary;
++      msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]) |
++                              ms_hyperv.shared_gpa_boundary;
+       msg->target_vcpu = hv_cpu_number_to_vp_number(VMBUS_CONNECT_CPU);
+@@ -219,72 +225,27 @@ int vmbus_connect(void)
+        * Setup the monitor notification facility. The 1st page for
+        * parent->child and the 2nd page for child->parent
+        */
+-      vmbus_connection.monitor_pages[0] = (void *)hv_alloc_hyperv_zeroed_page();
+-      vmbus_connection.monitor_pages[1] = (void *)hv_alloc_hyperv_zeroed_page();
++      vmbus_connection.monitor_pages[0] = (void *)hv_alloc_hyperv_page();
++      vmbus_connection.monitor_pages[1] = (void *)hv_alloc_hyperv_page();
+       if ((vmbus_connection.monitor_pages[0] == NULL) ||
+           (vmbus_connection.monitor_pages[1] == NULL)) {
+               ret = -ENOMEM;
+               goto cleanup;
+       }
+-      vmbus_connection.monitor_pages_original[0]
+-              = vmbus_connection.monitor_pages[0];
+-      vmbus_connection.monitor_pages_original[1]
+-              = vmbus_connection.monitor_pages[1];
+-      vmbus_connection.monitor_pages_pa[0]
+-              = virt_to_phys(vmbus_connection.monitor_pages[0]);
+-      vmbus_connection.monitor_pages_pa[1]
+-              = virt_to_phys(vmbus_connection.monitor_pages[1]);
+-
+-      if (hv_is_isolation_supported()) {
+-              ret = set_memory_decrypted((unsigned long)
+-                                         vmbus_connection.monitor_pages[0],
+-                                         1);
+-              ret |= set_memory_decrypted((unsigned long)
+-                                          vmbus_connection.monitor_pages[1],
+-                                          1);
+-              if (ret)
+-                      goto cleanup;
+-
+-              /*
+-               * Isolation VM with AMD SNP needs to access monitor page via
+-               * address space above shared gpa boundary.
+-               */
+-              if (hv_isolation_type_snp()) {
+-                      vmbus_connection.monitor_pages_pa[0] +=
+-                              ms_hyperv.shared_gpa_boundary;
+-                      vmbus_connection.monitor_pages_pa[1] +=
+-                              ms_hyperv.shared_gpa_boundary;
+-
+-                      vmbus_connection.monitor_pages[0]
+-                              = memremap(vmbus_connection.monitor_pages_pa[0],
+-                                         HV_HYP_PAGE_SIZE,
+-                                         MEMREMAP_WB);
+-                      if (!vmbus_connection.monitor_pages[0]) {
+-                              ret = -ENOMEM;
+-                              goto cleanup;
+-                      }
+-
+-                      vmbus_connection.monitor_pages[1]
+-                              = memremap(vmbus_connection.monitor_pages_pa[1],
+-                                         HV_HYP_PAGE_SIZE,
+-                                         MEMREMAP_WB);
+-                      if (!vmbus_connection.monitor_pages[1]) {
+-                              ret = -ENOMEM;
+-                              goto cleanup;
+-                      }
+-              }
+-
+-              /*
+-               * Set memory host visibility hvcall smears memory
+-               * and so zero monitor pages here.
+-               */
+-              memset(vmbus_connection.monitor_pages[0], 0x00,
+-                     HV_HYP_PAGE_SIZE);
+-              memset(vmbus_connection.monitor_pages[1], 0x00,
+-                     HV_HYP_PAGE_SIZE);
++      ret = set_memory_decrypted((unsigned long)
++                              vmbus_connection.monitor_pages[0], 1);
++      ret |= set_memory_decrypted((unsigned long)
++                              vmbus_connection.monitor_pages[1], 1);
++      if (ret)
++              goto cleanup;
+-      }
++      /*
++       * Set_memory_decrypted() will change the memory contents if
++       * decryption occurs, so zero monitor pages here.
++       */
++      memset(vmbus_connection.monitor_pages[0], 0x00, HV_HYP_PAGE_SIZE);
++      memset(vmbus_connection.monitor_pages[1], 0x00, HV_HYP_PAGE_SIZE);
+       msginfo = kzalloc(sizeof(*msginfo) +
+                         sizeof(struct vmbus_channel_initiate_contact),
+@@ -376,31 +337,13 @@ void vmbus_disconnect(void)
+               vmbus_connection.int_page = NULL;
+       }
+-      if (hv_is_isolation_supported()) {
+-              /*
+-               * memunmap() checks input address is ioremap address or not
+-               * inside. It doesn't unmap any thing in the non-SNP CVM and
+-               * so not check CVM type here.
+-               */
+-              memunmap(vmbus_connection.monitor_pages[0]);
+-              memunmap(vmbus_connection.monitor_pages[1]);
+-
+-              set_memory_encrypted((unsigned long)
+-                      vmbus_connection.monitor_pages_original[0],
+-                      1);
+-              set_memory_encrypted((unsigned long)
+-                      vmbus_connection.monitor_pages_original[1],
+-                      1);
+-      }
++      set_memory_encrypted((unsigned long)vmbus_connection.monitor_pages[0], 1);
++      set_memory_encrypted((unsigned long)vmbus_connection.monitor_pages[1], 1);
+-      hv_free_hyperv_page((unsigned long)
+-              vmbus_connection.monitor_pages_original[0]);
+-      hv_free_hyperv_page((unsigned long)
+-              vmbus_connection.monitor_pages_original[1]);
+-      vmbus_connection.monitor_pages_original[0] =
+-              vmbus_connection.monitor_pages[0] = NULL;
+-      vmbus_connection.monitor_pages_original[1] =
+-              vmbus_connection.monitor_pages[1] = NULL;
++      hv_free_hyperv_page((unsigned long)vmbus_connection.monitor_pages[0]);
++      hv_free_hyperv_page((unsigned long)vmbus_connection.monitor_pages[1]);
++      vmbus_connection.monitor_pages[0] = NULL;
++      vmbus_connection.monitor_pages[1] = NULL;
+ }
+ /*
+diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
+index ab12e21bf5fc7..4cff3997c3ccd 100644
+--- a/drivers/hv/hyperv_vmbus.h
++++ b/drivers/hv/hyperv_vmbus.h
+@@ -241,8 +241,6 @@ struct vmbus_connection {
+        * is child->parent notification
+        */
+       struct hv_monitor_page *monitor_pages[2];
+-      void *monitor_pages_original[2];
+-      phys_addr_t monitor_pages_pa[2];
+       struct list_head chn_msg_list;
+       spinlock_t channelmsg_lock;
+-- 
+2.39.5
+
diff --git a/queue-6.1/drm-i915-gem-allow-exec_capture-on-recoverable-conte.patch b/queue-6.1/drm-i915-gem-allow-exec_capture-on-recoverable-conte.patch
new file mode 100644 (file)
index 0000000..1e3546a
--- /dev/null
@@ -0,0 +1,52 @@
+From ec5042528c46add45ea46642ec09d41b4b939cda Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 May 2025 21:22:15 +0200
+Subject: drm/i915/gem: Allow EXEC_CAPTURE on recoverable contexts on DG1
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+
+[ Upstream commit 25eeba495b2fc16037647c1a51bcdf6fc157af5c ]
+
+The intel-media-driver is currently broken on DG1 because
+it uses EXEC_CAPTURE with recovarable contexts. Relax the
+check to allow that.
+
+I've also submitted a fix for the intel-media-driver:
+https://github.com/intel/media-driver/pull/1920
+
+Cc: stable@vger.kernel.org # v6.0+
+Cc: Matthew Auld <matthew.auld@intel.com>
+Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Testcase: igt/gem_exec_capture/capture-invisible
+Fixes: 71b1669ea9bd ("drm/i915/uapi: tweak error capture on recoverable contexts")
+Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
+Link: https://lore.kernel.org/r/20250411144313.11660-2-ville.syrjala@linux.intel.com
+(cherry picked from commit d6e020819612a4a06207af858e0978be4d3e3140)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Stable-dep-of: ed5915cfce2a ("Revert "drm/i915/gem: Allow EXEC_CAPTURE on recoverable contexts on DG1"")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+index 0a123bb44c9fb..9424606710a10 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+@@ -2001,7 +2001,7 @@ static int eb_capture_stage(struct i915_execbuffer *eb)
+                       continue;
+               if (i915_gem_context_is_recoverable(eb->gem_context) &&
+-                  (IS_DGFX(eb->i915) || GRAPHICS_VER_FULL(eb->i915) > IP_VER(12, 0)))
++                  GRAPHICS_VER_FULL(eb->i915) > IP_VER(12, 10))
+                       return -EINVAL;
+               for_each_batch_create_order(eb, j) {
+-- 
+2.39.5
+
diff --git a/queue-6.1/dummycon-trigger-redraw-when-switching-consoles-with.patch b/queue-6.1/dummycon-trigger-redraw-when-switching-consoles-with.patch
new file mode 100644 (file)
index 0000000..1739930
--- /dev/null
@@ -0,0 +1,96 @@
+From 85e1daec8908010338e753b5dc54fd1c54d3ed52 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 May 2025 09:14:00 +0200
+Subject: dummycon: Trigger redraw when switching consoles with deferred
+ takeover
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit 03bcbbb3995ba5df43af9aba45334e35f2dfe27b ]
+
+Signal vt subsystem to redraw console when switching to dummycon
+with deferred takeover enabled. Makes the console switch to fbcon
+and displays the available output.
+
+With deferred takeover enabled, dummycon acts as the placeholder
+until the first output to the console happens. At that point, fbcon
+takes over. If the output happens while dummycon is not active, it
+cannot inform fbcon. This is the case if the vt subsystem runs in
+graphics mode.
+
+A typical graphical boot starts plymouth, a display manager and a
+compositor; all while leaving out dummycon. Switching to a text-mode
+console leaves the console with dummycon even if a getty terminal
+has been started.
+
+Returning true from dummycon's con_switch helper signals the vt
+subsystem to redraw the screen. If there's output available dummycon's
+con_putc{s} helpers trigger deferred takeover of fbcon, which sets a
+display mode and displays the output. If no output is available,
+dummycon remains active.
+
+v2:
+- make the comment slightly more verbose (Javier)
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Reported-by: Andrei Borzenkov <arvidjaar@gmail.com>
+Closes: https://bugzilla.suse.com/show_bug.cgi?id=1242191
+Tested-by: Andrei Borzenkov <arvidjaar@gmail.com>
+Acked-by: Javier Martinez Canillas <javierm@redhat.com>
+Fixes: 83d83bebf401 ("console/fbcon: Add support for deferred console takeover")
+Cc: Hans de Goede <hdegoede@redhat.com>
+Cc: linux-fbdev@vger.kernel.org
+Cc: dri-devel@lists.freedesktop.org
+Cc: <stable@vger.kernel.org> # v4.19+
+Link: https://lore.kernel.org/r/20250520071418.8462-1-tzimmermann@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/console/dummycon.c | 18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c
+index d701f2b51f5b1..d99e1b3e4e5c1 100644
+--- a/drivers/video/console/dummycon.c
++++ b/drivers/video/console/dummycon.c
+@@ -82,6 +82,15 @@ static int dummycon_blank(struct vc_data *vc, int blank, int mode_switch)
+       /* Redraw, so that we get putc(s) for output done while blanked */
+       return 1;
+ }
++
++static bool dummycon_switch(struct vc_data *vc)
++{
++      /*
++       * Redraw, so that we get putc(s) for output done while switched
++       * away. Informs deferred consoles to take over the display.
++       */
++      return true;
++}
+ #else
+ static void dummycon_putc(struct vc_data *vc, int c, int ypos, int xpos) { }
+ static void dummycon_putcs(struct vc_data *vc, const unsigned short *s,
+@@ -90,6 +99,10 @@ static int dummycon_blank(struct vc_data *vc, int blank, int mode_switch)
+ {
+       return 0;
+ }
++static bool dummycon_switch(struct vc_data *vc)
++{
++      return false;
++}
+ #endif
+ static const char *dummycon_startup(void)
+@@ -119,11 +132,6 @@ static bool dummycon_scroll(struct vc_data *vc, unsigned int top,
+       return false;
+ }
+-static bool dummycon_switch(struct vc_data *vc)
+-{
+-      return false;
+-}
+-
+ /*
+  *  The console `switch' structure for the dummy console
+  *
+-- 
+2.39.5
+
diff --git a/queue-6.1/f2fs-don-t-over-report-free-space-or-inodes-in-statv.patch b/queue-6.1/f2fs-don-t-over-report-free-space-or-inodes-in-statv.patch
new file mode 100644 (file)
index 0000000..9b96bfe
--- /dev/null
@@ -0,0 +1,99 @@
+From 37918177736e2f021b34de305d9dd58901a92ada Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 May 2025 19:25:38 +0800
+Subject: f2fs: don't over-report free space or inodes in statvfs
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit a9201960623287927bf5776de3f70fb2fbde7e02 ]
+
+This fixes an analogus bug that was fixed in modern filesystems:
+a) xfs in commit 4b8d867ca6e2 ("xfs: don't over-report free space or
+inodes in statvfs")
+b) ext4 in commit f87d3af74193 ("ext4: don't over-report free space
+or inodes in statvfs")
+where statfs can report misleading / incorrect information where
+project quota is enabled, and the free space is less than the
+remaining quota.
+
+This commit will resolve a test failure in generic/762 which tests
+for this bug.
+
+generic/762       - output mismatch (see /share/git/fstests/results//generic/762.out.bad)
+    --- tests/generic/762.out   2025-04-15 10:21:53.371067071 +0800
+    +++ /share/git/fstests/results//generic/762.out.bad 2025-05-13 16:13:37.000000000 +0800
+    @@ -6,8 +6,10 @@
+     root blocks2 is in range
+     dir blocks2 is in range
+     root bavail2 is in range
+    -dir bavail2 is in range
+    +dir bavail2 has value of 1539066
+    +dir bavail2 is NOT in range 304734.87 .. 310891.13
+     root blocks3 is in range
+    ...
+    (Run 'diff -u /share/git/fstests/tests/generic/762.out /share/git/fstests/results//generic/762.out.bad'  to see the entire diff)
+
+HINT: You _MAY_ be missing kernel fix:
+      XXXXXXXXXXXXXX xfs: don't over-report free space or inodes in statvfs
+
+Cc: stable@kernel.org
+Fixes: ddc34e328d06 ("f2fs: introduce f2fs_statfs_project")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/super.c | 30 ++++++++++++++++++------------
+ 1 file changed, 18 insertions(+), 12 deletions(-)
+
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index f415bc073bb52..84fc6591e3f98 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -1753,26 +1753,32 @@ static int f2fs_statfs_project(struct super_block *sb,
+       limit = min_not_zero(dquot->dq_dqb.dqb_bsoftlimit,
+                                       dquot->dq_dqb.dqb_bhardlimit);
+-      if (limit)
+-              limit >>= sb->s_blocksize_bits;
++      limit >>= sb->s_blocksize_bits;
++
++      if (limit) {
++              uint64_t remaining = 0;
+-      if (limit && buf->f_blocks > limit) {
+               curblock = (dquot->dq_dqb.dqb_curspace +
+                           dquot->dq_dqb.dqb_rsvspace) >> sb->s_blocksize_bits;
+-              buf->f_blocks = limit;
+-              buf->f_bfree = buf->f_bavail =
+-                      (buf->f_blocks > curblock) ?
+-                       (buf->f_blocks - curblock) : 0;
++              if (limit > curblock)
++                      remaining = limit - curblock;
++
++              buf->f_blocks = min(buf->f_blocks, limit);
++              buf->f_bfree = min(buf->f_bfree, remaining);
++              buf->f_bavail = min(buf->f_bavail, remaining);
+       }
+       limit = min_not_zero(dquot->dq_dqb.dqb_isoftlimit,
+                                       dquot->dq_dqb.dqb_ihardlimit);
+-      if (limit && buf->f_files > limit) {
+-              buf->f_files = limit;
+-              buf->f_ffree =
+-                      (buf->f_files > dquot->dq_dqb.dqb_curinodes) ?
+-                       (buf->f_files - dquot->dq_dqb.dqb_curinodes) : 0;
++      if (limit) {
++              uint64_t remaining = 0;
++
++              if (limit > dquot->dq_dqb.dqb_curinodes)
++                      remaining = limit - dquot->dq_dqb.dqb_curinodes;
++
++              buf->f_files = min(buf->f_files, limit);
++              buf->f_ffree = min(buf->f_ffree, remaining);
+       }
+       spin_unlock(&dquot->dq_dqb_lock);
+-- 
+2.39.5
+
diff --git a/queue-6.1/fbdev-fix-do_register_framebuffer-to-prevent-null-pt.patch b/queue-6.1/fbdev-fix-do_register_framebuffer-to-prevent-null-pt.patch
new file mode 100644 (file)
index 0000000..6121c1a
--- /dev/null
@@ -0,0 +1,112 @@
+From d3b339f04188f7f1441b39705c2d83ef2539fa91 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 18:34:06 +0300
+Subject: fbdev: Fix do_register_framebuffer to prevent null-ptr-deref in
+ fb_videomode_to_var
+
+From: Murad Masimov <m.masimov@mt-integration.ru>
+
+[ Upstream commit 17186f1f90d34fa701e4f14e6818305151637b9e ]
+
+If fb_add_videomode() in do_register_framebuffer() fails to allocate
+memory for fb_videomode, it will later lead to a null-ptr dereference in
+fb_videomode_to_var(), as the fb_info is registered while not having the
+mode in modelist that is expected to be there, i.e. the one that is
+described in fb_info->var.
+
+================================================================
+general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] PREEMPT SMP KASAN NOPTI
+KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
+CPU: 1 PID: 30371 Comm: syz-executor.1 Not tainted 5.10.226-syzkaller #0
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
+RIP: 0010:fb_videomode_to_var+0x24/0x610 drivers/video/fbdev/core/modedb.c:901
+Call Trace:
+ display_to_var+0x3a/0x7c0 drivers/video/fbdev/core/fbcon.c:929
+ fbcon_resize+0x3e2/0x8f0 drivers/video/fbdev/core/fbcon.c:2071
+ resize_screen drivers/tty/vt/vt.c:1176 [inline]
+ vc_do_resize+0x53a/0x1170 drivers/tty/vt/vt.c:1263
+ fbcon_modechanged+0x3ac/0x6e0 drivers/video/fbdev/core/fbcon.c:2720
+ fbcon_update_vcs+0x43/0x60 drivers/video/fbdev/core/fbcon.c:2776
+ do_fb_ioctl+0x6d2/0x740 drivers/video/fbdev/core/fbmem.c:1128
+ fb_ioctl+0xe7/0x150 drivers/video/fbdev/core/fbmem.c:1203
+ vfs_ioctl fs/ioctl.c:48 [inline]
+ __do_sys_ioctl fs/ioctl.c:753 [inline]
+ __se_sys_ioctl fs/ioctl.c:739 [inline]
+ __x64_sys_ioctl+0x19a/0x210 fs/ioctl.c:739
+ do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46
+ entry_SYSCALL_64_after_hwframe+0x67/0xd1
+================================================================
+
+Even though fbcon_init() checks beforehand if fb_match_mode() in
+var_to_display() fails, it can not prevent the panic because fbcon_init()
+does not return error code. Considering this and the comment in the code
+about fb_match_mode() returning NULL - "This should not happen" - it is
+better to prevent registering the fb_info if its mode was not set
+successfully. Also move fb_add_videomode() closer to the beginning of
+do_register_framebuffer() to avoid having to do the cleanup on fail.
+
+Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Murad Masimov <m.masimov@mt-integration.ru>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/core/fbmem.c | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
+index 7355a299cdb5f..f8c32c58b5b2c 100644
+--- a/drivers/video/fbdev/core/fbmem.c
++++ b/drivers/video/fbdev/core/fbmem.c
+@@ -1536,7 +1536,7 @@ static int fb_check_foreignness(struct fb_info *fi)
+ static int do_register_framebuffer(struct fb_info *fb_info)
+ {
+-      int i;
++      int i, err = 0;
+       struct fb_videomode mode;
+       if (fb_check_foreignness(fb_info))
+@@ -1545,10 +1545,18 @@ static int do_register_framebuffer(struct fb_info *fb_info)
+       if (num_registered_fb == FB_MAX)
+               return -ENXIO;
+-      num_registered_fb++;
+       for (i = 0 ; i < FB_MAX; i++)
+               if (!registered_fb[i])
+                       break;
++
++      if (!fb_info->modelist.prev || !fb_info->modelist.next)
++              INIT_LIST_HEAD(&fb_info->modelist);
++
++      fb_var_to_videomode(&mode, &fb_info->var);
++      err = fb_add_videomode(&mode, &fb_info->modelist);
++      if (err < 0)
++              return err;
++
+       fb_info->node = i;
+       refcount_set(&fb_info->count, 1);
+       mutex_init(&fb_info->lock);
+@@ -1581,16 +1589,12 @@ static int do_register_framebuffer(struct fb_info *fb_info)
+       if (!fb_info->pixmap.blit_y)
+               fb_info->pixmap.blit_y = ~(u32)0;
+-      if (!fb_info->modelist.prev || !fb_info->modelist.next)
+-              INIT_LIST_HEAD(&fb_info->modelist);
+-
+       if (fb_info->skip_vt_switch)
+               pm_vt_switch_required(fb_info->dev, false);
+       else
+               pm_vt_switch_required(fb_info->dev, true);
+-      fb_var_to_videomode(&mode, &fb_info->var);
+-      fb_add_videomode(&mode, &fb_info->modelist);
++      num_registered_fb++;
+       registered_fb[i] = fb_info;
+ #ifdef CONFIG_GUMSTIX_AM200EPD
+-- 
+2.39.5
+
diff --git a/queue-6.1/fs-jfs-consolidate-sanity-checking-in-dbmount.patch b/queue-6.1/fs-jfs-consolidate-sanity-checking-in-dbmount.patch
new file mode 100644 (file)
index 0000000..f9e7ee4
--- /dev/null
@@ -0,0 +1,81 @@
+From 66b597079108b4a12e945e4b9ed8c6740e7bdb07 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Feb 2025 10:31:19 -0600
+Subject: fs/jfs: consolidate sanity checking in dbMount
+
+From: Dave Kleikamp <dave.kleikamp@oracle.com>
+
+[ Upstream commit 0d250b1c52484d489e31df2cf9118b7c4bd49d31 ]
+
+Sanity checks have been added to dbMount as individual if clauses with
+identical error handling. Move these all into one clause.
+
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Stable-dep-of: 37bfb464ddca ("jfs: validate AG parameters in dbMount() to prevent crashes")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jfs/jfs_dmap.c | 37 +++++++++----------------------------
+ 1 file changed, 9 insertions(+), 28 deletions(-)
+
+diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
+index 5e32526174e88..621f0d871af67 100644
+--- a/fs/jfs/jfs_dmap.c
++++ b/fs/jfs/jfs_dmap.c
+@@ -178,45 +178,26 @@ int dbMount(struct inode *ipbmap)
+       dbmp_le = (struct dbmap_disk *) mp->data;
+       bmp->db_mapsize = le64_to_cpu(dbmp_le->dn_mapsize);
+       bmp->db_nfree = le64_to_cpu(dbmp_le->dn_nfree);
+-
+       bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage);
+-      if (bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE ||
+-              bmp->db_l2nbperpage < 0) {
+-              err = -EINVAL;
+-              goto err_release_metapage;
+-      }
+-
+       bmp->db_numag = le32_to_cpu(dbmp_le->dn_numag);
+-      if (!bmp->db_numag || bmp->db_numag > MAXAG) {
+-              err = -EINVAL;
+-              goto err_release_metapage;
+-      }
+-
+       bmp->db_maxlevel = le32_to_cpu(dbmp_le->dn_maxlevel);
+       bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag);
+       bmp->db_agpref = le32_to_cpu(dbmp_le->dn_agpref);
+-      if (bmp->db_maxag >= MAXAG || bmp->db_maxag < 0 ||
+-              bmp->db_agpref >= MAXAG || bmp->db_agpref < 0) {
+-              err = -EINVAL;
+-              goto err_release_metapage;
+-      }
+-
+       bmp->db_aglevel = le32_to_cpu(dbmp_le->dn_aglevel);
+       bmp->db_agheight = le32_to_cpu(dbmp_le->dn_agheight);
+       bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth);
+-      if (!bmp->db_agwidth) {
+-              err = -EINVAL;
+-              goto err_release_metapage;
+-      }
+       bmp->db_agstart = le32_to_cpu(dbmp_le->dn_agstart);
+       bmp->db_agl2size = le32_to_cpu(dbmp_le->dn_agl2size);
+-      if (bmp->db_agl2size > L2MAXL2SIZE - L2MAXAG ||
+-          bmp->db_agl2size < 0) {
+-              err = -EINVAL;
+-              goto err_release_metapage;
+-      }
+-      if (((bmp->db_mapsize - 1) >> bmp->db_agl2size) > MAXAG) {
++      if ((bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE) ||
++          (bmp->db_l2nbperpage < 0) ||
++          !bmp->db_numag || (bmp->db_numag > MAXAG) ||
++          (bmp->db_maxag >= MAXAG) || (bmp->db_maxag < 0) ||
++          (bmp->db_agpref >= MAXAG) || (bmp->db_agpref < 0) ||
++          !bmp->db_agwidth ||
++          (bmp->db_agl2size > L2MAXL2SIZE - L2MAXAG) ||
++          (bmp->db_agl2size < 0) ||
++          ((bmp->db_mapsize - 1) >> bmp->db_agl2size) > MAXAG) {
+               err = -EINVAL;
+               goto err_release_metapage;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.1/hwmon-pmbus-max34440-fix-support-for-max34451.patch b/queue-6.1/hwmon-pmbus-max34440-fix-support-for-max34451.patch
new file mode 100644 (file)
index 0000000..f47bc89
--- /dev/null
@@ -0,0 +1,144 @@
+From 482e2294c981f29459f6af17a7f2277b43b8c7e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 11:47:24 +0800
+Subject: hwmon: (pmbus/max34440) Fix support for max34451
+
+From: Alexis Czezar Torreno <alexisczezar.torreno@analog.com>
+
+[ Upstream commit 19932f844f3f51646f762f3eac4744ec3a405064 ]
+
+The max344** family has an issue with some PMBUS address being switched.
+This includes max34451 however version MAX34451-NA6 and later has this
+issue fixed and this commit supports that update.
+
+Signed-off-by: Alexis Czezar Torreno <alexisczezar.torreno@analog.com>
+Link: https://lore.kernel.org/r/20250407-dev_adpm12160-v3-1-9cd3095445c8@analog.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/pmbus/max34440.c | 48 +++++++++++++++++++++++++++++++---
+ 1 file changed, 44 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/hwmon/pmbus/max34440.c b/drivers/hwmon/pmbus/max34440.c
+index ea7609058a12f..91359647d1e78 100644
+--- a/drivers/hwmon/pmbus/max34440.c
++++ b/drivers/hwmon/pmbus/max34440.c
+@@ -34,16 +34,21 @@ enum chips { max34440, max34441, max34446, max34451, max34460, max34461 };
+ /*
+  * The whole max344* family have IOUT_OC_WARN_LIMIT and IOUT_OC_FAULT_LIMIT
+  * swapped from the standard pmbus spec addresses.
++ * For max34451, version MAX34451ETNA6+ and later has this issue fixed.
+  */
+ #define MAX34440_IOUT_OC_WARN_LIMIT   0x46
+ #define MAX34440_IOUT_OC_FAULT_LIMIT  0x4A
++#define MAX34451ETNA6_MFR_REV         0x0012
++
+ #define MAX34451_MFR_CHANNEL_CONFIG   0xe4
+ #define MAX34451_MFR_CHANNEL_CONFIG_SEL_MASK  0x3f
+ struct max34440_data {
+       int id;
+       struct pmbus_driver_info info;
++      u8 iout_oc_warn_limit;
++      u8 iout_oc_fault_limit;
+ };
+ #define to_max34440_data(x)  container_of(x, struct max34440_data, info)
+@@ -60,11 +65,11 @@ static int max34440_read_word_data(struct i2c_client *client, int page,
+       switch (reg) {
+       case PMBUS_IOUT_OC_FAULT_LIMIT:
+               ret = pmbus_read_word_data(client, page, phase,
+-                                         MAX34440_IOUT_OC_FAULT_LIMIT);
++                                         data->iout_oc_fault_limit);
+               break;
+       case PMBUS_IOUT_OC_WARN_LIMIT:
+               ret = pmbus_read_word_data(client, page, phase,
+-                                         MAX34440_IOUT_OC_WARN_LIMIT);
++                                         data->iout_oc_warn_limit);
+               break;
+       case PMBUS_VIRT_READ_VOUT_MIN:
+               ret = pmbus_read_word_data(client, page, phase,
+@@ -133,11 +138,11 @@ static int max34440_write_word_data(struct i2c_client *client, int page,
+       switch (reg) {
+       case PMBUS_IOUT_OC_FAULT_LIMIT:
+-              ret = pmbus_write_word_data(client, page, MAX34440_IOUT_OC_FAULT_LIMIT,
++              ret = pmbus_write_word_data(client, page, data->iout_oc_fault_limit,
+                                           word);
+               break;
+       case PMBUS_IOUT_OC_WARN_LIMIT:
+-              ret = pmbus_write_word_data(client, page, MAX34440_IOUT_OC_WARN_LIMIT,
++              ret = pmbus_write_word_data(client, page, data->iout_oc_warn_limit,
+                                           word);
+               break;
+       case PMBUS_VIRT_RESET_POUT_HISTORY:
+@@ -235,6 +240,25 @@ static int max34451_set_supported_funcs(struct i2c_client *client,
+        */
+       int page, rv;
++      bool max34451_na6 = false;
++
++      rv = i2c_smbus_read_word_data(client, PMBUS_MFR_REVISION);
++      if (rv < 0)
++              return rv;
++
++      if (rv >= MAX34451ETNA6_MFR_REV) {
++              max34451_na6 = true;
++              data->info.format[PSC_VOLTAGE_IN] = direct;
++              data->info.format[PSC_CURRENT_IN] = direct;
++              data->info.m[PSC_VOLTAGE_IN] = 1;
++              data->info.b[PSC_VOLTAGE_IN] = 0;
++              data->info.R[PSC_VOLTAGE_IN] = 3;
++              data->info.m[PSC_CURRENT_IN] = 1;
++              data->info.b[PSC_CURRENT_IN] = 0;
++              data->info.R[PSC_CURRENT_IN] = 2;
++              data->iout_oc_fault_limit = PMBUS_IOUT_OC_FAULT_LIMIT;
++              data->iout_oc_warn_limit = PMBUS_IOUT_OC_WARN_LIMIT;
++      }
+       for (page = 0; page < 16; page++) {
+               rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
+@@ -251,16 +275,30 @@ static int max34451_set_supported_funcs(struct i2c_client *client,
+               case 0x20:
+                       data->info.func[page] = PMBUS_HAVE_VOUT |
+                               PMBUS_HAVE_STATUS_VOUT;
++
++                      if (max34451_na6)
++                              data->info.func[page] |= PMBUS_HAVE_VIN |
++                                      PMBUS_HAVE_STATUS_INPUT;
+                       break;
+               case 0x21:
+                       data->info.func[page] = PMBUS_HAVE_VOUT;
++
++                      if (max34451_na6)
++                              data->info.func[page] |= PMBUS_HAVE_VIN;
+                       break;
+               case 0x22:
+                       data->info.func[page] = PMBUS_HAVE_IOUT |
+                               PMBUS_HAVE_STATUS_IOUT;
++
++                      if (max34451_na6)
++                              data->info.func[page] |= PMBUS_HAVE_IIN |
++                                      PMBUS_HAVE_STATUS_INPUT;
+                       break;
+               case 0x23:
+                       data->info.func[page] = PMBUS_HAVE_IOUT;
++
++                      if (max34451_na6)
++                              data->info.func[page] |= PMBUS_HAVE_IIN;
+                       break;
+               default:
+                       break;
+@@ -494,6 +532,8 @@ static int max34440_probe(struct i2c_client *client)
+               return -ENOMEM;
+       data->id = i2c_match_id(max34440_id, client)->driver_data;
+       data->info = max34440_info[data->id];
++      data->iout_oc_fault_limit = MAX34440_IOUT_OC_FAULT_LIMIT;
++      data->iout_oc_warn_limit = MAX34440_IOUT_OC_WARN_LIMIT;
+       if (data->id == max34451) {
+               rv = max34451_set_supported_funcs(client, data);
+-- 
+2.39.5
+
diff --git a/queue-6.1/iio-adc-ad_sigma_delta-fix-use-of-uninitialized-stat.patch b/queue-6.1/iio-adc-ad_sigma_delta-fix-use-of-uninitialized-stat.patch
new file mode 100644 (file)
index 0000000..1962e1b
--- /dev/null
@@ -0,0 +1,47 @@
+From 930bdabf86692e4a0547eac08e70ea0470f9f730 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 22:34:08 +0530
+Subject: iio: adc: ad_sigma_delta: Fix use of uninitialized status_pos
+
+From: Purva Yeshi <purvayeshi550@gmail.com>
+
+[ Upstream commit e5cdb098a3cb165d52282ffc3a6448642953ea13 ]
+
+Fix Smatch-detected issue:
+drivers/iio/adc/ad_sigma_delta.c:604 ad_sd_trigger_handler() error:
+uninitialized symbol 'status_pos'.
+
+The variable `status_pos` was only initialized in specific switch cases
+(1, 2, 3, 4), which could leave it uninitialized if `reg_size` had an
+unexpected value.
+
+Fix by adding a default case to the switch block to catch unexpected
+values of `reg_size`. Use `dev_err_ratelimited()` for error logging and
+`goto irq_handled` instead of returning early.
+
+Signed-off-by: Purva Yeshi <purvayeshi550@gmail.com>
+Link: https://patch.msgid.link/20250410170408.8585-1-purvayeshi550@gmail.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad_sigma_delta.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c
+index 7e21928707437..533667eefe419 100644
+--- a/drivers/iio/adc/ad_sigma_delta.c
++++ b/drivers/iio/adc/ad_sigma_delta.c
+@@ -476,6 +476,10 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
+                * byte set to zero. */
+               ad_sd_read_reg_raw(sigma_delta, data_reg, transfer_size, &data[1]);
+               break;
++
++      default:
++              dev_err_ratelimited(&indio_dev->dev, "Unsupported reg_size: %u\n", reg_size);
++              goto irq_handled;
+       }
+       /*
+-- 
+2.39.5
+
diff --git a/queue-6.1/iio-pressure-zpa2326-use-aligned_s64-for-the-timesta.patch b/queue-6.1/iio-pressure-zpa2326-use-aligned_s64-for-the-timesta.patch
new file mode 100644 (file)
index 0000000..93e7e39
--- /dev/null
@@ -0,0 +1,36 @@
+From 07d97bcc3862faa5c844ef350c8f236b52044f0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Apr 2025 11:34:41 +0100
+Subject: iio: pressure: zpa2326: Use aligned_s64 for the timestamp
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 886a446b76afddfad307488e95e87f23a08ffd51 ]
+
+On x86_32 s64 fields are only 32-bit aligned.  Hence force the alignment of
+the field and padding in the structure by using aligned_s64 instead.
+
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Link: https://patch.msgid.link/20250413103443.2420727-19-jic23@kernel.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/pressure/zpa2326.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c
+index fdb1b765206bc..7f352a79c1a55 100644
+--- a/drivers/iio/pressure/zpa2326.c
++++ b/drivers/iio/pressure/zpa2326.c
+@@ -582,7 +582,7 @@ static int zpa2326_fill_sample_buffer(struct iio_dev               *indio_dev,
+       struct {
+               u32 pressure;
+               u16 temperature;
+-              u64 timestamp;
++              aligned_s64 timestamp;
+       }   sample;
+       int err;
+-- 
+2.39.5
+
diff --git a/queue-6.1/jfs-validate-ag-parameters-in-dbmount-to-prevent-cra.patch b/queue-6.1/jfs-validate-ag-parameters-in-dbmount-to-prevent-cra.patch
new file mode 100644 (file)
index 0000000..2e80047
--- /dev/null
@@ -0,0 +1,78 @@
+From cc2ece8f2813c40f1471a6dd155a94e681860e9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Mar 2025 11:56:02 +0300
+Subject: jfs: validate AG parameters in dbMount() to prevent crashes
+
+From: Vasiliy Kovalev <kovalev@altlinux.org>
+
+[ Upstream commit 37bfb464ddca87f203071b5bd562cd91ddc0b40a ]
+
+Validate db_agheight, db_agwidth, and db_agstart in dbMount to catch
+corrupted metadata early and avoid undefined behavior in dbAllocAG.
+Limits are derived from L2LPERCTL, LPERCTL/MAXAG, and CTLTREESIZE:
+
+- agheight: 0 to L2LPERCTL/2 (0 to 5) ensures shift
+  (L2LPERCTL - 2*agheight) >= 0.
+- agwidth: 1 to min(LPERCTL/MAXAG, 2^(L2LPERCTL - 2*agheight))
+  ensures agperlev >= 1.
+  - Ranges: 1-8 (agheight 0-3), 1-4 (agheight 4), 1 (agheight 5).
+  - LPERCTL/MAXAG = 1024/128 = 8 limits leaves per AG;
+    2^(10 - 2*agheight) prevents division to 0.
+- agstart: 0 to CTLTREESIZE-1 - agwidth*(MAXAG-1) keeps ti within
+  stree (size 1365).
+  - Ranges: 0-1237 (agwidth 1), 0-348 (agwidth 8).
+
+UBSAN: shift-out-of-bounds in fs/jfs/jfs_dmap.c:1400:9
+shift exponent -335544310 is negative
+CPU: 0 UID: 0 PID: 5822 Comm: syz-executor130 Not tainted 6.14.0-rc5-syzkaller #0
+Hardware name: Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2025
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:94 [inline]
+ dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120
+ ubsan_epilogue lib/ubsan.c:231 [inline]
+ __ubsan_handle_shift_out_of_bounds+0x3c8/0x420 lib/ubsan.c:468
+ dbAllocAG+0x1087/0x10b0 fs/jfs/jfs_dmap.c:1400
+ dbDiscardAG+0x352/0xa20 fs/jfs/jfs_dmap.c:1613
+ jfs_ioc_trim+0x45a/0x6b0 fs/jfs/jfs_discard.c:105
+ jfs_ioctl+0x2cd/0x3e0 fs/jfs/ioctl.c:131
+ vfs_ioctl fs/ioctl.c:51 [inline]
+ __do_sys_ioctl fs/ioctl.c:906 [inline]
+ __se_sys_ioctl+0xf5/0x170 fs/ioctl.c:892
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
+
+Cc: stable@vger.kernel.org
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+fe8264911355151c487f@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=fe8264911355151c487f
+Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jfs/jfs_dmap.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
+index 621f0d871af67..32ae408ee6997 100644
+--- a/fs/jfs/jfs_dmap.c
++++ b/fs/jfs/jfs_dmap.c
+@@ -194,7 +194,11 @@ int dbMount(struct inode *ipbmap)
+           !bmp->db_numag || (bmp->db_numag > MAXAG) ||
+           (bmp->db_maxag >= MAXAG) || (bmp->db_maxag < 0) ||
+           (bmp->db_agpref >= MAXAG) || (bmp->db_agpref < 0) ||
+-          !bmp->db_agwidth ||
++          (bmp->db_agheight < 0) || (bmp->db_agheight > (L2LPERCTL >> 1)) ||
++          (bmp->db_agwidth < 1) || (bmp->db_agwidth > (LPERCTL / MAXAG)) ||
++          (bmp->db_agwidth > (1 << (L2LPERCTL - (bmp->db_agheight << 1)))) ||
++          (bmp->db_agstart < 0) ||
++          (bmp->db_agstart > (CTLTREESIZE - 1 - bmp->db_agwidth * (MAXAG - 1))) ||
+           (bmp->db_agl2size > L2MAXL2SIZE - L2MAXAG) ||
+           (bmp->db_agl2size < 0) ||
+           ((bmp->db_mapsize - 1) >> bmp->db_agl2size) > MAXAG) {
+-- 
+2.39.5
+
diff --git a/queue-6.1/ksmbd-allow-a-filename-to-contain-special-characters.patch b/queue-6.1/ksmbd-allow-a-filename-to-contain-special-characters.patch
new file mode 100644 (file)
index 0000000..f6f1225
--- /dev/null
@@ -0,0 +1,109 @@
+From f18fae62ac10e80d09b2f856b71f87f714d960be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 May 2025 11:23:01 +0900
+Subject: ksmbd: allow a filename to contain special characters on SMB3.1.1
+ posix extension
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+[ Upstream commit dc3e0f17f74558e8a2fce00608855f050de10230 ]
+
+If client send SMB2_CREATE_POSIX_CONTEXT to ksmbd, Allow a filename
+to contain special characters.
+
+Reported-by: Philipp Kerling <pkerling@casix.org>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/server/smb2pdu.c | 53 +++++++++++++++++++++--------------------
+ 1 file changed, 27 insertions(+), 26 deletions(-)
+
+diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
+index ca54ac7ff6ea5..2f18229ee33c9 100644
+--- a/fs/smb/server/smb2pdu.c
++++ b/fs/smb/server/smb2pdu.c
+@@ -2686,7 +2686,7 @@ int smb2_open(struct ksmbd_work *work)
+       int req_op_level = 0, open_flags = 0, may_flags = 0, file_info = 0;
+       int rc = 0;
+       int contxt_cnt = 0, query_disk_id = 0;
+-      int maximal_access_ctxt = 0, posix_ctxt = 0;
++      bool maximal_access_ctxt = false, posix_ctxt = false;
+       int s_type = 0;
+       int next_off = 0;
+       char *name = NULL;
+@@ -2713,6 +2713,27 @@ int smb2_open(struct ksmbd_work *work)
+               return create_smb2_pipe(work);
+       }
++      if (req->CreateContextsOffset && tcon->posix_extensions) {
++              context = smb2_find_context_vals(req, SMB2_CREATE_TAG_POSIX, 16);
++              if (IS_ERR(context)) {
++                      rc = PTR_ERR(context);
++                      goto err_out2;
++              } else if (context) {
++                      struct create_posix *posix = (struct create_posix *)context;
++
++                      if (le16_to_cpu(context->DataOffset) +
++                              le32_to_cpu(context->DataLength) <
++                          sizeof(struct create_posix) - 4) {
++                              rc = -EINVAL;
++                              goto err_out2;
++                      }
++                      ksmbd_debug(SMB, "get posix context\n");
++
++                      posix_mode = le32_to_cpu(posix->Mode);
++                      posix_ctxt = true;
++              }
++      }
++
+       if (req->NameLength) {
+               if ((req->CreateOptions & FILE_DIRECTORY_FILE_LE) &&
+                   *(char *)req->Buffer == '\\') {
+@@ -2744,9 +2765,11 @@ int smb2_open(struct ksmbd_work *work)
+                               goto err_out2;
+               }
+-              rc = ksmbd_validate_filename(name);
+-              if (rc < 0)
+-                      goto err_out2;
++              if (posix_ctxt == false) {
++                      rc = ksmbd_validate_filename(name);
++                      if (rc < 0)
++                              goto err_out2;
++              }
+               if (ksmbd_share_veto_filename(share, name)) {
+                       rc = -ENOENT;
+@@ -2861,28 +2884,6 @@ int smb2_open(struct ksmbd_work *work)
+                       rc = -EBADF;
+                       goto err_out2;
+               }
+-
+-              if (tcon->posix_extensions) {
+-                      context = smb2_find_context_vals(req,
+-                                                       SMB2_CREATE_TAG_POSIX, 16);
+-                      if (IS_ERR(context)) {
+-                              rc = PTR_ERR(context);
+-                              goto err_out2;
+-                      } else if (context) {
+-                              struct create_posix *posix =
+-                                      (struct create_posix *)context;
+-                              if (le16_to_cpu(context->DataOffset) +
+-                                  le32_to_cpu(context->DataLength) <
+-                                  sizeof(struct create_posix) - 4) {
+-                                      rc = -EINVAL;
+-                                      goto err_out2;
+-                              }
+-                              ksmbd_debug(SMB, "get posix context\n");
+-
+-                              posix_mode = le32_to_cpu(posix->Mode);
+-                              posix_ctxt = 1;
+-                      }
+-              }
+       }
+       if (ksmbd_override_fsids(work)) {
+-- 
+2.39.5
+
diff --git a/queue-6.1/leds-multicolor-fix-intensity-setting-while-sw-blink.patch b/queue-6.1/leds-multicolor-fix-intensity-setting-while-sw-blink.patch
new file mode 100644 (file)
index 0000000..2a8900d
--- /dev/null
@@ -0,0 +1,48 @@
+From 649f8ba7105548a962fed7a948e97d958ce3e281 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 20:40:36 +0200
+Subject: leds: multicolor: Fix intensity setting while SW blinking
+
+From: Sven Schwermer <sven.schwermer@disruptive-technologies.com>
+
+[ Upstream commit e35ca991a777ef513040cbb36bc8245a031a2633 ]
+
+When writing to the multi_intensity file, don't unconditionally call
+led_set_brightness. By only doing this if blinking is inactive we
+prevent blinking from stopping if the blinking is in its off phase while
+the file is written.
+
+Instead, if blinking is active, the changed intensity values are applied
+upon the next blink. This is consistent with changing the brightness on
+monochrome LEDs with active blinking.
+
+Suggested-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
+Acked-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
+Acked-by: Pavel Machek <pavel@ucw.cz>
+Reviewed-by: Tobias Deiminger <tobias.deiminger@linutronix.de>
+Tested-by: Sven Schuchmann <schuchmann@schleissheimer.de>
+Signed-off-by: Sven Schwermer <sven.schwermer@disruptive-technologies.com>
+Link: https://lore.kernel.org/r/20250404184043.227116-1-sven@svenschwermer.de
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/led-class-multicolor.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/leds/led-class-multicolor.c b/drivers/leds/led-class-multicolor.c
+index ec62a48116135..e0785935f4ba6 100644
+--- a/drivers/leds/led-class-multicolor.c
++++ b/drivers/leds/led-class-multicolor.c
+@@ -61,7 +61,8 @@ static ssize_t multi_intensity_store(struct device *dev,
+       for (i = 0; i < mcled_cdev->num_colors; i++)
+               mcled_cdev->subled_info[i].intensity = intensity_value[i];
+-      led_set_brightness(led_cdev, led_cdev->brightness);
++      if (!test_bit(LED_BLINK_SW, &led_cdev->work_flags))
++              led_set_brightness(led_cdev, led_cdev->brightness);
+       ret = size;
+ err_out:
+       mutex_unlock(&led_cdev->led_access);
+-- 
+2.39.5
+
diff --git a/queue-6.1/mailbox-not-protect-module_put-with-spin_lock_irqsav.patch b/queue-6.1/mailbox-not-protect-module_put-with-spin_lock_irqsav.patch
new file mode 100644 (file)
index 0000000..64e4404
--- /dev/null
@@ -0,0 +1,38 @@
+From ec212d4c5b13227c628b788c63073aeb36bb709b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Apr 2025 21:14:10 +0800
+Subject: mailbox: Not protect module_put with spin_lock_irqsave
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit dddbd233e67e792bb0a3f9694a4707e6be29b2c6 ]
+
+&chan->lock is not supposed to protect 'chan->mbox'.
+And in __mbox_bind_client, try_module_get is also not protected
+by &chan->lock. So move module_put out of the lock protected
+region.
+
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/mailbox.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
+index 6f54501dc7762..cb31ad917b352 100644
+--- a/drivers/mailbox/mailbox.c
++++ b/drivers/mailbox/mailbox.c
+@@ -459,8 +459,8 @@ void mbox_free_channel(struct mbox_chan *chan)
+       if (chan->txdone_method == TXDONE_BY_ACK)
+               chan->txdone_method = TXDONE_BY_POLL;
+-      module_put(chan->mbox->dev->driver->owner);
+       spin_unlock_irqrestore(&chan->lock, flags);
++      module_put(chan->mbox->dev->driver->owner);
+ }
+ EXPORT_SYMBOL_GPL(mbox_free_channel);
+-- 
+2.39.5
+
diff --git a/queue-6.1/md-md-bitmap-fix-dm-raid-max_write_behind-setting.patch b/queue-6.1/md-md-bitmap-fix-dm-raid-max_write_behind-setting.patch
new file mode 100644 (file)
index 0000000..31a5739
--- /dev/null
@@ -0,0 +1,36 @@
+From 81015117f25e4e65bbf9eebf452379f5f035398e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 24 May 2025 14:13:10 +0800
+Subject: md/md-bitmap: fix dm-raid max_write_behind setting
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 2afe17794cfed5f80295b1b9facd66e6f65e5002 ]
+
+It's supposed to be COUNTER_MAX / 2, not COUNTER_MAX.
+
+Link: https://lore.kernel.org/linux-raid/20250524061320.370630-14-yukuai1@huaweicloud.com
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md-bitmap.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
+index 02629516748e4..dac27206cd3df 100644
+--- a/drivers/md/md-bitmap.c
++++ b/drivers/md/md-bitmap.c
+@@ -546,7 +546,7 @@ static int md_bitmap_new_disk_sb(struct bitmap *bitmap)
+        * is a good choice?  We choose COUNTER_MAX / 2 arbitrarily.
+        */
+       write_behind = bitmap->mddev->bitmap_info.max_write_behind;
+-      if (write_behind > COUNTER_MAX)
++      if (write_behind > COUNTER_MAX / 2)
+               write_behind = COUNTER_MAX / 2;
+       sb->write_behind = cpu_to_le32(write_behind);
+       bitmap->mddev->bitmap_info.max_write_behind = write_behind;
+-- 
+2.39.5
+
diff --git a/queue-6.1/media-imx-jpeg-add-a-timeout-mechanism-for-each-fram.patch b/queue-6.1/media-imx-jpeg-add-a-timeout-mechanism-for-each-fram.patch
new file mode 100644 (file)
index 0000000..5bf877c
--- /dev/null
@@ -0,0 +1,148 @@
+From 3dfc8f2839ddcab7ce48232419f93e7685aa803d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 10:37:37 +0800
+Subject: media: imx-jpeg: Add a timeout mechanism for each frame
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit cfed9632ca8e8bdf0128745ae2400b72c4292886 ]
+
+Add a timeout mechanism for each frame.
+If the frame can't be decoded or encoded,
+driver can cancel it to avoid hang.
+
+Fixes: 2db16c6ed72ce ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Reviewed-by: Mirela Rabulea <mirela.rabulea@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Stable-dep-of: 46e9c092f850 ("media: imx-jpeg: Move mxc_jpeg_free_slot_data() ahead")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../media/platform/nxp/imx-jpeg/mxc-jpeg.c    | 55 ++++++++++++++++---
+ .../media/platform/nxp/imx-jpeg/mxc-jpeg.h    |  1 +
+ 2 files changed, 49 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+index c3655ab4511b4..5e897dda0ac63 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+@@ -330,6 +330,10 @@ static unsigned int debug;
+ module_param(debug, int, 0644);
+ MODULE_PARM_DESC(debug, "Debug level (0-3)");
++static unsigned int hw_timeout = 2000;
++module_param(hw_timeout, int, 0644);
++MODULE_PARM_DESC(hw_timeout, "MXC JPEG hw timeout, the number of milliseconds");
++
+ static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q, u32 precision);
+ static void mxc_jpeg_sizeimage(struct mxc_jpeg_q_data *q);
+@@ -569,6 +573,26 @@ static void mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx *ctx,
+       }
+ }
++static void mxc_jpeg_job_finish(struct mxc_jpeg_ctx *ctx, enum vb2_buffer_state state, bool reset)
++{
++      struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
++      void __iomem *reg = jpeg->base_reg;
++      struct vb2_v4l2_buffer *src_buf, *dst_buf;
++
++      dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
++      src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
++      mxc_jpeg_check_and_set_last_buffer(ctx, src_buf, dst_buf);
++      v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
++      v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
++      v4l2_m2m_buf_done(src_buf, state);
++      v4l2_m2m_buf_done(dst_buf, state);
++
++      mxc_jpeg_disable_irq(reg, ctx->slot);
++      ctx->mxc_jpeg->slot_data[ctx->slot].used = false;
++      if (reset)
++              mxc_jpeg_sw_reset(reg);
++}
++
+ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
+ {
+       struct mxc_jpeg_dev *jpeg = priv;
+@@ -601,6 +625,9 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
+               goto job_unlock;
+       }
++      if (!jpeg->slot_data[slot].used)
++              goto job_unlock;
++
+       dec_ret = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS));
+       writel(dec_ret, reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS)); /* w1c */
+@@ -665,14 +692,9 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
+       buf_state = VB2_BUF_STATE_DONE;
+ buffers_done:
+-      mxc_jpeg_disable_irq(reg, ctx->slot);
+-      jpeg->slot_data[slot].used = false; /* unused, but don't free */
+-      mxc_jpeg_check_and_set_last_buffer(ctx, src_buf, dst_buf);
+-      v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+-      v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+-      v4l2_m2m_buf_done(src_buf, buf_state);
+-      v4l2_m2m_buf_done(dst_buf, buf_state);
++      mxc_jpeg_job_finish(ctx, buf_state, false);
+       spin_unlock(&jpeg->hw_lock);
++      cancel_delayed_work(&ctx->task_timer);
+       v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
+       return IRQ_HANDLED;
+ job_unlock:
+@@ -1003,6 +1025,23 @@ static int mxc_jpeg_job_ready(void *priv)
+       return ctx->source_change ? 0 : 1;
+ }
++static void mxc_jpeg_device_run_timeout(struct work_struct *work)
++{
++      struct delayed_work *dwork = to_delayed_work(work);
++      struct mxc_jpeg_ctx *ctx = container_of(dwork, struct mxc_jpeg_ctx, task_timer);
++      struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
++      unsigned long flags;
++
++      spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags);
++      if (ctx->slot < MXC_MAX_SLOTS && ctx->mxc_jpeg->slot_data[ctx->slot].used) {
++              dev_warn(jpeg->dev, "%s timeout, cancel it\n",
++                       ctx->mxc_jpeg->mode == MXC_JPEG_DECODE ? "decode" : "encode");
++              mxc_jpeg_job_finish(ctx, VB2_BUF_STATE_ERROR, true);
++              v4l2_m2m_job_finish(ctx->mxc_jpeg->m2m_dev, ctx->fh.m2m_ctx);
++      }
++      spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
++}
++
+ static void mxc_jpeg_device_run(void *priv)
+ {
+       struct mxc_jpeg_ctx *ctx = priv;
+@@ -1088,6 +1127,7 @@ static void mxc_jpeg_device_run(void *priv)
+                                        &src_buf->vb2_buf, &dst_buf->vb2_buf);
+               mxc_jpeg_dec_mode_go(dev, reg);
+       }
++      schedule_delayed_work(&ctx->task_timer, msecs_to_jiffies(hw_timeout));
+ end:
+       spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
+ }
+@@ -1681,6 +1721,7 @@ static int mxc_jpeg_open(struct file *file)
+       ctx->fh.ctrl_handler = &ctx->ctrl_handler;
+       mxc_jpeg_set_default_params(ctx);
+       ctx->slot = MXC_MAX_SLOTS; /* slot not allocated yet */
++      INIT_DELAYED_WORK(&ctx->task_timer, mxc_jpeg_device_run_timeout);
+       if (mxc_jpeg->mode == MXC_JPEG_DECODE)
+               dev_dbg(dev, "Opened JPEG decoder instance %p\n", ctx);
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
+index d742b638ddc93..a0dad86e40eab 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
+@@ -97,6 +97,7 @@ struct mxc_jpeg_ctx {
+       bool                            header_parsed;
+       struct v4l2_ctrl_handler        ctrl_handler;
+       u8                              jpeg_quality;
++      struct delayed_work             task_timer;
+ };
+ struct mxc_jpeg_slot_data {
+-- 
+2.39.5
+
diff --git a/queue-6.1/media-imx-jpeg-cleanup-after-an-allocation-error.patch b/queue-6.1/media-imx-jpeg-cleanup-after-an-allocation-error.patch
new file mode 100644 (file)
index 0000000..5ae6c59
--- /dev/null
@@ -0,0 +1,40 @@
+From fb42b71fd8515553ed5bd5face3f44ed236795f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Apr 2025 16:12:54 +0800
+Subject: media: imx-jpeg: Cleanup after an allocation error
+
+From: Ming Qian <ming.qian@oss.nxp.com>
+
+[ Upstream commit 7500bb9cf164edbb2c8117d57620227b1a4a8369 ]
+
+When allocation failures are not cleaned up by the driver, further
+allocation errors will be false-positives, which will cause buffers to
+remain uninitialized and cause NULL pointer dereferences.
+Ensure proper cleanup of failed allocations to prevent these issues.
+
+Fixes: 2db16c6ed72c ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder")
+Cc: stable@vger.kernel.org
+Signed-off-by: Ming Qian <ming.qian@oss.nxp.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+index 3602324b254a6..6e8d95a2406fd 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+@@ -553,6 +553,7 @@ static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg)
+       return true;
+ err:
+       dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", jpeg->slot_data.slot);
++      mxc_jpeg_free_slot_data(jpeg);
+       return false;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.1/media-imx-jpeg-move-mxc_jpeg_free_slot_data-ahead.patch b/queue-6.1/media-imx-jpeg-move-mxc_jpeg_free_slot_data-ahead.patch
new file mode 100644 (file)
index 0000000..476d71a
--- /dev/null
@@ -0,0 +1,86 @@
+From a95dcab6172ea8e41d6f627d33404b8ce2dc4fb3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Apr 2025 16:12:52 +0800
+Subject: media: imx-jpeg: Move mxc_jpeg_free_slot_data() ahead
+
+From: Ming Qian <ming.qian@oss.nxp.com>
+
+[ Upstream commit 46e9c092f850bd7b4d06de92d3d21877f49a3fcb ]
+
+Move function mxc_jpeg_free_slot_data() above mxc_jpeg_alloc_slot_data()
+allowing to call that function during allocation failures.
+No functional changes are made.
+
+Fixes: 2db16c6ed72c ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder")
+Cc: stable@vger.kernel.org
+Signed-off-by: Ming Qian <ming.qian@oss.nxp.com>
+Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../media/platform/nxp/imx-jpeg/mxc-jpeg.c    | 40 +++++++++----------
+ 1 file changed, 20 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+index 1fb065978b919..bfab38eec3e64 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+@@ -485,6 +485,26 @@ static int mxc_get_free_slot(struct mxc_jpeg_slot_data *slot_data)
+       return -1;
+ }
++static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg)
++{
++      /* free descriptor for decoding/encoding phase */
++      dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
++                        jpeg->slot_data.desc,
++                        jpeg->slot_data.desc_handle);
++
++      /* free descriptor for encoder configuration phase / decoder DHT */
++      dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
++                        jpeg->slot_data.cfg_desc,
++                        jpeg->slot_data.cfg_desc_handle);
++
++      /* free configuration stream */
++      dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM,
++                        jpeg->slot_data.cfg_stream_vaddr,
++                        jpeg->slot_data.cfg_stream_handle);
++
++      jpeg->slot_data.used = false;
++}
++
+ static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg)
+ {
+       struct mxc_jpeg_desc *desc;
+@@ -531,26 +551,6 @@ static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg)
+       return false;
+ }
+-static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg)
+-{
+-      /* free descriptor for decoding/encoding phase */
+-      dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
+-                        jpeg->slot_data.desc,
+-                        jpeg->slot_data.desc_handle);
+-
+-      /* free descriptor for encoder configuration phase / decoder DHT */
+-      dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
+-                        jpeg->slot_data.cfg_desc,
+-                        jpeg->slot_data.cfg_desc_handle);
+-
+-      /* free configuration stream */
+-      dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM,
+-                        jpeg->slot_data.cfg_stream_vaddr,
+-                        jpeg->slot_data.cfg_stream_handle);
+-
+-      jpeg->slot_data.used = false;
+-}
+-
+ static void mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx *ctx,
+                                              struct vb2_v4l2_buffer *src_buf,
+                                              struct vb2_v4l2_buffer *dst_buf)
+-- 
+2.39.5
+
diff --git a/queue-6.1/media-imx-jpeg-remove-unnecessary-memset-after-dma_a.patch b/queue-6.1/media-imx-jpeg-remove-unnecessary-memset-after-dma_a.patch
new file mode 100644 (file)
index 0000000..c2ac4f6
--- /dev/null
@@ -0,0 +1,36 @@
+From f01056f4295d9b73518e238b6a74e2f0a163356b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 Jul 2022 20:25:43 +0800
+Subject: media: imx-jpeg: Remove unnecessary memset() after
+ dma_alloc_coherent()
+
+From: Jason Wang <wangborong@cdjrlc.com>
+
+[ Upstream commit 2bcc3b48c8ddf2d83cf00a00c0d021970c271fff ]
+
+The `dma_alloc_coherent()' already zeroes out memory for us, so we don't
+need the redundant memset().
+
+Signed-off-by: Jason Wang <wangborong@cdjrlc.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Stable-dep-of: 46e9c092f850 ("media: imx-jpeg: Move mxc_jpeg_free_slot_data() ahead")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+index 7d6dd7a4833ce..c3655ab4511b4 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+@@ -519,7 +519,6 @@ static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg,
+                                    GFP_ATOMIC);
+       if (!cfg_stm)
+               goto err;
+-      memset(cfg_stm, 0, MXC_JPEG_MAX_CFG_STREAM);
+       jpeg->slot_data[slot].cfg_stream_vaddr = cfg_stm;
+ skip_alloc:
+-- 
+2.39.5
+
diff --git a/queue-6.1/media-imx-jpeg-reset-slot-data-pointers-when-freed.patch b/queue-6.1/media-imx-jpeg-reset-slot-data-pointers-when-freed.patch
new file mode 100644 (file)
index 0000000..5a6badd
--- /dev/null
@@ -0,0 +1,56 @@
+From 91459839eff71cc330aba1f362931382c5b18ebe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Apr 2025 16:12:53 +0800
+Subject: media: imx-jpeg: Reset slot data pointers when freed
+
+From: Ming Qian <ming.qian@oss.nxp.com>
+
+[ Upstream commit faa8051b128f4b34277ea8a026d02d83826f8122 ]
+
+Ensure that the slot data pointers are reset to NULL and handles are
+set to 0 after freeing the coherent memory. This makes he function
+mxc_jpeg_alloc_slot_data() and mxc_jpeg_free_slot_data() safe to be
+called multiple times.
+
+Fixes: 2db16c6ed72c ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder")
+Cc: stable@vger.kernel.org
+Signed-off-by: Ming Qian <ming.qian@oss.nxp.com>
+Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+index bfab38eec3e64..3602324b254a6 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+@@ -491,16 +491,22 @@ static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg)
+       dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
+                         jpeg->slot_data.desc,
+                         jpeg->slot_data.desc_handle);
++      jpeg->slot_data.desc = NULL;
++      jpeg->slot_data.desc_handle = 0;
+       /* free descriptor for encoder configuration phase / decoder DHT */
+       dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
+                         jpeg->slot_data.cfg_desc,
+                         jpeg->slot_data.cfg_desc_handle);
++      jpeg->slot_data.cfg_desc_handle = 0;
++      jpeg->slot_data.cfg_desc = NULL;
+       /* free configuration stream */
+       dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM,
+                         jpeg->slot_data.cfg_stream_vaddr,
+                         jpeg->slot_data.cfg_stream_handle);
++      jpeg->slot_data.cfg_stream_vaddr = NULL;
++      jpeg->slot_data.cfg_stream_handle = 0;
+       jpeg->slot_data.used = false;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.1/media-imx-jpeg-support-to-assign-slot-for-encoder-de.patch b/queue-6.1/media-imx-jpeg-support-to-assign-slot-for-encoder-de.patch
new file mode 100644 (file)
index 0000000..5c330db
--- /dev/null
@@ -0,0 +1,364 @@
+From 422901474a4342d15647044bc7fd63a9f22c6079 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 09:16:30 +0200
+Subject: media: imx-jpeg: Support to assign slot for encoder/decoder
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit 53ebeea50599c1ed05277d7a57e331a34e6d6a82 ]
+
+imx jpeg encoder and decoder support 4 slots each,
+aim to support some virtualization scenarios.
+
+driver should only enable one slot one time.
+
+but due to some hardware issue,
+only slot 0 can be enabled in imx8q platform,
+and they may be fixed in imx9 platform.
+
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Stable-dep-of: 46e9c092f850 ("media: imx-jpeg: Move mxc_jpeg_free_slot_data() ahead")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h |   1 -
+ .../media/platform/nxp/imx-jpeg/mxc-jpeg.c    | 135 +++++++++---------
+ .../media/platform/nxp/imx-jpeg/mxc-jpeg.h    |   5 +-
+ 3 files changed, 68 insertions(+), 73 deletions(-)
+
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h
+index ecf3b6562ba26..c83dd0acb5b0c 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h
+@@ -58,7 +58,6 @@
+ #define CAST_OFBSIZE_LO                       CAST_STATUS18
+ #define CAST_OFBSIZE_HI                       CAST_STATUS19
+-#define MXC_MAX_SLOTS 1 /* TODO use all 4 slots*/
+ /* JPEG-Decoder Wrapper Slot Registers 0..3 */
+ #define SLOT_BASE                     0x10000
+ #define SLOT_STATUS                   0x0
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+index 5e897dda0ac63..1fb065978b919 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+@@ -478,87 +478,77 @@ static void notify_src_chg(struct mxc_jpeg_ctx *ctx)
+       v4l2_event_queue_fh(&ctx->fh, &ev);
+ }
+-static int mxc_get_free_slot(struct mxc_jpeg_slot_data slot_data[], int n)
++static int mxc_get_free_slot(struct mxc_jpeg_slot_data *slot_data)
+ {
+-      int free_slot = 0;
+-
+-      while (slot_data[free_slot].used && free_slot < n)
+-              free_slot++;
+-
+-      return free_slot; /* >=n when there are no more free slots */
++      if (!slot_data->used)
++              return slot_data->slot;
++      return -1;
+ }
+-static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg,
+-                                   unsigned int slot)
++static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg)
+ {
+       struct mxc_jpeg_desc *desc;
+       struct mxc_jpeg_desc *cfg_desc;
+       void *cfg_stm;
+-      if (jpeg->slot_data[slot].desc)
++      if (jpeg->slot_data.desc)
+               goto skip_alloc; /* already allocated, reuse it */
+       /* allocate descriptor for decoding/encoding phase */
+       desc = dma_alloc_coherent(jpeg->dev,
+                                 sizeof(struct mxc_jpeg_desc),
+-                                &jpeg->slot_data[slot].desc_handle,
++                                &jpeg->slot_data.desc_handle,
+                                 GFP_ATOMIC);
+       if (!desc)
+               goto err;
+-      jpeg->slot_data[slot].desc = desc;
++      jpeg->slot_data.desc = desc;
+       /* allocate descriptor for configuration phase (encoder only) */
+       cfg_desc = dma_alloc_coherent(jpeg->dev,
+                                     sizeof(struct mxc_jpeg_desc),
+-                                    &jpeg->slot_data[slot].cfg_desc_handle,
++                                    &jpeg->slot_data.cfg_desc_handle,
+                                     GFP_ATOMIC);
+       if (!cfg_desc)
+               goto err;
+-      jpeg->slot_data[slot].cfg_desc = cfg_desc;
++      jpeg->slot_data.cfg_desc = cfg_desc;
+       /* allocate configuration stream */
+       cfg_stm = dma_alloc_coherent(jpeg->dev,
+                                    MXC_JPEG_MAX_CFG_STREAM,
+-                                   &jpeg->slot_data[slot].cfg_stream_handle,
++                                   &jpeg->slot_data.cfg_stream_handle,
+                                    GFP_ATOMIC);
+       if (!cfg_stm)
+               goto err;
+-      jpeg->slot_data[slot].cfg_stream_vaddr = cfg_stm;
++      jpeg->slot_data.cfg_stream_vaddr = cfg_stm;
+ skip_alloc:
+-      jpeg->slot_data[slot].used = true;
++      jpeg->slot_data.used = true;
+       return true;
+ err:
+-      dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", slot);
++      dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", jpeg->slot_data.slot);
+       return false;
+ }
+-static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg,
+-                                  unsigned int slot)
++static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg)
+ {
+-      if (slot >= MXC_MAX_SLOTS) {
+-              dev_err(jpeg->dev, "Invalid slot %d, nothing to free.", slot);
+-              return;
+-      }
+-
+       /* free descriptor for decoding/encoding phase */
+       dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
+-                        jpeg->slot_data[slot].desc,
+-                        jpeg->slot_data[slot].desc_handle);
++                        jpeg->slot_data.desc,
++                        jpeg->slot_data.desc_handle);
+       /* free descriptor for encoder configuration phase / decoder DHT */
+       dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
+-                        jpeg->slot_data[slot].cfg_desc,
+-                        jpeg->slot_data[slot].cfg_desc_handle);
++                        jpeg->slot_data.cfg_desc,
++                        jpeg->slot_data.cfg_desc_handle);
+       /* free configuration stream */
+       dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM,
+-                        jpeg->slot_data[slot].cfg_stream_vaddr,
+-                        jpeg->slot_data[slot].cfg_stream_handle);
++                        jpeg->slot_data.cfg_stream_vaddr,
++                        jpeg->slot_data.cfg_stream_handle);
+-      jpeg->slot_data[slot].used = false;
++      jpeg->slot_data.used = false;
+ }
+ static void mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx *ctx,
+@@ -588,7 +578,7 @@ static void mxc_jpeg_job_finish(struct mxc_jpeg_ctx *ctx, enum vb2_buffer_state
+       v4l2_m2m_buf_done(dst_buf, state);
+       mxc_jpeg_disable_irq(reg, ctx->slot);
+-      ctx->mxc_jpeg->slot_data[ctx->slot].used = false;
++      jpeg->slot_data.used = false;
+       if (reset)
+               mxc_jpeg_sw_reset(reg);
+ }
+@@ -625,7 +615,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
+               goto job_unlock;
+       }
+-      if (!jpeg->slot_data[slot].used)
++      if (!jpeg->slot_data.used)
+               goto job_unlock;
+       dec_ret = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS));
+@@ -847,13 +837,13 @@ static void mxc_jpeg_config_dec_desc(struct vb2_buffer *out_buf,
+       struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
+       void __iomem *reg = jpeg->base_reg;
+       unsigned int slot = ctx->slot;
+-      struct mxc_jpeg_desc *desc = jpeg->slot_data[slot].desc;
+-      struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data[slot].cfg_desc;
+-      dma_addr_t desc_handle = jpeg->slot_data[slot].desc_handle;
+-      dma_addr_t cfg_desc_handle = jpeg->slot_data[slot].cfg_desc_handle;
+-      dma_addr_t cfg_stream_handle = jpeg->slot_data[slot].cfg_stream_handle;
+-      unsigned int *cfg_size = &jpeg->slot_data[slot].cfg_stream_size;
+-      void *cfg_stream_vaddr = jpeg->slot_data[slot].cfg_stream_vaddr;
++      struct mxc_jpeg_desc *desc = jpeg->slot_data.desc;
++      struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc;
++      dma_addr_t desc_handle = jpeg->slot_data.desc_handle;
++      dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle;
++      dma_addr_t cfg_stream_handle = jpeg->slot_data.cfg_stream_handle;
++      unsigned int *cfg_size = &jpeg->slot_data.cfg_stream_size;
++      void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr;
+       struct mxc_jpeg_src_buf *jpeg_src_buf;
+       jpeg_src_buf = vb2_to_mxc_buf(src_buf);
+@@ -909,18 +899,18 @@ static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf,
+       struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
+       void __iomem *reg = jpeg->base_reg;
+       unsigned int slot = ctx->slot;
+-      struct mxc_jpeg_desc *desc = jpeg->slot_data[slot].desc;
+-      struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data[slot].cfg_desc;
+-      dma_addr_t desc_handle = jpeg->slot_data[slot].desc_handle;
+-      dma_addr_t cfg_desc_handle = jpeg->slot_data[slot].cfg_desc_handle;
+-      void *cfg_stream_vaddr = jpeg->slot_data[slot].cfg_stream_vaddr;
++      struct mxc_jpeg_desc *desc = jpeg->slot_data.desc;
++      struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc;
++      dma_addr_t desc_handle = jpeg->slot_data.desc_handle;
++      dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle;
++      void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr;
+       struct mxc_jpeg_q_data *q_data;
+       enum mxc_jpeg_image_format img_fmt;
+       int w, h;
+       q_data = mxc_jpeg_get_q_data(ctx, src_buf->vb2_queue->type);
+-      jpeg->slot_data[slot].cfg_stream_size =
++      jpeg->slot_data.cfg_stream_size =
+                       mxc_jpeg_setup_cfg_stream(cfg_stream_vaddr,
+                                                 q_data->fmt->fourcc,
+                                                 q_data->w,
+@@ -929,7 +919,7 @@ static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf,
+       /* chain the config descriptor with the encoding descriptor */
+       cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN;
+-      cfg_desc->buf_base0 = jpeg->slot_data[slot].cfg_stream_handle;
++      cfg_desc->buf_base0 = jpeg->slot_data.cfg_stream_handle;
+       cfg_desc->buf_base1 = 0;
+       cfg_desc->line_pitch = 0;
+       cfg_desc->stm_bufbase = 0; /* no output expected */
+@@ -1033,7 +1023,7 @@ static void mxc_jpeg_device_run_timeout(struct work_struct *work)
+       unsigned long flags;
+       spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags);
+-      if (ctx->slot < MXC_MAX_SLOTS && ctx->mxc_jpeg->slot_data[ctx->slot].used) {
++      if (ctx->mxc_jpeg->slot_data.used) {
+               dev_warn(jpeg->dev, "%s timeout, cancel it\n",
+                        ctx->mxc_jpeg->mode == MXC_JPEG_DECODE ? "decode" : "encode");
+               mxc_jpeg_job_finish(ctx, VB2_BUF_STATE_ERROR, true);
+@@ -1101,12 +1091,12 @@ static void mxc_jpeg_device_run(void *priv)
+       mxc_jpeg_enable(reg);
+       mxc_jpeg_set_l_endian(reg, 1);
+-      ctx->slot = mxc_get_free_slot(jpeg->slot_data, MXC_MAX_SLOTS);
+-      if (ctx->slot >= MXC_MAX_SLOTS) {
++      ctx->slot = mxc_get_free_slot(&jpeg->slot_data);
++      if (ctx->slot < 0) {
+               dev_err(dev, "No more free slots\n");
+               goto end;
+       }
+-      if (!mxc_jpeg_alloc_slot_data(jpeg, ctx->slot)) {
++      if (!mxc_jpeg_alloc_slot_data(jpeg)) {
+               dev_err(dev, "Cannot allocate slot data\n");
+               goto end;
+       }
+@@ -1720,7 +1710,7 @@ static int mxc_jpeg_open(struct file *file)
+       }
+       ctx->fh.ctrl_handler = &ctx->ctrl_handler;
+       mxc_jpeg_set_default_params(ctx);
+-      ctx->slot = MXC_MAX_SLOTS; /* slot not allocated yet */
++      ctx->slot = -1; /* slot not allocated yet */
+       INIT_DELAYED_WORK(&ctx->task_timer, mxc_jpeg_device_run_timeout);
+       if (mxc_jpeg->mode == MXC_JPEG_DECODE)
+@@ -2172,6 +2162,11 @@ static int mxc_jpeg_attach_pm_domains(struct mxc_jpeg_dev *jpeg)
+               dev_err(dev, "No power domains defined for jpeg node\n");
+               return jpeg->num_domains;
+       }
++      if (jpeg->num_domains == 1) {
++              /* genpd_dev_pm_attach() attach automatically if power domains count is 1 */
++              jpeg->num_domains = 0;
++              return 0;
++      }
+       jpeg->pd_dev = devm_kmalloc_array(dev, jpeg->num_domains,
+                                         sizeof(*jpeg->pd_dev), GFP_KERNEL);
+@@ -2213,7 +2208,6 @@ static int mxc_jpeg_probe(struct platform_device *pdev)
+       int ret;
+       int mode;
+       const struct of_device_id *of_id;
+-      unsigned int slot;
+       of_id = of_match_node(mxc_jpeg_match, dev->of_node);
+       mode = *(const int *)of_id->data;
+@@ -2235,19 +2229,22 @@ static int mxc_jpeg_probe(struct platform_device *pdev)
+       if (IS_ERR(jpeg->base_reg))
+               return PTR_ERR(jpeg->base_reg);
+-      for (slot = 0; slot < MXC_MAX_SLOTS; slot++) {
+-              dec_irq = platform_get_irq(pdev, slot);
+-              if (dec_irq < 0) {
+-                      ret = dec_irq;
+-                      goto err_irq;
+-              }
+-              ret = devm_request_irq(&pdev->dev, dec_irq, mxc_jpeg_dec_irq,
+-                                     0, pdev->name, jpeg);
+-              if (ret) {
+-                      dev_err(&pdev->dev, "Failed to request irq %d (%d)\n",
+-                              dec_irq, ret);
+-                      goto err_irq;
+-              }
++      ret = of_property_read_u32_index(pdev->dev.of_node, "slot", 0, &jpeg->slot_data.slot);
++      if (ret)
++              jpeg->slot_data.slot = 0;
++      dev_info(&pdev->dev, "choose slot %d\n", jpeg->slot_data.slot);
++      dec_irq = platform_get_irq(pdev, 0);
++      if (dec_irq < 0) {
++              dev_err(&pdev->dev, "Failed to get irq %d\n", dec_irq);
++              ret = dec_irq;
++              goto err_irq;
++      }
++      ret = devm_request_irq(&pdev->dev, dec_irq, mxc_jpeg_dec_irq,
++                             0, pdev->name, jpeg);
++      if (ret) {
++              dev_err(&pdev->dev, "Failed to request irq %d (%d)\n",
++                      dec_irq, ret);
++              goto err_irq;
+       }
+       jpeg->pdev = pdev;
+@@ -2407,11 +2404,9 @@ static const struct dev_pm_ops  mxc_jpeg_pm_ops = {
+ static int mxc_jpeg_remove(struct platform_device *pdev)
+ {
+-      unsigned int slot;
+       struct mxc_jpeg_dev *jpeg = platform_get_drvdata(pdev);
+-      for (slot = 0; slot < MXC_MAX_SLOTS; slot++)
+-              mxc_jpeg_free_slot_data(jpeg, slot);
++      mxc_jpeg_free_slot_data(jpeg);
+       pm_runtime_disable(&pdev->dev);
+       video_unregister_device(jpeg->dec_vdev);
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
+index a0dad86e40eab..00ecb976fd75f 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
+@@ -92,7 +92,7 @@ struct mxc_jpeg_ctx {
+       struct mxc_jpeg_q_data          cap_q;
+       struct v4l2_fh                  fh;
+       enum mxc_jpeg_enc_state         enc_state;
+-      unsigned int                    slot;
++      int                             slot;
+       unsigned int                    source_change;
+       bool                            header_parsed;
+       struct v4l2_ctrl_handler        ctrl_handler;
+@@ -101,6 +101,7 @@ struct mxc_jpeg_ctx {
+ };
+ struct mxc_jpeg_slot_data {
++      int slot;
+       bool used;
+       struct mxc_jpeg_desc *desc; // enc/dec descriptor
+       struct mxc_jpeg_desc *cfg_desc; // configuration descriptor
+@@ -123,7 +124,7 @@ struct mxc_jpeg_dev {
+       struct v4l2_device              v4l2_dev;
+       struct v4l2_m2m_dev             *m2m_dev;
+       struct video_device             *dec_vdev;
+-      struct mxc_jpeg_slot_data       slot_data[MXC_MAX_SLOTS];
++      struct mxc_jpeg_slot_data       slot_data;
+       int                             num_domains;
+       struct device                   **pd_dev;
+       struct device_link              **pd_link;
+-- 
+2.39.5
+
diff --git a/queue-6.1/mfd-max14577-fix-wakeup-source-leaks-on-device-unbin.patch b/queue-6.1/mfd-max14577-fix-wakeup-source-leaks-on-device-unbin.patch
new file mode 100644 (file)
index 0000000..64a2b3c
--- /dev/null
@@ -0,0 +1,35 @@
+From 4708c68f547b3d56caeb2832a1c317953d5db81f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 6 Apr 2025 21:50:11 +0200
+Subject: mfd: max14577: Fix wakeup source leaks on device unbind
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit d905d06e64b0eb3da43af6186c132f5282197998 ]
+
+Device can be unbound, so driver must also release memory for the wakeup
+source.
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20250406-mfd-device-wakekup-leak-v1-3-318e14bdba0a@linaro.org
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/max14577.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c
+index d44ad6f337425..61a5ccafa18e0 100644
+--- a/drivers/mfd/max14577.c
++++ b/drivers/mfd/max14577.c
+@@ -467,6 +467,7 @@ static void max14577_i2c_remove(struct i2c_client *i2c)
+ {
+       struct max14577 *max14577 = i2c_get_clientdata(i2c);
++      device_init_wakeup(max14577->dev, false);
+       mfd_remove_devices(max14577->dev);
+       regmap_del_irq_chip(max14577->irq, max14577->irq_data);
+       if (max14577->dev_type == MAXIM_DEVICE_TYPE_MAX77836)
+-- 
+2.39.5
+
diff --git a/queue-6.1/nfsv4-always-set-nlink-even-if-the-server-doesn-t-su.patch b/queue-6.1/nfsv4-always-set-nlink-even-if-the-server-doesn-t-su.patch
new file mode 100644 (file)
index 0000000..f6905dd
--- /dev/null
@@ -0,0 +1,41 @@
+From e31183e28ddb612a27318469399cebeb9f28894c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 4 May 2025 20:57:04 +0800
+Subject: NFSv4: Always set NLINK even if the server doesn't support it
+
+From: Han Young <hanyang.tony@bytedance.com>
+
+[ Upstream commit 3a3065352f73381d3a1aa0ccab44aec3a5a9b365 ]
+
+fattr4_numlinks is a recommended attribute, so the client should emulate
+it even if the server doesn't support it. In decode_attr_nlink function
+in nfs4xdr.c, nlink is initialized to 1. However, this default value
+isn't set to the inode due to the check in nfs_fhget.
+
+So if the server doesn't support numlinks, inode's nlink will be zero,
+the mount will fail with error "Stale file handle". Set the nlink to 1
+if the server doesn't support it.
+
+Signed-off-by: Han Young <hanyang.tony@bytedance.com>
+Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/inode.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
+index f2e66b946f4b4..e774cfc85eeed 100644
+--- a/fs/nfs/inode.c
++++ b/fs/nfs/inode.c
+@@ -555,6 +555,8 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
+                       set_nlink(inode, fattr->nlink);
+               else if (fattr_supported & NFS_ATTR_FATTR_NLINK)
+                       nfs_set_cache_invalid(inode, NFS_INO_INVALID_NLINK);
++              else
++                      set_nlink(inode, 1);
+               if (fattr->valid & NFS_ATTR_FATTR_OWNER)
+                       inode->i_uid = fattr->uid;
+               else if (fattr_supported & NFS_ATTR_FATTR_OWNER)
+-- 
+2.39.5
+
diff --git a/queue-6.1/nfsv4-xattr-handlers-should-check-for-absent-nfs-fil.patch b/queue-6.1/nfsv4-xattr-handlers-should-check-for-absent-nfs-fil.patch
new file mode 100644 (file)
index 0000000..82f6287
--- /dev/null
@@ -0,0 +1,59 @@
+From 8b540c4f79bb382dbf2b566da5645c756d413286 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Apr 2025 11:23:38 -0400
+Subject: NFSv4: xattr handlers should check for absent nfs filehandles
+
+From: Scott Mayhew <smayhew@redhat.com>
+
+[ Upstream commit 6e9a2f8dbe93c8004c2af2c0158888628b7ca034 ]
+
+The nfs inodes for referral anchors that have not yet been followed have
+their filehandles zeroed out.
+
+Attempting to call getxattr() on one of these will cause the nfs client
+to send a GETATTR to the nfs server with the preceding PUTFH sans
+filehandle.  The server will reply NFS4ERR_NOFILEHANDLE, leading to -EIO
+being returned to the application.
+
+For example:
+
+$ strace -e trace=getxattr getfattr -n system.nfs4_acl /mnt/t/ref
+getxattr("/mnt/t/ref", "system.nfs4_acl", NULL, 0) = -1 EIO (Input/output error)
+/mnt/t/ref: system.nfs4_acl: Input/output error
++++ exited with 1 +++
+
+Have the xattr handlers return -ENODATA instead.
+
+Signed-off-by: Scott Mayhew <smayhew@redhat.com>
+Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs4proc.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 2d94d1d7b0c62..29f8a2df2c11a 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -6065,6 +6065,8 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen,
+       struct nfs_server *server = NFS_SERVER(inode);
+       int ret;
++      if (unlikely(NFS_FH(inode)->size == 0))
++              return -ENODATA;
+       if (!nfs4_server_supports_acls(server, type))
+               return -EOPNOTSUPP;
+       ret = nfs_revalidate_inode(inode, NFS_INO_INVALID_CHANGE);
+@@ -6139,6 +6141,9 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf,
+ {
+       struct nfs4_exception exception = { };
+       int err;
++
++      if (unlikely(NFS_FH(inode)->size == 0))
++              return -ENODATA;
+       do {
+               err = __nfs4_proc_set_acl(inode, buf, buflen, type);
+               trace_nfs4_set_acl(inode, err);
+-- 
+2.39.5
+
diff --git a/queue-6.1/nfsv4.2-fix-listxattr-to-return-selinux-security-lab.patch b/queue-6.1/nfsv4.2-fix-listxattr-to-return-selinux-security-lab.patch
new file mode 100644 (file)
index 0000000..d4356ab
--- /dev/null
@@ -0,0 +1,56 @@
+From 88f3d7b207112553648bdaab38b9ee93d52bbb17 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 14:09:21 -0400
+Subject: NFSv4.2: fix listxattr to return selinux security label
+
+From: Olga Kornievskaia <okorniev@redhat.com>
+
+[ Upstream commit 243fea134633ba3d64aceb4c16129c59541ea2c6 ]
+
+Currently, when NFS is queried for all the labels present on the
+file via a command example "getfattr -d -m . /mnt/testfile", it
+does not return the security label. Yet when asked specifically for
+the label (getfattr -n security.selinux) it will be returned.
+Include the security label when all attributes are queried.
+
+Signed-off-by: Olga Kornievskaia <okorniev@redhat.com>
+Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs4proc.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 0f28607c57473..2d94d1d7b0c62 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -10630,7 +10630,7 @@ const struct nfs4_minor_version_ops *nfs_v4_minor_ops[] = {
+ static ssize_t nfs4_listxattr(struct dentry *dentry, char *list, size_t size)
+ {
+-      ssize_t error, error2, error3;
++      ssize_t error, error2, error3, error4;
+       size_t left = size;
+       error = generic_listxattr(dentry, list, left);
+@@ -10653,8 +10653,16 @@ static ssize_t nfs4_listxattr(struct dentry *dentry, char *list, size_t size)
+       error3 = nfs4_listxattr_nfs4_user(d_inode(dentry), list, left);
+       if (error3 < 0)
+               return error3;
++      if (list) {
++              list += error3;
++              left -= error3;
++      }
++
++      error4 = security_inode_listsecurity(d_inode(dentry), list, left);
++      if (error4 < 0)
++              return error4;
+-      error += error2 + error3;
++      error += error2 + error3 + error4;
+       if (size && error > size)
+               return -ERANGE;
+       return error;
+-- 
+2.39.5
+
diff --git a/queue-6.1/ovl-check-for-null-d_inode-in-ovl_dentry_upper.patch b/queue-6.1/ovl-check-for-null-d_inode-in-ovl_dentry_upper.patch
new file mode 100644 (file)
index 0000000..885ac09
--- /dev/null
@@ -0,0 +1,68 @@
+From d33ed1620e18b28628691f0abd39af9fcd54a20c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Apr 2025 16:15:19 -0700
+Subject: ovl: Check for NULL d_inode() in ovl_dentry_upper()
+
+From: Kees Cook <kees@kernel.org>
+
+[ Upstream commit 8a39f1c870e9d6fbac5638f3a42a6a6363829c49 ]
+
+In ovl_path_type() and ovl_is_metacopy_dentry() GCC notices that it is
+possible for OVL_E() to return NULL (which implies that d_inode(dentry)
+may be NULL). This would result in out of bounds reads via container_of(),
+seen with GCC 15's -Warray-bounds -fdiagnostics-details. For example:
+
+In file included from arch/x86/include/generated/asm/rwonce.h:1,
+                 from include/linux/compiler.h:339,
+                 from include/linux/export.h:5,
+                 from include/linux/linkage.h:7,
+                 from include/linux/fs.h:5,
+                 from fs/overlayfs/util.c:7:
+In function 'ovl_upperdentry_dereference',
+    inlined from 'ovl_dentry_upper' at ../fs/overlayfs/util.c:305:9,
+    inlined from 'ovl_path_type' at ../fs/overlayfs/util.c:216:6:
+include/asm-generic/rwonce.h:44:26: error: array subscript 0 is outside array bounds of 'struct inode[7486503276667837]' [-Werror=array-bounds=]
+   44 | #define __READ_ONCE(x)  (*(const volatile __unqual_scalar_typeof(x) *)&(x))
+      |                         ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+include/asm-generic/rwonce.h:50:9: note: in expansion of macro '__READ_ONCE'
+   50 |         __READ_ONCE(x);                                                 \
+      |         ^~~~~~~~~~~
+fs/overlayfs/ovl_entry.h:195:16: note: in expansion of macro 'READ_ONCE'
+  195 |         return READ_ONCE(oi->__upperdentry);
+      |                ^~~~~~~~~
+  'ovl_path_type': event 1
+  185 |         return inode ? OVL_I(inode)->oe : NULL;
+  'ovl_path_type': event 2
+
+Avoid this by allowing ovl_dentry_upper() to return NULL if d_inode() is
+NULL, as that means the problematic dereferencing can never be reached.
+Note that this fixes the over-eager compiler warning in an effort to
+being able to enable -Warray-bounds globally. There is no known
+behavioral bug here.
+
+Suggested-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Kees Cook <kees@kernel.org>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/overlayfs/util.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
+index 83cd20f79c5c2..6922d8d705cb3 100644
+--- a/fs/overlayfs/util.c
++++ b/fs/overlayfs/util.c
+@@ -229,7 +229,9 @@ enum ovl_path_type ovl_path_realdata(struct dentry *dentry, struct path *path)
+ struct dentry *ovl_dentry_upper(struct dentry *dentry)
+ {
+-      return ovl_upperdentry_dereference(OVL_I(d_inode(dentry)));
++      struct inode *inode = d_inode(dentry);
++
++      return inode ? ovl_upperdentry_dereference(OVL_I(inode)) : NULL;
+ }
+ struct dentry *ovl_dentry_lower(struct dentry *dentry)
+-- 
+2.39.5
+
diff --git a/queue-6.1/pci-apple-fix-missing-of-node-reference-in-apple_pci.patch b/queue-6.1/pci-apple-fix-missing-of-node-reference-in-apple_pci.patch
new file mode 100644 (file)
index 0000000..01cfbfb
--- /dev/null
@@ -0,0 +1,44 @@
+From 31b29e191d2431e5005411a6a2db0650fdb5415e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 10:17:08 +0100
+Subject: PCI: apple: Fix missing OF node reference in apple_pcie_setup_port
+
+From: Hector Martin <marcan@marcan.st>
+
+[ Upstream commit 7fa9fbf39116b061f8a41cd84f1884c545f322c4 ]
+
+In the success path, we hang onto a reference to the node, so make sure
+to grab one. The caller iterator puts our borrowed reference when we
+return.
+
+Signed-off-by: Hector Martin <marcan@marcan.st>
+Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Tested-by: Janne Grunau <j@jannau.net>
+Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Acked-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
+Link: https://patch.msgid.link/20250401091713.2765724-9-maz@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-apple.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c
+index 487d01f6b4f56..fbe59139ab8fb 100644
+--- a/drivers/pci/controller/pcie-apple.c
++++ b/drivers/pci/controller/pcie-apple.c
+@@ -585,6 +585,9 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
+       list_add_tail(&port->entry, &pcie->ports);
+       init_completion(&pcie->event);
++      /* In the success path, we keep a reference to np around */
++      of_node_get(np);
++
+       ret = apple_pcie_port_register_irqs(port);
+       WARN_ON(ret);
+-- 
+2.39.5
+
diff --git a/queue-6.1/pci-apple-set-only-available-ports-up.patch b/queue-6.1/pci-apple-set-only-available-ports-up.patch
new file mode 100644 (file)
index 0000000..10502a4
--- /dev/null
@@ -0,0 +1,54 @@
+From 41c8da0231ef64badfeeafc5c27a87d0286bbb75 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 10:17:01 +0100
+Subject: PCI: apple: Set only available ports up
+
+From: Janne Grunau <j@jannau.net>
+
+[ Upstream commit 751bec089c4eed486578994abd2c5395f08d0302 ]
+
+Iterating over disabled ports results in of_irq_parse_raw() parsing
+the wrong "interrupt-map" entries, as it takes the status of the node
+into account.
+
+This became apparent after disabling unused PCIe ports in the Apple
+Silicon device trees instead of deleting them.
+
+Switching from for_each_child_of_node_scoped() to
+for_each_available_child_of_node_scoped() solves this issue.
+
+Fixes: 1e33888fbe44 ("PCI: apple: Add initial hardware bring-up")
+Fixes: a0189fdfb73d ("arm64: dts: apple: t8103: Disable unused PCIe ports")
+Signed-off-by: Janne Grunau <j@jannau.net>
+Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Tested-by: Janne Grunau <j@jannau.net>
+Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Acked-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/asahi/20230214-apple_dts_pcie_disable_unused-v1-0-5ea0d3ddcde3@jannau.net/
+Link: https://lore.kernel.org/asahi/1ea2107a-bb86-8c22-0bbc-82c453ab08ce@linaro.org/
+Link: https://patch.msgid.link/20250401091713.2765724-2-maz@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-apple.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c
+index b1f32e4c65989..1113e21ee386c 100644
+--- a/drivers/pci/controller/pcie-apple.c
++++ b/drivers/pci/controller/pcie-apple.c
+@@ -789,7 +789,7 @@ static int apple_pcie_init(struct pci_config_window *cfg)
+       if (ret)
+               return ret;
+-      for_each_child_of_node_scoped(dev->of_node, of_port) {
++      for_each_available_child_of_node_scoped(dev->of_node, of_port) {
+               ret = apple_pcie_setup_port(pcie, of_port);
+               if (ret) {
+                       dev_err(pcie->dev, "Port %pOF setup fail: %d\n", of_port, ret);
+-- 
+2.39.5
+
diff --git a/queue-6.1/pci-apple-use-helper-function-for_each_child_of_node.patch b/queue-6.1/pci-apple-use-helper-function-for_each_child_of_node.patch
new file mode 100644 (file)
index 0000000..063b57f
--- /dev/null
@@ -0,0 +1,59 @@
+From 973bfce99051a4b286f965b343a50f271c685510 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 31 Aug 2024 12:04:12 +0800
+Subject: PCI: apple: Use helper function for_each_child_of_node_scoped()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zhang Zekun <zhangzekun11@huawei.com>
+
+[ Upstream commit f60b4e06a945f25d463ae065c6e41c6e24faee0a ]
+
+The for_each_available_child_of_node_scoped() helper provides
+a scope-based clean-up functionality to put the device_node
+automatically, and as such, there is no need to call of_node_put()
+directly.
+
+Thus, use this helper to simplify the code.
+
+Signed-off-by: Zhang Zekun <zhangzekun11@huawei.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20240831040413.126417-6-zhangzekun11@huawei.com
+[kwilczynski: commit log]
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Stable-dep-of: 751bec089c4e ("PCI: apple: Set only available ports up")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-apple.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c
+index fbe59139ab8fb..b1f32e4c65989 100644
+--- a/drivers/pci/controller/pcie-apple.c
++++ b/drivers/pci/controller/pcie-apple.c
+@@ -767,7 +767,6 @@ static int apple_pcie_init(struct pci_config_window *cfg)
+ {
+       struct device *dev = cfg->parent;
+       struct platform_device *platform = to_platform_device(dev);
+-      struct device_node *of_port;
+       struct apple_pcie *pcie;
+       int ret;
+@@ -790,11 +789,10 @@ static int apple_pcie_init(struct pci_config_window *cfg)
+       if (ret)
+               return ret;
+-      for_each_child_of_node(dev->of_node, of_port) {
++      for_each_child_of_node_scoped(dev->of_node, of_port) {
+               ret = apple_pcie_setup_port(pcie, of_port);
+               if (ret) {
+                       dev_err(pcie->dev, "Port %pOF setup fail: %d\n", of_port, ret);
+-                      of_node_put(of_port);
+                       return ret;
+               }
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.1/revert-drm-i915-gem-allow-exec_capture-on-recoverabl.patch b/queue-6.1/revert-drm-i915-gem-allow-exec_capture-on-recoverabl.patch
new file mode 100644 (file)
index 0000000..bad0415
--- /dev/null
@@ -0,0 +1,58 @@
+From 5c23a1f832bdef3a6a6bd497b06f942e8e12da3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 May 2025 09:41:27 +0300
+Subject: Revert "drm/i915/gem: Allow EXEC_CAPTURE on recoverable contexts on
+ DG1"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+
+[ Upstream commit ed5915cfce2abb9a553c3737badebd4a11d6c9c7 ]
+
+This reverts commit d6e020819612a4a06207af858e0978be4d3e3140.
+
+The IS_DGFX check was put in place because error capture of buffer
+objects is expected to be broken on devices with VRAM.
+
+Userspace fix[1] to the impacted media driver has been submitted, merged
+and a new driver release is out as 25.2.3 where the capture flag is
+dropped on DG1 thus unblocking the usage of media driver on DG1.
+
+[1] https://github.com/intel/media-driver/commit/93c07d9b4b96a78bab21f6acd4eb863f4313ea4a
+
+Cc: stable@vger.kernel.org # v6.0+
+Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Cc: Andi Shyti <andi.shyti@linux.intel.com>
+Cc: Matthew Auld <matthew.auld@intel.com>
+Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Cc: Tvrtko Ursulin <tursulin@ursulin.net>
+Acked-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
+Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
+Link: https://lore.kernel.org/r/20250522064127.24293-1-joonas.lahtinen@linux.intel.com
+[Joonas: Update message to point out the merged userspace fix]
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+(cherry picked from commit d2dc30e0aa252830f908c8e793d3139d51321370)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+index 9424606710a10..0a123bb44c9fb 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+@@ -2001,7 +2001,7 @@ static int eb_capture_stage(struct i915_execbuffer *eb)
+                       continue;
+               if (i915_gem_context_is_recoverable(eb->gem_context) &&
+-                  GRAPHICS_VER_FULL(eb->i915) > IP_VER(12, 10))
++                  (IS_DGFX(eb->i915) || GRAPHICS_VER_FULL(eb->i915) > IP_VER(12, 0)))
+                       return -EINVAL;
+               for_each_batch_create_order(eb, j) {
+-- 
+2.39.5
+
diff --git a/queue-6.1/revert-iommu-amd-prevent-binding-other-pci-drivers-t.patch b/queue-6.1/revert-iommu-amd-prevent-binding-other-pci-drivers-t.patch
new file mode 100644 (file)
index 0000000..8175d0d
--- /dev/null
@@ -0,0 +1,60 @@
+From b65812bf9e3a32d4f65dcc9e233e00956614d37a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 11:24:21 +0200
+Subject: Revert "iommu/amd: Prevent binding other PCI drivers to IOMMU PCI
+ devices"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lukas Wunner <lukas@wunner.de>
+
+[ Upstream commit 3be5fa236649da6404f1bca1491bf02d4b0d5cce ]
+
+Commit 991de2e59090 ("PCI, x86: Implement pcibios_alloc_irq() and
+pcibios_free_irq()") changed IRQ handling on PCI driver probing.
+It inadvertently broke resume from system sleep on AMD platforms:
+
+  https://lore.kernel.org/r/20150926164651.GA3640@pd.tnic/
+
+This was fixed by two independent commits:
+
+* 8affb487d4a4 ("x86/PCI: Don't alloc pcibios-irq when MSI is enabled")
+* cbbc00be2ce3 ("iommu/amd: Prevent binding other PCI drivers to IOMMU PCI devices")
+
+The breaking change and one of these two fixes were subsequently reverted:
+
+* fe25d078874f ("Revert "x86/PCI: Don't alloc pcibios-irq when MSI is enabled"")
+* 6c777e8799a9 ("Revert "PCI, x86: Implement pcibios_alloc_irq() and pcibios_free_irq()"")
+
+This rendered the second fix unnecessary, so revert it as well.  It used
+the match_driver flag in struct pci_dev, which is internal to the PCI core
+and not supposed to be touched by arbitrary drivers.
+
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Acked-by: Joerg Roedel <jroedel@suse.de>
+Link: https://patch.msgid.link/9a3ddff5cc49512044f963ba0904347bd404094d.1745572340.git.lukas@wunner.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/amd/init.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
+index bc78e86655516..02e3167b02717 100644
+--- a/drivers/iommu/amd/init.c
++++ b/drivers/iommu/amd/init.c
+@@ -2053,9 +2053,6 @@ static int __init iommu_init_pci(struct amd_iommu *iommu)
+       if (!iommu->dev)
+               return -ENODEV;
+-      /* Prevent binding other PCI device drivers to IOMMU devices */
+-      iommu->dev->match_driver = false;
+-
+       /* ACPI _PRT won't have an IRQ for IOMMU */
+       iommu->dev->irq_managed = 1;
+-- 
+2.39.5
+
diff --git a/queue-6.1/rust-module-place-cleanup_module-in-.exit.text-secti.patch b/queue-6.1/rust-module-place-cleanup_module-in-.exit.text-secti.patch
new file mode 100644 (file)
index 0000000..dcbc53f
--- /dev/null
@@ -0,0 +1,61 @@
+From 29fc67c0c0f7e117cdf5cff9cf996268be8d03ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Mar 2025 13:45:06 +0900
+Subject: rust: module: place cleanup_module() in .exit.text section
+
+From: FUJITA Tomonori <fujita.tomonori@gmail.com>
+
+[ Upstream commit 249c3a0e53acefc2b06d3b3e1fc28fb2081f878d ]
+
+Place cleanup_module() in .exit.text section. Currently,
+cleanup_module() is likely placed in the .text section. It's
+inconsistent with the layout of C modules, where cleanup_module() is
+placed in .exit.text.
+
+[ Boqun asked for an example of how the section changed to be
+  put in the log. Tomonori provided the following examples:
+
+    C module:
+
+      $ objdump -t ~/build/x86/drivers/block/loop.o|grep clean
+      0000000000000000 l     O .exit.data    0000000000000008 __UNIQUE_ID___addressable_cleanup_module412
+      0000000000000000 g     F .exit.text    000000000000009c cleanup_module
+
+    Rust module without this patch:
+
+      $ objdump -t ~/build/x86/samples/rust/rust_minimal.o|grep clean
+      00000000000002b0 g     F .text         00000000000000c6 cleanup_module
+      0000000000000000 g     O .exit.data    0000000000000008 _R...___UNIQUE_ID___addressable_cleanup_module
+
+    Rust module with this patch:
+
+      $ objdump -t ~/build/x86/samples/rust/rust_minimal.o|grep clean
+      0000000000000000 g     F .exit.text    00000000000000c6 cleanup_module
+      0000000000000000 g     O .exit.data    0000000000000008 _R...___UNIQUE_ID___addressable_cleanup_module
+
+  - Miguel ]
+
+Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
+Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
+Link: https://lore.kernel.org/r/20250308044506.14458-1-fujita.tomonori@gmail.com
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ rust/macros/module.rs | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/rust/macros/module.rs b/rust/macros/module.rs
+index 94a92ab82b6b3..eeca6b2d5160a 100644
+--- a/rust/macros/module.rs
++++ b/rust/macros/module.rs
+@@ -229,6 +229,7 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
+                     #[cfg(MODULE)]
+                     #[doc(hidden)]
+                     #[no_mangle]
++                    #[link_section = \".exit.text\"]
+                     pub extern \"C\" fn cleanup_module() {{
+                         // SAFETY:
+                         // - This function is inaccessible to the outside due to the double
+-- 
+2.39.5
+
diff --git a/queue-6.1/series b/queue-6.1/series
new file mode 100644 (file)
index 0000000..bc59838
--- /dev/null
@@ -0,0 +1,70 @@
+cifs-correctly-set-smb1-sessionkey-field-in-session-.patch
+cifs-fix-cifs_query_path_info-for-windows-nt-servers.patch
+nfsv4-always-set-nlink-even-if-the-server-doesn-t-su.patch
+nfsv4.2-fix-listxattr-to-return-selinux-security-lab.patch
+mailbox-not-protect-module_put-with-spin_lock_irqsav.patch
+mfd-max14577-fix-wakeup-source-leaks-on-device-unbin.patch
+leds-multicolor-fix-intensity-setting-while-sw-blink.patch
+nfsv4-xattr-handlers-should-check-for-absent-nfs-fil.patch
+hwmon-pmbus-max34440-fix-support-for-max34451.patch
+ksmbd-allow-a-filename-to-contain-special-characters.patch
+rust-module-place-cleanup_module-in-.exit.text-secti.patch
+revert-iommu-amd-prevent-binding-other-pci-drivers-t.patch
+dmaengine-xilinx_dma-set-dma_device-directions.patch
+pci-apple-fix-missing-of-node-reference-in-apple_pci.patch
+md-md-bitmap-fix-dm-raid-max_write_behind-setting.patch
+amd-amdkfd-fix-a-kfd_process-ref-leak.patch
+bcache-fix-null-pointer-in-cache_set_flush.patch
+iio-pressure-zpa2326-use-aligned_s64-for-the-timesta.patch
+um-add-cmpxchg8b_emu-and-checksum-functions-to-asm-p.patch
+um-use-proper-care-when-taking-mmap-lock-during-segf.patch
+coresight-only-check-bottom-two-claim-bits.patch
+usb-dwc2-also-exit-clock_gating-when-stopping-udc-wh.patch
+iio-adc-ad_sigma_delta-fix-use-of-uninitialized-stat.patch
+usb-potential-integer-overflow-in-usbg_make_tpg.patch
+tty-serial-uartlite-register-uart-driver-in-init.patch
+usb-common-usb-conn-gpio-use-a-unique-name-for-usb-c.patch
+usb-add-checks-for-snprintf-calls-in-usb_alloc_dev.patch
+usb-cdc-wdm-avoid-setting-wdm_read-for-zlp-s.patch
+usb-typec-displayport-receive-dp-status-update-nak-r.patch
+usb-typec-mux-do-not-return-on-eopnotsupp-in-mux-swi.patch
+alsa-hda-ignore-unsol-events-for-cards-being-shut-do.patch
+alsa-hda-add-new-pci-id-for-amd-gpu-display-hd-audio.patch
+alsa-usb-audio-add-a-quirk-for-lenovo-thinkpad-thund.patch
+ceph-fix-possible-integer-overflow-in-ceph_zero_obje.patch
+ovl-check-for-null-d_inode-in-ovl_dentry_upper.patch
+btrfs-handle-csum-tree-error-with-rescue-ibadroots-c.patch
+drm-i915-gem-allow-exec_capture-on-recoverable-conte.patch
+revert-drm-i915-gem-allow-exec_capture-on-recoverabl.patch
+fs-jfs-consolidate-sanity-checking-in-dbmount.patch
+jfs-validate-ag-parameters-in-dbmount-to-prevent-cra.patch
+media-imx-jpeg-remove-unnecessary-memset-after-dma_a.patch
+media-imx-jpeg-add-a-timeout-mechanism-for-each-fram.patch
+media-imx-jpeg-support-to-assign-slot-for-encoder-de.patch
+media-imx-jpeg-move-mxc_jpeg_free_slot_data-ahead.patch
+media-imx-jpeg-reset-slot-data-pointers-when-freed.patch
+media-imx-jpeg-cleanup-after-an-allocation-error.patch
+asoc-codecs-wcd9335-handle-nicer-probe-deferral-and-.patch
+asoc-codec-wcd9335-convert-to-gpio-descriptors.patch
+asoc-codecs-wcd9335-fix-missing-free-of-regulator-su.patch
+f2fs-don-t-over-report-free-space-or-inodes-in-statv.patch
+fbdev-fix-do_register_framebuffer-to-prevent-null-pt.patch
+drivers-hv-hyperv_fb-untangle-and-refactor-hyper-v-p.patch
+drivers-hv-vmbus-remove-second-mapping-of-vmbus-moni.patch
+drivers-hv-move-panic-report-code-from-vmbus-to-hv-e.patch
+drivers-hv-change-hv_free_hyperv_page-to-take-void-a.patch
+drivers-hv-vmbus-leak-pages-if-set_memory_encrypted-.patch
+drivers-hv-allocate-interrupt-and-monitor-pages-alig.patch
+drivers-hv-vmbus-add-utility-function-for-querying-r.patch
+uio_hv_generic-query-the-ringbuffer-size-for-device.patch
+uio_hv_generic-align-ring-size-to-system-page.patch
+pci-apple-use-helper-function-for_each_child_of_node.patch
+pci-apple-set-only-available-ports-up.patch
+vgacon-switch-vgacon_scrolldelta-and-vgacon_restore_.patch
+vgacon-remove-unneeded-forward-declarations.patch
+tty-vt-make-init-parameter-of-consw-con_init-a-bool.patch
+tty-vt-sanitize-arguments-of-consw-con_clear.patch
+tty-vt-make-consw-con_switch-return-a-bool.patch
+dummycon-trigger-redraw-when-switching-consoles-with.patch
+af_unix-don-t-call-skb_get-for-oob-skb.patch
+af_unix-don-t-leave-consecutive-consumed-oob-skbs.patch
diff --git a/queue-6.1/tty-serial-uartlite-register-uart-driver-in-init.patch b/queue-6.1/tty-serial-uartlite-register-uart-driver-in-init.patch
new file mode 100644 (file)
index 0000000..7f1b660
--- /dev/null
@@ -0,0 +1,101 @@
+From 0ed6d5bc510d99fdfa1b344d4f2024c747776032 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Mar 2025 18:06:19 +0200
+Subject: tty: serial: uartlite: register uart driver in init
+
+From: Jakub Lewalski <jakub.lewalski@nokia.com>
+
+[ Upstream commit 6bd697b5fc39fd24e2aa418c7b7d14469f550a93 ]
+
+When two instances of uart devices are probing, a concurrency race can
+occur. If one thread calls uart_register_driver function, which first
+allocates and assigns memory to 'uart_state' member of uart_driver
+structure, the other instance can bypass uart driver registration and
+call ulite_assign. This calls uart_add_one_port, which expects the uart
+driver to be fully initialized. This leads to a kernel panic due to a
+null pointer dereference:
+
+[    8.143581] BUG: kernel NULL pointer dereference, address: 00000000000002b8
+[    8.156982] #PF: supervisor write access in kernel mode
+[    8.156984] #PF: error_code(0x0002) - not-present page
+[    8.156986] PGD 0 P4D 0
+...
+[    8.180668] RIP: 0010:mutex_lock+0x19/0x30
+[    8.188624] Call Trace:
+[    8.188629]  ? __die_body.cold+0x1a/0x1f
+[    8.195260]  ? page_fault_oops+0x15c/0x290
+[    8.209183]  ? __irq_resolve_mapping+0x47/0x80
+[    8.209187]  ? exc_page_fault+0x64/0x140
+[    8.209190]  ? asm_exc_page_fault+0x22/0x30
+[    8.209196]  ? mutex_lock+0x19/0x30
+[    8.223116]  uart_add_one_port+0x60/0x440
+[    8.223122]  ? proc_tty_register_driver+0x43/0x50
+[    8.223126]  ? tty_register_driver+0x1ca/0x1e0
+[    8.246250]  ulite_probe+0x357/0x4b0 [uartlite]
+
+To prevent it, move uart driver registration in to init function. This
+will ensure that uart_driver is always registered when probe function
+is called.
+
+Signed-off-by: Jakub Lewalski <jakub.lewalski@nokia.com>
+Signed-off-by: Elodie Decerle <elodie.decerle@nokia.com>
+Link: https://lore.kernel.org/r/20250331160732.2042-1-elodie.decerle@nokia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/uartlite.c | 25 ++++++++++++-------------
+ 1 file changed, 12 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c
+index eca41ac5477cb..a75677d5cbefd 100644
+--- a/drivers/tty/serial/uartlite.c
++++ b/drivers/tty/serial/uartlite.c
+@@ -879,16 +879,6 @@ static int ulite_probe(struct platform_device *pdev)
+       pm_runtime_set_active(&pdev->dev);
+       pm_runtime_enable(&pdev->dev);
+-      if (!ulite_uart_driver.state) {
+-              dev_dbg(&pdev->dev, "uartlite: calling uart_register_driver()\n");
+-              ret = uart_register_driver(&ulite_uart_driver);
+-              if (ret < 0) {
+-                      dev_err(&pdev->dev, "Failed to register driver\n");
+-                      clk_disable_unprepare(pdata->clk);
+-                      return ret;
+-              }
+-      }
+-
+       ret = ulite_assign(&pdev->dev, id, res->start, irq, pdata);
+       pm_runtime_mark_last_busy(&pdev->dev);
+@@ -930,16 +920,25 @@ static struct platform_driver ulite_platform_driver = {
+ static int __init ulite_init(void)
+ {
++      int ret;
++
++      pr_debug("uartlite: calling uart_register_driver()\n");
++      ret = uart_register_driver(&ulite_uart_driver);
++      if (ret)
++              return ret;
+       pr_debug("uartlite: calling platform_driver_register()\n");
+-      return platform_driver_register(&ulite_platform_driver);
++      ret = platform_driver_register(&ulite_platform_driver);
++      if (ret)
++              uart_unregister_driver(&ulite_uart_driver);
++
++      return ret;
+ }
+ static void __exit ulite_exit(void)
+ {
+       platform_driver_unregister(&ulite_platform_driver);
+-      if (ulite_uart_driver.state)
+-              uart_unregister_driver(&ulite_uart_driver);
++      uart_unregister_driver(&ulite_uart_driver);
+ }
+ module_init(ulite_init);
+-- 
+2.39.5
+
diff --git a/queue-6.1/tty-vt-make-consw-con_switch-return-a-bool.patch b/queue-6.1/tty-vt-make-consw-con_switch-return-a-bool.patch
new file mode 100644 (file)
index 0000000..83c8c3e
--- /dev/null
@@ -0,0 +1,193 @@
+From 85e02e04c16982d897c39ab31b6c8b0e797c182b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Jan 2024 12:03:44 +0100
+Subject: tty: vt: make consw::con_switch() return a bool
+
+From: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+
+[ Upstream commit 8d5cc8eed738e3202379722295c626cba0849785 ]
+
+The non-zero (true) return value from consw::con_switch() means a redraw
+is needed. So make this return type a bool explicitly instead of int.
+The latter might imply that -Eerrors are expected. They are not.
+
+And document the hook.
+
+Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>
+Cc: Helge Deller <deller@gmx.de>
+Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
+Cc: Daniel Vetter <daniel@ffwll.ch>
+Cc: linux-fbdev@vger.kernel.org
+Cc: dri-devel@lists.freedesktop.org
+Cc: linux-parisc@vger.kernel.org
+Tested-by: Helge Deller <deller@gmx.de> # parisc STI console
+Link: https://lore.kernel.org/r/20240122110401.7289-31-jirislaby@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/vt/vt.c                 | 2 +-
+ drivers/video/console/dummycon.c    | 4 ++--
+ drivers/video/console/mdacon.c      | 4 ++--
+ drivers/video/console/newport_con.c | 4 ++--
+ drivers/video/console/sticon.c      | 4 ++--
+ drivers/video/console/vgacon.c      | 4 ++--
+ drivers/video/fbdev/core/fbcon.c    | 6 +++---
+ include/linux/console.h             | 4 +++-
+ 8 files changed, 17 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
+index 609d2bac58d0b..ccfd9d93c10c5 100644
+--- a/drivers/tty/vt/vt.c
++++ b/drivers/tty/vt/vt.c
+@@ -1014,7 +1014,7 @@ void redraw_screen(struct vc_data *vc, int is_switch)
+       }
+       if (redraw) {
+-              int update;
++              bool update;
+               int old_was_color = vc->vc_can_do_color;
+               set_origin(vc);
+diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c
+index 6918014b02408..d701f2b51f5b1 100644
+--- a/drivers/video/console/dummycon.c
++++ b/drivers/video/console/dummycon.c
+@@ -119,9 +119,9 @@ static bool dummycon_scroll(struct vc_data *vc, unsigned int top,
+       return false;
+ }
+-static int dummycon_switch(struct vc_data *vc)
++static bool dummycon_switch(struct vc_data *vc)
+ {
+-      return 0;
++      return false;
+ }
+ /*
+diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
+index 1ddbb6cd5b0ca..26b41a8f36c87 100644
+--- a/drivers/video/console/mdacon.c
++++ b/drivers/video/console/mdacon.c
+@@ -454,9 +454,9 @@ static void mdacon_clear(struct vc_data *c, unsigned int y, unsigned int x,
+       scr_memsetw(dest, eattr, width * 2);
+ }
+-static int mdacon_switch(struct vc_data *c)
++static bool mdacon_switch(struct vc_data *c)
+ {
+-      return 1;       /* redrawing needed */
++      return true;    /* redrawing needed */
+ }
+ static int mdacon_blank(struct vc_data *c, int blank, int mode_switch)
+diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
+index 5dac00c825946..1ebb18bf10983 100644
+--- a/drivers/video/console/newport_con.c
++++ b/drivers/video/console/newport_con.c
+@@ -462,7 +462,7 @@ static void newport_cursor(struct vc_data *vc, int mode)
+       }
+ }
+-static int newport_switch(struct vc_data *vc)
++static bool newport_switch(struct vc_data *vc)
+ {
+       static int logo_drawn = 0;
+@@ -476,7 +476,7 @@ static int newport_switch(struct vc_data *vc)
+               }
+       }
+-      return 1;
++      return true;
+ }
+ static int newport_blank(struct vc_data *c, int blank, int mode_switch)
+diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
+index 58e983b18f1f4..6b82194a8ef36 100644
+--- a/drivers/video/console/sticon.c
++++ b/drivers/video/console/sticon.c
+@@ -309,9 +309,9 @@ static void sticon_clear(struct vc_data *conp, unsigned int sy, unsigned int sx,
+             conp->vc_video_erase_char, font_data[conp->vc_num]);
+ }
+-static int sticon_switch(struct vc_data *conp)
++static bool sticon_switch(struct vc_data *conp)
+ {
+-    return 1; /* needs refreshing */
++    return true;      /* needs refreshing */
+ }
+ static int sticon_blank(struct vc_data *c, int blank, int mode_switch)
+diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
+index 6998e28441c97..81f27cd610271 100644
+--- a/drivers/video/console/vgacon.c
++++ b/drivers/video/console/vgacon.c
+@@ -595,7 +595,7 @@ static int vgacon_doresize(struct vc_data *c,
+       return 0;
+ }
+-static int vgacon_switch(struct vc_data *c)
++static bool vgacon_switch(struct vc_data *c)
+ {
+       int x = c->vc_cols * VGA_FONTWIDTH;
+       int y = c->vc_rows * c->vc_cell_height;
+@@ -624,7 +624,7 @@ static int vgacon_switch(struct vc_data *c)
+                       vgacon_doresize(c, c->vc_cols, c->vc_rows);
+       }
+-      return 0;               /* Redrawing not needed */
++      return false;           /* Redrawing not needed */
+ }
+ static void vga_set_palette(struct vc_data *vc, const unsigned char *table)
+diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
+index 3fd76dc6010b4..1a17274187112 100644
+--- a/drivers/video/fbdev/core/fbcon.c
++++ b/drivers/video/fbdev/core/fbcon.c
+@@ -2073,7 +2073,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
+       return 0;
+ }
+-static int fbcon_switch(struct vc_data *vc)
++static bool fbcon_switch(struct vc_data *vc)
+ {
+       struct fb_info *info, *old_info = NULL;
+       struct fbcon_ops *ops;
+@@ -2195,9 +2195,9 @@ static int fbcon_switch(struct vc_data *vc)
+                             vc->vc_origin + vc->vc_size_row * vc->vc_top,
+                             vc->vc_size_row * (vc->vc_bottom -
+                                                vc->vc_top) / 2);
+-              return 0;
++              return false;
+       }
+-      return 1;
++      return true;
+ }
+ static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info,
+diff --git a/include/linux/console.h b/include/linux/console.h
+index d7b45c60cf02f..ab8b19f6affab 100644
+--- a/include/linux/console.h
++++ b/include/linux/console.h
+@@ -40,6 +40,8 @@ enum vc_intensity;
+  * @con_scroll: move lines from @top to @bottom in direction @dir by @lines.
+  *            Return true if no generic handling should be done.
+  *            Invoked by csi_M and printing to the console.
++ * @con_switch: notifier about the console switch; it is supposed to return
++ *            true if a redraw is needed.
+  * @con_set_palette: sets the palette of the console to @table (optional)
+  * @con_scrolldelta: the contents of the console should be scrolled by @lines.
+  *                 Invoked by user. (optional)
+@@ -58,7 +60,7 @@ struct consw {
+       bool    (*con_scroll)(struct vc_data *vc, unsigned int top,
+                       unsigned int bottom, enum con_scroll dir,
+                       unsigned int lines);
+-      int     (*con_switch)(struct vc_data *vc);
++      bool    (*con_switch)(struct vc_data *vc);
+       int     (*con_blank)(struct vc_data *vc, int blank, int mode_switch);
+       int     (*con_font_set)(struct vc_data *vc, struct console_font *font,
+                       unsigned int flags);
+-- 
+2.39.5
+
diff --git a/queue-6.1/tty-vt-make-init-parameter-of-consw-con_init-a-bool.patch b/queue-6.1/tty-vt-make-init-parameter-of-consw-con_init-a-bool.patch
new file mode 100644 (file)
index 0000000..2bede2f
--- /dev/null
@@ -0,0 +1,190 @@
+From b2a965c1cdc07eb5c5de21aa764475e2a3740242 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Jan 2024 12:03:34 +0100
+Subject: tty: vt: make init parameter of consw::con_init() a bool
+
+From: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+
+[ Upstream commit dae3e6b6180f1a2394b984c596d39ed2c57d25fe ]
+
+The 'init' parameter of consw::con_init() is true for the first call of
+the hook on a particular console. So make the parameter a bool.
+
+And document the hook.
+
+Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Cc: Helge Deller <deller@gmx.de>
+Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
+Cc: Daniel Vetter <daniel@ffwll.ch>
+Cc: linux-fbdev@vger.kernel.org
+Cc: dri-devel@lists.freedesktop.org
+Cc: linux-parisc@vger.kernel.org
+Tested-by: Helge Deller <deller@gmx.de> # parisc STI console
+Link: https://lore.kernel.org/r/20240122110401.7289-21-jirislaby@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/vt/vt.c                 | 8 ++++----
+ drivers/video/console/dummycon.c    | 2 +-
+ drivers/video/console/mdacon.c      | 2 +-
+ drivers/video/console/newport_con.c | 2 +-
+ drivers/video/console/sticon.c      | 2 +-
+ drivers/video/console/vgacon.c      | 4 ++--
+ drivers/video/fbdev/core/fbcon.c    | 2 +-
+ include/linux/console.h             | 4 +++-
+ 8 files changed, 14 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
+index e1b40a3848683..cca448ea758b8 100644
+--- a/drivers/tty/vt/vt.c
++++ b/drivers/tty/vt/vt.c
+@@ -1050,7 +1050,7 @@ int vc_cons_allocated(unsigned int i)
+       return (i < MAX_NR_CONSOLES && vc_cons[i].d);
+ }
+-static void visual_init(struct vc_data *vc, int num, int init)
++static void visual_init(struct vc_data *vc, int num, bool init)
+ {
+       /* ++Geert: vc->vc_sw->con_init determines console size */
+       if (vc->vc_sw)
+@@ -1134,7 +1134,7 @@ int vc_allocate(unsigned int currcons)   /* return 0 on success */
+       vc->port.ops = &vc_port_ops;
+       INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
+-      visual_init(vc, currcons, 1);
++      visual_init(vc, currcons, true);
+       if (!*vc->uni_pagedict_loc)
+               con_set_default_unimap(vc);
+@@ -3530,7 +3530,7 @@ static int __init con_init(void)
+               vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT);
+               INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
+               tty_port_init(&vc->port);
+-              visual_init(vc, currcons, 1);
++              visual_init(vc, currcons, true);
+               /* Assuming vc->vc_{cols,rows,screenbuf_size} are sane here. */
+               vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT);
+               vc_init(vc, vc->vc_rows, vc->vc_cols,
+@@ -3701,7 +3701,7 @@ static int do_bind_con_driver(const struct consw *csw, int first, int last,
+               old_was_color = vc->vc_can_do_color;
+               vc->vc_sw->con_deinit(vc);
+               vc->vc_origin = (unsigned long)vc->vc_screenbuf;
+-              visual_init(vc, i, 0);
++              visual_init(vc, i, false);
+               set_origin(vc);
+               update_attr(vc);
+diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c
+index f1711b2f9ff05..9a19eb72a18b9 100644
+--- a/drivers/video/console/dummycon.c
++++ b/drivers/video/console/dummycon.c
+@@ -97,7 +97,7 @@ static const char *dummycon_startup(void)
+     return "dummy device";
+ }
+-static void dummycon_init(struct vc_data *vc, int init)
++static void dummycon_init(struct vc_data *vc, bool init)
+ {
+     vc->vc_can_do_color = 1;
+     if (init) {
+diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
+index ef29b321967f0..c5b255c968794 100644
+--- a/drivers/video/console/mdacon.c
++++ b/drivers/video/console/mdacon.c
+@@ -352,7 +352,7 @@ static const char *mdacon_startup(void)
+       return "MDA-2";
+ }
+-static void mdacon_init(struct vc_data *c, int init)
++static void mdacon_init(struct vc_data *c, bool init)
+ {
+       c->vc_complement_mask = 0x0800;  /* reverse video */
+       c->vc_display_fg = &mda_display_fg;
+diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
+index d9c682ae03926..4b7161a81b2f6 100644
+--- a/drivers/video/console/newport_con.c
++++ b/drivers/video/console/newport_con.c
+@@ -324,7 +324,7 @@ static const char *newport_startup(void)
+       return NULL;
+ }
+-static void newport_init(struct vc_data *vc, int init)
++static void newport_init(struct vc_data *vc, bool init)
+ {
+       int cols, rows;
+diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
+index f304163e87e99..10302df885147 100644
+--- a/drivers/video/console/sticon.c
++++ b/drivers/video/console/sticon.c
+@@ -272,7 +272,7 @@ static int sticon_font_set(struct vc_data *vc, struct console_font *font,
+       return sticon_set_font(vc, font);
+ }
+-static void sticon_init(struct vc_data *c, int init)
++static void sticon_init(struct vc_data *c, bool init)
+ {
+     struct sti_struct *sti = sticon_sti;
+     int vc_cols, vc_rows;
+diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
+index e0d340f5c2dd5..45c611cfce292 100644
+--- a/drivers/video/console/vgacon.c
++++ b/drivers/video/console/vgacon.c
+@@ -332,7 +332,7 @@ static const char *vgacon_startup(void)
+       return display_desc;
+ }
+-static void vgacon_init(struct vc_data *c, int init)
++static void vgacon_init(struct vc_data *c, bool init)
+ {
+       struct uni_pagedict *p;
+@@ -349,7 +349,7 @@ static void vgacon_init(struct vc_data *c, int init)
+       c->vc_scan_lines = vga_scan_lines;
+       c->vc_font.height = c->vc_cell_height = vga_video_font_height;
+-      /* set dimensions manually if init != 0 since vc_resize() will fail */
++      /* set dimensions manually if init is true since vc_resize() will fail */
+       if (init) {
+               c->vc_cols = vga_video_num_columns;
+               c->vc_rows = vga_video_num_lines;
+diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
+index 3f9d2178d3871..3ab08af9cb416 100644
+--- a/drivers/video/fbdev/core/fbcon.c
++++ b/drivers/video/fbdev/core/fbcon.c
+@@ -993,7 +993,7 @@ static const char *fbcon_startup(void)
+       return display_desc;
+ }
+-static void fbcon_init(struct vc_data *vc, int init)
++static void fbcon_init(struct vc_data *vc, bool init)
+ {
+       struct fb_info *info;
+       struct fbcon_ops *ops;
+diff --git a/include/linux/console.h b/include/linux/console.h
+index 8c1686e2c2337..7c17e0cc24f16 100644
+--- a/include/linux/console.h
++++ b/include/linux/console.h
+@@ -34,6 +34,8 @@ enum vc_intensity;
+ /**
+  * struct consw - callbacks for consoles
+  *
++ * @con_init:   initialize the console on @vc. @init is true for the very first
++ *            call on this @vc.
+  * @con_scroll: move lines from @top to @bottom in direction @dir by @lines.
+  *            Return true if no generic handling should be done.
+  *            Invoked by csi_M and printing to the console.
+@@ -44,7 +46,7 @@ enum vc_intensity;
+ struct consw {
+       struct module *owner;
+       const char *(*con_startup)(void);
+-      void    (*con_init)(struct vc_data *vc, int init);
++      void    (*con_init)(struct vc_data *vc, bool init);
+       void    (*con_deinit)(struct vc_data *vc);
+       void    (*con_clear)(struct vc_data *vc, int sy, int sx, int height,
+                       int width);
+-- 
+2.39.5
+
diff --git a/queue-6.1/tty-vt-sanitize-arguments-of-consw-con_clear.patch b/queue-6.1/tty-vt-sanitize-arguments-of-consw-con_clear.patch
new file mode 100644 (file)
index 0000000..8dba316
--- /dev/null
@@ -0,0 +1,313 @@
+From 61d8fa3082a910da782fe7650f129a0e7b180e87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Jan 2024 12:03:35 +0100
+Subject: tty: vt: sanitize arguments of consw::con_clear()
+
+From: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+
+[ Upstream commit 559f01a0ee6d924c6fec3eaf6a5b078b15e71070 ]
+
+In consw::con_clear():
+* Height is always 1, so drop it.
+* Offsets and width are always unsigned values, so re-type them as such.
+
+This needs a new __fbcon_clear() in the fbcon code to still handle
+height which might not be 1 when called internally.
+
+Note that tests for negative count/width are left in place -- they are
+taken care of in the next patches.
+
+And document the hook.
+
+Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>
+Cc: Helge Deller <deller@gmx.de>
+Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
+Cc: Daniel Vetter <daniel@ffwll.ch>
+Cc: linux-fbdev@vger.kernel.org
+Cc: dri-devel@lists.freedesktop.org
+Cc: linux-parisc@vger.kernel.org
+Tested-by: Helge Deller <deller@gmx.de> # parisc STI console
+Link: https://lore.kernel.org/r/20240122110401.7289-22-jirislaby@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/vt/vt.c                 |  2 +-
+ drivers/video/console/dummycon.c    |  4 ++--
+ drivers/video/console/mdacon.c      | 15 +++++---------
+ drivers/video/console/newport_con.c |  6 +++---
+ drivers/video/console/sticon.c      |  8 ++++----
+ drivers/video/console/vgacon.c      |  4 ++--
+ drivers/video/fbdev/core/fbcon.c    | 32 +++++++++++++++++------------
+ include/linux/console.h             |  5 +++--
+ 8 files changed, 39 insertions(+), 37 deletions(-)
+
+diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
+index cca448ea758b8..609d2bac58d0b 100644
+--- a/drivers/tty/vt/vt.c
++++ b/drivers/tty/vt/vt.c
+@@ -1628,7 +1628,7 @@ static void csi_X(struct vc_data *vc, unsigned int vpar)
+       vc_uniscr_clear_line(vc, vc->state.x, count);
+       scr_memsetw((unsigned short *)vc->vc_pos, vc->vc_video_erase_char, 2 * count);
+       if (con_should_update(vc))
+-              vc->vc_sw->con_clear(vc, vc->state.y, vc->state.x, 1, count);
++              vc->vc_sw->con_clear(vc, vc->state.y, vc->state.x, count);
+       vc->vc_need_wrap = 0;
+ }
+diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c
+index 9a19eb72a18b9..6918014b02408 100644
+--- a/drivers/video/console/dummycon.c
++++ b/drivers/video/console/dummycon.c
+@@ -108,8 +108,8 @@ static void dummycon_init(struct vc_data *vc, bool init)
+ }
+ static void dummycon_deinit(struct vc_data *vc) { }
+-static void dummycon_clear(struct vc_data *vc, int sy, int sx, int height,
+-                         int width) { }
++static void dummycon_clear(struct vc_data *vc, unsigned int sy, unsigned int sx,
++                         unsigned int width) { }
+ static void dummycon_cursor(struct vc_data *vc, int mode) { }
+ static bool dummycon_scroll(struct vc_data *vc, unsigned int top,
+diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
+index c5b255c968794..1ddbb6cd5b0ca 100644
+--- a/drivers/video/console/mdacon.c
++++ b/drivers/video/console/mdacon.c
+@@ -442,23 +442,18 @@ static void mdacon_putcs(struct vc_data *c, const unsigned short *s,
+       }
+ }
+-static void mdacon_clear(struct vc_data *c, int y, int x, 
+-                        int height, int width)
++static void mdacon_clear(struct vc_data *c, unsigned int y, unsigned int x,
++                       unsigned int width)
+ {
+       u16 *dest = mda_addr(x, y);
+       u16 eattr = mda_convert_attr(c->vc_video_erase_char);
+-      if (width <= 0 || height <= 0)
++      if (width <= 0)
+               return;
+-      if (x==0 && width==mda_num_columns) {
+-              scr_memsetw(dest, eattr, height*width*2);
+-      } else {
+-              for (; height > 0; height--, dest+=mda_num_columns)
+-                      scr_memsetw(dest, eattr, width*2);
+-      }
++      scr_memsetw(dest, eattr, width * 2);
+ }
+-                        
++
+ static int mdacon_switch(struct vc_data *c)
+ {
+       return 1;       /* redrawing needed */
+diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
+index 4b7161a81b2f6..5dac00c825946 100644
+--- a/drivers/video/console/newport_con.c
++++ b/drivers/video/console/newport_con.c
+@@ -346,12 +346,12 @@ static void newport_deinit(struct vc_data *c)
+       }
+ }
+-static void newport_clear(struct vc_data *vc, int sy, int sx, int height,
+-                        int width)
++static void newport_clear(struct vc_data *vc, unsigned int sy, unsigned int sx,
++                        unsigned int width)
+ {
+       int xend = ((sx + width) << 3) - 1;
+       int ystart = ((sy << 4) + topscan) & 0x3ff;
+-      int yend = (((sy + height) << 4) + topscan - 1) & 0x3ff;
++      int yend = (((sy + 1) << 4) + topscan - 1) & 0x3ff;
+       if (logo_active)
+               return;
+diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
+index 10302df885147..58e983b18f1f4 100644
+--- a/drivers/video/console/sticon.c
++++ b/drivers/video/console/sticon.c
+@@ -299,13 +299,13 @@ static void sticon_deinit(struct vc_data *c)
+       sticon_set_def_font(i, NULL);
+ }
+-static void sticon_clear(struct vc_data *conp, int sy, int sx, int height,
+-                       int width)
++static void sticon_clear(struct vc_data *conp, unsigned int sy, unsigned int sx,
++                       unsigned int width)
+ {
+-    if (!height || !width)
++    if (!width)
+       return;
+-    sti_clear(sticon_sti, sy, sx, height, width,
++    sti_clear(sticon_sti, sy, sx, 1, width,
+             conp->vc_video_erase_char, font_data[conp->vc_num]);
+ }
+diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
+index 45c611cfce292..6998e28441c97 100644
+--- a/drivers/video/console/vgacon.c
++++ b/drivers/video/console/vgacon.c
+@@ -1166,8 +1166,8 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b,
+  *  The console `switch' structure for the VGA based console
+  */
+-static void vgacon_clear(struct vc_data *vc, int sy, int sx, int height,
+-                       int width) { }
++static void vgacon_clear(struct vc_data *vc, unsigned int sy, unsigned int sx,
++                       unsigned int width) { }
+ static void vgacon_putc(struct vc_data *vc, int c, int ypos, int xpos) { }
+ static void vgacon_putcs(struct vc_data *vc, const unsigned short *s,
+                        int count, int ypos, int xpos) { }
+diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
+index 3ab08af9cb416..3fd76dc6010b4 100644
+--- a/drivers/video/fbdev/core/fbcon.c
++++ b/drivers/video/fbdev/core/fbcon.c
+@@ -1240,8 +1240,8 @@ static void fbcon_deinit(struct vc_data *vc)
+  *  restriction is simplicity & efficiency at the moment.
+  */
+-static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
+-                      int width)
++static void __fbcon_clear(struct vc_data *vc, unsigned int sy, unsigned int sx,
++                        unsigned int height, unsigned int width)
+ {
+       struct fb_info *info = fbcon_info_from_console(vc->vc_num);
+       struct fbcon_ops *ops = info->fbcon_par;
+@@ -1280,6 +1280,12 @@ static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
+               ops->clear(vc, info, real_y(p, sy), sx, height, width, fg, bg);
+ }
++static void fbcon_clear(struct vc_data *vc, unsigned int sy, unsigned int sx,
++                      unsigned int width)
++{
++      __fbcon_clear(vc, sy, sx, 1, width);
++}
++
+ static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
+                       int count, int ypos, int xpos)
+ {
+@@ -1768,7 +1774,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
+               case SCROLL_MOVE:
+                       fbcon_redraw_blit(vc, info, p, t, b - t - count,
+                                    count);
+-                      fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
++                      __fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
+                       scr_memsetw((unsigned short *) (vc->vc_origin +
+                                                       vc->vc_size_row *
+                                                       (b - count)),
+@@ -1791,7 +1797,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
+                                           b - t - count, vc->vc_cols);
+                       else
+                               goto redraw_up;
+-                      fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
++                      __fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
+                       break;
+               case SCROLL_PAN_REDRAW:
+@@ -1809,7 +1815,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
+                                                         vc->vc_rows - b, b);
+                       } else
+                               fbcon_redraw_move(vc, p, t + count, b - t - count, t);
+-                      fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
++                      __fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
+                       break;
+               case SCROLL_PAN_MOVE:
+@@ -1832,14 +1838,14 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
+                                           b - t - count, vc->vc_cols);
+                       else
+                               goto redraw_up;
+-                      fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
++                      __fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
+                       break;
+               case SCROLL_REDRAW:
+                     redraw_up:
+                       fbcon_redraw(vc, p, t, b - t - count,
+                                    count * vc->vc_cols);
+-                      fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
++                      __fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
+                       scr_memsetw((unsigned short *) (vc->vc_origin +
+                                                       vc->vc_size_row *
+                                                       (b - count)),
+@@ -1856,7 +1862,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
+               case SCROLL_MOVE:
+                       fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
+                                    -count);
+-                      fbcon_clear(vc, t, 0, count, vc->vc_cols);
++                      __fbcon_clear(vc, t, 0, count, vc->vc_cols);
+                       scr_memsetw((unsigned short *) (vc->vc_origin +
+                                                       vc->vc_size_row *
+                                                       t),
+@@ -1879,7 +1885,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
+                                           b - t - count, vc->vc_cols);
+                       else
+                               goto redraw_down;
+-                      fbcon_clear(vc, t, 0, count, vc->vc_cols);
++                      __fbcon_clear(vc, t, 0, count, vc->vc_cols);
+                       break;
+               case SCROLL_PAN_MOVE:
+@@ -1901,7 +1907,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
+                                           b - t - count, vc->vc_cols);
+                       else
+                               goto redraw_down;
+-                      fbcon_clear(vc, t, 0, count, vc->vc_cols);
++                      __fbcon_clear(vc, t, 0, count, vc->vc_cols);
+                       break;
+               case SCROLL_PAN_REDRAW:
+@@ -1918,14 +1924,14 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
+                                       fbcon_redraw_move(vc, p, count, t, 0);
+                       } else
+                               fbcon_redraw_move(vc, p, t, b - t - count, t + count);
+-                      fbcon_clear(vc, t, 0, count, vc->vc_cols);
++                      __fbcon_clear(vc, t, 0, count, vc->vc_cols);
+                       break;
+               case SCROLL_REDRAW:
+                     redraw_down:
+                       fbcon_redraw(vc, p, b - 1, b - t - count,
+                                    -count * vc->vc_cols);
+-                      fbcon_clear(vc, t, 0, count, vc->vc_cols);
++                      __fbcon_clear(vc, t, 0, count, vc->vc_cols);
+                       scr_memsetw((unsigned short *) (vc->vc_origin +
+                                                       vc->vc_size_row *
+                                                       t),
+@@ -2204,7 +2210,7 @@ static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info,
+               oldc = vc->vc_video_erase_char;
+               vc->vc_video_erase_char &= charmask;
+-              fbcon_clear(vc, 0, 0, vc->vc_rows, vc->vc_cols);
++              __fbcon_clear(vc, 0, 0, vc->vc_rows, vc->vc_cols);
+               vc->vc_video_erase_char = oldc;
+       }
+ }
+diff --git a/include/linux/console.h b/include/linux/console.h
+index 7c17e0cc24f16..d7b45c60cf02f 100644
+--- a/include/linux/console.h
++++ b/include/linux/console.h
+@@ -36,6 +36,7 @@ enum vc_intensity;
+  *
+  * @con_init:   initialize the console on @vc. @init is true for the very first
+  *            call on this @vc.
++ * @con_clear:  erase @count characters at [@x, @y] on @vc. @count >= 1.
+  * @con_scroll: move lines from @top to @bottom in direction @dir by @lines.
+  *            Return true if no generic handling should be done.
+  *            Invoked by csi_M and printing to the console.
+@@ -48,8 +49,8 @@ struct consw {
+       const char *(*con_startup)(void);
+       void    (*con_init)(struct vc_data *vc, bool init);
+       void    (*con_deinit)(struct vc_data *vc);
+-      void    (*con_clear)(struct vc_data *vc, int sy, int sx, int height,
+-                      int width);
++      void    (*con_clear)(struct vc_data *vc, unsigned int y,
++                           unsigned int x, unsigned int count);
+       void    (*con_putc)(struct vc_data *vc, int c, int ypos, int xpos);
+       void    (*con_putcs)(struct vc_data *vc, const unsigned short *s,
+                       int count, int ypos, int xpos);
+-- 
+2.39.5
+
diff --git a/queue-6.1/uio_hv_generic-align-ring-size-to-system-page.patch b/queue-6.1/uio_hv_generic-align-ring-size-to-system-page.patch
new file mode 100644 (file)
index 0000000..5792404
--- /dev/null
@@ -0,0 +1,41 @@
+From 17ea0c5c1d56de73a2922b416876bc3593b6ba8b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 May 2025 17:56:35 -0700
+Subject: uio_hv_generic: Align ring size to system page
+
+From: Long Li <longli@microsoft.com>
+
+[ Upstream commit 0315fef2aff9f251ddef8a4b53db9187429c3553 ]
+
+Following the ring header, the ring data should align to system page
+boundary. Adjust the size if necessary.
+
+Cc: stable@vger.kernel.org
+Fixes: 95096f2fbd10 ("uio-hv-generic: new userspace i/o driver for VMBus")
+Signed-off-by: Long Li <longli@microsoft.com>
+Reviewed-by: Michael Kelley <mhklinux@outlook.com>
+Link: https://lore.kernel.org/r/1746492997-4599-4-git-send-email-longli@linuxonhyperv.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Message-ID: <1746492997-4599-4-git-send-email-longli@linuxonhyperv.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/uio/uio_hv_generic.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c
+index 8cb724095be6d..2cfe0087abc19 100644
+--- a/drivers/uio/uio_hv_generic.c
++++ b/drivers/uio/uio_hv_generic.c
+@@ -260,6 +260,9 @@ hv_uio_probe(struct hv_device *dev,
+       if (!ring_size)
+               ring_size = HV_RING_SIZE * PAGE_SIZE;
++      /* Adjust ring size if necessary to have it page aligned */
++      ring_size = VMBUS_RING_SIZE(ring_size);
++
+       pdata = devm_kzalloc(&dev->device, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return -ENOMEM;
+-- 
+2.39.5
+
diff --git a/queue-6.1/uio_hv_generic-query-the-ringbuffer-size-for-device.patch b/queue-6.1/uio_hv_generic-query-the-ringbuffer-size-for-device.patch
new file mode 100644 (file)
index 0000000..77251f0
--- /dev/null
@@ -0,0 +1,56 @@
+From 2c938acf5c9e2d71c1447ea044a3268e4c398ac7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 Mar 2024 01:51:58 -0700
+Subject: uio_hv_generic: Query the ringbuffer size for device
+
+From: Saurabh Sengar <ssengar@linux.microsoft.com>
+
+[ Upstream commit e566ed5b64177a0c07b677568f623ed31d23406d ]
+
+Query the ring buffer size from pre defined table per device
+and use that value for allocating the ring buffer for that
+device. Keep the size as current default which is 2 MB if
+the device doesn't have any preferred ring size.
+
+Signed-off-by: Saurabh Sengar <ssengar@linux.microsoft.com>
+Reviewed-by: Long Li <longli@microsoft.com>
+Link: https://lore.kernel.org/r/1711788723-8593-3-git-send-email-ssengar@linux.microsoft.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 0315fef2aff9 ("uio_hv_generic: Align ring size to system page")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/uio/uio_hv_generic.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c
+index 94dda3d4d509f..8cb724095be6d 100644
+--- a/drivers/uio/uio_hv_generic.c
++++ b/drivers/uio/uio_hv_generic.c
+@@ -249,6 +249,7 @@ hv_uio_probe(struct hv_device *dev,
+       struct hv_uio_private_data *pdata;
+       void *ring_buffer;
+       int ret;
++      size_t ring_size = hv_dev_ring_size(channel);
+       /* Communicating with host has to be via shared memory not hypercall */
+       if (!channel->offermsg.monitor_allocated) {
+@@ -256,12 +257,14 @@ hv_uio_probe(struct hv_device *dev,
+               return -ENOTSUPP;
+       }
++      if (!ring_size)
++              ring_size = HV_RING_SIZE * PAGE_SIZE;
++
+       pdata = devm_kzalloc(&dev->device, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return -ENOMEM;
+-      ret = vmbus_alloc_ring(channel, HV_RING_SIZE * PAGE_SIZE,
+-                             HV_RING_SIZE * PAGE_SIZE);
++      ret = vmbus_alloc_ring(channel, ring_size, ring_size);
+       if (ret)
+               return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.1/um-add-cmpxchg8b_emu-and-checksum-functions-to-asm-p.patch b/queue-6.1/um-add-cmpxchg8b_emu-and-checksum-functions-to-asm-p.patch
new file mode 100644 (file)
index 0000000..f10297d
--- /dev/null
@@ -0,0 +1,55 @@
+From 73a6923c066978c7a5a4b18660e1e38b263ec409 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Mar 2025 19:05:00 +0000
+Subject: um: Add cmpxchg8b_emu and checksum functions to asm-prototypes.h
+
+From: Sami Tolvanen <samitolvanen@google.com>
+
+[ Upstream commit 674d03f6bd6b0f8327f1a4920ff5893557facfbd ]
+
+With CONFIG_GENDWARFKSYMS, um builds fail due to missing prototypes
+in asm/asm-prototypes.h. Add declarations for cmpxchg8b_emu and the
+exported checksum functions, including csum_partial_copy_generic as
+it's also exported.
+
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: linux-kbuild@vger.kernel.org
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202503251216.lE4t9Ikj-lkp@intel.com/
+Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
+Link: https://patch.msgid.link/20250326190500.847236-2-samitolvanen@google.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/um/include/asm/asm-prototypes.h | 5 +++++
+ arch/x86/um/asm/checksum.h           | 3 +++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/arch/um/include/asm/asm-prototypes.h b/arch/um/include/asm/asm-prototypes.h
+index 5898a26daa0dd..408b31d591279 100644
+--- a/arch/um/include/asm/asm-prototypes.h
++++ b/arch/um/include/asm/asm-prototypes.h
+@@ -1 +1,6 @@
+ #include <asm-generic/asm-prototypes.h>
++#include <asm/checksum.h>
++
++#ifdef CONFIG_UML_X86
++extern void cmpxchg8b_emu(void);
++#endif
+diff --git a/arch/x86/um/asm/checksum.h b/arch/x86/um/asm/checksum.h
+index b07824500363f..ddc144657efad 100644
+--- a/arch/x86/um/asm/checksum.h
++++ b/arch/x86/um/asm/checksum.h
+@@ -20,6 +20,9 @@
+  */
+ extern __wsum csum_partial(const void *buff, int len, __wsum sum);
++/* Do not call this directly. Declared for export type visibility. */
++extern __visible __wsum csum_partial_copy_generic(const void *src, void *dst, int len);
++
+ /**
+  * csum_fold - Fold and invert a 32bit checksum.
+  * sum: 32bit unfolded sum
+-- 
+2.39.5
+
diff --git a/queue-6.1/um-use-proper-care-when-taking-mmap-lock-during-segf.patch b/queue-6.1/um-use-proper-care-when-taking-mmap-lock-during-segf.patch
new file mode 100644 (file)
index 0000000..6773a92
--- /dev/null
@@ -0,0 +1,177 @@
+From fc7af87ac02d1bb82d42d35d01d5f03b441e2afe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 09:45:24 +0200
+Subject: um: use proper care when taking mmap lock during segfault
+
+From: Benjamin Berg <benjamin.berg@intel.com>
+
+[ Upstream commit 6767e8784cd2e8b386a62330ea6864949d983a3e ]
+
+Segfaults can occur at times where the mmap lock cannot be taken. If
+that happens the segfault handler may not be able to take the mmap lock.
+
+Fix the code to use the same approach as most other architectures.
+Unfortunately, this requires copying code from mm/memory.c and modifying
+it slightly as UML does not have exception tables.
+
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Link: https://patch.msgid.link/20250408074524.300153-2-benjamin@sipsolutions.net
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/um/kernel/trap.c | 129 ++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 117 insertions(+), 12 deletions(-)
+
+diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
+index 6d8ae86ae978f..c16b80011adaa 100644
+--- a/arch/um/kernel/trap.c
++++ b/arch/um/kernel/trap.c
+@@ -17,6 +17,122 @@
+ #include <os.h>
+ #include <skas.h>
++/*
++ * NOTE: UML does not have exception tables. As such, this is almost a copy
++ * of the code in mm/memory.c, only adjusting the logic to simply check whether
++ * we are coming from the kernel instead of doing an additional lookup in the
++ * exception table.
++ * We can do this simplification because we never get here if the exception was
++ * fixable.
++ */
++static inline bool get_mmap_lock_carefully(struct mm_struct *mm, bool is_user)
++{
++      if (likely(mmap_read_trylock(mm)))
++              return true;
++
++      if (!is_user)
++              return false;
++
++      return !mmap_read_lock_killable(mm);
++}
++
++static inline bool mmap_upgrade_trylock(struct mm_struct *mm)
++{
++      /*
++       * We don't have this operation yet.
++       *
++       * It should be easy enough to do: it's basically a
++       *    atomic_long_try_cmpxchg_acquire()
++       * from RWSEM_READER_BIAS -> RWSEM_WRITER_LOCKED, but
++       * it also needs the proper lockdep magic etc.
++       */
++      return false;
++}
++
++static inline bool upgrade_mmap_lock_carefully(struct mm_struct *mm, bool is_user)
++{
++      mmap_read_unlock(mm);
++      if (!is_user)
++              return false;
++
++      return !mmap_write_lock_killable(mm);
++}
++
++/*
++ * Helper for page fault handling.
++ *
++ * This is kind of equivalend to "mmap_read_lock()" followed
++ * by "find_extend_vma()", except it's a lot more careful about
++ * the locking (and will drop the lock on failure).
++ *
++ * For example, if we have a kernel bug that causes a page
++ * fault, we don't want to just use mmap_read_lock() to get
++ * the mm lock, because that would deadlock if the bug were
++ * to happen while we're holding the mm lock for writing.
++ *
++ * So this checks the exception tables on kernel faults in
++ * order to only do this all for instructions that are actually
++ * expected to fault.
++ *
++ * We can also actually take the mm lock for writing if we
++ * need to extend the vma, which helps the VM layer a lot.
++ */
++static struct vm_area_struct *
++um_lock_mm_and_find_vma(struct mm_struct *mm,
++                      unsigned long addr, bool is_user)
++{
++      struct vm_area_struct *vma;
++
++      if (!get_mmap_lock_carefully(mm, is_user))
++              return NULL;
++
++      vma = find_vma(mm, addr);
++      if (likely(vma && (vma->vm_start <= addr)))
++              return vma;
++
++      /*
++       * Well, dang. We might still be successful, but only
++       * if we can extend a vma to do so.
++       */
++      if (!vma || !(vma->vm_flags & VM_GROWSDOWN)) {
++              mmap_read_unlock(mm);
++              return NULL;
++      }
++
++      /*
++       * We can try to upgrade the mmap lock atomically,
++       * in which case we can continue to use the vma
++       * we already looked up.
++       *
++       * Otherwise we'll have to drop the mmap lock and
++       * re-take it, and also look up the vma again,
++       * re-checking it.
++       */
++      if (!mmap_upgrade_trylock(mm)) {
++              if (!upgrade_mmap_lock_carefully(mm, is_user))
++                      return NULL;
++
++              vma = find_vma(mm, addr);
++              if (!vma)
++                      goto fail;
++              if (vma->vm_start <= addr)
++                      goto success;
++              if (!(vma->vm_flags & VM_GROWSDOWN))
++                      goto fail;
++      }
++
++      if (expand_stack_locked(vma, addr))
++              goto fail;
++
++success:
++      mmap_write_downgrade(mm);
++      return vma;
++
++fail:
++      mmap_write_unlock(mm);
++      return NULL;
++}
++
+ /*
+  * Note this is constrained to return 0, -EFAULT, -EACCES, -ENOMEM by
+  * segv().
+@@ -43,21 +159,10 @@ int handle_page_fault(unsigned long address, unsigned long ip,
+       if (is_user)
+               flags |= FAULT_FLAG_USER;
+ retry:
+-      mmap_read_lock(mm);
+-      vma = find_vma(mm, address);
+-      if (!vma)
+-              goto out;
+-      if (vma->vm_start <= address)
+-              goto good_area;
+-      if (!(vma->vm_flags & VM_GROWSDOWN))
+-              goto out;
+-      if (is_user && !ARCH_IS_STACKGROW(address))
+-              goto out;
+-      vma = expand_stack(mm, address);
++      vma = um_lock_mm_and_find_vma(mm, address, is_user);
+       if (!vma)
+               goto out_nosemaphore;
+-good_area:
+       *code_out = SEGV_ACCERR;
+       if (is_write) {
+               if (!(vma->vm_flags & VM_WRITE))
+-- 
+2.39.5
+
diff --git a/queue-6.1/usb-add-checks-for-snprintf-calls-in-usb_alloc_dev.patch b/queue-6.1/usb-add-checks-for-snprintf-calls-in-usb_alloc_dev.patch
new file mode 100644 (file)
index 0000000..7392539
--- /dev/null
@@ -0,0 +1,72 @@
+From a9e35ebfc537bf2fe7ff000358dc2ca26545f8f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Mar 2025 18:49:49 +0200
+Subject: usb: Add checks for snprintf() calls in usb_alloc_dev()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 82fe5107fa3d21d6c3fba091c9dbc50495588630 ]
+
+When creating a device path in the driver the snprintf() takes
+up to 16 characters long argument along with the additional up to
+12 characters for the signed integer (as it can't see the actual limits)
+and tries to pack this into 16 bytes array. GCC complains about that
+when build with `make W=1`:
+
+  drivers/usb/core/usb.c:705:25: note: ‘snprintf’ output between 3 and 28 bytes into a destination of size 16
+
+Since everything works until now, let's just check for the potential
+buffer overflow and bail out. It is most likely a never happen situation,
+but at least it makes GCC happy.
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20250321164949.423957-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/core/usb.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
+index 3500e3c94c4b8..2215f8ca54170 100644
+--- a/drivers/usb/core/usb.c
++++ b/drivers/usb/core/usb.c
+@@ -704,15 +704,16 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
+               dev_set_name(&dev->dev, "usb%d", bus->busnum);
+               root_hub = 1;
+       } else {
++              int n;
++
+               /* match any labeling on the hubs; it's one-based */
+               if (parent->devpath[0] == '0') {
+-                      snprintf(dev->devpath, sizeof dev->devpath,
+-                              "%d", port1);
++                      n = snprintf(dev->devpath, sizeof(dev->devpath), "%d", port1);
+                       /* Root ports are not counted in route string */
+                       dev->route = 0;
+               } else {
+-                      snprintf(dev->devpath, sizeof dev->devpath,
+-                              "%s.%d", parent->devpath, port1);
++                      n = snprintf(dev->devpath, sizeof(dev->devpath), "%s.%d",
++                                   parent->devpath, port1);
+                       /* Route string assumes hubs have less than 16 ports */
+                       if (port1 < 15)
+                               dev->route = parent->route +
+@@ -721,6 +722,11 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
+                               dev->route = parent->route +
+                                       (15 << ((parent->level - 1)*4));
+               }
++              if (n >= sizeof(dev->devpath)) {
++                      usb_put_hcd(bus_to_hcd(bus));
++                      usb_put_dev(dev);
++                      return NULL;
++              }
+               dev->dev.parent = &parent->dev;
+               dev_set_name(&dev->dev, "%d-%s", bus->busnum, dev->devpath);
+-- 
+2.39.5
+
diff --git a/queue-6.1/usb-cdc-wdm-avoid-setting-wdm_read-for-zlp-s.patch b/queue-6.1/usb-cdc-wdm-avoid-setting-wdm_read-for-zlp-s.patch
new file mode 100644 (file)
index 0000000..d26db4d
--- /dev/null
@@ -0,0 +1,114 @@
+From cad5c627f78e4ec85a26e6dc3959b9bc561bda72 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 16:40:04 +0200
+Subject: usb: cdc-wdm: avoid setting WDM_READ for ZLP-s
+
+From: Robert Hodaszi <robert.hodaszi@digi.com>
+
+[ Upstream commit 387602d8a75574fafb451b7a8215e78dfd67ee63 ]
+
+Don't set WDM_READ flag in wdm_in_callback() for ZLP-s, otherwise when
+userspace tries to poll for available data, it might - incorrectly -
+believe there is something available, and when it tries to non-blocking
+read it, it might get stuck in the read loop.
+
+For example this is what glib does for non-blocking read (briefly):
+
+  1. poll()
+  2. if poll returns with non-zero, starts a read data loop:
+    a. loop on poll() (EINTR disabled)
+    b. if revents was set, reads data
+      I. if read returns with EINTR or EAGAIN, goto 2.a.
+      II. otherwise return with data
+
+So if ZLP sets WDM_READ (#1), we expect data, and try to read it (#2).
+But as that was a ZLP, and we are doing non-blocking read, wdm_read()
+returns with EAGAIN (#2.b.I), so loop again, and try to read again
+(#2.a.).
+
+With glib, we might stuck in this loop forever, as EINTR is disabled
+(#2.a).
+
+Signed-off-by: Robert Hodaszi <robert.hodaszi@digi.com>
+Acked-by: Oliver Neukum <oneukum@suse.com>
+Link: https://lore.kernel.org/r/20250403144004.3889125-1-robert.hodaszi@digi.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/class/cdc-wdm.c | 23 +++++++++--------------
+ 1 file changed, 9 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
+index e3408a67af452..3da91bb8b3161 100644
+--- a/drivers/usb/class/cdc-wdm.c
++++ b/drivers/usb/class/cdc-wdm.c
+@@ -92,7 +92,6 @@ struct wdm_device {
+       u16                     wMaxCommand;
+       u16                     wMaxPacketSize;
+       __le16                  inum;
+-      int                     reslength;
+       int                     length;
+       int                     read;
+       int                     count;
+@@ -214,6 +213,11 @@ static void wdm_in_callback(struct urb *urb)
+       if (desc->rerr == 0 && status != -EPIPE)
+               desc->rerr = status;
++      if (length == 0) {
++              dev_dbg(&desc->intf->dev, "received ZLP\n");
++              goto skip_zlp;
++      }
++
+       if (length + desc->length > desc->wMaxCommand) {
+               /* The buffer would overflow */
+               set_bit(WDM_OVERFLOW, &desc->flags);
+@@ -222,18 +226,18 @@ static void wdm_in_callback(struct urb *urb)
+               if (!test_bit(WDM_OVERFLOW, &desc->flags)) {
+                       memmove(desc->ubuf + desc->length, desc->inbuf, length);
+                       desc->length += length;
+-                      desc->reslength = length;
+               }
+       }
+ skip_error:
+       if (desc->rerr) {
+               /*
+-               * Since there was an error, userspace may decide to not read
+-               * any data after poll'ing.
++               * If there was a ZLP or an error, userspace may decide to not
++               * read any data after poll'ing.
+                * We should respond to further attempts from the device to send
+                * data, so that we can get unstuck.
+                */
++skip_zlp:
+               schedule_work(&desc->service_outs_intr);
+       } else {
+               set_bit(WDM_READ, &desc->flags);
+@@ -585,15 +589,6 @@ static ssize_t wdm_read
+                       goto retry;
+               }
+-              if (!desc->reslength) { /* zero length read */
+-                      dev_dbg(&desc->intf->dev, "zero length - clearing WDM_READ\n");
+-                      clear_bit(WDM_READ, &desc->flags);
+-                      rv = service_outstanding_interrupt(desc);
+-                      spin_unlock_irq(&desc->iuspin);
+-                      if (rv < 0)
+-                              goto err;
+-                      goto retry;
+-              }
+               cntr = desc->length;
+               spin_unlock_irq(&desc->iuspin);
+       }
+@@ -1015,7 +1010,7 @@ static void service_interrupt_work(struct work_struct *work)
+       spin_lock_irq(&desc->iuspin);
+       service_outstanding_interrupt(desc);
+-      if (!desc->resp_count) {
++      if (!desc->resp_count && (desc->length || desc->rerr)) {
+               set_bit(WDM_READ, &desc->flags);
+               wake_up(&desc->wait);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.1/usb-common-usb-conn-gpio-use-a-unique-name-for-usb-c.patch b/queue-6.1/usb-common-usb-conn-gpio-use-a-unique-name-for-usb-c.patch
new file mode 100644 (file)
index 0000000..aa7df4c
--- /dev/null
@@ -0,0 +1,93 @@
+From 91d9e64dbdb5a72df14513dcbc0b6a76c71e323b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Apr 2025 16:33:26 +0800
+Subject: usb: common: usb-conn-gpio: use a unique name for usb connector
+ device
+
+From: Chance Yang <chance.yang@kneron.us>
+
+[ Upstream commit d4e5b10c55627e2f3fc9e5b337a28b4e2f02a55e ]
+
+The current implementation of the usb-conn-gpio driver uses a fixed
+"usb-charger" name for all USB connector devices. This causes conflicts
+in the power supply subsystem when multiple USB connectors are present,
+as duplicate names are not allowed.
+
+Use IDA to manage unique IDs for naming usb connectors (e.g.,
+usb-charger-0, usb-charger-1).
+
+Signed-off-by: Chance Yang <chance.yang@kneron.us>
+Link: https://lore.kernel.org/r/20250411-work-next-v3-1-7cd9aa80190c@kneron.us
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/common/usb-conn-gpio.c | 25 ++++++++++++++++++++++---
+ 1 file changed, 22 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/common/usb-conn-gpio.c b/drivers/usb/common/usb-conn-gpio.c
+index 3f5180d64931b..91461c744fcdd 100644
+--- a/drivers/usb/common/usb-conn-gpio.c
++++ b/drivers/usb/common/usb-conn-gpio.c
+@@ -20,6 +20,9 @@
+ #include <linux/power_supply.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/usb/role.h>
++#include <linux/idr.h>
++
++static DEFINE_IDA(usb_conn_ida);
+ #define USB_GPIO_DEB_MS               20      /* ms */
+ #define USB_GPIO_DEB_US               ((USB_GPIO_DEB_MS) * 1000)      /* us */
+@@ -29,6 +32,7 @@
+ struct usb_conn_info {
+       struct device *dev;
++      int conn_id; /* store the IDA-allocated ID */
+       struct usb_role_switch *role_sw;
+       enum usb_role last_role;
+       struct regulator *vbus;
+@@ -160,7 +164,17 @@ static int usb_conn_psy_register(struct usb_conn_info *info)
+               .of_node = dev->of_node,
+       };
+-      desc->name = "usb-charger";
++      info->conn_id = ida_alloc(&usb_conn_ida, GFP_KERNEL);
++      if (info->conn_id < 0)
++              return info->conn_id;
++
++      desc->name = devm_kasprintf(dev, GFP_KERNEL, "usb-charger-%d",
++                                  info->conn_id);
++      if (!desc->name) {
++              ida_free(&usb_conn_ida, info->conn_id);
++              return -ENOMEM;
++      }
++
+       desc->properties = usb_charger_properties;
+       desc->num_properties = ARRAY_SIZE(usb_charger_properties);
+       desc->get_property = usb_charger_get_property;
+@@ -168,8 +182,10 @@ static int usb_conn_psy_register(struct usb_conn_info *info)
+       cfg.drv_data = info;
+       info->charger = devm_power_supply_register(dev, desc, &cfg);
+-      if (IS_ERR(info->charger))
+-              dev_err(dev, "Unable to register charger\n");
++      if (IS_ERR(info->charger)) {
++              dev_err(dev, "Unable to register charger %d\n", info->conn_id);
++              ida_free(&usb_conn_ida, info->conn_id);
++      }
+       return PTR_ERR_OR_ZERO(info->charger);
+ }
+@@ -277,6 +293,9 @@ static int usb_conn_remove(struct platform_device *pdev)
+       cancel_delayed_work_sync(&info->dw_det);
++      if (info->charger)
++              ida_free(&usb_conn_ida, info->conn_id);
++
+       if (info->last_role == USB_ROLE_HOST && info->vbus)
+               regulator_disable(info->vbus);
+-- 
+2.39.5
+
diff --git a/queue-6.1/usb-dwc2-also-exit-clock_gating-when-stopping-udc-wh.patch b/queue-6.1/usb-dwc2-also-exit-clock_gating-when-stopping-udc-wh.patch
new file mode 100644 (file)
index 0000000..4c9bfad
--- /dev/null
@@ -0,0 +1,47 @@
+From c4faddc0e12d8704ff870628f5b9d4a6b02ed169 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Apr 2025 19:40:17 +0200
+Subject: usb: dwc2: also exit clock_gating when stopping udc while suspended
+
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+
+[ Upstream commit af076a41f8a28faf9ceb9dd2d88aef2c202ef39a ]
+
+It is possible that the gadget will be disabled, while the udc is
+suspended. When enabling the udc in that case, the clock gating
+will not be enabled again. Leaving the phy unclocked. Even when the
+udc is not enabled, connecting this powered but not clocked phy leads
+to enumeration errors on the host side.
+
+To ensure that the clock gating will be in an valid state, we ensure
+that the clock gating will be enabled before stopping the udc.
+
+Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Acked-by: Minas Harutyunyan <hminas@synopsys.com>
+Link: https://lore.kernel.org/r/20250417-dwc2_clock_gating-v1-1-8ea7c4d53d73@pengutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc2/gadget.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
+index cea6c4fc79956..d4ca1677ad234 100644
+--- a/drivers/usb/dwc2/gadget.c
++++ b/drivers/usb/dwc2/gadget.c
+@@ -4602,6 +4602,12 @@ static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget)
+       if (!hsotg)
+               return -ENODEV;
++      /* Exit clock gating when driver is stopped. */
++      if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_NONE &&
++          hsotg->bus_suspended && !hsotg->params.no_clock_gating) {
++              dwc2_gadget_exit_clock_gating(hsotg, 0);
++      }
++
+       /* all endpoints should be shutdown */
+       for (ep = 1; ep < hsotg->num_of_eps; ep++) {
+               if (hsotg->eps_in[ep])
+-- 
+2.39.5
+
diff --git a/queue-6.1/usb-potential-integer-overflow-in-usbg_make_tpg.patch b/queue-6.1/usb-potential-integer-overflow-in-usbg_make_tpg.patch
new file mode 100644 (file)
index 0000000..03d9777
--- /dev/null
@@ -0,0 +1,53 @@
+From b9f72c4165d0b755361c4c6405e2d22dca67b8e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 14:58:57 +0800
+Subject: usb: potential integer overflow in usbg_make_tpg()
+
+From: Chen Yufeng <chenyufeng@iie.ac.cn>
+
+[ Upstream commit 153874010354d050f62f8ae25cbb960c17633dc5 ]
+
+The variable tpgt in usbg_make_tpg() is defined as unsigned long and is
+assigned to tpgt->tport_tpgt, which is defined as u16. This may cause an
+integer overflow when tpgt is greater than USHRT_MAX (65535). I
+haven't tried to trigger it myself, but it is possible to trigger it
+by calling usbg_make_tpg() with a large value for tpgt.
+
+I modified the type of tpgt to match tpgt->tport_tpgt and adjusted the
+relevant code accordingly.
+
+This patch is similar to commit 59c816c1f24d ("vhost/scsi: potential
+memory corruption").
+
+Signed-off-by: Chen Yufeng <chenyufeng@iie.ac.cn>
+Link: https://lore.kernel.org/r/20250415065857.1619-1-chenyufeng@iie.ac.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/f_tcm.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c
+index 3c9541357c241..55a81ad6837b6 100644
+--- a/drivers/usb/gadget/function/f_tcm.c
++++ b/drivers/usb/gadget/function/f_tcm.c
+@@ -1321,14 +1321,14 @@ static struct se_portal_group *usbg_make_tpg(struct se_wwn *wwn,
+       struct usbg_tport *tport = container_of(wwn, struct usbg_tport,
+                       tport_wwn);
+       struct usbg_tpg *tpg;
+-      unsigned long tpgt;
++      u16 tpgt;
+       int ret;
+       struct f_tcm_opts *opts;
+       unsigned i;
+       if (strstr(name, "tpgt_") != name)
+               return ERR_PTR(-EINVAL);
+-      if (kstrtoul(name + 5, 0, &tpgt) || tpgt > UINT_MAX)
++      if (kstrtou16(name + 5, 0, &tpgt))
+               return ERR_PTR(-EINVAL);
+       ret = -ENODEV;
+       mutex_lock(&tpg_instances_lock);
+-- 
+2.39.5
+
diff --git a/queue-6.1/usb-typec-displayport-receive-dp-status-update-nak-r.patch b/queue-6.1/usb-typec-displayport-receive-dp-status-update-nak-r.patch
new file mode 100644 (file)
index 0000000..dd5853c
--- /dev/null
@@ -0,0 +1,56 @@
+From 01433343c1353fbeda457f0d2507b8e3ba54fa58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Feb 2025 15:19:26 +0800
+Subject: usb: typec: displayport: Receive DP Status Update NAK request exit dp
+ altmode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jos Wang <joswang@lenovo.com>
+
+[ Upstream commit b4b38ffb38c91afd4dc387608db26f6fc34ed40b ]
+
+Although some Type-C DRD devices that do not support the DP Sink
+function (such as Huawei Mate 40Pro), the Source Port initiates
+Enter Mode CMD, but the device responds to Enter Mode ACK, the
+Source port then initiates DP Status Update CMD, and the device
+responds to DP Status Update NAK.
+
+As PD2.0 spec ("6.4.4.3.4 Enter Mode Command"),A DR_Swap Message
+Shall Not be sent during Modal Operation between the Port Partners.
+At this time, the source port initiates DR_Swap message through the
+"echo device > /sys/class/typec/port0/data_role" command to switch
+the data role from host to device. The device will initiate a Hard
+Reset for recovery, resulting in the failure of data role swap.
+
+Therefore, when DP Status Update NAK is received, Exit Mode CMD is
+initiated to exit the currently entered DP altmode.
+
+Signed-off-by: Jos Wang <joswang@lenovo.com>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20250209071926.69625-1-joswang1221@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/altmodes/displayport.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c
+index f80124102328c..26e0e72f4f166 100644
+--- a/drivers/usb/typec/altmodes/displayport.c
++++ b/drivers/usb/typec/altmodes/displayport.c
+@@ -320,6 +320,10 @@ static int dp_altmode_vdm(struct typec_altmode *alt,
+               break;
+       case CMDT_RSP_NAK:
+               switch (cmd) {
++              case DP_CMD_STATUS_UPDATE:
++                      if (typec_altmode_exit(alt))
++                              dev_err(&dp->alt->dev, "Exit Mode Failed!\n");
++                      break;
+               case DP_CMD_CONFIGURE:
+                       dp->data.conf = 0;
+                       ret = dp_altmode_configured(dp);
+-- 
+2.39.5
+
diff --git a/queue-6.1/usb-typec-mux-do-not-return-on-eopnotsupp-in-mux-swi.patch b/queue-6.1/usb-typec-mux-do-not-return-on-eopnotsupp-in-mux-swi.patch
new file mode 100644 (file)
index 0000000..3ba7d8f
--- /dev/null
@@ -0,0 +1,52 @@
+From 3ed3cf0bdd43734189cc2568a6e7ac2b30ce652b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 00:21:01 +0200
+Subject: usb: typec: mux: do not return on EOPNOTSUPP in {mux, switch}_set
+
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+
+[ Upstream commit 0f7bbef1794dc87141897f804e5871a293aa174b ]
+
+Since the typec connectors can have many muxes or switches for different
+lanes (sbu, usb2, usb3) going into different modal states (usb2, usb3,
+audio, debug) all of them will be called on typec_switch_set and
+typec_mux_set. But not all of them will be handling the expected mode.
+
+If one of the mux or switch will come back with EOPTNOSUPP this is no
+reason to stop running through the next ones. Therefor we skip this
+particular error value and continue calling the next.
+
+Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20250404-ml-topic-typec-mux-v1-1-22c0526381ba@pengutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/mux.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c
+index 941735c731619..a74f8e1a28c21 100644
+--- a/drivers/usb/typec/mux.c
++++ b/drivers/usb/typec/mux.c
+@@ -214,7 +214,7 @@ int typec_switch_set(struct typec_switch *sw,
+               sw_dev = sw->sw_devs[i];
+               ret = sw_dev->set(sw_dev, orientation);
+-              if (ret)
++              if (ret && ret != -EOPNOTSUPP)
+                       return ret;
+       }
+@@ -421,7 +421,7 @@ int typec_mux_set(struct typec_mux *mux, struct typec_mux_state *state)
+               mux_dev = mux->mux_devs[i];
+               ret = mux_dev->set(mux_dev, state);
+-              if (ret)
++              if (ret && ret != -EOPNOTSUPP)
+                       return ret;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.1/vgacon-remove-unneeded-forward-declarations.patch b/queue-6.1/vgacon-remove-unneeded-forward-declarations.patch
new file mode 100644 (file)
index 0000000..8bd4819
--- /dev/null
@@ -0,0 +1,47 @@
+From 44056744695a4ba72206d9c1c744d487d1c60b46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Jul 2023 10:59:37 +0200
+Subject: vgacon: remove unneeded forward declarations
+
+From: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+
+[ Upstream commit 6ceed69cde8fe4a78fe50d62d7a88a5c1eed4709 ]
+
+Most of the forward declarations in vgacon are not needed. Drop them.
+
+Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>
+Cc: Helge Deller <deller@gmx.de>
+Cc: linux-fbdev@vger.kernel.org
+Cc: dri-devel@lists.freedesktop.org
+Signed-off-by: Helge Deller <deller@gmx.de>
+Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/console/vgacon.c | 10 +---------
+ 1 file changed, 1 insertion(+), 9 deletions(-)
+
+diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
+index 065da55f20d89..e0d340f5c2dd5 100644
+--- a/drivers/video/console/vgacon.c
++++ b/drivers/video/console/vgacon.c
+@@ -65,16 +65,8 @@ static struct vgastate vgastate;
+  *  Interface used by the world
+  */
+-static const char *vgacon_startup(void);
+-static void vgacon_init(struct vc_data *c, int init);
+-static void vgacon_deinit(struct vc_data *c);
+-static void vgacon_cursor(struct vc_data *c, int mode);
+-static int vgacon_switch(struct vc_data *c);
+-static int vgacon_blank(struct vc_data *c, int blank, int mode_switch);
+-static void vgacon_scrolldelta(struct vc_data *c, int lines);
+ static int vgacon_set_origin(struct vc_data *c);
+-static void vgacon_save_screen(struct vc_data *c);
+-static void vgacon_invert_region(struct vc_data *c, u16 * p, int count);
++
+ static struct uni_pagedict *vgacon_uni_pagedir;
+ static int vgacon_refcount;
+-- 
+2.39.5
+
diff --git a/queue-6.1/vgacon-switch-vgacon_scrolldelta-and-vgacon_restore_.patch b/queue-6.1/vgacon-switch-vgacon_scrolldelta-and-vgacon_restore_.patch
new file mode 100644 (file)
index 0000000..782a374
--- /dev/null
@@ -0,0 +1,56 @@
+From fb7a1380020942db1f3549e6eceb7b6c8789bb2f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Jul 2023 10:59:36 +0200
+Subject: vgacon: switch vgacon_scrolldelta() and vgacon_restore_screen()
+
+From: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+
+[ Upstream commit 03b89a08484a88fb9e0604cab2b3eb0c2f265c74 ]
+
+Switch vgacon_scrolldelta() and vgacon_restore_screen() positions, so
+that the former is not needed to be forward-declared.
+
+Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>
+Cc: Helge Deller <deller@gmx.de>
+Cc: linux-fbdev@vger.kernel.org
+Cc: dri-devel@lists.freedesktop.org
+Signed-off-by: Helge Deller <deller@gmx.de>
+Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/console/vgacon.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
+index e960b27caadab..065da55f20d89 100644
+--- a/drivers/video/console/vgacon.c
++++ b/drivers/video/console/vgacon.c
+@@ -142,12 +142,6 @@ static inline void vga_set_mem_top(struct vc_data *c)
+       write_vga(12, (c->vc_visible_origin - vga_vram_base) / 2);
+ }
+-static void vgacon_restore_screen(struct vc_data *c)
+-{
+-      if (c->vc_origin != c->vc_visible_origin)
+-              vgacon_scrolldelta(c, 0);
+-}
+-
+ static void vgacon_scrolldelta(struct vc_data *c, int lines)
+ {
+       vc_scrolldelta_helper(c, lines, vga_rolled_over, (void *)vga_vram_base,
+@@ -155,6 +149,12 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
+       vga_set_mem_top(c);
+ }
++static void vgacon_restore_screen(struct vc_data *c)
++{
++      if (c->vc_origin != c->vc_visible_origin)
++              vgacon_scrolldelta(c, 0);
++}
++
+ static const char *vgacon_startup(void)
+ {
+       const char *display_desc = NULL;
+-- 
+2.39.5
+