From: Sasha Levin Date: Fri, 27 Jun 2025 14:02:14 +0000 (-0400) Subject: Fixes for 6.1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d7127cc309df18c72520207bd67c4a577cd1d3e3;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.1 Signed-off-by: Sasha Levin --- 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 index 0000000000..fba7522a35 --- /dev/null +++ b/queue-6.1/af_unix-don-t-call-skb_get-for-oob-skb.patch @@ -0,0 +1,163 @@ +From b62b799a9d16603f259104460e835c859d6686c6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 16 Aug 2024 16:39:21 -0700 +Subject: af_unix: Don't call skb_get() for OOB skb. + +From: Kuniyuki Iwashima + +[ 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 +Link: https://patch.msgid.link/20240816233921.57800-1-kuniyu@amazon.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 32ca245464e1 ("af_unix: Don't leave consecutive consumed OOB skbs.") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..8eb095719b --- /dev/null +++ b/queue-6.1/af_unix-don-t-leave-consecutive-consumed-oob-skbs.patch @@ -0,0 +1,203 @@ +From 4258a01d2ae3218fe4f93ddb7d50b1cf5df1cc18 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Jun 2025 21:13:55 -0700 +Subject: af_unix: Don't leave consecutive consumed OOB skbs. + +From: Kuniyuki Iwashima + +[ 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: + + 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 + + +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 +Signed-off-by: Kuniyuki Iwashima +Reviewed-by: Jann Horn +Link: https://patch.msgid.link/20250619041457.1132791-2-kuni1840@gmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..090dd69526 --- /dev/null +++ b/queue-6.1/alsa-hda-add-new-pci-id-for-amd-gpu-display-hd-audio.patch @@ -0,0 +1,37 @@ +From 8cbe0c5c12b4b2e0ab8d0170a1d476249c21cd7f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ Upstream commit ab72bfce7647522e01a181e3600c3d14ff5c143e ] + +Add new pci id for AMD GPU display HD audio controller(device id- 0xab40). + +Signed-off-by: Vijendar Mukunda +Reviewed-by: Alex Deucher +Link: https://patch.msgid.link/20250529053838.2350071-1-Vijendar.Mukunda@amd.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..f33f4780e3 --- /dev/null +++ b/queue-6.1/alsa-hda-ignore-unsol-events-for-cards-being-shut-do.patch @@ -0,0 +1,48 @@ +From ca2434bb757cc1cc11e826d751a1927ddeb07950 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Cezary Rojewski +Link: https://patch.msgid.link/20250530141309.2943404-1-cezary.rojewski@intel.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..a87174a89d --- /dev/null +++ b/queue-6.1/alsa-usb-audio-add-a-quirk-for-lenovo-thinkpad-thund.patch @@ -0,0 +1,39 @@ +From e303c7a4635f58f39abd546b4d16d0f08207d57d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Mario Limonciello +Link: https://patch.msgid.link/20250527172657.1972565-1-superm1@kernel.org +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..0afd4f4b67 --- /dev/null +++ b/queue-6.1/amd-amdkfd-fix-a-kfd_process-ref-leak.patch @@ -0,0 +1,34 @@ +From 0a503068666ea91a5b0fee5037e9c212780788b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 May 2025 18:06:28 +0800 +Subject: amd/amdkfd: fix a kfd_process ref leak + +From: Yifan Zhang + +[ Upstream commit 90237b16ec1d7afa16e2173cc9a664377214cdd9 ] + +This patch is to fix a kfd_prcess ref leak. + +Signed-off-by: Yifan Zhang +Reviewed-by: Philip Yang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..afe0ea5703 --- /dev/null +++ b/queue-6.1/asoc-codec-wcd9335-convert-to-gpio-descriptors.patch @@ -0,0 +1,85 @@ +From 4a30d35cebf8ff3f75c9733c4a8cca8d4a68d180 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Mar 2025 19:51:29 +0800 +Subject: ASoC: codec: wcd9335: Convert to GPIO descriptors + +From: Peng Fan + +[ 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 +Signed-off-by: Peng Fan +Link: https://patch.msgid.link/20250324-wcd-gpiod-v2-3-773f67ce3b56@nxp.com +Reviewed-by: Bartosz Golaszewski +Signed-off-by: Mark Brown +Stable-dep-of: 9079db287fc3 ("ASoC: codecs: wcd9335: Fix missing free of regulator supplies") +Signed-off-by: Sasha Levin +--- + 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 + #include + #include +-#include ++#include + #include + #include + #include +@@ -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 index 0000000000..59a35c60c2 --- /dev/null +++ b/queue-6.1/asoc-codecs-wcd9335-fix-missing-free-of-regulator-su.patch @@ -0,0 +1,88 @@ +From 4107c0989c5328da6147955e7dccb4d7b63ad1c7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 May 2025 11:47:01 +0200 +Subject: ASoC: codecs: wcd9335: Fix missing free of regulator supplies + +From: Krzysztof Kozlowski + +[ 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 +Link: https://patch.msgid.link/20250526-b4-b4-asoc-wcd9395-vdd-px-fixes-v1-1-0b8a2993b7d3@linaro.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..8e92d500fe --- /dev/null +++ b/queue-6.1/asoc-codecs-wcd9335-handle-nicer-probe-deferral-and-.patch @@ -0,0 +1,85 @@ +From 26adeaccaf41165b8138fd17076e4bc831811684 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://msgid.link/r/20240612-asoc-wcd9xxx-wide-cleanups-v1-4-0d15885b2a06@linaro.org +Signed-off-by: Mark Brown +Stable-dep-of: 9079db287fc3 ("ASoC: codecs: wcd9335: Fix missing free of regulator supplies") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..2ebc749b76 --- /dev/null +++ b/queue-6.1/bcache-fix-null-pointer-in-cache_set_flush.patch @@ -0,0 +1,151 @@ +From 61550af1fd70a1de3e5cb10132462532e4f33fce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 May 2025 13:15:59 +0800 +Subject: bcache: fix NULL pointer in cache_set_flush() + +From: Linggang Zeng + +[ 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 +Signed-off-by: Mingzhe Zou +Signed-off-by: Coly Li +Link: https://lore.kernel.org/r/20250527051601.74407-2-colyli@kernel.org +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..d8fcbcd874 --- /dev/null +++ b/queue-6.1/btrfs-handle-csum-tree-error-with-rescue-ibadroots-c.patch @@ -0,0 +1,117 @@ +From be3be775c11712090f6b032dfe43e2d64347e4f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Jun 2025 09:18:43 +0930 +Subject: btrfs: handle csum tree error with rescue=ibadroots correctly + +From: Qu Wenruo + +[ 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: + + 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 +Reported-by: Longxing Li +Reviewed-by: David Sterba +Signed-off-by: Qu Wenruo +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..1c97015202 --- /dev/null +++ b/queue-6.1/ceph-fix-possible-integer-overflow-in-ceph_zero_obje.patch @@ -0,0 +1,40 @@ +From bc79a6e1f347f76c980c4866af630d9cc830a92c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Apr 2025 12:32:04 +0300 +Subject: ceph: fix possible integer overflow in ceph_zero_objects() + +From: Dmitry Kandybka + +[ 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 +Reviewed-by: Viacheslav Dubeyko +Signed-off-by: Ilya Dryomov +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..de45739c8a --- /dev/null +++ b/queue-6.1/cifs-correctly-set-smb1-sessionkey-field-in-session-.patch @@ -0,0 +1,106 @@ +From 6894f13dccde7b51e28c19386d575bd7f73b6dc1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..ee85500b18 --- /dev/null +++ b/queue-6.1/cifs-fix-cifs_query_path_info-for-windows-nt-servers.patch @@ -0,0 +1,55 @@ +From 09e875bed00dc991cf41d1cb8d9c2995145b2729 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..597c332b55 --- /dev/null +++ b/queue-6.1/coresight-only-check-bottom-two-claim-bits.patch @@ -0,0 +1,55 @@ +From 67d3bf4826dbfb4b1b2e7dfefc87012a8aea9445 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Mar 2025 11:58:47 +0000 +Subject: coresight: Only check bottom two claim bits + +From: James Clark + +[ 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 +Reviewed-by: Yeoreum Yun +Signed-off-by: James Clark +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20250325-james-coresight-claim-tags-v4-2-dfbd3822b2e5@linaro.org +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..0dc0212f82 --- /dev/null +++ b/queue-6.1/dmaengine-xilinx_dma-set-dma_device-directions.patch @@ -0,0 +1,40 @@ +From ec49cbd8771a4b6c7dae6614e73d0cfa88f2a4fc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 May 2025 20:21:01 +0200 +Subject: dmaengine: xilinx_dma: Set dma_device directions + +From: Thomas Gessler + +[ 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 +Reviewed-by: Suraj Gupta +Tested-by: Folker Schwesinger +Link: https://lore.kernel.org/r/20250507182101.909010-1-thomas.gessler@brueckmann-gmbh.de +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..2d8b920888 --- /dev/null +++ b/queue-6.1/drivers-hv-allocate-interrupt-and-monitor-pages-alig.patch @@ -0,0 +1,96 @@ +From d11c03274d259be97eaa503045723953ecba4614 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Michael Kelley +Link: https://lore.kernel.org/r/1746492997-4599-2-git-send-email-longli@linuxonhyperv.com +Signed-off-by: Wei Liu +Message-ID: <1746492997-4599-2-git-send-email-longli@linuxonhyperv.com> +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..bb9cbd2805 --- /dev/null +++ b/queue-6.1/drivers-hv-change-hv_free_hyperv_page-to-take-void-a.patch @@ -0,0 +1,129 @@ +From 6f635403871e09472c9616c303e0be40915f197d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Jun 2023 15:09:49 -0700 +Subject: Drivers: hv: Change hv_free_hyperv_page() to take void * argument + +From: Kameron Carr + +[ 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 +Reviewed-by: Nuno Das Neves +Reviewed-by: Dexuan Cui +Link: https://lore.kernel.org/r/1687558189-19734-1-git-send-email-kameroncarr@linux.microsoft.com +Signed-off-by: Wei Liu +Stable-dep-of: 09eea7ad0b8e ("Drivers: hv: Allocate interrupt and monitor pages aligned to system page boundary") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..3f5135c7dd --- /dev/null +++ b/queue-6.1/drivers-hv-hyperv_fb-untangle-and-refactor-hyper-v-p.patch @@ -0,0 +1,250 @@ +From 123ce5247a672409de0f968486882483567f5211 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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) +Cc: Dexuan Cui +Cc: Haiyang Zhang +Cc: "K. Y. Srinivasan" +Cc: Petr Mladek +Cc: Stephen Hemminger +Cc: Tianyu Lan +Cc: Wei Liu +Reviewed-by: Michael Kelley +Tested-by: Fabio A M Martins +Signed-off-by: Guilherme G. Piccoli +Tested-by: Michael Kelley +Link: https://lore.kernel.org/r/20220819221731.480795-11-gpiccoli@igalia.com +Signed-off-by: Wei Liu +Stable-dep-of: 09eea7ad0b8e ("Drivers: hv: Allocate interrupt and monitor pages aligned to system page boundary") +Signed-off-by: Sasha Levin +--- + 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 + + #include +-#include + #include + #include + #include +@@ -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 index 0000000000..aa8830f985 --- /dev/null +++ b/queue-6.1/drivers-hv-move-panic-report-code-from-vmbus-to-hv-e.patch @@ -0,0 +1,625 @@ +From b486cba57a668d5f00e285f5b855ee76e0fe690c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Michael Kelley +Link: https://lore.kernel.org/r/1682030946-6372-1-git-send-email-longli@linuxonhyperv.com +Signed-off-by: Wei Liu +Stable-dep-of: 09eea7ad0b8e ("Drivers: hv: Allocate interrupt and monitor pages aligned to system page boundary") +Signed-off-by: Sasha Levin +--- + 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 + #include + #include ++#include + #include + #include ++#include ++#include + #include + #include + #include +@@ -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 + #include + #include +-#include + #include + #include + #include +@@ -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 index 0000000000..d5358fcf5a --- /dev/null +++ b/queue-6.1/drivers-hv-vmbus-add-utility-function-for-querying-r.patch @@ -0,0 +1,94 @@ +From 8c27055a51360031a58ec44fb2bf252bd5cd055f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 30 Mar 2024 01:51:57 -0700 +Subject: Drivers: hv: vmbus: Add utility function for querying ring size + +From: Saurabh Sengar + +[ 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 +Reviewed-by: Long Li +Link: https://lore.kernel.org/r/1711788723-8593-2-git-send-email-ssengar@linux.microsoft.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 0315fef2aff9 ("uio_hv_generic: Align ring size to system page") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..a8dc8639b6 --- /dev/null +++ b/queue-6.1/drivers-hv-vmbus-leak-pages-if-set_memory_encrypted-.patch @@ -0,0 +1,84 @@ +From e4b216b69bde01026a2872446e6e97211b2d3e59 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Mar 2024 09:15:54 -0700 +Subject: Drivers: hv: vmbus: Leak pages if set_memory_encrypted() fails + +From: Rick Edgecombe + +[ 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 +Signed-off-by: Michael Kelley +Reviewed-by: Kuppuswamy Sathyanarayanan +Acked-by: Kirill A. Shutemov +Link: https://lore.kernel.org/r/20240311161558.1310-2-mhklinux@outlook.com +Signed-off-by: Wei Liu +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 +--- + 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 index 0000000000..35104c8a18 --- /dev/null +++ b/queue-6.1/drivers-hv-vmbus-remove-second-mapping-of-vmbus-moni.patch @@ -0,0 +1,193 @@ +From 7dcf90097793ec1eb2b6935efadbd414c89249a8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 26 Mar 2023 06:52:03 -0700 +Subject: Drivers: hv: vmbus: Remove second mapping of VMBus monitor pages + +From: Michael Kelley + +[ 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 +Reviewed-by: Tianyu Lan +Link: https://lore.kernel.org/r/1679838727-87310-9-git-send-email-mikelley@microsoft.com +Signed-off-by: Wei Liu +Stable-dep-of: 09eea7ad0b8e ("Drivers: hv: Allocate interrupt and monitor pages aligned to system page boundary") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..1e3546a78a --- /dev/null +++ b/queue-6.1/drm-i915-gem-allow-exec_capture-on-recoverable-conte.patch @@ -0,0 +1,52 @@ +From ec5042528c46add45ea46642ec09d41b4b939cda Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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ä + +[ 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 +Cc: Thomas Hellström +Testcase: igt/gem_exec_capture/capture-invisible +Fixes: 71b1669ea9bd ("drm/i915/uapi: tweak error capture on recoverable contexts") +Reviewed-by: Andi Shyti +Signed-off-by: Ville Syrjälä +Signed-off-by: Andi Shyti +Link: https://lore.kernel.org/r/20250411144313.11660-2-ville.syrjala@linux.intel.com +(cherry picked from commit d6e020819612a4a06207af858e0978be4d3e3140) +Signed-off-by: Joonas Lahtinen +Stable-dep-of: ed5915cfce2a ("Revert "drm/i915/gem: Allow EXEC_CAPTURE on recoverable contexts on DG1"") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..17399307f1 --- /dev/null +++ b/queue-6.1/dummycon-trigger-redraw-when-switching-consoles-with.patch @@ -0,0 +1,96 @@ +From 85e1daec8908010338e753b5dc54fd1c54d3ed52 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 May 2025 09:14:00 +0200 +Subject: dummycon: Trigger redraw when switching consoles with deferred + takeover + +From: Thomas Zimmermann + +[ 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 +Reported-by: Andrei Borzenkov +Closes: https://bugzilla.suse.com/show_bug.cgi?id=1242191 +Tested-by: Andrei Borzenkov +Acked-by: Javier Martinez Canillas +Fixes: 83d83bebf401 ("console/fbcon: Add support for deferred console takeover") +Cc: Hans de Goede +Cc: linux-fbdev@vger.kernel.org +Cc: dri-devel@lists.freedesktop.org +Cc: # v4.19+ +Link: https://lore.kernel.org/r/20250520071418.8462-1-tzimmermann@suse.de +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..9b96bfedbb --- /dev/null +++ b/queue-6.1/f2fs-don-t-over-report-free-space-or-inodes-in-statv.patch @@ -0,0 +1,99 @@ +From 37918177736e2f021b34de305d9dd58901a92ada Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 May 2025 19:25:38 +0800 +Subject: f2fs: don't over-report free space or inodes in statvfs + +From: Chao Yu + +[ 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 +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..6121c1a5b6 --- /dev/null +++ b/queue-6.1/fbdev-fix-do_register_framebuffer-to-prevent-null-pt.patch @@ -0,0 +1,112 @@ +From d3b339f04188f7f1441b39705c2d83ef2539fa91 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Helge Deller +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..f9e7ee43bd --- /dev/null +++ b/queue-6.1/fs-jfs-consolidate-sanity-checking-in-dbmount.patch @@ -0,0 +1,81 @@ +From 66b597079108b4a12e945e4b9ed8c6740e7bdb07 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Feb 2025 10:31:19 -0600 +Subject: fs/jfs: consolidate sanity checking in dbMount + +From: Dave Kleikamp + +[ 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 +Stable-dep-of: 37bfb464ddca ("jfs: validate AG parameters in dbMount() to prevent crashes") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..f47bc89d88 --- /dev/null +++ b/queue-6.1/hwmon-pmbus-max34440-fix-support-for-max34451.patch @@ -0,0 +1,144 @@ +From 482e2294c981f29459f6af17a7f2277b43b8c7e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Apr 2025 11:47:24 +0800 +Subject: hwmon: (pmbus/max34440) Fix support for max34451 + +From: Alexis Czezar Torreno + +[ 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 +Link: https://lore.kernel.org/r/20250407-dev_adpm12160-v3-1-9cd3095445c8@analog.com +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..1962e1beea --- /dev/null +++ b/queue-6.1/iio-adc-ad_sigma_delta-fix-use-of-uninitialized-stat.patch @@ -0,0 +1,47 @@ +From 930bdabf86692e4a0547eac08e70ea0470f9f730 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 10 Apr 2025 22:34:08 +0530 +Subject: iio: adc: ad_sigma_delta: Fix use of uninitialized status_pos + +From: Purva Yeshi + +[ 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 +Link: https://patch.msgid.link/20250410170408.8585-1-purvayeshi550@gmail.com +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..93e7e39364 --- /dev/null +++ b/queue-6.1/iio-pressure-zpa2326-use-aligned_s64-for-the-timesta.patch @@ -0,0 +1,36 @@ +From 07d97bcc3862faa5c844ef350c8f236b52044f0c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 13 Apr 2025 11:34:41 +0100 +Subject: iio: pressure: zpa2326: Use aligned_s64 for the timestamp + +From: Jonathan Cameron + +[ 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 +Link: https://patch.msgid.link/20250413103443.2420727-19-jic23@kernel.org +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..2e800478a0 --- /dev/null +++ b/queue-6.1/jfs-validate-ag-parameters-in-dbmount-to-prevent-cra.patch @@ -0,0 +1,78 @@ +From cc2ece8f2813c40f1471a6dd155a94e681860e9c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Mar 2025 11:56:02 +0300 +Subject: jfs: validate AG parameters in dbMount() to prevent crashes + +From: Vasiliy Kovalev + +[ 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: + + __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 +Signed-off-by: Dave Kleikamp +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..f6f1225f5a --- /dev/null +++ b/queue-6.1/ksmbd-allow-a-filename-to-contain-special-characters.patch @@ -0,0 +1,109 @@ +From f18fae62ac10e80d09b2f856b71f87f714d960be Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ Upstream commit dc3e0f17f74558e8a2fce00608855f050de10230 ] + +If client send SMB2_CREATE_POSIX_CONTEXT to ksmbd, Allow a filename +to contain special characters. + +Reported-by: Philipp Kerling +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..2a8900d405 --- /dev/null +++ b/queue-6.1/leds-multicolor-fix-intensity-setting-while-sw-blink.patch @@ -0,0 +1,48 @@ +From 649f8ba7105548a962fed7a948e97d958ce3e281 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Apr 2025 20:40:36 +0200 +Subject: leds: multicolor: Fix intensity setting while SW blinking + +From: Sven Schwermer + +[ 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 +Acked-by: Jacek Anaszewski +Acked-by: Pavel Machek +Reviewed-by: Tobias Deiminger +Tested-by: Sven Schuchmann +Signed-off-by: Sven Schwermer +Link: https://lore.kernel.org/r/20250404184043.227116-1-sven@svenschwermer.de +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..64e4404e62 --- /dev/null +++ b/queue-6.1/mailbox-not-protect-module_put-with-spin_lock_irqsav.patch @@ -0,0 +1,38 @@ +From ec212d4c5b13227c628b788c63073aeb36bb709b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 11 Apr 2025 21:14:10 +0800 +Subject: mailbox: Not protect module_put with spin_lock_irqsave + +From: Peng Fan + +[ 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 +Signed-off-by: Jassi Brar +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..31a57394a9 --- /dev/null +++ b/queue-6.1/md-md-bitmap-fix-dm-raid-max_write_behind-setting.patch @@ -0,0 +1,36 @@ +From 81015117f25e4e65bbf9eebf452379f5f035398e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 24 May 2025 14:13:10 +0800 +Subject: md/md-bitmap: fix dm-raid max_write_behind setting + +From: Yu Kuai + +[ 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 +Reviewed-by: Christoph Hellwig +Reviewed-by: Hannes Reinecke +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..5bf877c00c --- /dev/null +++ b/queue-6.1/media-imx-jpeg-add-a-timeout-mechanism-for-each-fram.patch @@ -0,0 +1,148 @@ +From 3dfc8f2839ddcab7ce48232419f93e7685aa803d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Jul 2022 10:37:37 +0800 +Subject: media: imx-jpeg: Add a timeout mechanism for each frame + +From: Ming Qian + +[ 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 +Reviewed-by: Mirela Rabulea +Signed-off-by: Hans Verkuil +Stable-dep-of: 46e9c092f850 ("media: imx-jpeg: Move mxc_jpeg_free_slot_data() ahead") +Signed-off-by: Sasha Levin +--- + .../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 index 0000000000..5ae6c59cdc --- /dev/null +++ b/queue-6.1/media-imx-jpeg-cleanup-after-an-allocation-error.patch @@ -0,0 +1,40 @@ +From fb42b71fd8515553ed5bd5face3f44ed236795f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Apr 2025 16:12:54 +0800 +Subject: media: imx-jpeg: Cleanup after an allocation error + +From: Ming Qian + +[ 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 +Reviewed-by: Frank Li +Signed-off-by: Nicolas Dufresne +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..476d71aeae --- /dev/null +++ b/queue-6.1/media-imx-jpeg-move-mxc_jpeg_free_slot_data-ahead.patch @@ -0,0 +1,86 @@ +From a95dcab6172ea8e41d6f627d33404b8ce2dc4fb3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Apr 2025 16:12:52 +0800 +Subject: media: imx-jpeg: Move mxc_jpeg_free_slot_data() ahead + +From: Ming Qian + +[ 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 +Reviewed-by: Nicolas Dufresne +Reviewed-by: Frank Li +Signed-off-by: Nicolas Dufresne +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + .../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 index 0000000000..c2ac4f6d2a --- /dev/null +++ b/queue-6.1/media-imx-jpeg-remove-unnecessary-memset-after-dma_a.patch @@ -0,0 +1,36 @@ +From f01056f4295d9b73518e238b6a74e2f0a163356b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 16 Jul 2022 20:25:43 +0800 +Subject: media: imx-jpeg: Remove unnecessary memset() after + dma_alloc_coherent() + +From: Jason Wang + +[ 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 +Signed-off-by: Hans Verkuil +Stable-dep-of: 46e9c092f850 ("media: imx-jpeg: Move mxc_jpeg_free_slot_data() ahead") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..5a6badd965 --- /dev/null +++ b/queue-6.1/media-imx-jpeg-reset-slot-data-pointers-when-freed.patch @@ -0,0 +1,56 @@ +From 91459839eff71cc330aba1f362931382c5b18ebe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Apr 2025 16:12:53 +0800 +Subject: media: imx-jpeg: Reset slot data pointers when freed + +From: Ming Qian + +[ 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 +Reviewed-by: Nicolas Dufresne +Reviewed-by: Frank Li +Signed-off-by: Nicolas Dufresne +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..5c330db090 --- /dev/null +++ b/queue-6.1/media-imx-jpeg-support-to-assign-slot-for-encoder-de.patch @@ -0,0 +1,364 @@ +From 422901474a4342d15647044bc7fd63a9f22c6079 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 May 2023 09:16:30 +0200 +Subject: media: imx-jpeg: Support to assign slot for encoder/decoder + +From: Ming Qian + +[ 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 +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Stable-dep-of: 46e9c092f850 ("media: imx-jpeg: Move mxc_jpeg_free_slot_data() ahead") +Signed-off-by: Sasha Levin +--- + .../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 index 0000000000..64a2b3c846 --- /dev/null +++ b/queue-6.1/mfd-max14577-fix-wakeup-source-leaks-on-device-unbin.patch @@ -0,0 +1,35 @@ +From 4708c68f547b3d56caeb2832a1c317953d5db81f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 6 Apr 2025 21:50:11 +0200 +Subject: mfd: max14577: Fix wakeup source leaks on device unbind + +From: Krzysztof Kozlowski + +[ Upstream commit d905d06e64b0eb3da43af6186c132f5282197998 ] + +Device can be unbound, so driver must also release memory for the wakeup +source. + +Signed-off-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20250406-mfd-device-wakekup-leak-v1-3-318e14bdba0a@linaro.org +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..f6905dd863 --- /dev/null +++ b/queue-6.1/nfsv4-always-set-nlink-even-if-the-server-doesn-t-su.patch @@ -0,0 +1,41 @@ +From e31183e28ddb612a27318469399cebeb9f28894c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Anna Schumaker +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..82f6287631 --- /dev/null +++ b/queue-6.1/nfsv4-xattr-handlers-should-check-for-absent-nfs-fil.patch @@ -0,0 +1,59 @@ +From 8b540c4f79bb382dbf2b566da5645c756d413286 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Apr 2025 11:23:38 -0400 +Subject: NFSv4: xattr handlers should check for absent nfs filehandles + +From: Scott Mayhew + +[ 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 +Signed-off-by: Anna Schumaker +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..d4356abb7d --- /dev/null +++ b/queue-6.1/nfsv4.2-fix-listxattr-to-return-selinux-security-lab.patch @@ -0,0 +1,56 @@ +From 88f3d7b207112553648bdaab38b9ee93d52bbb17 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 14:09:21 -0400 +Subject: NFSv4.2: fix listxattr to return selinux security label + +From: Olga Kornievskaia + +[ 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 +Signed-off-by: Anna Schumaker +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..885ac098b1 --- /dev/null +++ b/queue-6.1/ovl-check-for-null-d_inode-in-ovl_dentry_upper.patch @@ -0,0 +1,68 @@ +From d33ed1620e18b28628691f0abd39af9fcd54a20c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Apr 2025 16:15:19 -0700 +Subject: ovl: Check for NULL d_inode() in ovl_dentry_upper() + +From: Kees Cook + +[ 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 +Signed-off-by: Kees Cook +Signed-off-by: Miklos Szeredi +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..01cfbfb38c --- /dev/null +++ b/queue-6.1/pci-apple-fix-missing-of-node-reference-in-apple_pci.patch @@ -0,0 +1,44 @@ +From 31b29e191d2431e5005411a6a2db0650fdb5415e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Alyssa Rosenzweig +Signed-off-by: Marc Zyngier +Signed-off-by: Manivannan Sadhasivam +Tested-by: Janne Grunau +Reviewed-by: Rob Herring (Arm) +Reviewed-by: Manivannan Sadhasivam +Acked-by: Alyssa Rosenzweig +Link: https://patch.msgid.link/20250401091713.2765724-9-maz@kernel.org +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..10502a4d43 --- /dev/null +++ b/queue-6.1/pci-apple-set-only-available-ports-up.patch @@ -0,0 +1,54 @@ +From 41c8da0231ef64badfeeafc5c27a87d0286bbb75 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Apr 2025 10:17:01 +0100 +Subject: PCI: apple: Set only available ports up + +From: Janne Grunau + +[ 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 +Signed-off-by: Alyssa Rosenzweig +Signed-off-by: Marc Zyngier +Signed-off-by: Manivannan Sadhasivam +Tested-by: Janne Grunau +Reviewed-by: Rob Herring (Arm) +Reviewed-by: Manivannan Sadhasivam +Acked-by: Alyssa Rosenzweig +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 +--- + 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 index 0000000000..063b57fdda --- /dev/null +++ b/queue-6.1/pci-apple-use-helper-function-for_each_child_of_node.patch @@ -0,0 +1,59 @@ +From 973bfce99051a4b286f965b343a50f271c685510 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Jonathan Cameron +Reviewed-by: Manivannan Sadhasivam +Link: https://lore.kernel.org/r/20240831040413.126417-6-zhangzekun11@huawei.com +[kwilczynski: commit log] +Signed-off-by: Krzysztof Wilczyński +Stable-dep-of: 751bec089c4e ("PCI: apple: Set only available ports up") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..bad0415d3b --- /dev/null +++ b/queue-6.1/revert-drm-i915-gem-allow-exec_capture-on-recoverabl.patch @@ -0,0 +1,58 @@ +From 5c23a1f832bdef3a6a6bd497b06f942e8e12da3f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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ä +Cc: Andi Shyti +Cc: Matthew Auld +Cc: Thomas Hellström +Cc: Tvrtko Ursulin +Acked-by: Tvrtko Ursulin +Reviewed-by: Andi Shyti +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 +(cherry picked from commit d2dc30e0aa252830f908c8e793d3139d51321370) +Signed-off-by: Joonas Lahtinen +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..8175d0db31 --- /dev/null +++ b/queue-6.1/revert-iommu-amd-prevent-binding-other-pci-drivers-t.patch @@ -0,0 +1,60 @@ +From b65812bf9e3a32d4f65dcc9e233e00956614d37a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Bjorn Helgaas +Signed-off-by: Krzysztof Wilczyński +Acked-by: Joerg Roedel +Link: https://patch.msgid.link/9a3ddff5cc49512044f963ba0904347bd404094d.1745572340.git.lukas@wunner.de +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..dcbc53fbc0 --- /dev/null +++ b/queue-6.1/rust-module-place-cleanup_module-in-.exit.text-secti.patch @@ -0,0 +1,61 @@ +From 29fc67c0c0f7e117cdf5cff9cf996268be8d03ca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Mar 2025 13:45:06 +0900 +Subject: rust: module: place cleanup_module() in .exit.text section + +From: FUJITA Tomonori + +[ 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 +Acked-by: Jarkko Sakkinen +Link: https://lore.kernel.org/r/20250308044506.14458-1-fujita.tomonori@gmail.com +Signed-off-by: Miguel Ojeda +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..bc59838fde --- /dev/null +++ b/queue-6.1/series @@ -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 index 0000000000..7f1b660cec --- /dev/null +++ b/queue-6.1/tty-serial-uartlite-register-uart-driver-in-init.patch @@ -0,0 +1,101 @@ +From 0ed6d5bc510d99fdfa1b344d4f2024c747776032 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 31 Mar 2025 18:06:19 +0200 +Subject: tty: serial: uartlite: register uart driver in init + +From: Jakub Lewalski + +[ 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 +Signed-off-by: Elodie Decerle +Link: https://lore.kernel.org/r/20250331160732.2042-1-elodie.decerle@nokia.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..83c8c3e432 --- /dev/null +++ b/queue-6.1/tty-vt-make-consw-con_switch-return-a-bool.patch @@ -0,0 +1,193 @@ +From 85e02e04c16982d897c39ab31b6c8b0e797c182b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Jan 2024 12:03:44 +0100 +Subject: tty: vt: make consw::con_switch() return a bool + +From: Jiri Slaby (SUSE) + +[ 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)" +Cc: Helge Deller +Cc: "James E.J. Bottomley" +Cc: Daniel Vetter +Cc: linux-fbdev@vger.kernel.org +Cc: dri-devel@lists.freedesktop.org +Cc: linux-parisc@vger.kernel.org +Tested-by: Helge Deller # parisc STI console +Link: https://lore.kernel.org/r/20240122110401.7289-31-jirislaby@kernel.org +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..2bede2f298 --- /dev/null +++ b/queue-6.1/tty-vt-make-init-parameter-of-consw-con_init-a-bool.patch @@ -0,0 +1,190 @@ +From b2a965c1cdc07eb5c5de21aa764475e2a3740242 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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) + +[ 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)" +Reviewed-by: Geert Uytterhoeven +Cc: Helge Deller +Cc: "James E.J. Bottomley" +Cc: Daniel Vetter +Cc: linux-fbdev@vger.kernel.org +Cc: dri-devel@lists.freedesktop.org +Cc: linux-parisc@vger.kernel.org +Tested-by: Helge Deller # parisc STI console +Link: https://lore.kernel.org/r/20240122110401.7289-21-jirislaby@kernel.org +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..8dba316641 --- /dev/null +++ b/queue-6.1/tty-vt-sanitize-arguments-of-consw-con_clear.patch @@ -0,0 +1,313 @@ +From 61d8fa3082a910da782fe7650f129a0e7b180e87 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Jan 2024 12:03:35 +0100 +Subject: tty: vt: sanitize arguments of consw::con_clear() + +From: Jiri Slaby (SUSE) + +[ 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)" +Cc: Helge Deller +Cc: "James E.J. Bottomley" +Cc: Daniel Vetter +Cc: linux-fbdev@vger.kernel.org +Cc: dri-devel@lists.freedesktop.org +Cc: linux-parisc@vger.kernel.org +Tested-by: Helge Deller # parisc STI console +Link: https://lore.kernel.org/r/20240122110401.7289-22-jirislaby@kernel.org +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..5792404a18 --- /dev/null +++ b/queue-6.1/uio_hv_generic-align-ring-size-to-system-page.patch @@ -0,0 +1,41 @@ +From 17ea0c5c1d56de73a2922b416876bc3593b6ba8b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 May 2025 17:56:35 -0700 +Subject: uio_hv_generic: Align ring size to system page + +From: Long Li + +[ 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 +Reviewed-by: Michael Kelley +Link: https://lore.kernel.org/r/1746492997-4599-4-git-send-email-longli@linuxonhyperv.com +Signed-off-by: Wei Liu +Message-ID: <1746492997-4599-4-git-send-email-longli@linuxonhyperv.com> +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..77251f0cf9 --- /dev/null +++ b/queue-6.1/uio_hv_generic-query-the-ringbuffer-size-for-device.patch @@ -0,0 +1,56 @@ +From 2c938acf5c9e2d71c1447ea044a3268e4c398ac7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 30 Mar 2024 01:51:58 -0700 +Subject: uio_hv_generic: Query the ringbuffer size for device + +From: Saurabh Sengar + +[ 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 +Reviewed-by: Long Li +Link: https://lore.kernel.org/r/1711788723-8593-3-git-send-email-ssengar@linux.microsoft.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 0315fef2aff9 ("uio_hv_generic: Align ring size to system page") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..f10297daea --- /dev/null +++ b/queue-6.1/um-add-cmpxchg8b_emu-and-checksum-functions-to-asm-p.patch @@ -0,0 +1,55 @@ +From 73a6923c066978c7a5a4b18660e1e38b263ec409 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Mar 2025 19:05:00 +0000 +Subject: um: Add cmpxchg8b_emu and checksum functions to asm-prototypes.h + +From: Sami Tolvanen + +[ 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 +Cc: linux-kbuild@vger.kernel.org +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202503251216.lE4t9Ikj-lkp@intel.com/ +Signed-off-by: Sami Tolvanen +Link: https://patch.msgid.link/20250326190500.847236-2-samitolvanen@google.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + 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 ++#include ++ ++#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 index 0000000000..6773a92821 --- /dev/null +++ b/queue-6.1/um-use-proper-care-when-taking-mmap-lock-during-segf.patch @@ -0,0 +1,177 @@ +From fc7af87ac02d1bb82d42d35d01d5f03b441e2afe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Apr 2025 09:45:24 +0200 +Subject: um: use proper care when taking mmap lock during segfault + +From: Benjamin Berg + +[ 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 +Link: https://patch.msgid.link/20250408074524.300153-2-benjamin@sipsolutions.net +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + 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 + #include + ++/* ++ * 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 index 0000000000..73925391d7 --- /dev/null +++ b/queue-6.1/usb-add-checks-for-snprintf-calls-in-usb_alloc_dev.patch @@ -0,0 +1,72 @@ +From a9e35ebfc537bf2fe7ff000358dc2ca26545f8f6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/20250321164949.423957-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..d26db4d562 --- /dev/null +++ b/queue-6.1/usb-cdc-wdm-avoid-setting-wdm_read-for-zlp-s.patch @@ -0,0 +1,114 @@ +From cad5c627f78e4ec85a26e6dc3959b9bc561bda72 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 3 Apr 2025 16:40:04 +0200 +Subject: usb: cdc-wdm: avoid setting WDM_READ for ZLP-s + +From: Robert Hodaszi + +[ 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 +Acked-by: Oliver Neukum +Link: https://lore.kernel.org/r/20250403144004.3889125-1-robert.hodaszi@digi.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..aa7df4c70b --- /dev/null +++ b/queue-6.1/usb-common-usb-conn-gpio-use-a-unique-name-for-usb-c.patch @@ -0,0 +1,93 @@ +From 91d9e64dbdb5a72df14513dcbc0b6a76c71e323b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/20250411-work-next-v3-1-7cd9aa80190c@kneron.us +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + #include + #include ++#include ++ ++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 index 0000000000..4c9bfad2e2 --- /dev/null +++ b/queue-6.1/usb-dwc2-also-exit-clock_gating-when-stopping-udc-wh.patch @@ -0,0 +1,47 @@ +From c4faddc0e12d8704ff870628f5b9d4a6b02ed169 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Apr 2025 19:40:17 +0200 +Subject: usb: dwc2: also exit clock_gating when stopping udc while suspended + +From: Michael Grzeschik + +[ 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 +Acked-by: Minas Harutyunyan +Link: https://lore.kernel.org/r/20250417-dwc2_clock_gating-v1-1-8ea7c4d53d73@pengutronix.de +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..03d9777a8c --- /dev/null +++ b/queue-6.1/usb-potential-integer-overflow-in-usbg_make_tpg.patch @@ -0,0 +1,53 @@ +From b9f72c4165d0b755361c4c6405e2d22dca67b8e1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Apr 2025 14:58:57 +0800 +Subject: usb: potential integer overflow in usbg_make_tpg() + +From: Chen Yufeng + +[ 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 +Link: https://lore.kernel.org/r/20250415065857.1619-1-chenyufeng@iie.ac.cn +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..dd5853ccc6 --- /dev/null +++ b/queue-6.1/usb-typec-displayport-receive-dp-status-update-nak-r.patch @@ -0,0 +1,56 @@ +From 01433343c1353fbeda457f0d2507b8e3ba54fa58 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20250209071926.69625-1-joswang1221@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..3ba7d8f615 --- /dev/null +++ b/queue-6.1/usb-typec-mux-do-not-return-on-eopnotsupp-in-mux-swi.patch @@ -0,0 +1,52 @@ +From 3ed3cf0bdd43734189cc2568a6e7ac2b30ce652b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20250404-ml-topic-typec-mux-v1-1-22c0526381ba@pengutronix.de +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..8bd4819705 --- /dev/null +++ b/queue-6.1/vgacon-remove-unneeded-forward-declarations.patch @@ -0,0 +1,47 @@ +From 44056744695a4ba72206d9c1c744d487d1c60b46 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Jul 2023 10:59:37 +0200 +Subject: vgacon: remove unneeded forward declarations + +From: Jiri Slaby (SUSE) + +[ Upstream commit 6ceed69cde8fe4a78fe50d62d7a88a5c1eed4709 ] + +Most of the forward declarations in vgacon are not needed. Drop them. + +Signed-off-by: "Jiri Slaby (SUSE)" +Cc: Helge Deller +Cc: linux-fbdev@vger.kernel.org +Cc: dri-devel@lists.freedesktop.org +Signed-off-by: Helge Deller +Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..782a3749a0 --- /dev/null +++ b/queue-6.1/vgacon-switch-vgacon_scrolldelta-and-vgacon_restore_.patch @@ -0,0 +1,56 @@ +From fb7a1380020942db1f3549e6eceb7b6c8789bb2f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Jul 2023 10:59:36 +0200 +Subject: vgacon: switch vgacon_scrolldelta() and vgacon_restore_screen() + +From: Jiri Slaby (SUSE) + +[ 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)" +Cc: Helge Deller +Cc: linux-fbdev@vger.kernel.org +Cc: dri-devel@lists.freedesktop.org +Signed-off-by: Helge Deller +Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover") +Signed-off-by: Sasha Levin +--- + 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 +