diff options
71 files changed, 6272 insertions, 0 deletions
diff --git a/queue-6.6/af_unix-define-locking-order-for-u_lock_second-in-un.patch b/queue-6.6/af_unix-define-locking-order-for-u_lock_second-in-un.patch new file mode 100644 index 0000000000..abf049d260 --- /dev/null +++ b/queue-6.6/af_unix-define-locking-order-for-u_lock_second-in-un.patch @@ -0,0 +1,73 @@ +From d445308567b10a49dc0a022d4d5668c4a4bda6f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Thu, 20 Jun 2024 13:56:14 -0700 +Subject: af_unix: Define locking order for U_LOCK_SECOND in + unix_state_double_lock(). + +From: Kuniyuki Iwashima <kuniyu@amazon.com> + +[ Upstream commit ed99822817cb728eee8786c1c921c69c6be206fe ] + +unix_dgram_connect() and unix_dgram_{send,recv}msg() lock the socket +and peer in ascending order of the socket address. + +Let's define the order as unix_state_lock_cmp_fn() instead of using +unix_state_lock_nested(). + +Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> +Reviewed-by: Kent Overstreet <kent.overstreet@linux.dev> +Signed-off-by: Paolo Abeni <pabeni@redhat.com> +Stable-dep-of: 32ca245464e1 ("af_unix: Don't leave consecutive consumed OOB skbs.") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + net/unix/af_unix.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 4f839d687c1e4..a6f0cc635f4dd 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -133,6 +133,18 @@ static int unix_table_lock_cmp_fn(const struct lockdep_map *a, + { + return cmp_ptr(a, b); + } ++ ++static int unix_state_lock_cmp_fn(const struct lockdep_map *_a, ++ const struct lockdep_map *_b) ++{ ++ const struct unix_sock *a, *b; ++ ++ a = container_of(_a, struct unix_sock, lock.dep_map); ++ b = container_of(_b, struct unix_sock, lock.dep_map); ++ ++ /* unix_state_double_lock(): ascending address order. */ ++ return cmp_ptr(a, b); ++} + #endif + + static unsigned int unix_unbound_hash(struct sock *sk) +@@ -992,6 +1004,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern, + u->path.dentry = NULL; + u->path.mnt = NULL; + spin_lock_init(&u->lock); ++ lock_set_cmp_fn(&u->lock, unix_state_lock_cmp_fn, NULL); + mutex_init(&u->iolock); /* single task reading lock */ + mutex_init(&u->bindlock); /* single task binding lock */ + init_waitqueue_head(&u->peer_wait); +@@ -1340,11 +1353,12 @@ static void unix_state_double_lock(struct sock *sk1, struct sock *sk2) + unix_state_lock(sk1); + return; + } ++ + if (sk1 > sk2) + swap(sk1, sk2); + + unix_state_lock(sk1); +- unix_state_lock_nested(sk2, U_LOCK_SECOND); ++ unix_state_lock(sk2); + } + + static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2) +-- +2.39.5 + diff --git a/queue-6.6/af_unix-define-locking-order-for-u_recvq_lock_embryo.patch b/queue-6.6/af_unix-define-locking-order-for-u_recvq_lock_embryo.patch new file mode 100644 index 0000000000..c03e4a7015 --- /dev/null +++ b/queue-6.6/af_unix-define-locking-order-for-u_recvq_lock_embryo.patch @@ -0,0 +1,101 @@ +From 518dfc7fa6f47d9f392289a99bb6eb8f0a9ee587 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Thu, 20 Jun 2024 13:56:20 -0700 +Subject: af_unix: Define locking order for U_RECVQ_LOCK_EMBRYO in + unix_collect_skb(). + +From: Kuniyuki Iwashima <kuniyu@amazon.com> + +[ Upstream commit 8647ece4814f3bfdb5f7a8e19f882c9b89299a07 ] + +While GC is cleaning up cyclic references by SCM_RIGHTS, +unix_collect_skb() collects skb in the socket's recvq. + +If the socket is TCP_LISTEN, we need to collect skb in the +embryo's queue. Then, both the listener's recvq lock and +the embroy's one are held. + +The locking is always done in the listener -> embryo order. + +Let's define it as unix_recvq_lock_cmp_fn() instead of using +spin_lock_nested(). + +Note that the reverse order is defined for consistency. + +Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> +Signed-off-by: Paolo Abeni <pabeni@redhat.com> +Stable-dep-of: 32ca245464e1 ("af_unix: Don't leave consecutive consumed OOB skbs.") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + net/unix/af_unix.c | 21 +++++++++++++++++++++ + net/unix/garbage.c | 8 +------- + 2 files changed, 22 insertions(+), 7 deletions(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index a6f0cc635f4dd..7546654f8273a 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -145,6 +145,25 @@ static int unix_state_lock_cmp_fn(const struct lockdep_map *_a, + /* unix_state_double_lock(): ascending address order. */ + return cmp_ptr(a, b); + } ++ ++static int unix_recvq_lock_cmp_fn(const struct lockdep_map *_a, ++ const struct lockdep_map *_b) ++{ ++ const struct sock *a, *b; ++ ++ a = container_of(_a, struct sock, sk_receive_queue.lock.dep_map); ++ b = container_of(_b, struct sock, sk_receive_queue.lock.dep_map); ++ ++ /* unix_collect_skb(): listener -> embryo order. */ ++ if (a->sk_state == TCP_LISTEN && unix_sk(b)->listener == a) ++ return -1; ++ ++ /* Should never happen. Just to be symmetric. */ ++ if (b->sk_state == TCP_LISTEN && unix_sk(a)->listener == b) ++ return 1; ++ ++ return 0; ++} + #endif + + static unsigned int unix_unbound_hash(struct sock *sk) +@@ -998,6 +1017,8 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern, + sk->sk_write_space = unix_write_space; + sk->sk_max_ack_backlog = READ_ONCE(net->unx.sysctl_max_dgram_qlen); + sk->sk_destruct = unix_sock_destructor; ++ lock_set_cmp_fn(&sk->sk_receive_queue.lock, unix_recvq_lock_cmp_fn, NULL); ++ + u = unix_sk(sk); + u->listener = NULL; + u->vertex = NULL; +diff --git a/net/unix/garbage.c b/net/unix/garbage.c +index 23efb78fe9ef4..06d94ad999e99 100644 +--- a/net/unix/garbage.c ++++ b/net/unix/garbage.c +@@ -337,11 +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); +@@ -375,8 +370,7 @@ 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); ++ spin_lock(&embryo_queue->lock); + unix_collect_queue(unix_sk(skb->sk), hitlist); + spin_unlock(&embryo_queue->lock); + } +-- +2.39.5 + diff --git a/queue-6.6/af_unix-define-locking-order-for-unix_table_double_l.patch b/queue-6.6/af_unix-define-locking-order-for-unix_table_double_l.patch new file mode 100644 index 0000000000..e7a2835ade --- /dev/null +++ b/queue-6.6/af_unix-define-locking-order-for-unix_table_double_l.patch @@ -0,0 +1,83 @@ +From 9c7753ad583ea4a8de90bf8078f800020e957bf5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Thu, 20 Jun 2024 13:56:13 -0700 +Subject: af_unix: Define locking order for unix_table_double_lock(). + +From: Kuniyuki Iwashima <kuniyu@amazon.com> + +[ Upstream commit 3955802f160b5c61ac00d7e54da8d746f2e4a2d5 ] + +When created, AF_UNIX socket is put into net->unx.table.buckets[], +and the hash is stored in sk->sk_hash. + + * unbound socket : 0 <= sk_hash <= UNIX_HASH_MOD + +When bind() is called, the socket could be moved to another bucket. + + * pathname socket : 0 <= sk_hash <= UNIX_HASH_MOD + * abstract socket : UNIX_HASH_MOD + 1 <= sk_hash <= UNIX_HASH_MOD * 2 + 1 + +Then, we call unix_table_double_lock() which locks a single bucket +or two. + +Let's define the order as unix_table_lock_cmp_fn() instead of using +spin_lock_nested(). + +The locking is always done in ascending order of sk->sk_hash, which +is the index of buckets/locks array allocated by kvmalloc_array(). + + sk_hash_A < sk_hash_B + <=> &locks[sk_hash_A].dep_map < &locks[sk_hash_B].dep_map + +So, the relation of two sk->sk_hash can be derived from the addresses +of dep_map in the array of locks. + +Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> +Reviewed-by: Kent Overstreet <kent.overstreet@linux.dev> +Signed-off-by: Paolo Abeni <pabeni@redhat.com> +Stable-dep-of: 32ca245464e1 ("af_unix: Don't leave consecutive consumed OOB skbs.") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + net/unix/af_unix.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 236a2cd2bc93d..4f839d687c1e4 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -125,6 +125,15 @@ static spinlock_t bsd_socket_locks[UNIX_HASH_SIZE / 2]; + * hash table is protected with spinlock. + * each socket state is protected by separate spinlock. + */ ++#ifdef CONFIG_PROVE_LOCKING ++#define cmp_ptr(l, r) (((l) > (r)) - ((l) < (r))) ++ ++static int unix_table_lock_cmp_fn(const struct lockdep_map *a, ++ const struct lockdep_map *b) ++{ ++ return cmp_ptr(a, b); ++} ++#endif + + static unsigned int unix_unbound_hash(struct sock *sk) + { +@@ -167,7 +176,7 @@ static void unix_table_double_lock(struct net *net, + swap(hash1, hash2); + + spin_lock(&net->unx.table.locks[hash1]); +- spin_lock_nested(&net->unx.table.locks[hash2], SINGLE_DEPTH_NESTING); ++ spin_lock(&net->unx.table.locks[hash2]); + } + + static void unix_table_double_unlock(struct net *net, +@@ -3598,6 +3607,7 @@ static int __net_init unix_net_init(struct net *net) + + for (i = 0; i < UNIX_HASH_SIZE; i++) { + spin_lock_init(&net->unx.table.locks[i]); ++ lock_set_cmp_fn(&net->unx.table.locks[i], unix_table_lock_cmp_fn, NULL); + INIT_HLIST_HEAD(&net->unx.table.buckets[i]); + } + +-- +2.39.5 + diff --git a/queue-6.6/af_unix-don-t-call-skb_get-for-oob-skb.patch b/queue-6.6/af_unix-don-t-call-skb_get-for-oob-skb.patch new file mode 100644 index 0000000000..3fe8a20106 --- /dev/null +++ b/queue-6.6/af_unix-don-t-call-skb_get-for-oob-skb.patch @@ -0,0 +1,155 @@ +From c635e0d369d04d6edb816ee1c07a8d64656296d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 16 Aug 2024 16:39:21 -0700 +Subject: af_unix: Don't call skb_get() for OOB skb. + +From: Kuniyuki Iwashima <kuniyu@amazon.com> + +[ Upstream commit 8594d9b85c07f05e431bd07e895c2a3ad9b85d6f ] + +Since introduced, OOB skb holds an additional reference count with no +special reason and caused many issues. + +Also, kfree_skb() and consume_skb() are used to decrement the count, +which is confusing. + +Let's drop the unnecessary skb_get() in queue_oob() and corresponding +kfree_skb(), consume_skb(), and skb_unref(). + +Now unix_sk(sk)->oob_skb is just a pointer to skb in the receive queue, +so special handing is no longer needed in GC. + +Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> +Link: https://patch.msgid.link/20240816233921.57800-1-kuniyu@amazon.com +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +Stable-dep-of: 32ca245464e1 ("af_unix: Don't leave consecutive consumed OOB skbs.") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + net/unix/af_unix.c | 27 +++++---------------------- + net/unix/garbage.c | 16 ++-------------- + 2 files changed, 7 insertions(+), 36 deletions(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 7546654f8273a..3cfc781214227 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -657,10 +657,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); +@@ -2189,13 +2186,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); +@@ -2599,8 +2592,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); +@@ -2610,8 +2601,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) +@@ -2639,12 +2628,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); + } +@@ -2655,10 +2642,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; + } +@@ -2701,7 +2685,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 06d94ad999e99..0068e758be4dd 100644 +--- a/net/unix/garbage.c ++++ b/net/unix/garbage.c +@@ -337,18 +337,6 @@ static bool unix_vertex_dead(struct unix_vertex *vertex) + return true; + } + +-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; +@@ -371,11 +359,11 @@ static void unix_collect_skb(struct list_head *scc, struct sk_buff_head *hitlist + struct sk_buff_head *embryo_queue = &skb->sk->sk_receive_queue; + + spin_lock(&embryo_queue->lock); +- unix_collect_queue(unix_sk(skb->sk), hitlist); ++ 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.6/af_unix-don-t-leave-consecutive-consumed-oob-skbs.patch b/queue-6.6/af_unix-don-t-leave-consecutive-consumed-oob-skbs.patch new file mode 100644 index 0000000000..db994eceec --- /dev/null +++ b/queue-6.6/af_unix-don-t-leave-consecutive-consumed-oob-skbs.patch @@ -0,0 +1,203 @@ +From 17e6b0c29086ac2941feeb2b40f7f6b256fc2056 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Wed, 18 Jun 2025 21:13:55 -0700 +Subject: af_unix: Don't leave consecutive consumed OOB skbs. + +From: Kuniyuki Iwashima <kuniyu@google.com> + +[ Upstream commit 32ca245464e1479bfea8592b9db227fdc1641705 ] + +Jann Horn reported a use-after-free in unix_stream_read_generic(). + +The following sequences reproduce the issue: + + $ python3 + from socket import * + s1, s2 = socketpair(AF_UNIX, SOCK_STREAM) + s1.send(b'x', MSG_OOB) + s2.recv(1, MSG_OOB) # leave a consumed OOB skb + s1.send(b'y', MSG_OOB) + s2.recv(1, MSG_OOB) # leave a consumed OOB skb + s1.send(b'z', MSG_OOB) + s2.recv(1) # recv 'z' illegally + s2.recv(1, MSG_OOB) # access 'z' skb (use-after-free) + +Even though a user reads OOB data, the skb holding the data stays on +the recv queue to mark the OOB boundary and break the next recv(). + +After the last send() in the scenario above, the sk2's recv queue has +2 leading consumed OOB skbs and 1 real OOB skb. + +Then, the following happens during the next recv() without MSG_OOB + + 1. unix_stream_read_generic() peeks the first consumed OOB skb + 2. manage_oob() returns the next consumed OOB skb + 3. unix_stream_read_generic() fetches the next not-yet-consumed OOB skb + 4. unix_stream_read_generic() reads and frees the OOB skb + +, and the last recv(MSG_OOB) triggers KASAN splat. + +The 3. above occurs because of the SO_PEEK_OFF code, which does not +expect unix_skb_len(skb) to be 0, but this is true for such consumed +OOB skbs. + + while (skip >= unix_skb_len(skb)) { + skip -= unix_skb_len(skb); + skb = skb_peek_next(skb, &sk->sk_receive_queue); + ... + } + +In addition to this use-after-free, there is another issue that +ioctl(SIOCATMARK) does not function properly with consecutive consumed +OOB skbs. + +So, nothing good comes out of such a situation. + +Instead of complicating manage_oob(), ioctl() handling, and the next +ECONNRESET fix by introducing a loop for consecutive consumed OOB skbs, +let's not leave such consecutive OOB unnecessarily. + +Now, while receiving an OOB skb in unix_stream_recv_urg(), if its +previous skb is a consumed OOB skb, it is freed. + +[0]: +BUG: KASAN: slab-use-after-free in unix_stream_read_actor (net/unix/af_unix.c:3027) +Read of size 4 at addr ffff888106ef2904 by task python3/315 + +CPU: 2 UID: 0 PID: 315 Comm: python3 Not tainted 6.16.0-rc1-00407-gec315832f6f9 #8 PREEMPT(voluntary) +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-4.fc42 04/01/2014 +Call Trace: + <TASK> + dump_stack_lvl (lib/dump_stack.c:122) + print_report (mm/kasan/report.c:409 mm/kasan/report.c:521) + kasan_report (mm/kasan/report.c:636) + unix_stream_read_actor (net/unix/af_unix.c:3027) + unix_stream_read_generic (net/unix/af_unix.c:2708 net/unix/af_unix.c:2847) + unix_stream_recvmsg (net/unix/af_unix.c:3048) + sock_recvmsg (net/socket.c:1063 (discriminator 20) net/socket.c:1085 (discriminator 20)) + __sys_recvfrom (net/socket.c:2278) + __x64_sys_recvfrom (net/socket.c:2291 (discriminator 1) net/socket.c:2287 (discriminator 1) net/socket.c:2287 (discriminator 1)) + do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1)) + entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130) +RIP: 0033:0x7f8911fcea06 +Code: 5d e8 41 8b 93 08 03 00 00 59 5e 48 83 f8 fc 75 19 83 e2 39 83 fa 08 75 11 e8 26 ff ff ff 66 0f 1f 44 00 00 48 8b 45 10 0f 05 <48> 8b 5d f8 c9 c3 0f 1f 40 00 f3 0f 1e fa 55 48 89 e5 48 83 ec 08 +RSP: 002b:00007fffdb0dccb0 EFLAGS: 00000202 ORIG_RAX: 000000000000002d +RAX: ffffffffffffffda RBX: 00007fffdb0dcdc8 RCX: 00007f8911fcea06 +RDX: 0000000000000001 RSI: 00007f8911a5e060 RDI: 0000000000000006 +RBP: 00007fffdb0dccd0 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000001 R11: 0000000000000202 R12: 00007f89119a7d20 +R13: ffffffffc4653600 R14: 0000000000000000 R15: 0000000000000000 + </TASK> + +Allocated by task 315: + kasan_save_stack (mm/kasan/common.c:48) + kasan_save_track (mm/kasan/common.c:60 (discriminator 1) mm/kasan/common.c:69 (discriminator 1)) + __kasan_slab_alloc (mm/kasan/common.c:348) + kmem_cache_alloc_node_noprof (./include/linux/kasan.h:250 mm/slub.c:4148 mm/slub.c:4197 mm/slub.c:4249) + __alloc_skb (net/core/skbuff.c:660 (discriminator 4)) + alloc_skb_with_frags (./include/linux/skbuff.h:1336 net/core/skbuff.c:6668) + sock_alloc_send_pskb (net/core/sock.c:2993) + unix_stream_sendmsg (./include/net/sock.h:1847 net/unix/af_unix.c:2256 net/unix/af_unix.c:2418) + __sys_sendto (net/socket.c:712 (discriminator 20) net/socket.c:727 (discriminator 20) net/socket.c:2226 (discriminator 20)) + __x64_sys_sendto (net/socket.c:2233 (discriminator 1) net/socket.c:2229 (discriminator 1) net/socket.c:2229 (discriminator 1)) + do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1)) + entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130) + +Freed by task 315: + kasan_save_stack (mm/kasan/common.c:48) + kasan_save_track (mm/kasan/common.c:60 (discriminator 1) mm/kasan/common.c:69 (discriminator 1)) + kasan_save_free_info (mm/kasan/generic.c:579 (discriminator 1)) + __kasan_slab_free (mm/kasan/common.c:271) + kmem_cache_free (mm/slub.c:4643 (discriminator 3) mm/slub.c:4745 (discriminator 3)) + unix_stream_read_generic (net/unix/af_unix.c:3010) + unix_stream_recvmsg (net/unix/af_unix.c:3048) + sock_recvmsg (net/socket.c:1063 (discriminator 20) net/socket.c:1085 (discriminator 20)) + __sys_recvfrom (net/socket.c:2278) + __x64_sys_recvfrom (net/socket.c:2291 (discriminator 1) net/socket.c:2287 (discriminator 1) net/socket.c:2287 (discriminator 1)) + do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1)) + entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130) + +The buggy address belongs to the object at ffff888106ef28c0 + which belongs to the cache skbuff_head_cache of size 224 +The buggy address is located 68 bytes inside of + freed 224-byte region [ffff888106ef28c0, ffff888106ef29a0) + +The buggy address belongs to the physical page: +page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff888106ef3cc0 pfn:0x106ef2 +head: order:1 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 +flags: 0x200000000000040(head|node=0|zone=2) +page_type: f5(slab) +raw: 0200000000000040 ffff8881001d28c0 ffffea000422fe00 0000000000000004 +raw: ffff888106ef3cc0 0000000080190010 00000000f5000000 0000000000000000 +head: 0200000000000040 ffff8881001d28c0 ffffea000422fe00 0000000000000004 +head: ffff888106ef3cc0 0000000080190010 00000000f5000000 0000000000000000 +head: 0200000000000001 ffffea00041bbc81 00000000ffffffff 00000000ffffffff +head: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 +page dumped because: kasan: bad access detected + +Memory state around the buggy address: + ffff888106ef2800: 00 00 00 00 00 00 00 00 00 00 00 00 fc fc fc fc + ffff888106ef2880: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb +>ffff888106ef2900: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + ^ + ffff888106ef2980: fb fb fb fb fc fc fc fc fc fc fc fc fc fc fc fc + ffff888106ef2a00: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + +Fixes: 314001f0bf92 ("af_unix: Add OOB support") +Reported-by: Jann Horn <jannh@google.com> +Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> +Reviewed-by: Jann Horn <jannh@google.com> +Link: https://patch.msgid.link/20250619041457.1132791-2-kuni1840@gmail.com +Signed-off-by: Paolo Abeni <pabeni@redhat.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + net/unix/af_unix.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 3cfc781214227..7604d399a7788 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -2571,11 +2571,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); +@@ -2590,9 +2590,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); + +@@ -2603,6 +2610,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.6/alsa-hda-add-new-pci-id-for-amd-gpu-display-hd-audio.patch b/queue-6.6/alsa-hda-add-new-pci-id-for-amd-gpu-display-hd-audio.patch new file mode 100644 index 0000000000..c43e2f9c1f --- /dev/null +++ b/queue-6.6/alsa-hda-add-new-pci-id-for-amd-gpu-display-hd-audio.patch @@ -0,0 +1,37 @@ +From 2a0a4024a031b8f384090a229b78ac3b64bed996 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Thu, 29 May 2025 11:08:13 +0530 +Subject: ALSA: hda: Add new pci id for AMD GPU display HD audio controller + +From: Vijendar Mukunda <Vijendar.Mukunda@amd.com> + +[ Upstream commit ab72bfce7647522e01a181e3600c3d14ff5c143e ] + +Add new pci id for AMD GPU display HD audio controller(device id- 0xab40). + +Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com> +Reviewed-by: Alex Deucher <alexander.deucher@amd.com> +Link: https://patch.msgid.link/20250529053838.2350071-1-Vijendar.Mukunda@amd.com +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + sound/pci/hda/hda_intel.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c +index 3cd5b7da8e152..059693e03fd96 100644 +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -2727,6 +2727,9 @@ static const struct pci_device_id azx_ids[] = { + { PCI_VDEVICE(ATI, 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.6/alsa-hda-ignore-unsol-events-for-cards-being-shut-do.patch b/queue-6.6/alsa-hda-ignore-unsol-events-for-cards-being-shut-do.patch new file mode 100644 index 0000000000..c06fae2bae --- /dev/null +++ b/queue-6.6/alsa-hda-ignore-unsol-events-for-cards-being-shut-do.patch @@ -0,0 +1,48 @@ +From 053bb403c51810d8bf2831dddc3e430e3d237c12 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 30 May 2025 16:13:09 +0200 +Subject: ALSA: hda: Ignore unsol events for cards being shut down +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Cezary Rojewski <cezary.rojewski@intel.com> + +[ Upstream commit 3f100f524e75586537e337b34d18c8d604b398e7 ] + +For the classic snd_hda_intel driver, codec->card and bus->card point to +the exact same thing. When snd_card_diconnect() fires, bus->shutdown is +set thanks to azx_dev_disconnect(). card->shutdown is already set when +that happens but both provide basically the same functionality. + +For the DSP snd_soc_avs driver where multiple codecs are located on +multiple cards, bus->shutdown 'shortcut' is not sufficient. One codec +card may be unregistered while other codecs are still operational. +Proper check in form of card->shutdown must be used to verify whether +the codec's card is being shut down. + +Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com> +Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com> +Link: https://patch.msgid.link/20250530141309.2943404-1-cezary.rojewski@intel.com +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + sound/pci/hda/hda_bind.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c +index b7ca2a83fbb08..95786bdadfe6a 100644 +--- a/sound/pci/hda/hda_bind.c ++++ b/sound/pci/hda/hda_bind.c +@@ -44,7 +44,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.6/alsa-usb-audio-add-a-quirk-for-lenovo-thinkpad-thund.patch b/queue-6.6/alsa-usb-audio-add-a-quirk-for-lenovo-thinkpad-thund.patch new file mode 100644 index 0000000000..91e83c01e7 --- /dev/null +++ b/queue-6.6/alsa-usb-audio-add-a-quirk-for-lenovo-thinkpad-thund.patch @@ -0,0 +1,39 @@ +From 12e986d06ea544182f33e276f0e5f1317cb06851 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 27 May 2025 12:26:56 -0500 +Subject: ALSA: usb-audio: Add a quirk for Lenovo Thinkpad Thunderbolt 3 dock + +From: Mario Limonciello <mario.limonciello@amd.com> + +[ Upstream commit 4919353c7789b8047e06a9b2b943f775a8f72883 ] + +The audio controller in the Lenovo Thinkpad Thunderbolt 3 dock doesn't +support reading the sampling rate. + +Add a quirk for it. + +Suggested-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> +Link: https://patch.msgid.link/20250527172657.1972565-1-superm1@kernel.org +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + sound/usb/quirks.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index 0b8b20550ab38..f19c808444c97 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -2182,6 +2182,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.6/amd-amdkfd-fix-a-kfd_process-ref-leak.patch b/queue-6.6/amd-amdkfd-fix-a-kfd_process-ref-leak.patch new file mode 100644 index 0000000000..c872d3a6d4 --- /dev/null +++ b/queue-6.6/amd-amdkfd-fix-a-kfd_process-ref-leak.patch @@ -0,0 +1,34 @@ +From 3a3a3d0746a9ae956e301e19fc7def1d3a0e70a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Wed, 21 May 2025 18:06:28 +0800 +Subject: amd/amdkfd: fix a kfd_process ref leak + +From: Yifan Zhang <yifan1.zhang@amd.com> + +[ Upstream commit 90237b16ec1d7afa16e2173cc9a664377214cdd9 ] + +This patch is to fix a kfd_prcess ref leak. + +Signed-off-by: Yifan Zhang <yifan1.zhang@amd.com> +Reviewed-by: Philip Yang <Philip.Yang@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/gpu/drm/amd/amdkfd/kfd_events.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c +index 0f58be65132fc..2b07c0000df6e 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c +@@ -1287,6 +1287,7 @@ void kfd_signal_poison_consumed_event(struct kfd_node *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.6/asoc-codec-wcd9335-convert-to-gpio-descriptors.patch b/queue-6.6/asoc-codec-wcd9335-convert-to-gpio-descriptors.patch new file mode 100644 index 0000000000..e8aacc058a --- /dev/null +++ b/queue-6.6/asoc-codec-wcd9335-convert-to-gpio-descriptors.patch @@ -0,0 +1,85 @@ +From f7a7e7811f75b81ef069402b33fe02d01b2a7e3d Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 24 Mar 2025 19:51:29 +0800 +Subject: ASoC: codec: wcd9335: Convert to GPIO descriptors + +From: Peng Fan <peng.fan@nxp.com> + +[ Upstream commit d5099bc1b56417733f4cccf10c61ee74dadd5562 ] + +of_gpio.h is deprecated, update the driver to use GPIO descriptors. +- Use dev_gpiod_get to get GPIO descriptor. +- Use gpiod_set_value to configure output value. + +With legacy of_gpio API, the driver set gpio value 0 to assert reset, +and 1 to deassert reset. And the reset-gpios use GPIO_ACTIVE_LOW flag in +DTS, so set GPIOD_OUT_LOW when get GPIO descriptors, and set value 1 means +output low, set value 0 means output high with gpiod API. + +The in-tree DTS files have the right polarity set up already so we can +expect this to "just work" + +Reviewed-by: Linus Walleij <linus.walleij@linaro.org> +Signed-off-by: Peng Fan <peng.fan@nxp.com> +Link: https://patch.msgid.link/20250324-wcd-gpiod-v2-3-773f67ce3b56@nxp.com +Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> +Signed-off-by: Mark Brown <broonie@kernel.org> +Stable-dep-of: 9079db287fc3 ("ASoC: codecs: wcd9335: Fix missing free of regulator supplies") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + sound/soc/codecs/wcd9335.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c +index 6e172be34ac91..15f263087bb8a 100644 +--- a/sound/soc/codecs/wcd9335.c ++++ b/sound/soc/codecs/wcd9335.c +@@ -16,7 +16,7 @@ + #include <sound/soc.h> + #include <sound/pcm_params.h> + #include <sound/soc-dapm.h> +-#include <linux/of_gpio.h> ++#include <linux/gpio/consumer.h> + #include <linux/of.h> + #include <linux/of_irq.h> + #include <sound/tlv.h> +@@ -329,7 +329,7 @@ struct wcd9335_codec { + int comp_enabled[COMPANDER_MAX]; + + int intr1; +- int reset_gpio; ++ struct gpio_desc *reset_gpio; + struct regulator_bulk_data supplies[WCD9335_MAX_SUPPLY]; + + unsigned int rx_port_value[WCD9335_RX_MAX]; +@@ -5032,12 +5032,11 @@ static const struct regmap_irq_chip wcd9335_regmap_irq1_chip = { + static int wcd9335_parse_dt(struct wcd9335_codec *wcd) + { + struct device *dev = wcd->dev; +- struct device_node *np = dev->of_node; + int ret; + +- wcd->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0); +- if (wcd->reset_gpio < 0) +- return dev_err_probe(dev, wcd->reset_gpio, "Reset GPIO missing from DT\n"); ++ wcd->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); ++ if (IS_ERR(wcd->reset_gpio)) ++ return dev_err_probe(dev, PTR_ERR(wcd->reset_gpio), "Reset GPIO missing from DT\n"); + + wcd->mclk = devm_clk_get(dev, "mclk"); + if (IS_ERR(wcd->mclk)) +@@ -5080,9 +5079,9 @@ static int wcd9335_power_on_reset(struct wcd9335_codec *wcd) + */ + usleep_range(600, 650); + +- gpio_direction_output(wcd->reset_gpio, 0); ++ gpiod_set_value(wcd->reset_gpio, 1); + msleep(20); +- gpio_set_value(wcd->reset_gpio, 1); ++ gpiod_set_value(wcd->reset_gpio, 0); + msleep(20); + + return 0; +-- +2.39.5 + diff --git a/queue-6.6/asoc-codecs-wcd9335-fix-missing-free-of-regulator-su.patch b/queue-6.6/asoc-codecs-wcd9335-fix-missing-free-of-regulator-su.patch new file mode 100644 index 0000000000..f1f99a786b --- /dev/null +++ b/queue-6.6/asoc-codecs-wcd9335-fix-missing-free-of-regulator-su.patch @@ -0,0 +1,88 @@ +From 09031aa12ca6da18e99a588094033942db04322b Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 26 May 2025 11:47:01 +0200 +Subject: ASoC: codecs: wcd9335: Fix missing free of regulator supplies + +From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> + +[ Upstream commit 9079db287fc3e38e040b0edeb0a25770bb679c8e ] + +Driver gets and enables all regulator supplies in probe path +(wcd9335_parse_dt() and wcd9335_power_on_reset()), but does not cleanup +in final error paths and in unbind (missing remove() callback). This +leads to leaked memory and unbalanced regulator enable count during +probe errors or unbind. + +Fix this by converting entire code into devm_regulator_bulk_get_enable() +which also greatly simplifies the code. + +Fixes: 20aedafdf492 ("ASoC: wcd9335: add support to wcd9335 codec") +Cc: stable@vger.kernel.org +Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> +Link: https://patch.msgid.link/20250526-b4-b4-asoc-wcd9395-vdd-px-fixes-v1-1-0b8a2993b7d3@linaro.org +Signed-off-by: Mark Brown <broonie@kernel.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + sound/soc/codecs/wcd9335.c | 25 +++++++------------------ + 1 file changed, 7 insertions(+), 18 deletions(-) + +diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c +index 15f263087bb8a..8d5d186fd5802 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.6/asoc-codecs-wcd9335-handle-nicer-probe-deferral-and-.patch b/queue-6.6/asoc-codecs-wcd9335-handle-nicer-probe-deferral-and-.patch new file mode 100644 index 0000000000..fc37aff5a5 --- /dev/null +++ b/queue-6.6/asoc-codecs-wcd9335-handle-nicer-probe-deferral-and-.patch @@ -0,0 +1,85 @@ +From b7a596658fb1c0e15fc7956f35aa4814644114d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Wed, 12 Jun 2024 18:15:17 +0200 +Subject: ASoC: codecs: wcd9335: Handle nicer probe deferral and simplify with + dev_err_probe() + +From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> + +[ Upstream commit 4a03b5dbad466c902d522f3405daa4e5d80578c5 ] + +wcd9335_parse_dt() function is called only from probe(), so printing +errors on resource acquisition is discouraged, because it can pollute +dmesg. Use dev_err_probe() to fix this and also make the code a bit +simpler. + +Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> +Link: https://msgid.link/r/20240612-asoc-wcd9xxx-wide-cleanups-v1-4-0d15885b2a06@linaro.org +Signed-off-by: Mark Brown <broonie@kernel.org> +Stable-dep-of: 9079db287fc3 ("ASoC: codecs: wcd9335: Fix missing free of regulator supplies") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + sound/soc/codecs/wcd9335.c | 28 +++++++++------------------- + 1 file changed, 9 insertions(+), 19 deletions(-) + +diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c +index a05b553e6472f..6e172be34ac91 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; + } +@@ -5163,10 +5155,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.6/bcache-fix-null-pointer-in-cache_set_flush.patch b/queue-6.6/bcache-fix-null-pointer-in-cache_set_flush.patch new file mode 100644 index 0000000000..5720efaff3 --- /dev/null +++ b/queue-6.6/bcache-fix-null-pointer-in-cache_set_flush.patch @@ -0,0 +1,151 @@ +From 6ee677d8b3874eb7730307bc04e862eac93c4d96 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 27 May 2025 13:15:59 +0800 +Subject: bcache: fix NULL pointer in cache_set_flush() + +From: Linggang Zeng <linggang.zeng@easystack.cn> + +[ Upstream commit 1e46ed947ec658f89f1a910d880cd05e42d3763e ] + +1. LINE#1794 - LINE#1887 is some codes about function of + bch_cache_set_alloc(). +2. LINE#2078 - LINE#2142 is some codes about function of + register_cache_set(). +3. register_cache_set() will call bch_cache_set_alloc() in LINE#2098. + + 1794 struct cache_set *bch_cache_set_alloc(struct cache_sb *sb) + 1795 { + ... + 1860 if (!(c->devices = kcalloc(c->nr_uuids, sizeof(void *), GFP_KERNEL)) || + 1861 mempool_init_slab_pool(&c->search, 32, bch_search_cache) || + 1862 mempool_init_kmalloc_pool(&c->bio_meta, 2, + 1863 sizeof(struct bbio) + sizeof(struct bio_vec) * + 1864 bucket_pages(c)) || + 1865 mempool_init_kmalloc_pool(&c->fill_iter, 1, iter_size) || + 1866 bioset_init(&c->bio_split, 4, offsetof(struct bbio, bio), + 1867 BIOSET_NEED_BVECS|BIOSET_NEED_RESCUER) || + 1868 !(c->uuids = alloc_bucket_pages(GFP_KERNEL, c)) || + 1869 !(c->moving_gc_wq = alloc_workqueue("bcache_gc", + 1870 WQ_MEM_RECLAIM, 0)) || + 1871 bch_journal_alloc(c) || + 1872 bch_btree_cache_alloc(c) || + 1873 bch_open_buckets_alloc(c) || + 1874 bch_bset_sort_state_init(&c->sort, ilog2(c->btree_pages))) + 1875 goto err; + ^^^^^^^^ + 1876 + ... + 1883 return c; + 1884 err: + 1885 bch_cache_set_unregister(c); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 1886 return NULL; + 1887 } + ... + 2078 static const char *register_cache_set(struct cache *ca) + 2079 { + ... + 2098 c = bch_cache_set_alloc(&ca->sb); + 2099 if (!c) + 2100 return err; + ^^^^^^^^^^ + ... + 2128 ca->set = c; + 2129 ca->set->cache[ca->sb.nr_this_dev] = ca; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ... + 2138 return NULL; + 2139 err: + 2140 bch_cache_set_unregister(c); + 2141 return err; + 2142 } + +(1) If LINE#1860 - LINE#1874 is true, then do 'goto err'(LINE#1875) and + call bch_cache_set_unregister()(LINE#1885). +(2) As (1) return NULL(LINE#1886), LINE#2098 - LINE#2100 would return. +(3) As (2) has returned, LINE#2128 - LINE#2129 would do *not* give the + value to c->cache[], it means that c->cache[] is NULL. + +LINE#1624 - LINE#1665 is some codes about function of cache_set_flush(). +As (1), in LINE#1885 call +bch_cache_set_unregister() +---> bch_cache_set_stop() + ---> closure_queue() + -.-> cache_set_flush() (as below LINE#1624) + + 1624 static void cache_set_flush(struct closure *cl) + 1625 { + ... + 1654 for_each_cache(ca, c, i) + 1655 if (ca->alloc_thread) + ^^ + 1656 kthread_stop(ca->alloc_thread); + ... + 1665 } + +(4) In LINE#1655 ca is NULL(see (3)) in cache_set_flush() then the + kernel crash occurred as below: +[ 846.712887] bcache: register_cache() error drbd6: cannot allocate memory +[ 846.713242] bcache: register_bcache() error : failed to register device +[ 846.713336] bcache: cache_set_free() Cache set 2f84bdc1-498a-4f2f-98a7-01946bf54287 unregistered +[ 846.713768] BUG: unable to handle kernel NULL pointer dereference at 00000000000009f8 +[ 846.714790] PGD 0 P4D 0 +[ 846.715129] Oops: 0000 [#1] SMP PTI +[ 846.715472] CPU: 19 PID: 5057 Comm: kworker/19:16 Kdump: loaded Tainted: G OE --------- - - 4.18.0-147.5.1.el8_1.5es.3.x86_64 #1 +[ 846.716082] Hardware name: ESPAN GI-25212/X11DPL-i, BIOS 2.1 06/15/2018 +[ 846.716451] Workqueue: events cache_set_flush [bcache] +[ 846.716808] RIP: 0010:cache_set_flush+0xc9/0x1b0 [bcache] +[ 846.717155] Code: 00 4c 89 a5 b0 03 00 00 48 8b 85 68 f6 ff ff a8 08 0f 84 88 00 00 00 31 db 66 83 bd 3c f7 ff ff 00 48 8b 85 48 ff ff ff 74 28 <48> 8b b8 f8 09 00 00 48 85 ff 74 05 e8 b6 58 a2 e1 0f b7 95 3c f7 +[ 846.718026] RSP: 0018:ffffb56dcf85fe70 EFLAGS: 00010202 +[ 846.718372] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000 +[ 846.718725] RDX: 0000000000000001 RSI: 0000000040000001 RDI: 0000000000000000 +[ 846.719076] RBP: ffffa0ccc0f20df8 R08: ffffa0ce1fedb118 R09: 000073746e657665 +[ 846.719428] R10: 8080808080808080 R11: 0000000000000000 R12: ffffa0ce1fee8700 +[ 846.719779] R13: ffffa0ccc0f211a8 R14: ffffa0cd1b902840 R15: ffffa0ccc0f20e00 +[ 846.720132] FS: 0000000000000000(0000) GS:ffffa0ce1fec0000(0000) knlGS:0000000000000000 +[ 846.720726] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 846.721073] CR2: 00000000000009f8 CR3: 00000008ba00a005 CR4: 00000000007606e0 +[ 846.721426] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +[ 846.721778] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +[ 846.722131] PKRU: 55555554 +[ 846.722467] Call Trace: +[ 846.722814] process_one_work+0x1a7/0x3b0 +[ 846.723157] worker_thread+0x30/0x390 +[ 846.723501] ? create_worker+0x1a0/0x1a0 +[ 846.723844] kthread+0x112/0x130 +[ 846.724184] ? kthread_flush_work_fn+0x10/0x10 +[ 846.724535] ret_from_fork+0x35/0x40 + +Now, check whether that ca is NULL in LINE#1655 to fix the issue. + +Signed-off-by: Linggang Zeng <linggang.zeng@easystack.cn> +Signed-off-by: Mingzhe Zou <mingzhe.zou@easystack.cn> +Signed-off-by: Coly Li <colyli@kernel.org> +Link: https://lore.kernel.org/r/20250527051601.74407-2-colyli@kernel.org +Signed-off-by: Jens Axboe <axboe@kernel.dk> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/md/bcache/super.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c +index 8440b56e385d5..b9dfebaa9eae5 100644 +--- a/drivers/md/bcache/super.c ++++ b/drivers/md/bcache/super.c +@@ -1739,7 +1739,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.6/btrfs-handle-csum-tree-error-with-rescue-ibadroots-c.patch b/queue-6.6/btrfs-handle-csum-tree-error-with-rescue-ibadroots-c.patch new file mode 100644 index 0000000000..6d2513e5f0 --- /dev/null +++ b/queue-6.6/btrfs-handle-csum-tree-error-with-rescue-ibadroots-c.patch @@ -0,0 +1,117 @@ +From cc99d7af17ae4bd09634e00e2eaa730bc02b718c Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sat, 7 Jun 2025 09:18:43 +0930 +Subject: btrfs: handle csum tree error with rescue=ibadroots correctly + +From: Qu Wenruo <wqu@suse.com> + +[ Upstream commit 547e836661554dcfa15c212a3821664e85b4191a ] + +[BUG] +There is syzbot based reproducer that can crash the kernel, with the +following call trace: (With some debug output added) + + DEBUG: rescue=ibadroots parsed + BTRFS: device fsid 14d642db-7b15-43e4-81e6-4b8fac6a25f8 devid 1 transid 8 /dev/loop0 (7:0) scanned by repro (1010) + BTRFS info (device loop0): first mount of filesystem 14d642db-7b15-43e4-81e6-4b8fac6a25f8 + BTRFS info (device loop0): using blake2b (blake2b-256-generic) checksum algorithm + BTRFS info (device loop0): using free-space-tree + BTRFS warning (device loop0): checksum verify failed on logical 5312512 mirror 1 wanted 0xb043382657aede36608fd3386d6b001692ff406164733d94e2d9a180412c6003 found 0x810ceb2bacb7f0f9eb2bf3b2b15c02af867cb35ad450898169f3b1f0bd818651 level 0 + DEBUG: read tree root path failed for tree csum, ret=-5 + BTRFS warning (device loop0): checksum verify failed on logical 5328896 mirror 1 wanted 0x51be4e8b303da58e6340226815b70e3a93592dac3f30dd510c7517454de8567a found 0x51be4e8b303da58e634022a315b70e3a93592dac3f30dd510c7517454de8567a level 0 + BTRFS warning (device loop0): checksum verify failed on logical 5292032 mirror 1 wanted 0x1924ccd683be9efc2fa98582ef58760e3848e9043db8649ee382681e220cdee4 found 0x0cb6184f6e8799d9f8cb335dccd1d1832da1071d12290dab3b85b587ecacca6e level 0 + process 'repro' launched './file2' with NULL argv: empty string added + DEBUG: no csum root, idatacsums=0 ibadroots=134217728 + Oops: general protection fault, probably for non-canonical address 0xdffffc0000000041: 0000 [#1] SMP KASAN NOPTI + KASAN: null-ptr-deref in range [0x0000000000000208-0x000000000000020f] + CPU: 5 UID: 0 PID: 1010 Comm: repro Tainted: G OE 6.15.0-custom+ #249 PREEMPT(full) + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS unknown 02/02/2022 + RIP: 0010:btrfs_lookup_csum+0x93/0x3d0 [btrfs] + Call Trace: + <TASK> + btrfs_lookup_bio_sums+0x47a/0xdf0 [btrfs] + btrfs_submit_bbio+0x43e/0x1a80 [btrfs] + submit_one_bio+0xde/0x160 [btrfs] + btrfs_readahead+0x498/0x6a0 [btrfs] + read_pages+0x1c3/0xb20 + page_cache_ra_order+0x4b5/0xc20 + filemap_get_pages+0x2d3/0x19e0 + filemap_read+0x314/0xde0 + __kernel_read+0x35b/0x900 + bprm_execve+0x62e/0x1140 + do_execveat_common.isra.0+0x3fc/0x520 + __x64_sys_execveat+0xdc/0x130 + do_syscall_64+0x54/0x1d0 + entry_SYSCALL_64_after_hwframe+0x76/0x7e + ---[ end trace 0000000000000000 ]--- + +[CAUSE] +Firstly the fs has a corrupted csum tree root, thus to mount the fs we +have to go "ro,rescue=ibadroots" mount option. + +Normally with that mount option, a bad csum tree root should set +BTRFS_FS_STATE_NO_DATA_CSUMS flag, so that any future data read will +ignore csum search. + +But in this particular case, we have the following call trace that +caused NULL csum root, but not setting BTRFS_FS_STATE_NO_DATA_CSUMS: + +load_global_roots_objectid(): + + ret = btrfs_search_slot(); + /* Succeeded */ + btrfs_item_key_to_cpu() + found = true; + /* We found the root item for csum tree. */ + root = read_tree_root_path(); + if (IS_ERR(root)) { + if (!btrfs_test_opt(fs_info, IGNOREBADROOTS)) + /* + * Since we have rescue=ibadroots mount option, + * @ret is still 0. + */ + break; + if (!found || ret) { + /* @found is true, @ret is 0, error handling for csum + * tree is skipped. + */ + } + +This means we completely skipped to set BTRFS_FS_STATE_NO_DATA_CSUMS if +the csum tree is corrupted, which results unexpected later csum lookup. + +[FIX] +If read_tree_root_path() failed, always populate @ret to the error +number. + +As at the end of the function, we need @ret to determine if we need to +do the extra error handling for csum tree. + +Fixes: abed4aaae4f7 ("btrfs: track the csum, extent, and free space trees in a rb tree") +Reported-by: Zhiyu Zhang <zhiyuzhang999@gmail.com> +Reported-by: Longxing Li <coregee2000@gmail.com> +Reviewed-by: David Sterba <dsterba@suse.com> +Signed-off-by: Qu Wenruo <wqu@suse.com> +Signed-off-by: David Sterba <dsterba@suse.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/btrfs/disk-io.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c +index 34a30d61b470c..bb5f7911d473c 100644 +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -2148,8 +2148,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.6/ceph-fix-possible-integer-overflow-in-ceph_zero_obje.patch b/queue-6.6/ceph-fix-possible-integer-overflow-in-ceph_zero_obje.patch new file mode 100644 index 0000000000..17db242ab7 --- /dev/null +++ b/queue-6.6/ceph-fix-possible-integer-overflow-in-ceph_zero_obje.patch @@ -0,0 +1,40 @@ +From 4a686ec6b8f97d9cd6d9cac1b344dafcaaa808fc Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 22 Apr 2025 12:32:04 +0300 +Subject: ceph: fix possible integer overflow in ceph_zero_objects() + +From: Dmitry Kandybka <d.kandybka@gmail.com> + +[ Upstream commit 0abd87942e0c93964e93224836944712feba1d91 ] + +In 'ceph_zero_objects', promote 'object_size' to 'u64' to avoid possible +integer overflow. + +Compile tested only. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Signed-off-by: Dmitry Kandybka <d.kandybka@gmail.com> +Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com> +Signed-off-by: Ilya Dryomov <idryomov@gmail.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/ceph/file.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ceph/file.c b/fs/ceph/file.c +index a03b11cf78872..e12657b4c3e04 100644 +--- a/fs/ceph/file.c ++++ b/fs/ceph/file.c +@@ -2513,7 +2513,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.6/cifs-correctly-set-smb1-sessionkey-field-in-session-.patch b/queue-6.6/cifs-correctly-set-smb1-sessionkey-field-in-session-.patch new file mode 100644 index 0000000000..c951f8de1f --- /dev/null +++ b/queue-6.6/cifs-correctly-set-smb1-sessionkey-field-in-session-.patch @@ -0,0 +1,106 @@ +From 80a9fff73d502e982e5095995cd460ba43a6737c Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sat, 2 Nov 2024 17:58:31 +0100 +Subject: cifs: Correctly set SMB1 SessionKey field in Session Setup Request +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár <pali@kernel.org> + +[ Upstream commit 89381c72d52094988e11d23ef24a00066a0fa458 ] + +[MS-CIFS] specification in section 2.2.4.53.1 where is described +SMB_COM_SESSION_SETUP_ANDX Request, for SessionKey field says: + + The client MUST set this field to be equal to the SessionKey field in + the SMB_COM_NEGOTIATE Response for this SMB connection. + +Linux SMB client currently set this field to zero. This is working fine +against Windows NT SMB servers thanks to [MS-CIFS] product behavior <94>: + + Windows NT Server ignores the client's SessionKey. + +For compatibility with [MS-CIFS], set this SessionKey field in Session +Setup Request to value retrieved from Negotiate response. + +Signed-off-by: Pali Rohár <pali@kernel.org> +Signed-off-by: Steve French <stfrench@microsoft.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/smb/client/cifsglob.h | 1 + + fs/smb/client/cifspdu.h | 6 +++--- + fs/smb/client/cifssmb.c | 1 + + fs/smb/client/sess.c | 1 + + 4 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h +index 6a4ed99e162c5..c7da6bf2f44be 100644 +--- a/fs/smb/client/cifsglob.h ++++ b/fs/smb/client/cifsglob.h +@@ -739,6 +739,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 ca33f6cd6a800..763178b774542 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 c36ab20050c16..db35e68e8a583 100644 +--- a/fs/smb/client/cifssmb.c ++++ b/fs/smb/client/cifssmb.c +@@ -479,6 +479,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 8959206a0353e..81ac4196bb743 100644 +--- a/fs/smb/client/sess.c ++++ b/fs/smb/client/sess.c +@@ -683,6 +683,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.6/cifs-fix-cifs_query_path_info-for-windows-nt-servers.patch b/queue-6.6/cifs-fix-cifs_query_path_info-for-windows-nt-servers.patch new file mode 100644 index 0000000000..c9907e7884 --- /dev/null +++ b/queue-6.6/cifs-fix-cifs_query_path_info-for-windows-nt-servers.patch @@ -0,0 +1,55 @@ +From 856c23a1d34bc3ad09ce213a74af524816ed9088 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 31 Dec 2024 16:06:22 +0100 +Subject: cifs: Fix cifs_query_path_info() for Windows NT servers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár <pali@kernel.org> + +[ Upstream commit a3e771afbb3bce91c8296828304903e7348003fe ] + +For TRANS2 QUERY_PATH_INFO request when the path does not exist, the +Windows NT SMB server returns error response STATUS_OBJECT_NAME_NOT_FOUND +or ERRDOS/ERRbadfile without the SMBFLG_RESPONSE flag set. Similarly it +returns STATUS_DELETE_PENDING when the file is being deleted. And looks +like that any error response from TRANS2 QUERY_PATH_INFO does not have +SMBFLG_RESPONSE flag set. + +So relax check in check_smb_hdr() for detecting if the packet is response +for this special case. + +This change fixes stat() operation against Windows NT SMB servers and also +all operations which depends on -ENOENT result from stat like creat() or +mkdir(). + +Signed-off-by: Pali Rohár <pali@kernel.org> +Signed-off-by: Steve French <stfrench@microsoft.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/smb/client/misc.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c +index 65d4b72b4d51a..9e8e0a01ae8eb 100644 +--- a/fs/smb/client/misc.c ++++ b/fs/smb/client/misc.c +@@ -320,6 +320,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.6/cifs-fix-encoding-of-smb1-session-setup-ntlmssp-requ.patch b/queue-6.6/cifs-fix-encoding-of-smb1-session-setup-ntlmssp-requ.patch new file mode 100644 index 0000000000..8a684f373b --- /dev/null +++ b/queue-6.6/cifs-fix-encoding-of-smb1-session-setup-ntlmssp-requ.patch @@ -0,0 +1,69 @@ +From f3c3113738f2c12ca7447b1c5426769357aa8371 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sun, 6 Oct 2024 19:24:29 +0200 +Subject: cifs: Fix encoding of SMB1 Session Setup NTLMSSP Request in + non-UNICODE mode +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár <pali@kernel.org> + +[ Upstream commit 6510ef4230b68c960309e0c1d6eb3e32eb785142 ] + +SMB1 Session Setup NTLMSSP Request in non-UNICODE mode is similar to +UNICODE mode, just strings are encoded in ASCII and not in UTF-16. + +With this change it is possible to setup SMB1 session with NTLM +authentication in non-UNICODE mode with Windows SMB server. + +This change fixes mounting SMB1 servers with -o nounicode mount option +together with -o sec=ntlmssp mount option (which is the default sec=). + +Signed-off-by: Pali Rohár <pali@kernel.org> +Signed-off-by: Steve French <stfrench@microsoft.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/smb/client/sess.c | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c +index 81ac4196bb743..c351da8c3e2ea 100644 +--- a/fs/smb/client/sess.c ++++ b/fs/smb/client/sess.c +@@ -1740,22 +1740,22 @@ _sess_auth_rawntlmssp_assemble_req(struct sess_data *sess_data) + pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base; + + capabilities = cifs_ssetup_hdr(ses, server, pSMB); +- if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) { +- cifs_dbg(VFS, "NTLMSSP requires Unicode support\n"); +- return -ENOSYS; +- } +- + pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; + capabilities |= CAP_EXTENDED_SECURITY; + pSMB->req.Capabilities |= cpu_to_le32(capabilities); + + bcc_ptr = sess_data->iov[2].iov_base; +- /* unicode strings must be word aligned */ +- if (!IS_ALIGNED(sess_data->iov[0].iov_len + sess_data->iov[1].iov_len, 2)) { +- *bcc_ptr = 0; +- bcc_ptr++; ++ ++ if (pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) { ++ /* unicode strings must be word aligned */ ++ if (!IS_ALIGNED(sess_data->iov[0].iov_len + sess_data->iov[1].iov_len, 2)) { ++ *bcc_ptr = 0; ++ bcc_ptr++; ++ } ++ unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp); ++ } else { ++ ascii_oslm_strings(&bcc_ptr, sess_data->nls_cp); + } +- unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp); + + sess_data->iov[2].iov_len = (long) bcc_ptr - + (long) sess_data->iov[2].iov_base; +-- +2.39.5 + diff --git a/queue-6.6/coresight-only-check-bottom-two-claim-bits.patch b/queue-6.6/coresight-only-check-bottom-two-claim-bits.patch new file mode 100644 index 0000000000..fc8c1fe406 --- /dev/null +++ b/queue-6.6/coresight-only-check-bottom-two-claim-bits.patch @@ -0,0 +1,55 @@ +From a637780b085b4362ab742c97c744ec88e582cdb3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 25 Mar 2025 11:58:47 +0000 +Subject: coresight: Only check bottom two claim bits + +From: James Clark <james.clark@linaro.org> + +[ Upstream commit a4e65842e1142aa18ef36113fbd81d614eaefe5a ] + +The use of the whole register and == could break the claim mechanism if +any of the other bits are used in the future. The referenced doc "PSCI - +ARM DEN 0022D" also says to only read and clear the bottom two bits. + +Use FIELD_GET() to extract only the relevant part. + +Reviewed-by: Leo Yan <leo.yan@arm.com> +Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com> +Signed-off-by: James Clark <james.clark@linaro.org> +Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> +Link: https://lore.kernel.org/r/20250325-james-coresight-claim-tags-v4-2-dfbd3822b2e5@linaro.org +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/hwtracing/coresight/coresight-core.c | 3 ++- + drivers/hwtracing/coresight/coresight-priv.h | 1 + + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c +index 783e259c37612..3b57851869eaa 100644 +--- a/drivers/hwtracing/coresight/coresight-core.c ++++ b/drivers/hwtracing/coresight/coresight-core.c +@@ -135,7 +135,8 @@ coresight_find_out_connection(struct coresight_device *src_dev, + + 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 30c051055e54b..b758a42ed8c73 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.6/cxl-region-add-a-dev_err-on-missing-target-list-entr.patch b/queue-6.6/cxl-region-add-a-dev_err-on-missing-target-list-entr.patch new file mode 100644 index 0000000000..9069fad144 --- /dev/null +++ b/queue-6.6/cxl-region-add-a-dev_err-on-missing-target-list-entr.patch @@ -0,0 +1,55 @@ +From fa02da0a1a976aa3e301a9f623a075a6560662c6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 9 May 2025 17:06:58 +0200 +Subject: cxl/region: Add a dev_err() on missing target list entries + +From: Robert Richter <rrichter@amd.com> + +[ Upstream commit d90acdf49e18029cfe4194475c45ef143657737a ] + +Broken target lists are hard to discover as the driver fails at a +later initialization stage. Add an error message for this. + +Example log messages: + + cxl_mem mem1: failed to find endpoint6:0000:e0:01.3 in target list of decoder1.1 + cxl_port endpoint6: failed to register decoder6.0: -6 + cxl_port endpoint6: probe: 0 + +Signed-off-by: Robert Richter <rrichter@amd.com> +Reviewed-by: Gregory Price <gourry@gourry.net> +Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> +Reviewed-by: Dave Jiang <dave.jiang@intel.com> +Reviewed-by: Dan Williams <dan.j.williams@intel.com> +Reviewed-by: Alison Schofield <alison.schofield@intel.com> +Reviewed-by: "Fabio M. De Francesco" <fabio.m.de.francesco@linux.intel.com> +Tested-by: Gregory Price <gourry@gourry.net> +Acked-by: Dan Williams <dan.j.williams@intel.com> +Link: https://patch.msgid.link/20250509150700.2817697-14-rrichter@amd.com +Signed-off-by: Dave Jiang <dave.jiang@intel.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/cxl/core/region.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c +index d7f7f88009d7d..1728cae1e8409 100644 +--- a/drivers/cxl/core/region.c ++++ b/drivers/cxl/core/region.c +@@ -1653,6 +1653,13 @@ static int find_pos_and_ways(struct cxl_port *port, struct range *range, + } + put_device(dev); + ++ if (rc) ++ dev_err(port->uport_dev, ++ "failed to find %s:%s in target list of %s\n", ++ dev_name(&port->dev), ++ dev_name(port->parent_dport->dport_dev), ++ dev_name(&cxlsd->cxld.dev)); ++ + return rc; + } + +-- +2.39.5 + diff --git a/queue-6.6/dmaengine-idxd-check-availability-of-workqueue-alloc.patch b/queue-6.6/dmaengine-idxd-check-availability-of-workqueue-alloc.patch new file mode 100644 index 0000000000..b28ed1a603 --- /dev/null +++ b/queue-6.6/dmaengine-idxd-check-availability-of-workqueue-alloc.patch @@ -0,0 +1,50 @@ +From a2a17519c122440d7f2bbb5d7869d3d0b87f3376 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 9 May 2025 08:03:04 +0800 +Subject: dmaengine: idxd: Check availability of workqueue allocated by idxd wq + driver before using + +From: Yi Sun <yi.sun@intel.com> + +[ Upstream commit 17502e7d7b7113346296f6758324798d536c31fd ] + +Running IDXD workloads in a container with the /dev directory mounted can +trigger a call trace or even a kernel panic when the parent process of the +container is terminated. + +This issue occurs because, under certain configurations, Docker does not +properly propagate the mount replica back to the original mount point. + +In this case, when the user driver detaches, the WQ is destroyed but it +still calls destroy_workqueue() attempting to completes all pending work. +It's necessary to check wq->wq and skip the drain if it no longer exists. + +Signed-off-by: Yi Sun <yi.sun@intel.com> +Reviewed-by: Dave Jiang <dave.jiang@intel.com> +Reviewed-by: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> + +Link: https://lore.kernel.org/r/20250509000304.1402863-1-yi.sun@intel.com +Signed-off-by: Vinod Koul <vkoul@kernel.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/dma/idxd/cdev.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/dma/idxd/cdev.c b/drivers/dma/idxd/cdev.c +index 7e3a67f9f0a65..aa39fcd389a94 100644 +--- a/drivers/dma/idxd/cdev.c ++++ b/drivers/dma/idxd/cdev.c +@@ -354,7 +354,9 @@ static void idxd_cdev_evl_drain_pasid(struct idxd_wq *wq, u32 pasid) + set_bit(h, evl->bmap); + h = (h + 1) % size; + } +- drain_workqueue(wq->wq); ++ if (wq->wq) ++ drain_workqueue(wq->wq); ++ + mutex_unlock(&evl->lock); + } + +-- +2.39.5 + diff --git a/queue-6.6/dmaengine-xilinx_dma-set-dma_device-directions.patch b/queue-6.6/dmaengine-xilinx_dma-set-dma_device-directions.patch new file mode 100644 index 0000000000..ba04055d5d --- /dev/null +++ b/queue-6.6/dmaengine-xilinx_dma-set-dma_device-directions.patch @@ -0,0 +1,40 @@ +From f286f5d986abb04344841cbf61cdb8299b982437 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Wed, 7 May 2025 20:21:01 +0200 +Subject: dmaengine: xilinx_dma: Set dma_device directions + +From: Thomas Gessler <thomas.gessler@brueckmann-gmbh.de> + +[ Upstream commit 7e01511443c30a55a5ae78d3debd46d4d872517e ] + +Coalesce the direction bits from the enabled TX and/or RX channels into +the directions bit mask of dma_device. Without this mask set, +dma_get_slave_caps() in the DMAEngine fails, which prevents the driver +from being used with an IIO DMAEngine buffer. + +Signed-off-by: Thomas Gessler <thomas.gessler@brueckmann-gmbh.de> +Reviewed-by: Suraj Gupta <suraj.gupta2@amd.com> +Tested-by: Folker Schwesinger <dev@folker-schwesinger.de> +Link: https://lore.kernel.org/r/20250507182101.909010-1-thomas.gessler@brueckmann-gmbh.de +Signed-off-by: Vinod Koul <vkoul@kernel.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/dma/xilinx/xilinx_dma.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c +index 0a3b2e22f23db..14c4c5031b556 100644 +--- a/drivers/dma/xilinx/xilinx_dma.c ++++ b/drivers/dma/xilinx/xilinx_dma.c +@@ -2900,6 +2900,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.6/drivers-hv-vmbus-add-utility-function-for-querying-r.patch b/queue-6.6/drivers-hv-vmbus-add-utility-function-for-querying-r.patch new file mode 100644 index 0000000000..ef03f261b6 --- /dev/null +++ b/queue-6.6/drivers-hv-vmbus-add-utility-function-for-querying-r.patch @@ -0,0 +1,94 @@ +From c1a77ba90ea5e92c9ed53e7c76c72511ca3db5ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sat, 30 Mar 2024 01:51:57 -0700 +Subject: Drivers: hv: vmbus: Add utility function for querying ring size + +From: Saurabh Sengar <ssengar@linux.microsoft.com> + +[ Upstream commit e8c4bd6c6e6b7e7b416c42806981c2a81370001e ] + +Add a function to query for the preferred ring buffer size of VMBus +device. This will allow the drivers (eg. UIO) to allocate the most +optimized ring buffer size for devices. + +Signed-off-by: Saurabh Sengar <ssengar@linux.microsoft.com> +Reviewed-by: Long Li <longli@microsoft.com> +Link: https://lore.kernel.org/r/1711788723-8593-2-git-send-email-ssengar@linux.microsoft.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Stable-dep-of: 0315fef2aff9 ("uio_hv_generic: Align ring size to system page") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/hv/channel_mgmt.c | 15 ++++++++++++--- + drivers/hv/hyperv_vmbus.h | 5 +++++ + include/linux/hyperv.h | 2 ++ + 3 files changed, 19 insertions(+), 3 deletions(-) + +diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c +index 2f4d09ce027a3..3c6011a48dabe 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 787b150686418..34b60009114a6 100644 +--- a/drivers/hv/hyperv_vmbus.h ++++ b/drivers/hv/hyperv_vmbus.h +@@ -419,6 +419,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 b5bf5315ca8c1..e4ad9760774e1 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.6/drm-scheduler-signal-scheduled-fence-when-kill-job.patch b/queue-6.6/drm-scheduler-signal-scheduled-fence-when-kill-job.patch new file mode 100644 index 0000000000..74e4d60a30 --- /dev/null +++ b/queue-6.6/drm-scheduler-signal-scheduled-fence-when-kill-job.patch @@ -0,0 +1,48 @@ +From 5f3d541bff7a4527a913b9b241924b9c2d8fa00c Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Thu, 15 May 2025 10:07:13 +0800 +Subject: drm/scheduler: signal scheduled fence when kill job +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Lin.Cao <lincao12@amd.com> + +[ Upstream commit 471db2c2d4f80ee94225a1ef246e4f5011733e50 ] + +When an entity from application B is killed, drm_sched_entity_kill() +removes all jobs belonging to that entity through +drm_sched_entity_kill_jobs_work(). If application A's job depends on a +scheduled fence from application B's job, and that fence is not properly +signaled during the killing process, application A's dependency cannot be +cleared. + +This leads to application A hanging indefinitely while waiting for a +dependency that will never be resolved. Fix this issue by ensuring that +scheduled fences are properly signaled when an entity is killed, allowing +dependent applications to continue execution. + +Signed-off-by: Lin.Cao <lincao12@amd.com> +Reviewed-by: Philipp Stanner <phasta@kernel.org> +Signed-off-by: Christian König <christian.koenig@amd.com> +Link: https://lore.kernel.org/r/20250515020713.1110476-1-lincao12@amd.com +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/gpu/drm/scheduler/sched_entity.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c +index 53130a50584ca..eed3b8bed9e40 100644 +--- a/drivers/gpu/drm/scheduler/sched_entity.c ++++ b/drivers/gpu/drm/scheduler/sched_entity.c +@@ -167,6 +167,7 @@ static void drm_sched_entity_kill_jobs_work(struct work_struct *wrk) + { + struct drm_sched_job *job = container_of(wrk, typeof(*job), work); + ++ drm_sched_fence_scheduled(job->s_fence, NULL); + drm_sched_fence_finished(job->s_fence, -ESRCH); + WARN_ON(job->s_fence->parent); + job->sched->ops->free_job(job); +-- +2.39.5 + diff --git a/queue-6.6/dummycon-trigger-redraw-when-switching-consoles-with.patch b/queue-6.6/dummycon-trigger-redraw-when-switching-consoles-with.patch new file mode 100644 index 0000000000..e69f079337 --- /dev/null +++ b/queue-6.6/dummycon-trigger-redraw-when-switching-consoles-with.patch @@ -0,0 +1,96 @@ +From 84154bf81a79be1af1789dbe8f5da7daea52843a Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 20 May 2025 09:14:00 +0200 +Subject: dummycon: Trigger redraw when switching consoles with deferred + takeover + +From: Thomas Zimmermann <tzimmermann@suse.de> + +[ Upstream commit 03bcbbb3995ba5df43af9aba45334e35f2dfe27b ] + +Signal vt subsystem to redraw console when switching to dummycon +with deferred takeover enabled. Makes the console switch to fbcon +and displays the available output. + +With deferred takeover enabled, dummycon acts as the placeholder +until the first output to the console happens. At that point, fbcon +takes over. If the output happens while dummycon is not active, it +cannot inform fbcon. This is the case if the vt subsystem runs in +graphics mode. + +A typical graphical boot starts plymouth, a display manager and a +compositor; all while leaving out dummycon. Switching to a text-mode +console leaves the console with dummycon even if a getty terminal +has been started. + +Returning true from dummycon's con_switch helper signals the vt +subsystem to redraw the screen. If there's output available dummycon's +con_putc{s} helpers trigger deferred takeover of fbcon, which sets a +display mode and displays the output. If no output is available, +dummycon remains active. + +v2: +- make the comment slightly more verbose (Javier) + +Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> +Reported-by: Andrei Borzenkov <arvidjaar@gmail.com> +Closes: https://bugzilla.suse.com/show_bug.cgi?id=1242191 +Tested-by: Andrei Borzenkov <arvidjaar@gmail.com> +Acked-by: Javier Martinez Canillas <javierm@redhat.com> +Fixes: 83d83bebf401 ("console/fbcon: Add support for deferred console takeover") +Cc: Hans de Goede <hdegoede@redhat.com> +Cc: linux-fbdev@vger.kernel.org +Cc: dri-devel@lists.freedesktop.org +Cc: <stable@vger.kernel.org> # v4.19+ +Link: https://lore.kernel.org/r/20250520071418.8462-1-tzimmermann@suse.de +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/video/console/dummycon.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c +index d701f2b51f5b1..d99e1b3e4e5c1 100644 +--- a/drivers/video/console/dummycon.c ++++ b/drivers/video/console/dummycon.c +@@ -82,6 +82,15 @@ static int dummycon_blank(struct vc_data *vc, int blank, int mode_switch) + /* Redraw, so that we get putc(s) for output done while blanked */ + return 1; + } ++ ++static bool dummycon_switch(struct vc_data *vc) ++{ ++ /* ++ * Redraw, so that we get putc(s) for output done while switched ++ * away. Informs deferred consoles to take over the display. ++ */ ++ return true; ++} + #else + static void dummycon_putc(struct vc_data *vc, int c, int ypos, int xpos) { } + static void dummycon_putcs(struct vc_data *vc, const unsigned short *s, +@@ -90,6 +99,10 @@ static int dummycon_blank(struct vc_data *vc, int blank, int mode_switch) + { + return 0; + } ++static bool dummycon_switch(struct vc_data *vc) ++{ ++ return false; ++} + #endif + + static const char *dummycon_startup(void) +@@ -119,11 +132,6 @@ static bool dummycon_scroll(struct vc_data *vc, unsigned int top, + return false; + } + +-static bool dummycon_switch(struct vc_data *vc) +-{ +- return false; +-} +- + /* + * The console `switch' structure for the dummy console + * +-- +2.39.5 + diff --git a/queue-6.6/f2fs-don-t-over-report-free-space-or-inodes-in-statv.patch b/queue-6.6/f2fs-don-t-over-report-free-space-or-inodes-in-statv.patch new file mode 100644 index 0000000000..c3755d3bb9 --- /dev/null +++ b/queue-6.6/f2fs-don-t-over-report-free-space-or-inodes-in-statv.patch @@ -0,0 +1,99 @@ +From 306a1788abdf44cd89e856bf8a41c1549f3ef9f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 13 May 2025 19:25:38 +0800 +Subject: f2fs: don't over-report free space or inodes in statvfs + +From: Chao Yu <chao@kernel.org> + +[ Upstream commit a9201960623287927bf5776de3f70fb2fbde7e02 ] + +This fixes an analogus bug that was fixed in modern filesystems: +a) xfs in commit 4b8d867ca6e2 ("xfs: don't over-report free space or +inodes in statvfs") +b) ext4 in commit f87d3af74193 ("ext4: don't over-report free space +or inodes in statvfs") +where statfs can report misleading / incorrect information where +project quota is enabled, and the free space is less than the +remaining quota. + +This commit will resolve a test failure in generic/762 which tests +for this bug. + +generic/762 - output mismatch (see /share/git/fstests/results//generic/762.out.bad) + --- tests/generic/762.out 2025-04-15 10:21:53.371067071 +0800 + +++ /share/git/fstests/results//generic/762.out.bad 2025-05-13 16:13:37.000000000 +0800 + @@ -6,8 +6,10 @@ + root blocks2 is in range + dir blocks2 is in range + root bavail2 is in range + -dir bavail2 is in range + +dir bavail2 has value of 1539066 + +dir bavail2 is NOT in range 304734.87 .. 310891.13 + root blocks3 is in range + ... + (Run 'diff -u /share/git/fstests/tests/generic/762.out /share/git/fstests/results//generic/762.out.bad' to see the entire diff) + +HINT: You _MAY_ be missing kernel fix: + XXXXXXXXXXXXXX xfs: don't over-report free space or inodes in statvfs + +Cc: stable@kernel.org +Fixes: ddc34e328d06 ("f2fs: introduce f2fs_statfs_project") +Signed-off-by: Chao Yu <chao@kernel.org> +Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/f2fs/super.c | 30 ++++++++++++++++++------------ + 1 file changed, 18 insertions(+), 12 deletions(-) + +diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c +index 702137eafaa67..b9913ab526fd1 100644 +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -1774,26 +1774,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.6/fs-jfs-consolidate-sanity-checking-in-dbmount.patch b/queue-6.6/fs-jfs-consolidate-sanity-checking-in-dbmount.patch new file mode 100644 index 0000000000..cccd117e6b --- /dev/null +++ b/queue-6.6/fs-jfs-consolidate-sanity-checking-in-dbmount.patch @@ -0,0 +1,81 @@ +From f1aea9fb6ee29aee2c7dd63475c5dbac82f4c46e Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Thu, 20 Feb 2025 10:31:19 -0600 +Subject: fs/jfs: consolidate sanity checking in dbMount + +From: Dave Kleikamp <dave.kleikamp@oracle.com> + +[ Upstream commit 0d250b1c52484d489e31df2cf9118b7c4bd49d31 ] + +Sanity checks have been added to dbMount as individual if clauses with +identical error handling. Move these all into one clause. + +Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com> +Stable-dep-of: 37bfb464ddca ("jfs: validate AG parameters in dbMount() to prevent crashes") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/jfs/jfs_dmap.c | 37 +++++++++---------------------------- + 1 file changed, 9 insertions(+), 28 deletions(-) + +diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c +index 0e1019382cf51..26e89d0c69b61 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.6/fuse-fix-race-between-concurrent-setattrs-from-multi.patch b/queue-6.6/fuse-fix-race-between-concurrent-setattrs-from-multi.patch new file mode 100644 index 0000000000..29669dfab8 --- /dev/null +++ b/queue-6.6/fuse-fix-race-between-concurrent-setattrs-from-multi.patch @@ -0,0 +1,89 @@ +From 2b95543fac0388a8de65c492ff9666d4b5a85cff Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 2 May 2025 04:04:21 +0000 +Subject: fuse: fix race between concurrent setattrs from multiple nodes + +From: Guang Yuan Wu <gwu@ddn.com> + +[ Upstream commit 69efbff69f89c9b2b72c4d82ad8b59706add768a ] + +When mounting a user-space filesystem on multiple clients, after +concurrent ->setattr() calls from different node, stale inode +attributes may be cached in some node. + +This is caused by fuse_setattr() racing with +fuse_reverse_inval_inode(). + +When filesystem server receives setattr request, the client node +with valid iattr cached will be required to update the fuse_inode's +attr_version and invalidate the cache by fuse_reverse_inval_inode(), +and at the next call to ->getattr() they will be fetched from user +space. + +The race scenario is: +1. client-1 sends setattr (iattr-1) request to server +2. client-1 receives the reply from server +3. before client-1 updates iattr-1 to the cached attributes by + fuse_change_attributes_common(), server receives another setattr + (iattr-2) request from client-2 +4. server requests client-1 to update the inode attr_version and + invalidate the cached iattr, and iattr-1 becomes staled +5. client-2 receives the reply from server, and caches iattr-2 +6. continue with step 2, client-1 invokes + fuse_change_attributes_common(), and caches iattr-1 + +The issue has been observed from concurrent of chmod, chown, or +truncate, which all invoke ->setattr() call. + +The solution is to use fuse_inode's attr_version to check whether +the attributes have been modified during the setattr request's +lifetime. If so, mark the attributes as invalid in the function +fuse_change_attributes_common(). + +Signed-off-by: Guang Yuan Wu <gwu@ddn.com> +Reviewed-by: Bernd Schubert <bschubert@ddn.com> +Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/fuse/dir.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c +index 82951a535d2d4..0b84284ece98f 100644 +--- a/fs/fuse/dir.c ++++ b/fs/fuse/dir.c +@@ -1860,6 +1860,7 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr, + int err; + bool trust_local_cmtime = is_wb; + bool fault_blocked = false; ++ u64 attr_version; + + if (!fc->default_permissions) + attr->ia_valid |= ATTR_FORCE; +@@ -1944,6 +1945,8 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr, + if (fc->handle_killpriv_v2 && !capable(CAP_FSETID)) + inarg.valid |= FATTR_KILL_SUIDGID; + } ++ ++ attr_version = fuse_get_attr_version(fm->fc); + fuse_setattr_fill(fc, &args, inode, &inarg, &outarg); + err = fuse_simple_request(fm, &args); + if (err) { +@@ -1969,6 +1972,14 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr, + /* FIXME: clear I_DIRTY_SYNC? */ + } + ++ if (fi->attr_version > attr_version) { ++ /* ++ * Apply attributes, for example for fsnotify_change(), but set ++ * attribute timeout to zero. ++ */ ++ outarg.attr_valid = outarg.attr_valid_nsec = 0; ++ } ++ + fuse_change_attributes_common(inode, &outarg.attr, NULL, + ATTR_TIMEOUT(&outarg), + fuse_get_cache_mask(inode)); +-- +2.39.5 + diff --git a/queue-6.6/hwmon-pmbus-max34440-fix-support-for-max34451.patch b/queue-6.6/hwmon-pmbus-max34440-fix-support-for-max34451.patch new file mode 100644 index 0000000000..a09f07891c --- /dev/null +++ b/queue-6.6/hwmon-pmbus-max34440-fix-support-for-max34451.patch @@ -0,0 +1,144 @@ +From ac96f77033111b0165862a3bd0fa2b45692fd6d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 7 Apr 2025 11:47:24 +0800 +Subject: hwmon: (pmbus/max34440) Fix support for max34451 + +From: Alexis Czezar Torreno <alexisczezar.torreno@analog.com> + +[ Upstream commit 19932f844f3f51646f762f3eac4744ec3a405064 ] + +The max344** family has an issue with some PMBUS address being switched. +This includes max34451 however version MAX34451-NA6 and later has this +issue fixed and this commit supports that update. + +Signed-off-by: Alexis Czezar Torreno <alexisczezar.torreno@analog.com> +Link: https://lore.kernel.org/r/20250407-dev_adpm12160-v3-1-9cd3095445c8@analog.com +Signed-off-by: Guenter Roeck <linux@roeck-us.net> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/hwmon/pmbus/max34440.c | 48 +++++++++++++++++++++++++++++++--- + 1 file changed, 44 insertions(+), 4 deletions(-) + +diff --git a/drivers/hwmon/pmbus/max34440.c b/drivers/hwmon/pmbus/max34440.c +index fe7f6b1b09851..e14be8ebaad30 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.6/iio-adc-ad_sigma_delta-fix-use-of-uninitialized-stat.patch b/queue-6.6/iio-adc-ad_sigma_delta-fix-use-of-uninitialized-stat.patch new file mode 100644 index 0000000000..995c764f46 --- /dev/null +++ b/queue-6.6/iio-adc-ad_sigma_delta-fix-use-of-uninitialized-stat.patch @@ -0,0 +1,47 @@ +From 88c18910054c570b376d7619e08f4bda5a3fe58c Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Thu, 10 Apr 2025 22:34:08 +0530 +Subject: iio: adc: ad_sigma_delta: Fix use of uninitialized status_pos + +From: Purva Yeshi <purvayeshi550@gmail.com> + +[ Upstream commit e5cdb098a3cb165d52282ffc3a6448642953ea13 ] + +Fix Smatch-detected issue: +drivers/iio/adc/ad_sigma_delta.c:604 ad_sd_trigger_handler() error: +uninitialized symbol 'status_pos'. + +The variable `status_pos` was only initialized in specific switch cases +(1, 2, 3, 4), which could leave it uninitialized if `reg_size` had an +unexpected value. + +Fix by adding a default case to the switch block to catch unexpected +values of `reg_size`. Use `dev_err_ratelimited()` for error logging and +`goto irq_handled` instead of returning early. + +Signed-off-by: Purva Yeshi <purvayeshi550@gmail.com> +Link: https://patch.msgid.link/20250410170408.8585-1-purvayeshi550@gmail.com +Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/iio/adc/ad_sigma_delta.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c +index 7e21928707437..533667eefe419 100644 +--- a/drivers/iio/adc/ad_sigma_delta.c ++++ b/drivers/iio/adc/ad_sigma_delta.c +@@ -476,6 +476,10 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p) + * byte set to zero. */ + ad_sd_read_reg_raw(sigma_delta, data_reg, transfer_size, &data[1]); + break; ++ ++ default: ++ dev_err_ratelimited(&indio_dev->dev, "Unsupported reg_size: %u\n", reg_size); ++ goto irq_handled; + } + + /* +-- +2.39.5 + diff --git a/queue-6.6/iio-pressure-zpa2326-use-aligned_s64-for-the-timesta.patch b/queue-6.6/iio-pressure-zpa2326-use-aligned_s64-for-the-timesta.patch new file mode 100644 index 0000000000..1fdd8dbe8b --- /dev/null +++ b/queue-6.6/iio-pressure-zpa2326-use-aligned_s64-for-the-timesta.patch @@ -0,0 +1,36 @@ +From 05f2c4f5950f0a943267695cc0d93f837a414912 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sun, 13 Apr 2025 11:34:41 +0100 +Subject: iio: pressure: zpa2326: Use aligned_s64 for the timestamp + +From: Jonathan Cameron <Jonathan.Cameron@huawei.com> + +[ Upstream commit 886a446b76afddfad307488e95e87f23a08ffd51 ] + +On x86_32 s64 fields are only 32-bit aligned. Hence force the alignment of +the field and padding in the structure by using aligned_s64 instead. + +Reviewed-by: David Lechner <dlechner@baylibre.com> +Link: https://patch.msgid.link/20250413103443.2420727-19-jic23@kernel.org +Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/iio/pressure/zpa2326.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c +index ef1d0349f4247..a1c694199c989 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.6/jfs-validate-ag-parameters-in-dbmount-to-prevent-cra.patch b/queue-6.6/jfs-validate-ag-parameters-in-dbmount-to-prevent-cra.patch new file mode 100644 index 0000000000..d2783945e6 --- /dev/null +++ b/queue-6.6/jfs-validate-ag-parameters-in-dbmount-to-prevent-cra.patch @@ -0,0 +1,78 @@ +From 40c2804c43a589363604dc72e1138a8ea5ef4de4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 10 Mar 2025 11:56:02 +0300 +Subject: jfs: validate AG parameters in dbMount() to prevent crashes + +From: Vasiliy Kovalev <kovalev@altlinux.org> + +[ Upstream commit 37bfb464ddca87f203071b5bd562cd91ddc0b40a ] + +Validate db_agheight, db_agwidth, and db_agstart in dbMount to catch +corrupted metadata early and avoid undefined behavior in dbAllocAG. +Limits are derived from L2LPERCTL, LPERCTL/MAXAG, and CTLTREESIZE: + +- agheight: 0 to L2LPERCTL/2 (0 to 5) ensures shift + (L2LPERCTL - 2*agheight) >= 0. +- agwidth: 1 to min(LPERCTL/MAXAG, 2^(L2LPERCTL - 2*agheight)) + ensures agperlev >= 1. + - Ranges: 1-8 (agheight 0-3), 1-4 (agheight 4), 1 (agheight 5). + - LPERCTL/MAXAG = 1024/128 = 8 limits leaves per AG; + 2^(10 - 2*agheight) prevents division to 0. +- agstart: 0 to CTLTREESIZE-1 - agwidth*(MAXAG-1) keeps ti within + stree (size 1365). + - Ranges: 0-1237 (agwidth 1), 0-348 (agwidth 8). + +UBSAN: shift-out-of-bounds in fs/jfs/jfs_dmap.c:1400:9 +shift exponent -335544310 is negative +CPU: 0 UID: 0 PID: 5822 Comm: syz-executor130 Not tainted 6.14.0-rc5-syzkaller #0 +Hardware name: Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2025 +Call Trace: + <TASK> + __dump_stack lib/dump_stack.c:94 [inline] + dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120 + ubsan_epilogue lib/ubsan.c:231 [inline] + __ubsan_handle_shift_out_of_bounds+0x3c8/0x420 lib/ubsan.c:468 + dbAllocAG+0x1087/0x10b0 fs/jfs/jfs_dmap.c:1400 + dbDiscardAG+0x352/0xa20 fs/jfs/jfs_dmap.c:1613 + jfs_ioc_trim+0x45a/0x6b0 fs/jfs/jfs_discard.c:105 + jfs_ioctl+0x2cd/0x3e0 fs/jfs/ioctl.c:131 + vfs_ioctl fs/ioctl.c:51 [inline] + __do_sys_ioctl fs/ioctl.c:906 [inline] + __se_sys_ioctl+0xf5/0x170 fs/ioctl.c:892 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +Found by Linux Verification Center (linuxtesting.org) with Syzkaller. + +Cc: stable@vger.kernel.org +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: syzbot+fe8264911355151c487f@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=fe8264911355151c487f +Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org> +Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/jfs/jfs_dmap.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c +index 26e89d0c69b61..35e063c9f3a42 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.6/ksmbd-allow-a-filename-to-contain-special-characters.patch b/queue-6.6/ksmbd-allow-a-filename-to-contain-special-characters.patch new file mode 100644 index 0000000000..b5de70d9d1 --- /dev/null +++ b/queue-6.6/ksmbd-allow-a-filename-to-contain-special-characters.patch @@ -0,0 +1,109 @@ +From 0b46fc4d332364f68027bcc13b742ec43dcecc88 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 27 May 2025 11:23:01 +0900 +Subject: ksmbd: allow a filename to contain special characters on SMB3.1.1 + posix extension + +From: Namjae Jeon <linkinjeon@kernel.org> + +[ Upstream commit dc3e0f17f74558e8a2fce00608855f050de10230 ] + +If client send SMB2_CREATE_POSIX_CONTEXT to ksmbd, Allow a filename +to contain special characters. + +Reported-by: Philipp Kerling <pkerling@casix.org> +Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> +Signed-off-by: Steve French <stfrench@microsoft.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/smb/server/smb2pdu.c | 53 +++++++++++++++++++++-------------------- + 1 file changed, 27 insertions(+), 26 deletions(-) + +diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c +index d8325504a1624..b851cd7d19b48 100644 +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -2862,7 +2862,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; +@@ -2889,6 +2889,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) { + name = smb2_get_name((char *)req + le16_to_cpu(req->NameOffset), + le16_to_cpu(req->NameLength), +@@ -2911,9 +2932,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; +@@ -3071,28 +3094,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.6/ksmbd-provide-zero-as-a-unique-id-to-the-mac-client.patch b/queue-6.6/ksmbd-provide-zero-as-a-unique-id-to-the-mac-client.patch new file mode 100644 index 0000000000..a8e39891b2 --- /dev/null +++ b/queue-6.6/ksmbd-provide-zero-as-a-unique-id-to-the-mac-client.patch @@ -0,0 +1,102 @@ +From 252769ac2050b739391782560b4cfa9f003cb35b Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Wed, 21 May 2025 09:02:29 +0900 +Subject: ksmbd: provide zero as a unique ID to the Mac client + +From: Namjae Jeon <linkinjeon@kernel.org> + +[ Upstream commit 571781eb7ffefa65b0e922c8031e42b4411a40d4 ] + +The Mac SMB client code seems to expect the on-disk file identifier +to have the semantics of HFS+ Catalog Node Identifier (CNID). +ksmbd provides the inode number as a unique ID to the client, +but in the case of subvolumes of btrfs, there are cases where different +files have the same inode number, so the mac smb client treats it +as an error. There is a report that a similar problem occurs +when the share is ZFS. +Returning UniqueId of zero will make the Mac client to stop using and +trusting the file id returned from the server. + +Reported-by: Justin Turner Arthur <justinarthur@gmail.com> +Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> +Signed-off-by: Steve French <stfrench@microsoft.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/smb/server/connection.h | 1 + + fs/smb/server/smb2pdu.c | 19 +++++++++++++++++-- + fs/smb/server/smb2pdu.h | 3 +++ + 3 files changed, 21 insertions(+), 2 deletions(-) + +diff --git a/fs/smb/server/connection.h b/fs/smb/server/connection.h +index 4fdd76ce53b90..dc07c6eb8c192 100644 +--- a/fs/smb/server/connection.h ++++ b/fs/smb/server/connection.h +@@ -107,6 +107,7 @@ struct ksmbd_conn { + __le16 signing_algorithm; + bool binding; + atomic_t refcnt; ++ bool is_aapl; + }; + + struct ksmbd_conn_ops { +diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c +index b851cd7d19b48..185f7e0744f8a 100644 +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -3527,6 +3527,15 @@ int smb2_open(struct ksmbd_work *work) + ksmbd_debug(SMB, "get query on disk id context\n"); + query_disk_id = 1; + } ++ ++ if (conn->is_aapl == false) { ++ context = smb2_find_context_vals(req, SMB2_CREATE_AAPL, 4); ++ if (IS_ERR(context)) { ++ rc = PTR_ERR(context); ++ goto err_out1; ++ } else if (context) ++ conn->is_aapl = true; ++ } + } + + rc = ksmbd_vfs_getattr(&path, &stat); +@@ -3965,7 +3974,10 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level, + if (dinfo->EaSize) + dinfo->ExtFileAttributes = FILE_ATTRIBUTE_REPARSE_POINT_LE; + dinfo->Reserved = 0; +- dinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino); ++ if (conn->is_aapl) ++ dinfo->UniqueId = 0; ++ else ++ dinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino); + if (d_info->hide_dot_file && d_info->name[0] == '.') + dinfo->ExtFileAttributes |= FILE_ATTRIBUTE_HIDDEN_LE; + memcpy(dinfo->FileName, conv_name, conv_len); +@@ -3982,7 +3994,10 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level, + smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode); + if (fibdinfo->EaSize) + fibdinfo->ExtFileAttributes = FILE_ATTRIBUTE_REPARSE_POINT_LE; +- fibdinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino); ++ if (conn->is_aapl) ++ fibdinfo->UniqueId = 0; ++ else ++ fibdinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino); + fibdinfo->ShortNameLength = 0; + fibdinfo->Reserved = 0; + fibdinfo->Reserved2 = cpu_to_le16(0); +diff --git a/fs/smb/server/smb2pdu.h b/fs/smb/server/smb2pdu.h +index 25cc81aac350f..2821e6c8298f4 100644 +--- a/fs/smb/server/smb2pdu.h ++++ b/fs/smb/server/smb2pdu.h +@@ -63,6 +63,9 @@ struct preauth_integrity_info { + + #define SMB2_SESSION_TIMEOUT (10 * HZ) + ++/* Apple Defined Contexts */ ++#define SMB2_CREATE_AAPL "AAPL" ++ + struct create_durable_req_v2 { + struct create_context_hdr ccontext; + __u8 Name[8]; +-- +2.39.5 + diff --git a/queue-6.6/leds-multicolor-fix-intensity-setting-while-sw-blink.patch b/queue-6.6/leds-multicolor-fix-intensity-setting-while-sw-blink.patch new file mode 100644 index 0000000000..827d3be483 --- /dev/null +++ b/queue-6.6/leds-multicolor-fix-intensity-setting-while-sw-blink.patch @@ -0,0 +1,48 @@ +From 45db65d7a4a93b08e3348a0c5e40cb444f12f28e Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 4 Apr 2025 20:40:36 +0200 +Subject: leds: multicolor: Fix intensity setting while SW blinking + +From: Sven Schwermer <sven.schwermer@disruptive-technologies.com> + +[ Upstream commit e35ca991a777ef513040cbb36bc8245a031a2633 ] + +When writing to the multi_intensity file, don't unconditionally call +led_set_brightness. By only doing this if blinking is inactive we +prevent blinking from stopping if the blinking is in its off phase while +the file is written. + +Instead, if blinking is active, the changed intensity values are applied +upon the next blink. This is consistent with changing the brightness on +monochrome LEDs with active blinking. + +Suggested-by: Jacek Anaszewski <jacek.anaszewski@gmail.com> +Acked-by: Jacek Anaszewski <jacek.anaszewski@gmail.com> +Acked-by: Pavel Machek <pavel@ucw.cz> +Reviewed-by: Tobias Deiminger <tobias.deiminger@linutronix.de> +Tested-by: Sven Schuchmann <schuchmann@schleissheimer.de> +Signed-off-by: Sven Schwermer <sven.schwermer@disruptive-technologies.com> +Link: https://lore.kernel.org/r/20250404184043.227116-1-sven@svenschwermer.de +Signed-off-by: Lee Jones <lee@kernel.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/leds/led-class-multicolor.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/leds/led-class-multicolor.c b/drivers/leds/led-class-multicolor.c +index ec62a48116135..e0785935f4ba6 100644 +--- a/drivers/leds/led-class-multicolor.c ++++ b/drivers/leds/led-class-multicolor.c +@@ -61,7 +61,8 @@ static ssize_t multi_intensity_store(struct device *dev, + for (i = 0; i < mcled_cdev->num_colors; i++) + mcled_cdev->subled_info[i].intensity = intensity_value[i]; + +- led_set_brightness(led_cdev, led_cdev->brightness); ++ if (!test_bit(LED_BLINK_SW, &led_cdev->work_flags)) ++ led_set_brightness(led_cdev, led_cdev->brightness); + ret = size; + err_out: + mutex_unlock(&led_cdev->led_access); +-- +2.39.5 + diff --git a/queue-6.6/mailbox-not-protect-module_put-with-spin_lock_irqsav.patch b/queue-6.6/mailbox-not-protect-module_put-with-spin_lock_irqsav.patch new file mode 100644 index 0000000000..e29f20473b --- /dev/null +++ b/queue-6.6/mailbox-not-protect-module_put-with-spin_lock_irqsav.patch @@ -0,0 +1,38 @@ +From 566afc48dbf22467f0089abd2aa36dbdb4fdc110 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 11 Apr 2025 21:14:10 +0800 +Subject: mailbox: Not protect module_put with spin_lock_irqsave + +From: Peng Fan <peng.fan@nxp.com> + +[ Upstream commit dddbd233e67e792bb0a3f9694a4707e6be29b2c6 ] + +&chan->lock is not supposed to protect 'chan->mbox'. +And in __mbox_bind_client, try_module_get is also not protected +by &chan->lock. So move module_put out of the lock protected +region. + +Signed-off-by: Peng Fan <peng.fan@nxp.com> +Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/mailbox/mailbox.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c +index f13d705f7861a..cb59b4dbad626 100644 +--- a/drivers/mailbox/mailbox.c ++++ b/drivers/mailbox/mailbox.c +@@ -500,8 +500,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.6/md-md-bitmap-fix-dm-raid-max_write_behind-setting.patch b/queue-6.6/md-md-bitmap-fix-dm-raid-max_write_behind-setting.patch new file mode 100644 index 0000000000..5cba876d80 --- /dev/null +++ b/queue-6.6/md-md-bitmap-fix-dm-raid-max_write_behind-setting.patch @@ -0,0 +1,36 @@ +From 19d5debdf740917ed4061633323aa2b8700a1f23 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sat, 24 May 2025 14:13:10 +0800 +Subject: md/md-bitmap: fix dm-raid max_write_behind setting + +From: Yu Kuai <yukuai3@huawei.com> + +[ Upstream commit 2afe17794cfed5f80295b1b9facd66e6f65e5002 ] + +It's supposed to be COUNTER_MAX / 2, not COUNTER_MAX. + +Link: https://lore.kernel.org/linux-raid/20250524061320.370630-14-yukuai1@huaweicloud.com +Signed-off-by: Yu Kuai <yukuai3@huawei.com> +Reviewed-by: Christoph Hellwig <hch@lst.de> +Reviewed-by: Hannes Reinecke <hare@suse.de> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/md/md-bitmap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c +index 8317e07b326d0..21decb97bc050 100644 +--- a/drivers/md/md-bitmap.c ++++ b/drivers/md/md-bitmap.c +@@ -589,7 +589,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.6/mfd-max14577-fix-wakeup-source-leaks-on-device-unbin.patch b/queue-6.6/mfd-max14577-fix-wakeup-source-leaks-on-device-unbin.patch new file mode 100644 index 0000000000..dae874e58e --- /dev/null +++ b/queue-6.6/mfd-max14577-fix-wakeup-source-leaks-on-device-unbin.patch @@ -0,0 +1,35 @@ +From a69985eddfb426ed2e8d8ac8c030d132f0073890 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sun, 6 Apr 2025 21:50:11 +0200 +Subject: mfd: max14577: Fix wakeup source leaks on device unbind + +From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> + +[ Upstream commit d905d06e64b0eb3da43af6186c132f5282197998 ] + +Device can be unbound, so driver must also release memory for the wakeup +source. + +Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> +Link: https://lore.kernel.org/r/20250406-mfd-device-wakekup-leak-v1-3-318e14bdba0a@linaro.org +Signed-off-by: Lee Jones <lee@kernel.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/mfd/max14577.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c +index 1f4f5002595c0..17672eeb1732a 100644 +--- a/drivers/mfd/max14577.c ++++ b/drivers/mfd/max14577.c +@@ -463,6 +463,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.6/misc-tps6594-pfsm-add-null-pointer-check-in-tps6594_.patch b/queue-6.6/misc-tps6594-pfsm-add-null-pointer-check-in-tps6594_.patch new file mode 100644 index 0000000000..1d42f50d17 --- /dev/null +++ b/queue-6.6/misc-tps6594-pfsm-add-null-pointer-check-in-tps6594_.patch @@ -0,0 +1,42 @@ +From 60a4f66f4c0c4e8fb216697787ea06fcbde74bb9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 10 Mar 2025 20:05:11 -0500 +Subject: misc: tps6594-pfsm: Add NULL pointer check in tps6594_pfsm_probe() + +From: Chenyuan Yang <chenyuan0y@gmail.com> + +[ Upstream commit a99b598d836c9c6411110c70a2da134c78d96e67 ] + +The returned value, pfsm->miscdev.name, from devm_kasprintf() +could be NULL. +A pointer check is added to prevent potential NULL pointer dereference. +This is similar to the fix in commit 3027e7b15b02 +("ice: Fix some null pointer dereference issues in ice_ptp.c"). + +This issue is found by our static analysis tool. + +Signed-off-by: Chenyuan Yang <chenyuan0y@gmail.com> +Link: https://lore.kernel.org/r/20250311010511.1028269-1-chenyuan0y@gmail.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/misc/tps6594-pfsm.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/misc/tps6594-pfsm.c b/drivers/misc/tps6594-pfsm.c +index 88dcac8148922..71fbe31542e56 100644 +--- a/drivers/misc/tps6594-pfsm.c ++++ b/drivers/misc/tps6594-pfsm.c +@@ -260,6 +260,9 @@ static int tps6594_pfsm_probe(struct platform_device *pdev) + pfsm->miscdev.minor = MISC_DYNAMIC_MINOR; + pfsm->miscdev.name = devm_kasprintf(dev, GFP_KERNEL, "pfsm-%ld-0x%02x", + tps->chip_id, tps->reg); ++ if (!pfsm->miscdev.name) ++ return -ENOMEM; ++ + pfsm->miscdev.fops = &tps6594_pfsm_fops; + pfsm->miscdev.parent = dev->parent; + +-- +2.39.5 + diff --git a/queue-6.6/nfsv4-always-set-nlink-even-if-the-server-doesn-t-su.patch b/queue-6.6/nfsv4-always-set-nlink-even-if-the-server-doesn-t-su.patch new file mode 100644 index 0000000000..c5edadd4b6 --- /dev/null +++ b/queue-6.6/nfsv4-always-set-nlink-even-if-the-server-doesn-t-su.patch @@ -0,0 +1,41 @@ +From 976cece443a24d179107289e6d7b5b4ce03c495d Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sun, 4 May 2025 20:57:04 +0800 +Subject: NFSv4: Always set NLINK even if the server doesn't support it + +From: Han Young <hanyang.tony@bytedance.com> + +[ Upstream commit 3a3065352f73381d3a1aa0ccab44aec3a5a9b365 ] + +fattr4_numlinks is a recommended attribute, so the client should emulate +it even if the server doesn't support it. In decode_attr_nlink function +in nfs4xdr.c, nlink is initialized to 1. However, this default value +isn't set to the inode due to the check in nfs_fhget. + +So if the server doesn't support numlinks, inode's nlink will be zero, +the mount will fail with error "Stale file handle". Set the nlink to 1 +if the server doesn't support it. + +Signed-off-by: Han Young <hanyang.tony@bytedance.com> +Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/nfs/inode.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c +index 06230baaa554e..419d98cf9e29f 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.6/nfsv4-xattr-handlers-should-check-for-absent-nfs-fil.patch b/queue-6.6/nfsv4-xattr-handlers-should-check-for-absent-nfs-fil.patch new file mode 100644 index 0000000000..471c2645aa --- /dev/null +++ b/queue-6.6/nfsv4-xattr-handlers-should-check-for-absent-nfs-fil.patch @@ -0,0 +1,59 @@ +From 9a321569c810b505bf2196eef6ea40100edb16ac Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Wed, 16 Apr 2025 11:23:38 -0400 +Subject: NFSv4: xattr handlers should check for absent nfs filehandles + +From: Scott Mayhew <smayhew@redhat.com> + +[ Upstream commit 6e9a2f8dbe93c8004c2af2c0158888628b7ca034 ] + +The nfs inodes for referral anchors that have not yet been followed have +their filehandles zeroed out. + +Attempting to call getxattr() on one of these will cause the nfs client +to send a GETATTR to the nfs server with the preceding PUTFH sans +filehandle. The server will reply NFS4ERR_NOFILEHANDLE, leading to -EIO +being returned to the application. + +For example: + +$ strace -e trace=getxattr getfattr -n system.nfs4_acl /mnt/t/ref +getxattr("/mnt/t/ref", "system.nfs4_acl", NULL, 0) = -1 EIO (Input/output error) +/mnt/t/ref: system.nfs4_acl: Input/output error ++++ exited with 1 +++ + +Have the xattr handlers return -ENODATA instead. + +Signed-off-by: Scott Mayhew <smayhew@redhat.com> +Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/nfs/nfs4proc.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 97a009e007f95..3085a2faab2d3 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -6059,6 +6059,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); +@@ -6133,6 +6135,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.6/nfsv4.2-fix-listxattr-to-return-selinux-security-lab.patch b/queue-6.6/nfsv4.2-fix-listxattr-to-return-selinux-security-lab.patch new file mode 100644 index 0000000000..78a7d50ce7 --- /dev/null +++ b/queue-6.6/nfsv4.2-fix-listxattr-to-return-selinux-security-lab.patch @@ -0,0 +1,56 @@ +From 2d3f24a891999c1e564e4922e8ce64473aeb61d4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 25 Apr 2025 14:09:21 -0400 +Subject: NFSv4.2: fix listxattr to return selinux security label + +From: Olga Kornievskaia <okorniev@redhat.com> + +[ Upstream commit 243fea134633ba3d64aceb4c16129c59541ea2c6 ] + +Currently, when NFS is queried for all the labels present on the +file via a command example "getfattr -d -m . /mnt/testfile", it +does not return the security label. Yet when asked specifically for +the label (getfattr -n security.selinux) it will be returned. +Include the security label when all attributes are queried. + +Signed-off-by: Olga Kornievskaia <okorniev@redhat.com> +Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/nfs/nfs4proc.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 1b94a55215e7d..97a009e007f95 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -10625,7 +10625,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); +@@ -10648,8 +10648,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.6/ovl-check-for-null-d_inode-in-ovl_dentry_upper.patch b/queue-6.6/ovl-check-for-null-d_inode-in-ovl_dentry_upper.patch new file mode 100644 index 0000000000..d5e923f2f0 --- /dev/null +++ b/queue-6.6/ovl-check-for-null-d_inode-in-ovl_dentry_upper.patch @@ -0,0 +1,68 @@ +From fc6c3b6ec13aae3defda64652663369d425df3b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 21 Apr 2025 16:15:19 -0700 +Subject: ovl: Check for NULL d_inode() in ovl_dentry_upper() + +From: Kees Cook <kees@kernel.org> + +[ Upstream commit 8a39f1c870e9d6fbac5638f3a42a6a6363829c49 ] + +In ovl_path_type() and ovl_is_metacopy_dentry() GCC notices that it is +possible for OVL_E() to return NULL (which implies that d_inode(dentry) +may be NULL). This would result in out of bounds reads via container_of(), +seen with GCC 15's -Warray-bounds -fdiagnostics-details. For example: + +In file included from arch/x86/include/generated/asm/rwonce.h:1, + from include/linux/compiler.h:339, + from include/linux/export.h:5, + from include/linux/linkage.h:7, + from include/linux/fs.h:5, + from fs/overlayfs/util.c:7: +In function 'ovl_upperdentry_dereference', + inlined from 'ovl_dentry_upper' at ../fs/overlayfs/util.c:305:9, + inlined from 'ovl_path_type' at ../fs/overlayfs/util.c:216:6: +include/asm-generic/rwonce.h:44:26: error: array subscript 0 is outside array bounds of 'struct inode[7486503276667837]' [-Werror=array-bounds=] + 44 | #define __READ_ONCE(x) (*(const volatile __unqual_scalar_typeof(x) *)&(x)) + | ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +include/asm-generic/rwonce.h:50:9: note: in expansion of macro '__READ_ONCE' + 50 | __READ_ONCE(x); \ + | ^~~~~~~~~~~ +fs/overlayfs/ovl_entry.h:195:16: note: in expansion of macro 'READ_ONCE' + 195 | return READ_ONCE(oi->__upperdentry); + | ^~~~~~~~~ + 'ovl_path_type': event 1 + 185 | return inode ? OVL_I(inode)->oe : NULL; + 'ovl_path_type': event 2 + +Avoid this by allowing ovl_dentry_upper() to return NULL if d_inode() is +NULL, as that means the problematic dereferencing can never be reached. +Note that this fixes the over-eager compiler warning in an effort to +being able to enable -Warray-bounds globally. There is no known +behavioral bug here. + +Suggested-by: Amir Goldstein <amir73il@gmail.com> +Signed-off-by: Kees Cook <kees@kernel.org> +Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/overlayfs/util.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c +index 0bf3ffcd072f6..0da1cd01d01cf 100644 +--- a/fs/overlayfs/util.c ++++ b/fs/overlayfs/util.c +@@ -274,7 +274,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.6/pci-apple-fix-missing-of-node-reference-in-apple_pci.patch b/queue-6.6/pci-apple-fix-missing-of-node-reference-in-apple_pci.patch new file mode 100644 index 0000000000..2ff9cb98d5 --- /dev/null +++ b/queue-6.6/pci-apple-fix-missing-of-node-reference-in-apple_pci.patch @@ -0,0 +1,44 @@ +From 7bc069e6542e25966d7a0ef9b28a39847735e8fa Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 1 Apr 2025 10:17:08 +0100 +Subject: PCI: apple: Fix missing OF node reference in apple_pcie_setup_port + +From: Hector Martin <marcan@marcan.st> + +[ Upstream commit 7fa9fbf39116b061f8a41cd84f1884c545f322c4 ] + +In the success path, we hang onto a reference to the node, so make sure +to grab one. The caller iterator puts our borrowed reference when we +return. + +Signed-off-by: Hector Martin <marcan@marcan.st> +Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> +Signed-off-by: Marc Zyngier <maz@kernel.org> +Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Tested-by: Janne Grunau <j@jannau.net> +Reviewed-by: Rob Herring (Arm) <robh@kernel.org> +Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Acked-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> +Link: https://patch.msgid.link/20250401091713.2765724-9-maz@kernel.org +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/pci/controller/pcie-apple.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c +index 7e6bd63a6425e..08b7070f05d82 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.6/pci-apple-set-only-available-ports-up.patch b/queue-6.6/pci-apple-set-only-available-ports-up.patch new file mode 100644 index 0000000000..da359e799a --- /dev/null +++ b/queue-6.6/pci-apple-set-only-available-ports-up.patch @@ -0,0 +1,54 @@ +From 043433a198f0ebb946021d9bfb684e43137edd4b Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 1 Apr 2025 10:17:01 +0100 +Subject: PCI: apple: Set only available ports up + +From: Janne Grunau <j@jannau.net> + +[ Upstream commit 751bec089c4eed486578994abd2c5395f08d0302 ] + +Iterating over disabled ports results in of_irq_parse_raw() parsing +the wrong "interrupt-map" entries, as it takes the status of the node +into account. + +This became apparent after disabling unused PCIe ports in the Apple +Silicon device trees instead of deleting them. + +Switching from for_each_child_of_node_scoped() to +for_each_available_child_of_node_scoped() solves this issue. + +Fixes: 1e33888fbe44 ("PCI: apple: Add initial hardware bring-up") +Fixes: a0189fdfb73d ("arm64: dts: apple: t8103: Disable unused PCIe ports") +Signed-off-by: Janne Grunau <j@jannau.net> +Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> +Signed-off-by: Marc Zyngier <maz@kernel.org> +Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Tested-by: Janne Grunau <j@jannau.net> +Reviewed-by: Rob Herring (Arm) <robh@kernel.org> +Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Acked-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/asahi/20230214-apple_dts_pcie_disable_unused-v1-0-5ea0d3ddcde3@jannau.net/ +Link: https://lore.kernel.org/asahi/1ea2107a-bb86-8c22-0bbc-82c453ab08ce@linaro.org/ +Link: https://patch.msgid.link/20250401091713.2765724-2-maz@kernel.org +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/pci/controller/pcie-apple.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c +index 66f8854fc3410..8dfea64a51e0f 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.6/pci-apple-use-helper-function-for_each_child_of_node.patch b/queue-6.6/pci-apple-use-helper-function-for_each_child_of_node.patch new file mode 100644 index 0000000000..3816774ca7 --- /dev/null +++ b/queue-6.6/pci-apple-use-helper-function-for_each_child_of_node.patch @@ -0,0 +1,59 @@ +From b2bfe044c040bb99bdc42c8e8277105796517844 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sat, 31 Aug 2024 12:04:12 +0800 +Subject: PCI: apple: Use helper function for_each_child_of_node_scoped() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Zhang Zekun <zhangzekun11@huawei.com> + +[ Upstream commit f60b4e06a945f25d463ae065c6e41c6e24faee0a ] + +The for_each_available_child_of_node_scoped() helper provides +a scope-based clean-up functionality to put the device_node +automatically, and as such, there is no need to call of_node_put() +directly. + +Thus, use this helper to simplify the code. + +Signed-off-by: Zhang Zekun <zhangzekun11@huawei.com> +Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> +Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Link: https://lore.kernel.org/r/20240831040413.126417-6-zhangzekun11@huawei.com +[kwilczynski: commit log] +Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> +Stable-dep-of: 751bec089c4e ("PCI: apple: Set only available ports up") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/pci/controller/pcie-apple.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c +index 08b7070f05d82..66f8854fc3410 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.6/pci-dwc-make-link-training-more-robust-by-setting-po.patch b/queue-6.6/pci-dwc-make-link-training-more-robust-by-setting-po.patch new file mode 100644 index 0000000000..e4c3ef2f3c --- /dev/null +++ b/queue-6.6/pci-dwc-make-link-training-more-robust-by-setting-po.patch @@ -0,0 +1,99 @@ +From 4693aff1d227db2f35eb158cf2fa63b4d4f989f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 22 Apr 2025 18:36:23 +0800 +Subject: PCI: dwc: Make link training more robust by setting + PORT_LOGIC_LINK_WIDTH to one lane + +From: Wenbin Yao <quic_wenbyao@quicinc.com> + +[ Upstream commit af3c6eacce0c464f28fe0e3d365b3860aba07931 ] + +As per DWC PCIe registers description 4.30a, section 1.13.43, NUM_OF_LANES +named as PORT_LOGIC_LINK_WIDTH in PCIe DWC driver, is referred to as the +"Predetermined Number of Lanes" in PCIe r6.0, sec 4.2.7.2.1, which explains +the conditions required to enter Polling.Configuration: + + Next state is Polling.Configuration after at least 1024 TS1 Ordered Sets + were transmitted, and all Lanes that detected a Receiver during Detect + receive eight consecutive training sequences ... + + Otherwise, after a 24 ms timeout the next state is: + + Polling.Configuration if, + + (i) Any Lane, which detected a Receiver during Detect, received eight + consecutive training sequences ... and a minimum of 1024 TS1 Ordered + Sets are transmitted after receiving one TS1 or TS2 Ordered Set. + + And + + (ii) At least a predetermined set of Lanes that detected a Receiver + during Detect have detected an exit from Electrical Idle at least + once since entering Polling.Active. + + Note: This may prevent one or more bad Receivers or Transmitters + from holding up a valid Link from being configured, and allow for + additional training in Polling.Configuration. The exact set of + predetermined Lanes is implementation specific. + + Note: Any Lane that receives eight consecutive TS1 or TS2 Ordered + Sets should have detected an exit from Electrical Idle at least + once since entering Polling.Active. + +In a PCIe link supporting multiple lanes, if PORT_LOGIC_LINK_WIDTH is set +to lane width the hardware supports, all lanes that detect a receiver +during the Detect phase must receive eight consecutive training sequences. +Otherwise, LTSSM will not enter Polling.Configuration and link training +will fail. + +Therefore, always set PORT_LOGIC_LINK_WIDTH to 1, regardless of the number +of lanes the port actually supports, to make link up more robust. This +setting will not affect the intended link width if all lanes are +functional. Additionally, the link can still be established with at least +one lane if other lanes are faulty. + +Co-developed-by: Qiang Yu <quic_qianyu@quicinc.com> +Signed-off-by: Qiang Yu <quic_qianyu@quicinc.com> +Signed-off-by: Wenbin Yao <quic_wenbyao@quicinc.com> +[mani: subject change] +Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +[bhelgaas: update PCIe spec citation, format quote] +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +Tested-by: Niklas Cassel <cassel@kernel.org> +Link: https://patch.msgid.link/20250422103623.462277-1-quic_wenbyao@quicinc.com +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/pci/controller/dwc/pcie-designware.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c +index 2b60d20dfdf59..717af1b757f0a 100644 +--- a/drivers/pci/controller/dwc/pcie-designware.c ++++ b/drivers/pci/controller/dwc/pcie-designware.c +@@ -748,22 +748,19 @@ static void dw_pcie_link_set_max_link_width(struct dw_pcie *pci, u32 num_lanes) + /* Set link width speed control register */ + lwsc = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL); + lwsc &= ~PORT_LOGIC_LINK_WIDTH_MASK; ++ lwsc |= PORT_LOGIC_LINK_WIDTH_1_LANES; + switch (num_lanes) { + case 1: + plc |= PORT_LINK_MODE_1_LANES; +- lwsc |= PORT_LOGIC_LINK_WIDTH_1_LANES; + break; + case 2: + plc |= PORT_LINK_MODE_2_LANES; +- lwsc |= PORT_LOGIC_LINK_WIDTH_2_LANES; + break; + case 4: + plc |= PORT_LINK_MODE_4_LANES; +- lwsc |= PORT_LOGIC_LINK_WIDTH_4_LANES; + break; + case 8: + plc |= PORT_LINK_MODE_8_LANES; +- lwsc |= PORT_LOGIC_LINK_WIDTH_8_LANES; + break; + default: + dev_err(pci->dev, "num-lanes %u: invalid value\n", num_lanes); +-- +2.39.5 + diff --git a/queue-6.6/platform-x86-ideapad-laptop-introduce-a-generic-noti.patch b/queue-6.6/platform-x86-ideapad-laptop-introduce-a-generic-noti.patch new file mode 100644 index 0000000000..d5ab4e2153 --- /dev/null +++ b/queue-6.6/platform-x86-ideapad-laptop-introduce-a-generic-noti.patch @@ -0,0 +1,109 @@ +From d11422dc0c2d6cdae5f26ee24fffa13483a22c70 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Thu, 25 Jul 2024 11:21:07 +0200 +Subject: platform/x86: ideapad-laptop: introduce a generic notification chain +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Gergo Koteles <soyer@irl.hu> + +[ Upstream commit 613e3900c24bb1379d994f44d75d31c3223cc263 ] + +There are several cases where a notification chain can simplify Lenovo +WMI drivers. + +Add a generic notification chain into ideapad-laptop. + +Signed-off-by: Gergo Koteles <soyer@irl.hu> +Link: https://lore.kernel.org/r/c5a43efae8a32bd034c3d19c0a686941347575a7.1721898747.git.soyer@irl.hu +Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> +Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> +Stable-dep-of: 5808c3421695 ("platform/x86: ideapad-laptop: use usleep_range() for EC polling") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/platform/x86/ideapad-laptop.c | 37 +++++++++++++++++++++++++++ + drivers/platform/x86/ideapad-laptop.h | 5 ++++ + 2 files changed, 42 insertions(+) + +diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c +index 50013af0537c3..e21b4dcfe1ddd 100644 +--- a/drivers/platform/x86/ideapad-laptop.c ++++ b/drivers/platform/x86/ideapad-laptop.c +@@ -1501,6 +1501,39 @@ static void ideapad_sync_touchpad_state(struct ideapad_private *priv, bool send_ + priv->r_touchpad_val = value; + } + ++static int ideapad_laptop_nb_notify(struct notifier_block *nb, ++ unsigned long action, void *data) ++{ ++ switch (action) { ++ } ++ ++ return 0; ++} ++ ++static struct notifier_block ideapad_laptop_notifier = { ++ .notifier_call = ideapad_laptop_nb_notify, ++}; ++ ++static BLOCKING_NOTIFIER_HEAD(ideapad_laptop_chain_head); ++ ++int ideapad_laptop_register_notifier(struct notifier_block *nb) ++{ ++ return blocking_notifier_chain_register(&ideapad_laptop_chain_head, nb); ++} ++EXPORT_SYMBOL_NS_GPL(ideapad_laptop_register_notifier, IDEAPAD_LAPTOP); ++ ++int ideapad_laptop_unregister_notifier(struct notifier_block *nb) ++{ ++ return blocking_notifier_chain_unregister(&ideapad_laptop_chain_head, nb); ++} ++EXPORT_SYMBOL_NS_GPL(ideapad_laptop_unregister_notifier, IDEAPAD_LAPTOP); ++ ++void ideapad_laptop_call_notifier(unsigned long action, void *data) ++{ ++ blocking_notifier_call_chain(&ideapad_laptop_chain_head, action, data); ++} ++EXPORT_SYMBOL_NS_GPL(ideapad_laptop_call_notifier, IDEAPAD_LAPTOP); ++ + static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data) + { + struct ideapad_private *priv = data; +@@ -1872,6 +1905,8 @@ static int ideapad_acpi_add(struct platform_device *pdev) + if (err) + goto shared_init_failed; + ++ ideapad_laptop_register_notifier(&ideapad_laptop_notifier); ++ + return 0; + + shared_init_failed: +@@ -1903,6 +1938,8 @@ static void ideapad_acpi_remove(struct platform_device *pdev) + struct ideapad_private *priv = dev_get_drvdata(&pdev->dev); + int i; + ++ ideapad_laptop_unregister_notifier(&ideapad_laptop_notifier); ++ + ideapad_shared_exit(priv); + + acpi_remove_notify_handler(priv->adev->handle, +diff --git a/drivers/platform/x86/ideapad-laptop.h b/drivers/platform/x86/ideapad-laptop.h +index 4498a96de5976..3eb0dcd6bf7ba 100644 +--- a/drivers/platform/x86/ideapad-laptop.h ++++ b/drivers/platform/x86/ideapad-laptop.h +@@ -12,6 +12,11 @@ + #include <linux/acpi.h> + #include <linux/jiffies.h> + #include <linux/errno.h> ++#include <linux/notifier.h> ++ ++int ideapad_laptop_register_notifier(struct notifier_block *nb); ++int ideapad_laptop_unregister_notifier(struct notifier_block *nb); ++void ideapad_laptop_call_notifier(unsigned long action, void *data); + + enum { + VPCCMD_R_VPC1 = 0x10, +-- +2.39.5 + diff --git a/queue-6.6/platform-x86-ideapad-laptop-move-acpi-helpers-from-h.patch b/queue-6.6/platform-x86-ideapad-laptop-move-acpi-helpers-from-h.patch new file mode 100644 index 0000000000..b180d80c95 --- /dev/null +++ b/queue-6.6/platform-x86-ideapad-laptop-move-acpi-helpers-from-h.patch @@ -0,0 +1,362 @@ +From ff051bd6363c43f97b419cb1a6b5fc7658d44b62 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Thu, 25 Jul 2024 11:21:09 +0200 +Subject: platform/x86: ideapad-laptop: move ACPI helpers from header to source + file +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Gergo Koteles <soyer@irl.hu> + +[ Upstream commit 6c1fa8edfef815a97db57f30216265bfa152792d ] + +Since moving ymc_trigger_ec from lenovo-ymc to ideapad-laptop, only the +latter uses these definitions and functions. + +Move them back to source file. + +Signed-off-by: Gergo Koteles <soyer@irl.hu> +Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> +Link: https://lore.kernel.org/r/57a48d2582b567f6c6fbcd3b379e17aee0fb5a94.1721898747.git.soyer@irl.hu +Signed-off-by: Hans de Goede <hdegoede@redhat.com> +Stable-dep-of: 5808c3421695 ("platform/x86: ideapad-laptop: use usleep_range() for EC polling") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/platform/x86/ideapad-laptop.c | 136 +++++++++++++++++++++++++ + drivers/platform/x86/ideapad-laptop.h | 139 -------------------------- + 2 files changed, 136 insertions(+), 139 deletions(-) + +diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c +index 3d23c4f908426..db8256cde34aa 100644 +--- a/drivers/platform/x86/ideapad-laptop.c ++++ b/drivers/platform/x86/ideapad-laptop.c +@@ -21,6 +21,7 @@ + #include <linux/init.h> + #include <linux/input.h> + #include <linux/input/sparse-keymap.h> ++#include <linux/jiffies.h> + #include <linux/kernel.h> + #include <linux/leds.h> + #include <linux/module.h> +@@ -86,6 +87,34 @@ enum { + SALS_FNLOCK_OFF = 0xf, + }; + ++enum { ++ VPCCMD_R_VPC1 = 0x10, ++ VPCCMD_R_BL_MAX, ++ VPCCMD_R_BL, ++ VPCCMD_W_BL, ++ VPCCMD_R_WIFI, ++ VPCCMD_W_WIFI, ++ VPCCMD_R_BT, ++ VPCCMD_W_BT, ++ VPCCMD_R_BL_POWER, ++ VPCCMD_R_NOVO, ++ VPCCMD_R_VPC2, ++ VPCCMD_R_TOUCHPAD, ++ VPCCMD_W_TOUCHPAD, ++ VPCCMD_R_CAMERA, ++ VPCCMD_W_CAMERA, ++ VPCCMD_R_3G, ++ VPCCMD_W_3G, ++ VPCCMD_R_ODD, /* 0x21 */ ++ VPCCMD_W_FAN, ++ VPCCMD_R_RF, ++ VPCCMD_W_RF, ++ VPCCMD_W_YMC = 0x2A, ++ VPCCMD_R_FAN = 0x2B, ++ VPCCMD_R_SPECIAL_BUTTONS = 0x31, ++ VPCCMD_W_BL_POWER = 0x33, ++}; ++ + /* + * These correspond to the number of supported states - 1 + * Future keyboard types may need a new system, if there's a collision +@@ -234,6 +263,7 @@ static void ideapad_shared_exit(struct ideapad_private *priv) + /* + * ACPI Helpers + */ ++#define IDEAPAD_EC_TIMEOUT 200 /* in ms */ + + static int eval_int(acpi_handle handle, const char *name, unsigned long *res) + { +@@ -249,6 +279,29 @@ static int eval_int(acpi_handle handle, const char *name, unsigned long *res) + return 0; + } + ++static int eval_int_with_arg(acpi_handle handle, const char *name, unsigned long arg, ++ unsigned long *res) ++{ ++ struct acpi_object_list params; ++ unsigned long long result; ++ union acpi_object in_obj; ++ acpi_status status; ++ ++ params.count = 1; ++ params.pointer = &in_obj; ++ in_obj.type = ACPI_TYPE_INTEGER; ++ in_obj.integer.value = arg; ++ ++ status = acpi_evaluate_integer(handle, (char *)name, ¶ms, &result); ++ if (ACPI_FAILURE(status)) ++ return -EIO; ++ ++ if (res) ++ *res = result; ++ ++ return 0; ++} ++ + static int exec_simple_method(acpi_handle handle, const char *name, unsigned long arg) + { + acpi_status status = acpi_execute_simple_method(handle, (char *)name, arg); +@@ -291,6 +344,89 @@ static int eval_dytc(acpi_handle handle, unsigned long cmd, unsigned long *res) + return eval_int_with_arg(handle, "DYTC", cmd, res); + } + ++static int eval_vpcr(acpi_handle handle, unsigned long cmd, unsigned long *res) ++{ ++ return eval_int_with_arg(handle, "VPCR", cmd, res); ++} ++ ++static int eval_vpcw(acpi_handle handle, unsigned long cmd, unsigned long data) ++{ ++ struct acpi_object_list params; ++ union acpi_object in_obj[2]; ++ acpi_status status; ++ ++ params.count = 2; ++ params.pointer = in_obj; ++ in_obj[0].type = ACPI_TYPE_INTEGER; ++ in_obj[0].integer.value = cmd; ++ in_obj[1].type = ACPI_TYPE_INTEGER; ++ in_obj[1].integer.value = data; ++ ++ status = acpi_evaluate_object(handle, "VPCW", ¶ms, NULL); ++ if (ACPI_FAILURE(status)) ++ return -EIO; ++ ++ return 0; ++} ++ ++static int read_ec_data(acpi_handle handle, unsigned long cmd, unsigned long *data) ++{ ++ unsigned long end_jiffies, val; ++ int err; ++ ++ err = eval_vpcw(handle, 1, cmd); ++ if (err) ++ return err; ++ ++ end_jiffies = jiffies + msecs_to_jiffies(IDEAPAD_EC_TIMEOUT) + 1; ++ ++ while (time_before(jiffies, end_jiffies)) { ++ schedule(); ++ ++ err = eval_vpcr(handle, 1, &val); ++ if (err) ++ return err; ++ ++ if (val == 0) ++ return eval_vpcr(handle, 0, data); ++ } ++ ++ acpi_handle_err(handle, "timeout in %s\n", __func__); ++ ++ return -ETIMEDOUT; ++} ++ ++static int write_ec_cmd(acpi_handle handle, unsigned long cmd, unsigned long data) ++{ ++ unsigned long end_jiffies, val; ++ int err; ++ ++ err = eval_vpcw(handle, 0, data); ++ if (err) ++ return err; ++ ++ err = eval_vpcw(handle, 1, cmd); ++ if (err) ++ return err; ++ ++ end_jiffies = jiffies + msecs_to_jiffies(IDEAPAD_EC_TIMEOUT) + 1; ++ ++ while (time_before(jiffies, end_jiffies)) { ++ schedule(); ++ ++ err = eval_vpcr(handle, 1, &val); ++ if (err) ++ return err; ++ ++ if (val == 0) ++ return 0; ++ } ++ ++ acpi_handle_err(handle, "timeout in %s\n", __func__); ++ ++ return -ETIMEDOUT; ++} ++ + /* + * debugfs + */ +diff --git a/drivers/platform/x86/ideapad-laptop.h b/drivers/platform/x86/ideapad-laptop.h +index 948cc61800a95..1e52f2aa0aac3 100644 +--- a/drivers/platform/x86/ideapad-laptop.h ++++ b/drivers/platform/x86/ideapad-laptop.h +@@ -9,9 +9,6 @@ + #ifndef _IDEAPAD_LAPTOP_H_ + #define _IDEAPAD_LAPTOP_H_ + +-#include <linux/acpi.h> +-#include <linux/jiffies.h> +-#include <linux/errno.h> + #include <linux/notifier.h> + + enum ideapad_laptop_notifier_actions { +@@ -22,140 +19,4 @@ int ideapad_laptop_register_notifier(struct notifier_block *nb); + int ideapad_laptop_unregister_notifier(struct notifier_block *nb); + void ideapad_laptop_call_notifier(unsigned long action, void *data); + +-enum { +- VPCCMD_R_VPC1 = 0x10, +- VPCCMD_R_BL_MAX, +- VPCCMD_R_BL, +- VPCCMD_W_BL, +- VPCCMD_R_WIFI, +- VPCCMD_W_WIFI, +- VPCCMD_R_BT, +- VPCCMD_W_BT, +- VPCCMD_R_BL_POWER, +- VPCCMD_R_NOVO, +- VPCCMD_R_VPC2, +- VPCCMD_R_TOUCHPAD, +- VPCCMD_W_TOUCHPAD, +- VPCCMD_R_CAMERA, +- VPCCMD_W_CAMERA, +- VPCCMD_R_3G, +- VPCCMD_W_3G, +- VPCCMD_R_ODD, /* 0x21 */ +- VPCCMD_W_FAN, +- VPCCMD_R_RF, +- VPCCMD_W_RF, +- VPCCMD_W_YMC = 0x2A, +- VPCCMD_R_FAN = 0x2B, +- VPCCMD_R_SPECIAL_BUTTONS = 0x31, +- VPCCMD_W_BL_POWER = 0x33, +-}; +- +-static inline int eval_int_with_arg(acpi_handle handle, const char *name, unsigned long arg, unsigned long *res) +-{ +- struct acpi_object_list params; +- unsigned long long result; +- union acpi_object in_obj; +- acpi_status status; +- +- params.count = 1; +- params.pointer = &in_obj; +- in_obj.type = ACPI_TYPE_INTEGER; +- in_obj.integer.value = arg; +- +- status = acpi_evaluate_integer(handle, (char *)name, ¶ms, &result); +- if (ACPI_FAILURE(status)) +- return -EIO; +- +- if (res) +- *res = result; +- +- return 0; +-} +- +-static inline int eval_vpcr(acpi_handle handle, unsigned long cmd, unsigned long *res) +-{ +- return eval_int_with_arg(handle, "VPCR", cmd, res); +-} +- +-static inline int eval_vpcw(acpi_handle handle, unsigned long cmd, unsigned long data) +-{ +- struct acpi_object_list params; +- union acpi_object in_obj[2]; +- acpi_status status; +- +- params.count = 2; +- params.pointer = in_obj; +- in_obj[0].type = ACPI_TYPE_INTEGER; +- in_obj[0].integer.value = cmd; +- in_obj[1].type = ACPI_TYPE_INTEGER; +- in_obj[1].integer.value = data; +- +- status = acpi_evaluate_object(handle, "VPCW", ¶ms, NULL); +- if (ACPI_FAILURE(status)) +- return -EIO; +- +- return 0; +-} +- +-#define IDEAPAD_EC_TIMEOUT 200 /* in ms */ +- +-static inline int read_ec_data(acpi_handle handle, unsigned long cmd, unsigned long *data) +-{ +- unsigned long end_jiffies, val; +- int err; +- +- err = eval_vpcw(handle, 1, cmd); +- if (err) +- return err; +- +- end_jiffies = jiffies + msecs_to_jiffies(IDEAPAD_EC_TIMEOUT) + 1; +- +- while (time_before(jiffies, end_jiffies)) { +- schedule(); +- +- err = eval_vpcr(handle, 1, &val); +- if (err) +- return err; +- +- if (val == 0) +- return eval_vpcr(handle, 0, data); +- } +- +- acpi_handle_err(handle, "timeout in %s\n", __func__); +- +- return -ETIMEDOUT; +-} +- +-static inline int write_ec_cmd(acpi_handle handle, unsigned long cmd, unsigned long data) +-{ +- unsigned long end_jiffies, val; +- int err; +- +- err = eval_vpcw(handle, 0, data); +- if (err) +- return err; +- +- err = eval_vpcw(handle, 1, cmd); +- if (err) +- return err; +- +- end_jiffies = jiffies + msecs_to_jiffies(IDEAPAD_EC_TIMEOUT) + 1; +- +- while (time_before(jiffies, end_jiffies)) { +- schedule(); +- +- err = eval_vpcr(handle, 1, &val); +- if (err) +- return err; +- +- if (val == 0) +- return 0; +- } +- +- acpi_handle_err(handle, "timeout in %s\n", __func__); +- +- return -ETIMEDOUT; +-} +- +-#undef IDEAPAD_EC_TIMEOUT + #endif /* !_IDEAPAD_LAPTOP_H_ */ +-- +2.39.5 + diff --git a/queue-6.6/platform-x86-ideapad-laptop-move-ymc_trigger_ec-from.patch b/queue-6.6/platform-x86-ideapad-laptop-move-ymc_trigger_ec-from.patch new file mode 100644 index 0000000000..954c5221af --- /dev/null +++ b/queue-6.6/platform-x86-ideapad-laptop-move-ymc_trigger_ec-from.patch @@ -0,0 +1,270 @@ +From 9fd3959939a4a2c42b766ea1ae1128b991b93f78 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Thu, 25 Jul 2024 11:21:08 +0200 +Subject: platform/x86: ideapad-laptop: move ymc_trigger_ec from lenovo-ymc +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Gergo Koteles <soyer@irl.hu> + +[ Upstream commit cde7886b35176d56e72bfc68dc104fa08e7b072c ] + +Some models need to trigger the EC after each YMC event for the yoga +mode control to work properly. EC triggering consist of a VPC call from +the lenovo-ymc module. Except for this, all VPC calls are in the +ideapad-laptop module. + +Since ideapad-laptop has a notification chain, a new YMC_EVENT action +can be added and triggered from the lenovo-ymc module. Then the +ideapad-laptop can trigger the EC. + +If the triggering is in the ideapad-laptop module, then the ec_trigger +module parameter should be there as well. + +Move the ymc_trigger_ec functionality and the ec_trigger module +parameter to the ideapad-laptop module. + +Signed-off-by: Gergo Koteles <soyer@irl.hu> +Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> +Link: https://lore.kernel.org/r/d980ab3ac32b5e554f456b0ff17279bfdbe2a203.1721898747.git.soyer@irl.hu +Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> +Stable-dep-of: 5808c3421695 ("platform/x86: ideapad-laptop: use usleep_range() for EC polling") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/platform/x86/Kconfig | 1 + + drivers/platform/x86/ideapad-laptop.c | 49 ++++++++++++++++++++++ + drivers/platform/x86/ideapad-laptop.h | 4 ++ + drivers/platform/x86/lenovo-ymc.c | 60 +-------------------------- + 4 files changed, 56 insertions(+), 58 deletions(-) + +diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig +index 07eea525091b0..1fd57eb867662 100644 +--- a/drivers/platform/x86/Kconfig ++++ b/drivers/platform/x86/Kconfig +@@ -466,6 +466,7 @@ config LENOVO_YMC + tristate "Lenovo Yoga Tablet Mode Control" + depends on ACPI_WMI + depends on INPUT ++ depends on IDEAPAD_LAPTOP + select INPUT_SPARSEKMAP + help + This driver maps the Tablet Mode Control switch to SW_TABLET_MODE input +diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c +index e21b4dcfe1ddd..3d23c4f908426 100644 +--- a/drivers/platform/x86/ideapad-laptop.c ++++ b/drivers/platform/x86/ideapad-laptop.c +@@ -145,6 +145,7 @@ struct ideapad_private { + bool touchpad_ctrl_via_ec : 1; + bool ctrl_ps2_aux_port : 1; + bool usb_charging : 1; ++ bool ymc_ec_trigger : 1; + } features; + struct { + bool initialized; +@@ -188,6 +189,12 @@ MODULE_PARM_DESC(touchpad_ctrl_via_ec, + "Enable registering a 'touchpad' sysfs-attribute which can be used to manually " + "tell the EC to enable/disable the touchpad. This may not work on all models."); + ++static bool ymc_ec_trigger __read_mostly; ++module_param(ymc_ec_trigger, bool, 0444); ++MODULE_PARM_DESC(ymc_ec_trigger, ++ "Enable EC triggering work-around to force emitting tablet mode events. " ++ "If you need this please report this to: platform-driver-x86@vger.kernel.org"); ++ + /* + * shared data + */ +@@ -1501,10 +1508,50 @@ static void ideapad_sync_touchpad_state(struct ideapad_private *priv, bool send_ + priv->r_touchpad_val = value; + } + ++static const struct dmi_system_id ymc_ec_trigger_quirk_dmi_table[] = { ++ { ++ /* Lenovo Yoga 7 14ARB7 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "82QF"), ++ }, ++ }, ++ { ++ /* Lenovo Yoga 7 14ACN6 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "82N7"), ++ }, ++ }, ++ { } ++}; ++ ++static void ideapad_laptop_trigger_ec(void) ++{ ++ struct ideapad_private *priv; ++ int ret; ++ ++ guard(mutex)(&ideapad_shared_mutex); ++ ++ priv = ideapad_shared; ++ if (!priv) ++ return; ++ ++ if (!priv->features.ymc_ec_trigger) ++ return; ++ ++ ret = write_ec_cmd(priv->adev->handle, VPCCMD_W_YMC, 1); ++ if (ret) ++ dev_warn(&priv->platform_device->dev, "Could not write YMC: %d\n", ret); ++} ++ + static int ideapad_laptop_nb_notify(struct notifier_block *nb, + unsigned long action, void *data) + { + switch (action) { ++ case IDEAPAD_LAPTOP_YMC_EVENT: ++ ideapad_laptop_trigger_ec(); ++ break; + } + + return 0; +@@ -1670,6 +1717,8 @@ static void ideapad_check_features(struct ideapad_private *priv) + priv->features.ctrl_ps2_aux_port = + ctrl_ps2_aux_port || dmi_check_system(ctrl_ps2_aux_port_list); + priv->features.touchpad_ctrl_via_ec = touchpad_ctrl_via_ec; ++ priv->features.ymc_ec_trigger = ++ ymc_ec_trigger || dmi_check_system(ymc_ec_trigger_quirk_dmi_table); + + if (!read_ec_data(handle, VPCCMD_R_FAN, &val)) + priv->features.fan_mode = true; +diff --git a/drivers/platform/x86/ideapad-laptop.h b/drivers/platform/x86/ideapad-laptop.h +index 3eb0dcd6bf7ba..948cc61800a95 100644 +--- a/drivers/platform/x86/ideapad-laptop.h ++++ b/drivers/platform/x86/ideapad-laptop.h +@@ -14,6 +14,10 @@ + #include <linux/errno.h> + #include <linux/notifier.h> + ++enum ideapad_laptop_notifier_actions { ++ IDEAPAD_LAPTOP_YMC_EVENT, ++}; ++ + int ideapad_laptop_register_notifier(struct notifier_block *nb); + int ideapad_laptop_unregister_notifier(struct notifier_block *nb); + void ideapad_laptop_call_notifier(unsigned long action, void *data); +diff --git a/drivers/platform/x86/lenovo-ymc.c b/drivers/platform/x86/lenovo-ymc.c +index ef2c267ab485c..bd9f95404c7cb 100644 +--- a/drivers/platform/x86/lenovo-ymc.c ++++ b/drivers/platform/x86/lenovo-ymc.c +@@ -20,32 +20,10 @@ + #define LENOVO_YMC_QUERY_INSTANCE 0 + #define LENOVO_YMC_QUERY_METHOD 0x01 + +-static bool ec_trigger __read_mostly; +-module_param(ec_trigger, bool, 0444); +-MODULE_PARM_DESC(ec_trigger, "Enable EC triggering work-around to force emitting tablet mode events"); +- + static bool force; + module_param(force, bool, 0444); + MODULE_PARM_DESC(force, "Force loading on boards without a convertible DMI chassis-type"); + +-static const struct dmi_system_id ec_trigger_quirk_dmi_table[] = { +- { +- /* Lenovo Yoga 7 14ARB7 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), +- DMI_MATCH(DMI_PRODUCT_NAME, "82QF"), +- }, +- }, +- { +- /* Lenovo Yoga 7 14ACN6 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), +- DMI_MATCH(DMI_PRODUCT_NAME, "82N7"), +- }, +- }, +- { } +-}; +- + static const struct dmi_system_id allowed_chasis_types_dmi_table[] = { + { + .matches = { +@@ -62,21 +40,8 @@ static const struct dmi_system_id allowed_chasis_types_dmi_table[] = { + + struct lenovo_ymc_private { + struct input_dev *input_dev; +- struct acpi_device *ec_acpi_dev; + }; + +-static void lenovo_ymc_trigger_ec(struct wmi_device *wdev, struct lenovo_ymc_private *priv) +-{ +- int err; +- +- if (!priv->ec_acpi_dev) +- return; +- +- err = write_ec_cmd(priv->ec_acpi_dev->handle, VPCCMD_W_YMC, 1); +- if (err) +- dev_warn(&wdev->dev, "Could not write YMC: %d\n", err); +-} +- + static const struct key_entry lenovo_ymc_keymap[] = { + /* Ignore the uninitialized state */ + { KE_IGNORE, 0x00 }, +@@ -127,11 +92,9 @@ static void lenovo_ymc_notify(struct wmi_device *wdev, union acpi_object *data) + + free_obj: + kfree(obj); +- lenovo_ymc_trigger_ec(wdev, priv); ++ ideapad_laptop_call_notifier(IDEAPAD_LAPTOP_YMC_EVENT, &code); + } + +-static void acpi_dev_put_helper(void *p) { acpi_dev_put(p); } +- + static int lenovo_ymc_probe(struct wmi_device *wdev, const void *ctx) + { + struct lenovo_ymc_private *priv; +@@ -145,29 +108,10 @@ static int lenovo_ymc_probe(struct wmi_device *wdev, const void *ctx) + return -ENODEV; + } + +- ec_trigger |= dmi_check_system(ec_trigger_quirk_dmi_table); +- + priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + +- if (ec_trigger) { +- pr_debug("Lenovo YMC enable EC triggering.\n"); +- priv->ec_acpi_dev = acpi_dev_get_first_match_dev("VPC2004", NULL, -1); +- +- if (!priv->ec_acpi_dev) { +- dev_err(&wdev->dev, "Could not find EC ACPI device.\n"); +- return -ENODEV; +- } +- err = devm_add_action_or_reset(&wdev->dev, +- acpi_dev_put_helper, priv->ec_acpi_dev); +- if (err) { +- dev_err(&wdev->dev, +- "Could not clean up EC ACPI device: %d\n", err); +- return err; +- } +- } +- + input_dev = devm_input_allocate_device(&wdev->dev); + if (!input_dev) + return -ENOMEM; +@@ -194,7 +138,6 @@ static int lenovo_ymc_probe(struct wmi_device *wdev, const void *ctx) + dev_set_drvdata(&wdev->dev, priv); + + /* Report the state for the first time on probe */ +- lenovo_ymc_trigger_ec(wdev, priv); + lenovo_ymc_notify(wdev, NULL); + return 0; + } +@@ -219,3 +162,4 @@ module_wmi_driver(lenovo_ymc_driver); + MODULE_AUTHOR("Gergo Koteles <soyer@irl.hu>"); + MODULE_DESCRIPTION("Lenovo Yoga Mode Control driver"); + MODULE_LICENSE("GPL"); ++MODULE_IMPORT_NS(IDEAPAD_LAPTOP); +-- +2.39.5 + diff --git a/queue-6.6/platform-x86-ideapad-laptop-use-usleep_range-for-ec-.patch b/queue-6.6/platform-x86-ideapad-laptop-use-usleep_range-for-ec-.patch new file mode 100644 index 0000000000..b0d4cdbc33 --- /dev/null +++ b/queue-6.6/platform-x86-ideapad-laptop-use-usleep_range-for-ec-.patch @@ -0,0 +1,127 @@ +From d74f2de78983932b0f610101f63a26cc9bd9b624 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 26 May 2025 04:18:07 +0800 +Subject: platform/x86: ideapad-laptop: use usleep_range() for EC polling +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rong Zhang <i@rong.moe> + +[ Upstream commit 5808c34216954cd832bd4b8bc52dfa287049122b ] + +It was reported that ideapad-laptop sometimes causes some recent (since +2024) Lenovo ThinkBook models shut down when: + - suspending/resuming + - closing/opening the lid + - (dis)connecting a charger + - reading/writing some sysfs properties, e.g., fan_mode, touchpad + - pressing down some Fn keys, e.g., Brightness Up/Down (Fn+F5/F6) + - (seldom) loading the kmod + +The issue has existed since the launch day of such models, and there +have been some out-of-tree workarounds (see Link:) for the issue. One +disables some functionalities, while another one simply shortens +IDEAPAD_EC_TIMEOUT. The disabled functionalities have read_ec_data() in +their call chains, which calls schedule() between each poll. + +It turns out that these models suffer from the indeterminacy of +schedule() because of their low tolerance for being polled too +frequently. Sometimes schedule() returns too soon due to the lack of +ready tasks, causing the margin between two polls to be too short. +In this case, the command is somehow aborted, and too many subsequent +polls (they poll for "nothing!") may eventually break the state machine +in the EC, resulting in a hard shutdown. This explains why shortening +IDEAPAD_EC_TIMEOUT works around the issue - it reduces the total number +of polls sent to the EC. + +Even when it doesn't lead to a shutdown, frequent polls may also disturb +the ongoing operation and notably delay (+ 10-20ms) the availability of +EC response. This phenomenon is unlikely to be exclusive to the models +mentioned above, so dropping the schedule() manner should also slightly +improve the responsiveness of various models. + +Fix these issues by migrating to usleep_range(150, 300). The interval is +chosen to add some margin to the minimal 50us and considering EC +responses are usually available after 150-2500us based on my test. It +should be enough to fix these issues on all models subject to the EC bug +without introducing latency on other models. + +Tested on ThinkBook 14 G7+ ASP and solved both issues. No regression was +introduced in the test on a model without the EC bug (ThinkBook X IMH, +thanks Eric). + +Link: https://github.com/ty2/ideapad-laptop-tb2024g6plus/commit/6c5db18c9e8109873c2c90a7d2d7f552148f7ad4 +Link: https://github.com/ferstar/ideapad-laptop-tb/commit/42d1e68e5009529d31bd23f978f636f79c023e80 +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218771 +Fixes: 6a09f21dd1e2 ("ideapad: add ACPI helpers") +Cc: stable@vger.kernel.org +Tested-by: Felix Yan <felixonmars@archlinux.org> +Tested-by: Eric Long <i@hack3r.moe> +Tested-by: Jianfei Zhang <zhangjianfei3@gmail.com> +Tested-by: Mingcong Bai <jeffbai@aosc.io> +Tested-by: Minh Le <minhld139@gmail.com> +Tested-by: Sicheng Zhu <Emmet_Z@outlook.com> +Signed-off-by: Rong Zhang <i@rong.moe> +Link: https://lore.kernel.org/r/20250525201833.37939-1-i@rong.moe +Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> +Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/platform/x86/ideapad-laptop.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c +index db8256cde34aa..e84fcb444d872 100644 +--- a/drivers/platform/x86/ideapad-laptop.c ++++ b/drivers/platform/x86/ideapad-laptop.c +@@ -14,6 +14,7 @@ + #include <linux/bitops.h> + #include <linux/bug.h> + #include <linux/debugfs.h> ++#include <linux/delay.h> + #include <linux/device.h> + #include <linux/dmi.h> + #include <linux/fb.h> +@@ -265,6 +266,20 @@ static void ideapad_shared_exit(struct ideapad_private *priv) + */ + #define IDEAPAD_EC_TIMEOUT 200 /* in ms */ + ++/* ++ * Some models (e.g., ThinkBook since 2024) have a low tolerance for being ++ * polled too frequently. Doing so may break the state machine in the EC, ++ * resulting in a hard shutdown. ++ * ++ * It is also observed that frequent polls may disturb the ongoing operation ++ * and notably delay the availability of EC response. ++ * ++ * These values are used as the delay before the first poll and the interval ++ * between subsequent polls to solve the above issues. ++ */ ++#define IDEAPAD_EC_POLL_MIN_US 150 ++#define IDEAPAD_EC_POLL_MAX_US 300 ++ + static int eval_int(acpi_handle handle, const char *name, unsigned long *res) + { + unsigned long long result; +@@ -381,7 +396,7 @@ static int read_ec_data(acpi_handle handle, unsigned long cmd, unsigned long *da + end_jiffies = jiffies + msecs_to_jiffies(IDEAPAD_EC_TIMEOUT) + 1; + + while (time_before(jiffies, end_jiffies)) { +- schedule(); ++ usleep_range(IDEAPAD_EC_POLL_MIN_US, IDEAPAD_EC_POLL_MAX_US); + + err = eval_vpcr(handle, 1, &val); + if (err) +@@ -412,7 +427,7 @@ static int write_ec_cmd(acpi_handle handle, unsigned long cmd, unsigned long dat + end_jiffies = jiffies + msecs_to_jiffies(IDEAPAD_EC_TIMEOUT) + 1; + + while (time_before(jiffies, end_jiffies)) { +- schedule(); ++ usleep_range(IDEAPAD_EC_POLL_MIN_US, IDEAPAD_EC_POLL_MAX_US); + + err = eval_vpcr(handle, 1, &val); + if (err) +-- +2.39.5 + diff --git a/queue-6.6/revert-iommu-amd-prevent-binding-other-pci-drivers-t.patch b/queue-6.6/revert-iommu-amd-prevent-binding-other-pci-drivers-t.patch new file mode 100644 index 0000000000..8e132b8e55 --- /dev/null +++ b/queue-6.6/revert-iommu-amd-prevent-binding-other-pci-drivers-t.patch @@ -0,0 +1,60 @@ +From 7a16f337cb396f3e1418c12ba5e9073baa434b08 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 25 Apr 2025 11:24:21 +0200 +Subject: Revert "iommu/amd: Prevent binding other PCI drivers to IOMMU PCI + devices" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Lukas Wunner <lukas@wunner.de> + +[ Upstream commit 3be5fa236649da6404f1bca1491bf02d4b0d5cce ] + +Commit 991de2e59090 ("PCI, x86: Implement pcibios_alloc_irq() and +pcibios_free_irq()") changed IRQ handling on PCI driver probing. +It inadvertently broke resume from system sleep on AMD platforms: + + https://lore.kernel.org/r/20150926164651.GA3640@pd.tnic/ + +This was fixed by two independent commits: + +* 8affb487d4a4 ("x86/PCI: Don't alloc pcibios-irq when MSI is enabled") +* cbbc00be2ce3 ("iommu/amd: Prevent binding other PCI drivers to IOMMU PCI devices") + +The breaking change and one of these two fixes were subsequently reverted: + +* fe25d078874f ("Revert "x86/PCI: Don't alloc pcibios-irq when MSI is enabled"") +* 6c777e8799a9 ("Revert "PCI, x86: Implement pcibios_alloc_irq() and pcibios_free_irq()"") + +This rendered the second fix unnecessary, so revert it as well. It used +the match_driver flag in struct pci_dev, which is internal to the PCI core +and not supposed to be touched by arbitrary drivers. + +Signed-off-by: Lukas Wunner <lukas@wunner.de> +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> +Acked-by: Joerg Roedel <jroedel@suse.de> +Link: https://patch.msgid.link/9a3ddff5cc49512044f963ba0904347bd404094d.1745572340.git.lukas@wunner.de +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/iommu/amd/init.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c +index 2e7a12f306510..7296e02e2b849 100644 +--- a/drivers/iommu/amd/init.c ++++ b/drivers/iommu/amd/init.c +@@ -2090,9 +2090,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.6/rust-module-place-cleanup_module-in-.exit.text-secti.patch b/queue-6.6/rust-module-place-cleanup_module-in-.exit.text-secti.patch new file mode 100644 index 0000000000..8b09279db2 --- /dev/null +++ b/queue-6.6/rust-module-place-cleanup_module-in-.exit.text-secti.patch @@ -0,0 +1,61 @@ +From f5dcd763bb0c9eb0526e33459364abdb59695ae3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sat, 8 Mar 2025 13:45:06 +0900 +Subject: rust: module: place cleanup_module() in .exit.text section + +From: FUJITA Tomonori <fujita.tomonori@gmail.com> + +[ Upstream commit 249c3a0e53acefc2b06d3b3e1fc28fb2081f878d ] + +Place cleanup_module() in .exit.text section. Currently, +cleanup_module() is likely placed in the .text section. It's +inconsistent with the layout of C modules, where cleanup_module() is +placed in .exit.text. + +[ Boqun asked for an example of how the section changed to be + put in the log. Tomonori provided the following examples: + + C module: + + $ objdump -t ~/build/x86/drivers/block/loop.o|grep clean + 0000000000000000 l O .exit.data 0000000000000008 __UNIQUE_ID___addressable_cleanup_module412 + 0000000000000000 g F .exit.text 000000000000009c cleanup_module + + Rust module without this patch: + + $ objdump -t ~/build/x86/samples/rust/rust_minimal.o|grep clean + 00000000000002b0 g F .text 00000000000000c6 cleanup_module + 0000000000000000 g O .exit.data 0000000000000008 _R...___UNIQUE_ID___addressable_cleanup_module + + Rust module with this patch: + + $ objdump -t ~/build/x86/samples/rust/rust_minimal.o|grep clean + 0000000000000000 g F .exit.text 00000000000000c6 cleanup_module + 0000000000000000 g O .exit.data 0000000000000008 _R...___UNIQUE_ID___addressable_cleanup_module + + - Miguel ] + +Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com> +Acked-by: Jarkko Sakkinen <jarkko@kernel.org> +Link: https://lore.kernel.org/r/20250308044506.14458-1-fujita.tomonori@gmail.com +Signed-off-by: Miguel Ojeda <ojeda@kernel.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + rust/macros/module.rs | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/rust/macros/module.rs b/rust/macros/module.rs +index 7dee348ef0cc8..7614a7198ce20 100644 +--- a/rust/macros/module.rs ++++ b/rust/macros/module.rs +@@ -249,6 +249,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.6/scsi-ufs-core-don-t-perform-ufs-clkscaling-during-ho.patch b/queue-6.6/scsi-ufs-core-don-t-perform-ufs-clkscaling-during-ho.patch new file mode 100644 index 0000000000..b6b8dc430b --- /dev/null +++ b/queue-6.6/scsi-ufs-core-don-t-perform-ufs-clkscaling-during-ho.patch @@ -0,0 +1,68 @@ +From 5058d2031009f282279f59bdd08f196b0597ee84 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Thu, 22 May 2025 16:12:28 +0800 +Subject: scsi: ufs: core: Don't perform UFS clkscaling during host async scan + +From: Ziqi Chen <quic_ziqichen@quicinc.com> + +[ Upstream commit e97633492f5a3eca7b3ff03b4ef6f993017f7955 ] + +When preparing for UFS clock scaling, the UFS driver will quiesce all +sdevs queues in the UFS SCSI host tagset list and then unquiesce them in +ufshcd_clock_scaling_unprepare(). If the UFS SCSI host async scan is in +progress at this time, some LUs may be added to the tagset list between +UFS clkscale prepare and unprepare. This can cause two issues: + +1. During clock scaling, there may be I/O requests issued through new +added queues that have not been quiesced, leading to task abort issue. + +2. These new added queues that have not been quiesced will be unquiesced +as well when UFS clkscale is unprepared, resulting in warning prints. + +Therefore, use the mutex lock scan_mutex in +ufshcd_clock_scaling_prepare() and ufshcd_clock_scaling_unprepare() to +protect it. + +Co-developed-by: Can Guo <quic_cang@quicinc.com> +Signed-off-by: Can Guo <quic_cang@quicinc.com> +Signed-off-by: Ziqi Chen <quic_ziqichen@quicinc.com> +Link: https://lore.kernel.org/r/20250522081233.2358565-1-quic_ziqichen@quicinc.com +Suggested-by: Bart Van Assche <bvanassche@acm.org> +Reviewed-by: Bart Van Assche <bvanassche@acm.org> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/ufs/core/ufshcd.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index 9dabc03675b00..412931cf240f6 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -1284,6 +1284,7 @@ static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba, u64 timeout_us) + * make sure that there are no outstanding requests when + * clock scaling is in progress + */ ++ mutex_lock(&hba->host->scan_mutex); + blk_mq_quiesce_tagset(&hba->host->tag_set); + mutex_lock(&hba->wb_mutex); + down_write(&hba->clk_scaling_lock); +@@ -1294,6 +1295,7 @@ static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba, u64 timeout_us) + up_write(&hba->clk_scaling_lock); + mutex_unlock(&hba->wb_mutex); + blk_mq_unquiesce_tagset(&hba->host->tag_set); ++ mutex_unlock(&hba->host->scan_mutex); + goto out; + } + +@@ -1315,6 +1317,7 @@ static void ufshcd_clock_scaling_unprepare(struct ufs_hba *hba, int err, bool sc + mutex_unlock(&hba->wb_mutex); + + blk_mq_unquiesce_tagset(&hba->host->tag_set); ++ mutex_unlock(&hba->host->scan_mutex); + ufshcd_release(hba); + } + +-- +2.39.5 + diff --git a/queue-6.6/series b/queue-6.6/series new file mode 100644 index 0000000000..2eab419dba --- /dev/null +++ b/queue-6.6/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 +cifs-fix-encoding-of-smb1-session-setup-ntlmssp-requ.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 +sunrpc-don-t-immediately-retransmit-on-seqno-miss.patch +leds-multicolor-fix-intensity-setting-while-sw-blink.patch +fuse-fix-race-between-concurrent-setattrs-from-multi.patch +cxl-region-add-a-dev_err-on-missing-target-list-entr.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 +ksmbd-provide-zero-as-a-unique-id-to-the-mac-client.patch +rust-module-place-cleanup_module-in-.exit.text-secti.patch +revert-iommu-amd-prevent-binding-other-pci-drivers-t.patch +dmaengine-idxd-check-availability-of-workqueue-alloc.patch +dmaengine-xilinx_dma-set-dma_device-directions.patch +pci-dwc-make-link-training-more-robust-by-setting-po.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 +drm-scheduler-signal-scheduled-fence-when-kill-job.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 +misc-tps6594-pfsm-add-null-pointer-check-in-tps6594_.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 +scsi-ufs-core-don-t-perform-ufs-clkscaling-during-ho.patch +ovl-check-for-null-d_inode-in-ovl_dentry_upper.patch +btrfs-handle-csum-tree-error-with-rescue-ibadroots-c.patch +fs-jfs-consolidate-sanity-checking-in-dbmount.patch +jfs-validate-ag-parameters-in-dbmount-to-prevent-cra.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 +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 +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 +platform-x86-ideapad-laptop-introduce-a-generic-noti.patch +platform-x86-ideapad-laptop-move-ymc_trigger_ec-from.patch +platform-x86-ideapad-laptop-move-acpi-helpers-from-h.patch +platform-x86-ideapad-laptop-use-usleep_range-for-ec-.patch +af_unix-define-locking-order-for-unix_table_double_l.patch +af_unix-define-locking-order-for-u_lock_second-in-un.patch +af_unix-define-locking-order-for-u_recvq_lock_embryo.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.6/sunrpc-don-t-immediately-retransmit-on-seqno-miss.patch b/queue-6.6/sunrpc-don-t-immediately-retransmit-on-seqno-miss.patch new file mode 100644 index 0000000000..769ba4b02e --- /dev/null +++ b/queue-6.6/sunrpc-don-t-immediately-retransmit-on-seqno-miss.patch @@ -0,0 +1,61 @@ +From 373e26fef1b5f700e71c1474690977cf9c3d35ee Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Wed, 19 Mar 2025 13:02:40 -0400 +Subject: sunrpc: don't immediately retransmit on seqno miss + +From: Nikhil Jha <njha@janestreet.com> + +[ Upstream commit fadc0f3bb2de8c570ced6d9c1f97222213d93140 ] + +RFC2203 requires that retransmitted messages use a new gss sequence +number, but the same XID. This means that if the server is just slow +(e.x. overloaded), the client might receive a response using an older +seqno than the one it has recorded. + +Currently, Linux's client immediately retransmits in this case. However, +this leads to a lot of wasted retransmits until the server eventually +responds faster than the client can resend. + +Client -> SEQ 1 -> Server +Client -> SEQ 2 -> Server +Client <- SEQ 1 <- Server (misses, expecting seqno = 2) +Client -> SEQ 3 -> Server (immediate retransmission on miss) +Client <- SEQ 2 <- Server (misses, expecting seqno = 3) +Client -> SEQ 4 -> Server (immediate retransmission on miss) +... and so on ... + +This commit makes it so that we ignore messages with bad checksums +due to seqnum mismatch, and rely on the usual timeout behavior for +retransmission instead of doing so immediately. + +Signed-off-by: Nikhil Jha <njha@janestreet.com> +Acked-by: Chuck Lever <chuck.lever@oracle.com> +Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + net/sunrpc/clnt.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c +index 4ffb2bcaf3648..63756607f6327 100644 +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -2733,8 +2733,13 @@ rpc_decode_header(struct rpc_task *task, struct xdr_stream *xdr) + case -EPROTONOSUPPORT: + goto out_err; + case -EACCES: +- /* Re-encode with a fresh cred */ +- fallthrough; ++ /* possible RPCSEC_GSS out-of-sequence event (RFC2203), ++ * reset recv state and keep waiting, don't retransmit ++ */ ++ task->tk_rqstp->rq_reply_bytes_recvd = 0; ++ task->tk_status = xprt_request_enqueue_receive(task); ++ task->tk_action = call_transmit_status; ++ return -EBADMSG; + default: + goto out_garbage; + } +-- +2.39.5 + diff --git a/queue-6.6/tty-serial-uartlite-register-uart-driver-in-init.patch b/queue-6.6/tty-serial-uartlite-register-uart-driver-in-init.patch new file mode 100644 index 0000000000..b779c448c0 --- /dev/null +++ b/queue-6.6/tty-serial-uartlite-register-uart-driver-in-init.patch @@ -0,0 +1,101 @@ +From 5ba78219d81706e698acc38e84b42b2a892884f6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 31 Mar 2025 18:06:19 +0200 +Subject: tty: serial: uartlite: register uart driver in init + +From: Jakub Lewalski <jakub.lewalski@nokia.com> + +[ Upstream commit 6bd697b5fc39fd24e2aa418c7b7d14469f550a93 ] + +When two instances of uart devices are probing, a concurrency race can +occur. If one thread calls uart_register_driver function, which first +allocates and assigns memory to 'uart_state' member of uart_driver +structure, the other instance can bypass uart driver registration and +call ulite_assign. This calls uart_add_one_port, which expects the uart +driver to be fully initialized. This leads to a kernel panic due to a +null pointer dereference: + +[ 8.143581] BUG: kernel NULL pointer dereference, address: 00000000000002b8 +[ 8.156982] #PF: supervisor write access in kernel mode +[ 8.156984] #PF: error_code(0x0002) - not-present page +[ 8.156986] PGD 0 P4D 0 +... +[ 8.180668] RIP: 0010:mutex_lock+0x19/0x30 +[ 8.188624] Call Trace: +[ 8.188629] ? __die_body.cold+0x1a/0x1f +[ 8.195260] ? page_fault_oops+0x15c/0x290 +[ 8.209183] ? __irq_resolve_mapping+0x47/0x80 +[ 8.209187] ? exc_page_fault+0x64/0x140 +[ 8.209190] ? asm_exc_page_fault+0x22/0x30 +[ 8.209196] ? mutex_lock+0x19/0x30 +[ 8.223116] uart_add_one_port+0x60/0x440 +[ 8.223122] ? proc_tty_register_driver+0x43/0x50 +[ 8.223126] ? tty_register_driver+0x1ca/0x1e0 +[ 8.246250] ulite_probe+0x357/0x4b0 [uartlite] + +To prevent it, move uart driver registration in to init function. This +will ensure that uart_driver is always registered when probe function +is called. + +Signed-off-by: Jakub Lewalski <jakub.lewalski@nokia.com> +Signed-off-by: Elodie Decerle <elodie.decerle@nokia.com> +Link: https://lore.kernel.org/r/20250331160732.2042-1-elodie.decerle@nokia.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/tty/serial/uartlite.c | 25 ++++++++++++------------- + 1 file changed, 12 insertions(+), 13 deletions(-) + +diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c +index b225a78f6175f..9f39bafa7fa96 100644 +--- a/drivers/tty/serial/uartlite.c ++++ b/drivers/tty/serial/uartlite.c +@@ -872,16 +872,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); +@@ -922,16 +912,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.6/tty-vt-make-consw-con_switch-return-a-bool.patch b/queue-6.6/tty-vt-make-consw-con_switch-return-a-bool.patch new file mode 100644 index 0000000000..15172ab136 --- /dev/null +++ b/queue-6.6/tty-vt-make-consw-con_switch-return-a-bool.patch @@ -0,0 +1,193 @@ +From 2044e361fe49521998c2b8421b6cb2a16af2eac0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 22 Jan 2024 12:03:44 +0100 +Subject: tty: vt: make consw::con_switch() return a bool + +From: Jiri Slaby (SUSE) <jirislaby@kernel.org> + +[ Upstream commit 8d5cc8eed738e3202379722295c626cba0849785 ] + +The non-zero (true) return value from consw::con_switch() means a redraw +is needed. So make this return type a bool explicitly instead of int. +The latter might imply that -Eerrors are expected. They are not. + +And document the hook. + +Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org> +Cc: Helge Deller <deller@gmx.de> +Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com> +Cc: Daniel Vetter <daniel@ffwll.ch> +Cc: linux-fbdev@vger.kernel.org +Cc: dri-devel@lists.freedesktop.org +Cc: linux-parisc@vger.kernel.org +Tested-by: Helge Deller <deller@gmx.de> # parisc STI console +Link: https://lore.kernel.org/r/20240122110401.7289-31-jirislaby@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/tty/vt/vt.c | 2 +- + drivers/video/console/dummycon.c | 4 ++-- + drivers/video/console/mdacon.c | 4 ++-- + drivers/video/console/newport_con.c | 4 ++-- + drivers/video/console/sticon.c | 4 ++-- + drivers/video/console/vgacon.c | 4 ++-- + drivers/video/fbdev/core/fbcon.c | 6 +++--- + include/linux/console.h | 4 +++- + 8 files changed, 17 insertions(+), 15 deletions(-) + +diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c +index a368c98c92be3..c5ec7306aa713 100644 +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -962,7 +962,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 55c6106b3507b..63d96c4bbdccd 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 d99c2a659bfd4..87900600eff11 100644 +--- a/drivers/video/console/sticon.c ++++ b/drivers/video/console/sticon.c +@@ -310,9 +310,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 5b5d1c9ef488c..bbc362db40c58 100644 +--- a/drivers/video/console/vgacon.c ++++ b/drivers/video/console/vgacon.c +@@ -585,7 +585,7 @@ static void vgacon_doresize(struct vc_data *c, + raw_spin_unlock_irqrestore(&vga_lock, flags); + } + +-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; +@@ -614,7 +614,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 c14dbb09341fc..9d095fe03e18b 100644 +--- a/drivers/video/fbdev/core/fbcon.c ++++ b/drivers/video/fbdev/core/fbcon.c +@@ -2072,7 +2072,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; +@@ -2194,9 +2194,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 e06cee4923fef..38571607065d7 100644 +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -42,6 +42,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) +@@ -60,7 +62,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 vpitch, unsigned int flags); +-- +2.39.5 + diff --git a/queue-6.6/tty-vt-make-init-parameter-of-consw-con_init-a-bool.patch b/queue-6.6/tty-vt-make-init-parameter-of-consw-con_init-a-bool.patch new file mode 100644 index 0000000000..9cb460d88e --- /dev/null +++ b/queue-6.6/tty-vt-make-init-parameter-of-consw-con_init-a-bool.patch @@ -0,0 +1,190 @@ +From d3f3aeafef8b800161dd225158625499a24779d0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 22 Jan 2024 12:03:34 +0100 +Subject: tty: vt: make init parameter of consw::con_init() a bool + +From: Jiri Slaby (SUSE) <jirislaby@kernel.org> + +[ Upstream commit dae3e6b6180f1a2394b984c596d39ed2c57d25fe ] + +The 'init' parameter of consw::con_init() is true for the first call of +the hook on a particular console. So make the parameter a bool. + +And document the hook. + +Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org> +Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> +Cc: Helge Deller <deller@gmx.de> +Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com> +Cc: Daniel Vetter <daniel@ffwll.ch> +Cc: linux-fbdev@vger.kernel.org +Cc: dri-devel@lists.freedesktop.org +Cc: linux-parisc@vger.kernel.org +Tested-by: Helge Deller <deller@gmx.de> # parisc STI console +Link: https://lore.kernel.org/r/20240122110401.7289-21-jirislaby@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/tty/vt/vt.c | 8 ++++---- + drivers/video/console/dummycon.c | 2 +- + drivers/video/console/mdacon.c | 2 +- + drivers/video/console/newport_con.c | 2 +- + drivers/video/console/sticon.c | 2 +- + drivers/video/console/vgacon.c | 4 ++-- + drivers/video/fbdev/core/fbcon.c | 2 +- + include/linux/console.h | 4 +++- + 8 files changed, 14 insertions(+), 12 deletions(-) + +diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c +index 6bd1a7785e888..83028ccf6e529 100644 +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -999,7 +999,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) +@@ -1083,7 +1083,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); +@@ -3474,7 +3474,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, currcons || !vc->vc_sw->con_save_screen); +@@ -3642,7 +3642,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 e8e4f82cd4a1b..12c64ef470877 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 992a4fa431aaa..0bfeabc3f7c72 100644 +--- a/drivers/video/console/sticon.c ++++ b/drivers/video/console/sticon.c +@@ -273,7 +273,7 @@ static int sticon_font_set(struct vc_data *vc, struct console_font *font, + return sticon_set_font(vc, font, vpitch); + } + +-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 c9ec89649b055..490e157aebdd4 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 75996ef9992e4..9f10a6e92e509 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 7de11c763eb35..4efe76ac56d74 100644 +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -36,6 +36,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. +@@ -46,7 +48,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.6/tty-vt-sanitize-arguments-of-consw-con_clear.patch b/queue-6.6/tty-vt-sanitize-arguments-of-consw-con_clear.patch new file mode 100644 index 0000000000..f8f7180745 --- /dev/null +++ b/queue-6.6/tty-vt-sanitize-arguments-of-consw-con_clear.patch @@ -0,0 +1,313 @@ +From 737c17c96dc0e16fa91426149f8570ffda2cf1ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 22 Jan 2024 12:03:35 +0100 +Subject: tty: vt: sanitize arguments of consw::con_clear() + +From: Jiri Slaby (SUSE) <jirislaby@kernel.org> + +[ Upstream commit 559f01a0ee6d924c6fec3eaf6a5b078b15e71070 ] + +In consw::con_clear(): +* Height is always 1, so drop it. +* Offsets and width are always unsigned values, so re-type them as such. + +This needs a new __fbcon_clear() in the fbcon code to still handle +height which might not be 1 when called internally. + +Note that tests for negative count/width are left in place -- they are +taken care of in the next patches. + +And document the hook. + +Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org> +Cc: Helge Deller <deller@gmx.de> +Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com> +Cc: Daniel Vetter <daniel@ffwll.ch> +Cc: linux-fbdev@vger.kernel.org +Cc: dri-devel@lists.freedesktop.org +Cc: linux-parisc@vger.kernel.org +Tested-by: Helge Deller <deller@gmx.de> # parisc STI console +Link: https://lore.kernel.org/r/20240122110401.7289-22-jirislaby@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/tty/vt/vt.c | 2 +- + drivers/video/console/dummycon.c | 4 ++-- + drivers/video/console/mdacon.c | 15 +++++--------- + drivers/video/console/newport_con.c | 6 +++--- + drivers/video/console/sticon.c | 8 ++++---- + drivers/video/console/vgacon.c | 4 ++-- + drivers/video/fbdev/core/fbcon.c | 32 +++++++++++++++++------------ + include/linux/console.h | 5 +++-- + 8 files changed, 39 insertions(+), 37 deletions(-) + +diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c +index 83028ccf6e529..a368c98c92be3 100644 +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -1582,7 +1582,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 12c64ef470877..55c6106b3507b 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 0bfeabc3f7c72..d99c2a659bfd4 100644 +--- a/drivers/video/console/sticon.c ++++ b/drivers/video/console/sticon.c +@@ -300,13 +300,13 @@ static void sticon_deinit(struct vc_data *c) + sticon_set_def_font(i); + } + +-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 490e157aebdd4..5b5d1c9ef488c 100644 +--- a/drivers/video/console/vgacon.c ++++ b/drivers/video/console/vgacon.c +@@ -1156,8 +1156,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 9f10a6e92e509..c14dbb09341fc 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) + { +@@ -1767,7 +1773,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)), +@@ -1790,7 +1796,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: +@@ -1808,7 +1814,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: +@@ -1831,14 +1837,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, 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)), +@@ -1855,7 +1861,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), +@@ -1878,7 +1884,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: +@@ -1900,7 +1906,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: +@@ -1917,14 +1923,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, 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), +@@ -2203,7 +2209,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 4efe76ac56d74..e06cee4923fef 100644 +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -38,6 +38,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. +@@ -50,8 +51,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.6/uio_hv_generic-align-ring-size-to-system-page.patch b/queue-6.6/uio_hv_generic-align-ring-size-to-system-page.patch new file mode 100644 index 0000000000..fb72055709 --- /dev/null +++ b/queue-6.6/uio_hv_generic-align-ring-size-to-system-page.patch @@ -0,0 +1,41 @@ +From 4d1c0af225f9b971225a385c932ed993b376941e Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 5 May 2025 17:56:35 -0700 +Subject: uio_hv_generic: Align ring size to system page + +From: Long Li <longli@microsoft.com> + +[ Upstream commit 0315fef2aff9f251ddef8a4b53db9187429c3553 ] + +Following the ring header, the ring data should align to system page +boundary. Adjust the size if necessary. + +Cc: stable@vger.kernel.org +Fixes: 95096f2fbd10 ("uio-hv-generic: new userspace i/o driver for VMBus") +Signed-off-by: Long Li <longli@microsoft.com> +Reviewed-by: Michael Kelley <mhklinux@outlook.com> +Link: https://lore.kernel.org/r/1746492997-4599-4-git-send-email-longli@linuxonhyperv.com +Signed-off-by: Wei Liu <wei.liu@kernel.org> +Message-ID: <1746492997-4599-4-git-send-email-longli@linuxonhyperv.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/uio/uio_hv_generic.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c +index 031f6a8f1ebb2..17c1f85f2b7ba 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.6/uio_hv_generic-query-the-ringbuffer-size-for-device.patch b/queue-6.6/uio_hv_generic-query-the-ringbuffer-size-for-device.patch new file mode 100644 index 0000000000..6269033750 --- /dev/null +++ b/queue-6.6/uio_hv_generic-query-the-ringbuffer-size-for-device.patch @@ -0,0 +1,56 @@ +From 6c8f8d0f060d6e5e720df713ba6fae29f453ba4a Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sat, 30 Mar 2024 01:51:58 -0700 +Subject: uio_hv_generic: Query the ringbuffer size for device + +From: Saurabh Sengar <ssengar@linux.microsoft.com> + +[ Upstream commit e566ed5b64177a0c07b677568f623ed31d23406d ] + +Query the ring buffer size from pre defined table per device +and use that value for allocating the ring buffer for that +device. Keep the size as current default which is 2 MB if +the device doesn't have any preferred ring size. + +Signed-off-by: Saurabh Sengar <ssengar@linux.microsoft.com> +Reviewed-by: Long Li <longli@microsoft.com> +Link: https://lore.kernel.org/r/1711788723-8593-3-git-send-email-ssengar@linux.microsoft.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Stable-dep-of: 0315fef2aff9 ("uio_hv_generic: Align ring size to system page") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/uio/uio_hv_generic.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c +index 2804a4f749750..031f6a8f1ebb2 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.6/um-add-cmpxchg8b_emu-and-checksum-functions-to-asm-p.patch b/queue-6.6/um-add-cmpxchg8b_emu-and-checksum-functions-to-asm-p.patch new file mode 100644 index 0000000000..2636a9ef2d --- /dev/null +++ b/queue-6.6/um-add-cmpxchg8b_emu-and-checksum-functions-to-asm-p.patch @@ -0,0 +1,55 @@ +From 475e51bd8ffa66477dc626d5ba50239973c90366 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Wed, 26 Mar 2025 19:05:00 +0000 +Subject: um: Add cmpxchg8b_emu and checksum functions to asm-prototypes.h + +From: Sami Tolvanen <samitolvanen@google.com> + +[ Upstream commit 674d03f6bd6b0f8327f1a4920ff5893557facfbd ] + +With CONFIG_GENDWARFKSYMS, um builds fail due to missing prototypes +in asm/asm-prototypes.h. Add declarations for cmpxchg8b_emu and the +exported checksum functions, including csum_partial_copy_generic as +it's also exported. + +Cc: Masahiro Yamada <masahiroy@kernel.org> +Cc: linux-kbuild@vger.kernel.org +Reported-by: kernel test robot <lkp@intel.com> +Closes: https://lore.kernel.org/oe-kbuild-all/202503251216.lE4t9Ikj-lkp@intel.com/ +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +Link: https://patch.msgid.link/20250326190500.847236-2-samitolvanen@google.com +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + arch/um/include/asm/asm-prototypes.h | 5 +++++ + arch/x86/um/asm/checksum.h | 3 +++ + 2 files changed, 8 insertions(+) + +diff --git a/arch/um/include/asm/asm-prototypes.h b/arch/um/include/asm/asm-prototypes.h +index 5898a26daa0dd..408b31d591279 100644 +--- a/arch/um/include/asm/asm-prototypes.h ++++ b/arch/um/include/asm/asm-prototypes.h +@@ -1 +1,6 @@ + #include <asm-generic/asm-prototypes.h> ++#include <asm/checksum.h> ++ ++#ifdef CONFIG_UML_X86 ++extern void cmpxchg8b_emu(void); ++#endif +diff --git a/arch/x86/um/asm/checksum.h b/arch/x86/um/asm/checksum.h +index b07824500363f..ddc144657efad 100644 +--- a/arch/x86/um/asm/checksum.h ++++ b/arch/x86/um/asm/checksum.h +@@ -20,6 +20,9 @@ + */ + extern __wsum csum_partial(const void *buff, int len, __wsum sum); + ++/* Do not call this directly. Declared for export type visibility. */ ++extern __visible __wsum csum_partial_copy_generic(const void *src, void *dst, int len); ++ + /** + * csum_fold - Fold and invert a 32bit checksum. + * sum: 32bit unfolded sum +-- +2.39.5 + diff --git a/queue-6.6/um-use-proper-care-when-taking-mmap-lock-during-segf.patch b/queue-6.6/um-use-proper-care-when-taking-mmap-lock-during-segf.patch new file mode 100644 index 0000000000..8ef59dabfb --- /dev/null +++ b/queue-6.6/um-use-proper-care-when-taking-mmap-lock-during-segf.patch @@ -0,0 +1,177 @@ +From c6e23a01bbbfefaee8ae4a83810fda51d5a040d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 8 Apr 2025 09:45:24 +0200 +Subject: um: use proper care when taking mmap lock during segfault + +From: Benjamin Berg <benjamin.berg@intel.com> + +[ Upstream commit 6767e8784cd2e8b386a62330ea6864949d983a3e ] + +Segfaults can occur at times where the mmap lock cannot be taken. If +that happens the segfault handler may not be able to take the mmap lock. + +Fix the code to use the same approach as most other architectures. +Unfortunately, this requires copying code from mm/memory.c and modifying +it slightly as UML does not have exception tables. + +Signed-off-by: Benjamin Berg <benjamin.berg@intel.com> +Link: https://patch.msgid.link/20250408074524.300153-2-benjamin@sipsolutions.net +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + arch/um/kernel/trap.c | 129 ++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 117 insertions(+), 12 deletions(-) + +diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c +index 6d8ae86ae978f..c16b80011adaa 100644 +--- a/arch/um/kernel/trap.c ++++ b/arch/um/kernel/trap.c +@@ -17,6 +17,122 @@ + #include <os.h> + #include <skas.h> + ++/* ++ * NOTE: UML does not have exception tables. As such, this is almost a copy ++ * of the code in mm/memory.c, only adjusting the logic to simply check whether ++ * we are coming from the kernel instead of doing an additional lookup in the ++ * exception table. ++ * We can do this simplification because we never get here if the exception was ++ * fixable. ++ */ ++static inline bool get_mmap_lock_carefully(struct mm_struct *mm, bool is_user) ++{ ++ if (likely(mmap_read_trylock(mm))) ++ return true; ++ ++ if (!is_user) ++ return false; ++ ++ return !mmap_read_lock_killable(mm); ++} ++ ++static inline bool mmap_upgrade_trylock(struct mm_struct *mm) ++{ ++ /* ++ * We don't have this operation yet. ++ * ++ * It should be easy enough to do: it's basically a ++ * atomic_long_try_cmpxchg_acquire() ++ * from RWSEM_READER_BIAS -> RWSEM_WRITER_LOCKED, but ++ * it also needs the proper lockdep magic etc. ++ */ ++ return false; ++} ++ ++static inline bool upgrade_mmap_lock_carefully(struct mm_struct *mm, bool is_user) ++{ ++ mmap_read_unlock(mm); ++ if (!is_user) ++ return false; ++ ++ return !mmap_write_lock_killable(mm); ++} ++ ++/* ++ * Helper for page fault handling. ++ * ++ * This is kind of equivalend to "mmap_read_lock()" followed ++ * by "find_extend_vma()", except it's a lot more careful about ++ * the locking (and will drop the lock on failure). ++ * ++ * For example, if we have a kernel bug that causes a page ++ * fault, we don't want to just use mmap_read_lock() to get ++ * the mm lock, because that would deadlock if the bug were ++ * to happen while we're holding the mm lock for writing. ++ * ++ * So this checks the exception tables on kernel faults in ++ * order to only do this all for instructions that are actually ++ * expected to fault. ++ * ++ * We can also actually take the mm lock for writing if we ++ * need to extend the vma, which helps the VM layer a lot. ++ */ ++static struct vm_area_struct * ++um_lock_mm_and_find_vma(struct mm_struct *mm, ++ unsigned long addr, bool is_user) ++{ ++ struct vm_area_struct *vma; ++ ++ if (!get_mmap_lock_carefully(mm, is_user)) ++ return NULL; ++ ++ vma = find_vma(mm, addr); ++ if (likely(vma && (vma->vm_start <= addr))) ++ return vma; ++ ++ /* ++ * Well, dang. We might still be successful, but only ++ * if we can extend a vma to do so. ++ */ ++ if (!vma || !(vma->vm_flags & VM_GROWSDOWN)) { ++ mmap_read_unlock(mm); ++ return NULL; ++ } ++ ++ /* ++ * We can try to upgrade the mmap lock atomically, ++ * in which case we can continue to use the vma ++ * we already looked up. ++ * ++ * Otherwise we'll have to drop the mmap lock and ++ * re-take it, and also look up the vma again, ++ * re-checking it. ++ */ ++ if (!mmap_upgrade_trylock(mm)) { ++ if (!upgrade_mmap_lock_carefully(mm, is_user)) ++ return NULL; ++ ++ vma = find_vma(mm, addr); ++ if (!vma) ++ goto fail; ++ if (vma->vm_start <= addr) ++ goto success; ++ if (!(vma->vm_flags & VM_GROWSDOWN)) ++ goto fail; ++ } ++ ++ if (expand_stack_locked(vma, addr)) ++ goto fail; ++ ++success: ++ mmap_write_downgrade(mm); ++ return vma; ++ ++fail: ++ mmap_write_unlock(mm); ++ return NULL; ++} ++ + /* + * Note this is constrained to return 0, -EFAULT, -EACCES, -ENOMEM by + * segv(). +@@ -43,21 +159,10 @@ int handle_page_fault(unsigned long address, unsigned long ip, + if (is_user) + flags |= FAULT_FLAG_USER; + retry: +- mmap_read_lock(mm); +- vma = find_vma(mm, address); +- if (!vma) +- goto out; +- if (vma->vm_start <= address) +- goto good_area; +- if (!(vma->vm_flags & VM_GROWSDOWN)) +- goto out; +- if (is_user && !ARCH_IS_STACKGROW(address)) +- goto out; +- vma = expand_stack(mm, address); ++ vma = um_lock_mm_and_find_vma(mm, address, is_user); + if (!vma) + goto out_nosemaphore; + +-good_area: + *code_out = SEGV_ACCERR; + if (is_write) { + if (!(vma->vm_flags & VM_WRITE)) +-- +2.39.5 + diff --git a/queue-6.6/usb-add-checks-for-snprintf-calls-in-usb_alloc_dev.patch b/queue-6.6/usb-add-checks-for-snprintf-calls-in-usb_alloc_dev.patch new file mode 100644 index 0000000000..34be30ca8b --- /dev/null +++ b/queue-6.6/usb-add-checks-for-snprintf-calls-in-usb_alloc_dev.patch @@ -0,0 +1,72 @@ +From 6153866166a7076bc54fce76f94082434356e493 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 21 Mar 2025 18:49:49 +0200 +Subject: usb: Add checks for snprintf() calls in usb_alloc_dev() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> + +[ Upstream commit 82fe5107fa3d21d6c3fba091c9dbc50495588630 ] + +When creating a device path in the driver the snprintf() takes +up to 16 characters long argument along with the additional up to +12 characters for the signed integer (as it can't see the actual limits) +and tries to pack this into 16 bytes array. GCC complains about that +when build with `make W=1`: + + drivers/usb/core/usb.c:705:25: note: ‘snprintf’ output between 3 and 28 bytes into a destination of size 16 + +Since everything works until now, let's just check for the potential +buffer overflow and bail out. It is most likely a never happen situation, +but at least it makes GCC happy. + +Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +Link: https://lore.kernel.org/r/20250321164949.423957-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/usb/core/usb.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c +index 2a938cf47ccd6..da6d5e5f79e7a 100644 +--- a/drivers/usb/core/usb.c ++++ b/drivers/usb/core/usb.c +@@ -695,15 +695,16 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, + device_set_of_node_from_dev(&dev->dev, bus->sysdev); + dev_set_name(&dev->dev, "usb%d", bus->busnum); + } 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 + +@@ -712,6 +713,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.6/usb-cdc-wdm-avoid-setting-wdm_read-for-zlp-s.patch b/queue-6.6/usb-cdc-wdm-avoid-setting-wdm_read-for-zlp-s.patch new file mode 100644 index 0000000000..1767e55f1b --- /dev/null +++ b/queue-6.6/usb-cdc-wdm-avoid-setting-wdm_read-for-zlp-s.patch @@ -0,0 +1,114 @@ +From 81fb78fe7f9b4ad3e6e0780ba3b8ed423a1377c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Thu, 3 Apr 2025 16:40:04 +0200 +Subject: usb: cdc-wdm: avoid setting WDM_READ for ZLP-s + +From: Robert Hodaszi <robert.hodaszi@digi.com> + +[ Upstream commit 387602d8a75574fafb451b7a8215e78dfd67ee63 ] + +Don't set WDM_READ flag in wdm_in_callback() for ZLP-s, otherwise when +userspace tries to poll for available data, it might - incorrectly - +believe there is something available, and when it tries to non-blocking +read it, it might get stuck in the read loop. + +For example this is what glib does for non-blocking read (briefly): + + 1. poll() + 2. if poll returns with non-zero, starts a read data loop: + a. loop on poll() (EINTR disabled) + b. if revents was set, reads data + I. if read returns with EINTR or EAGAIN, goto 2.a. + II. otherwise return with data + +So if ZLP sets WDM_READ (#1), we expect data, and try to read it (#2). +But as that was a ZLP, and we are doing non-blocking read, wdm_read() +returns with EAGAIN (#2.b.I), so loop again, and try to read again +(#2.a.). + +With glib, we might stuck in this loop forever, as EINTR is disabled +(#2.a). + +Signed-off-by: Robert Hodaszi <robert.hodaszi@digi.com> +Acked-by: Oliver Neukum <oneukum@suse.com> +Link: https://lore.kernel.org/r/20250403144004.3889125-1-robert.hodaszi@digi.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/usb/class/cdc-wdm.c | 23 +++++++++-------------- + 1 file changed, 9 insertions(+), 14 deletions(-) + +diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c +index 559c121f09230..600ad9412c146 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); + } +@@ -1016,7 +1011,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.6/usb-common-usb-conn-gpio-use-a-unique-name-for-usb-c.patch b/queue-6.6/usb-common-usb-conn-gpio-use-a-unique-name-for-usb-c.patch new file mode 100644 index 0000000000..c361bbbbef --- /dev/null +++ b/queue-6.6/usb-common-usb-conn-gpio-use-a-unique-name-for-usb-c.patch @@ -0,0 +1,93 @@ +From eadd2ed522200236a5979bcf07efa3ae6c28c839 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 11 Apr 2025 16:33:26 +0800 +Subject: usb: common: usb-conn-gpio: use a unique name for usb connector + device + +From: Chance Yang <chance.yang@kneron.us> + +[ Upstream commit d4e5b10c55627e2f3fc9e5b337a28b4e2f02a55e ] + +The current implementation of the usb-conn-gpio driver uses a fixed +"usb-charger" name for all USB connector devices. This causes conflicts +in the power supply subsystem when multiple USB connectors are present, +as duplicate names are not allowed. + +Use IDA to manage unique IDs for naming usb connectors (e.g., +usb-charger-0, usb-charger-1). + +Signed-off-by: Chance Yang <chance.yang@kneron.us> +Link: https://lore.kernel.org/r/20250411-work-next-v3-1-7cd9aa80190c@kneron.us +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/usb/common/usb-conn-gpio.c | 25 ++++++++++++++++++++++--- + 1 file changed, 22 insertions(+), 3 deletions(-) + +diff --git a/drivers/usb/common/usb-conn-gpio.c b/drivers/usb/common/usb-conn-gpio.c +index 501e8bc9738eb..1096a884c8d70 100644 +--- a/drivers/usb/common/usb-conn-gpio.c ++++ b/drivers/usb/common/usb-conn-gpio.c +@@ -20,6 +20,9 @@ + #include <linux/power_supply.h> + #include <linux/regulator/consumer.h> + #include <linux/usb/role.h> ++#include <linux/idr.h> ++ ++static DEFINE_IDA(usb_conn_ida); + + #define USB_GPIO_DEB_MS 20 /* ms */ + #define USB_GPIO_DEB_US ((USB_GPIO_DEB_MS) * 1000) /* us */ +@@ -29,6 +32,7 @@ + + struct usb_conn_info { + struct device *dev; ++ int conn_id; /* store the IDA-allocated ID */ + struct usb_role_switch *role_sw; + enum usb_role last_role; + struct regulator *vbus; +@@ -160,7 +164,17 @@ static int usb_conn_psy_register(struct usb_conn_info *info) + .of_node = dev->of_node, + }; + +- desc->name = "usb-charger"; ++ info->conn_id = ida_alloc(&usb_conn_ida, GFP_KERNEL); ++ if (info->conn_id < 0) ++ return info->conn_id; ++ ++ desc->name = devm_kasprintf(dev, GFP_KERNEL, "usb-charger-%d", ++ info->conn_id); ++ if (!desc->name) { ++ ida_free(&usb_conn_ida, info->conn_id); ++ return -ENOMEM; ++ } ++ + desc->properties = usb_charger_properties; + desc->num_properties = ARRAY_SIZE(usb_charger_properties); + desc->get_property = usb_charger_get_property; +@@ -168,8 +182,10 @@ static int usb_conn_psy_register(struct usb_conn_info *info) + cfg.drv_data = info; + + info->charger = devm_power_supply_register(dev, desc, &cfg); +- if (IS_ERR(info->charger)) +- dev_err(dev, "Unable to register charger\n"); ++ if (IS_ERR(info->charger)) { ++ dev_err(dev, "Unable to register charger %d\n", info->conn_id); ++ ida_free(&usb_conn_ida, info->conn_id); ++ } + + return PTR_ERR_OR_ZERO(info->charger); + } +@@ -277,6 +293,9 @@ static void 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.6/usb-dwc2-also-exit-clock_gating-when-stopping-udc-wh.patch b/queue-6.6/usb-dwc2-also-exit-clock_gating-when-stopping-udc-wh.patch new file mode 100644 index 0000000000..b53c7d261b --- /dev/null +++ b/queue-6.6/usb-dwc2-also-exit-clock_gating-when-stopping-udc-wh.patch @@ -0,0 +1,47 @@ +From 6a5e7c965ccc2a9ffa65cfc09cf7676b2ccf809d Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Thu, 17 Apr 2025 19:40:17 +0200 +Subject: usb: dwc2: also exit clock_gating when stopping udc while suspended + +From: Michael Grzeschik <m.grzeschik@pengutronix.de> + +[ Upstream commit af076a41f8a28faf9ceb9dd2d88aef2c202ef39a ] + +It is possible that the gadget will be disabled, while the udc is +suspended. When enabling the udc in that case, the clock gating +will not be enabled again. Leaving the phy unclocked. Even when the +udc is not enabled, connecting this powered but not clocked phy leads +to enumeration errors on the host side. + +To ensure that the clock gating will be in an valid state, we ensure +that the clock gating will be enabled before stopping the udc. + +Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de> +Acked-by: Minas Harutyunyan <hminas@synopsys.com> +Link: https://lore.kernel.org/r/20250417-dwc2_clock_gating-v1-1-8ea7c4d53d73@pengutronix.de +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/usb/dwc2/gadget.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c +index ce20c06a90253..c0db3c52831a2 100644 +--- a/drivers/usb/dwc2/gadget.c ++++ b/drivers/usb/dwc2/gadget.c +@@ -4601,6 +4601,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.6/usb-potential-integer-overflow-in-usbg_make_tpg.patch b/queue-6.6/usb-potential-integer-overflow-in-usbg_make_tpg.patch new file mode 100644 index 0000000000..5553012887 --- /dev/null +++ b/queue-6.6/usb-potential-integer-overflow-in-usbg_make_tpg.patch @@ -0,0 +1,53 @@ +From d501af7d82edd9be62e1453a46a4bb6891c37574 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 15 Apr 2025 14:58:57 +0800 +Subject: usb: potential integer overflow in usbg_make_tpg() + +From: Chen Yufeng <chenyufeng@iie.ac.cn> + +[ Upstream commit 153874010354d050f62f8ae25cbb960c17633dc5 ] + +The variable tpgt in usbg_make_tpg() is defined as unsigned long and is +assigned to tpgt->tport_tpgt, which is defined as u16. This may cause an +integer overflow when tpgt is greater than USHRT_MAX (65535). I +haven't tried to trigger it myself, but it is possible to trigger it +by calling usbg_make_tpg() with a large value for tpgt. + +I modified the type of tpgt to match tpgt->tport_tpgt and adjusted the +relevant code accordingly. + +This patch is similar to commit 59c816c1f24d ("vhost/scsi: potential +memory corruption"). + +Signed-off-by: Chen Yufeng <chenyufeng@iie.ac.cn> +Link: https://lore.kernel.org/r/20250415065857.1619-1-chenyufeng@iie.ac.cn +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/usb/gadget/function/f_tcm.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c +index a7cd0a06879e6..5d0d894953953 100644 +--- a/drivers/usb/gadget/function/f_tcm.c ++++ b/drivers/usb/gadget/function/f_tcm.c +@@ -1297,14 +1297,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.6/usb-typec-displayport-receive-dp-status-update-nak-r.patch b/queue-6.6/usb-typec-displayport-receive-dp-status-update-nak-r.patch new file mode 100644 index 0000000000..67fe32f600 --- /dev/null +++ b/queue-6.6/usb-typec-displayport-receive-dp-status-update-nak-r.patch @@ -0,0 +1,56 @@ +From 5ed2982d2c11dffa4fdb1b4eca7f408daaf4199b Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sun, 9 Feb 2025 15:19:26 +0800 +Subject: usb: typec: displayport: Receive DP Status Update NAK request exit dp + altmode +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jos Wang <joswang@lenovo.com> + +[ Upstream commit b4b38ffb38c91afd4dc387608db26f6fc34ed40b ] + +Although some Type-C DRD devices that do not support the DP Sink +function (such as Huawei Mate 40Pro), the Source Port initiates +Enter Mode CMD, but the device responds to Enter Mode ACK, the +Source port then initiates DP Status Update CMD, and the device +responds to DP Status Update NAK. + +As PD2.0 spec ("6.4.4.3.4 Enter Mode Command"),A DR_Swap Message +Shall Not be sent during Modal Operation between the Port Partners. +At this time, the source port initiates DR_Swap message through the +"echo device > /sys/class/typec/port0/data_role" command to switch +the data role from host to device. The device will initiate a Hard +Reset for recovery, resulting in the failure of data role swap. + +Therefore, when DP Status Update NAK is received, Exit Mode CMD is +initiated to exit the currently entered DP altmode. + +Signed-off-by: Jos Wang <joswang@lenovo.com> +Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> +Link: https://lore.kernel.org/r/20250209071926.69625-1-joswang1221@gmail.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/usb/typec/altmodes/displayport.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c +index ccff838ab89e1..5f6fc5b79212e 100644 +--- a/drivers/usb/typec/altmodes/displayport.c ++++ b/drivers/usb/typec/altmodes/displayport.c +@@ -323,6 +323,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.6/usb-typec-mux-do-not-return-on-eopnotsupp-in-mux-swi.patch b/queue-6.6/usb-typec-mux-do-not-return-on-eopnotsupp-in-mux-swi.patch new file mode 100644 index 0000000000..0c62e413fc --- /dev/null +++ b/queue-6.6/usb-typec-mux-do-not-return-on-eopnotsupp-in-mux-swi.patch @@ -0,0 +1,52 @@ +From 3003104edecc0ce5f77ffb4942d4f38f9ce1e95c Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 4 Apr 2025 00:21:01 +0200 +Subject: usb: typec: mux: do not return on EOPNOTSUPP in {mux, switch}_set + +From: Michael Grzeschik <m.grzeschik@pengutronix.de> + +[ Upstream commit 0f7bbef1794dc87141897f804e5871a293aa174b ] + +Since the typec connectors can have many muxes or switches for different +lanes (sbu, usb2, usb3) going into different modal states (usb2, usb3, +audio, debug) all of them will be called on typec_switch_set and +typec_mux_set. But not all of them will be handling the expected mode. + +If one of the mux or switch will come back with EOPTNOSUPP this is no +reason to stop running through the next ones. Therefor we skip this +particular error value and continue calling the next. + +Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de> +Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> +Link: https://lore.kernel.org/r/20250404-ml-topic-typec-mux-v1-1-22c0526381ba@pengutronix.de +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/usb/typec/mux.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c +index 80dd91938d960..a5b2a6f9c5795 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; + } + +@@ -378,7 +378,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 + |