From acc97866c1eae4d7704a67c2fb02c6b3429b254e Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:11 +0000 Subject: [PATCH 001/971] af_unix: Try to run GC async. commit d9f21b3613337b55cc9d4a6ead484dca68475143 upstream. If more than 16000 inflight AF_UNIX sockets exist and the garbage collector is not running, unix_(dgram|stream)_sendmsg() call unix_gc(). Also, they wait for unix_gc() to complete. In unix_gc(), all inflight AF_UNIX sockets are traversed at least once, and more if they are the GC candidate. Thus, sendmsg() significantly slows down with too many inflight AF_UNIX sockets. However, if a process sends data with no AF_UNIX FD, the sendmsg() call does not need to wait for GC. After this change, only the process that meets the condition below will be blocked under such a situation. 1) cmsg contains AF_UNIX socket 2) more than 32 AF_UNIX sent by the same user are still inflight Note that even a sendmsg() call that does not meet the condition but has AF_UNIX FD will be blocked later in unix_scm_to_skb() by the spinlock, but we allow that as a bonus for sane users. The results below are the time spent in unix_dgram_sendmsg() sending 1 byte of data with no FD 4096 times on a host where 32K inflight AF_UNIX sockets exist. Without series: the sane sendmsg() needs to wait gc unreasonably. $ sudo /usr/share/bcc/tools/funclatency -p 11165 unix_dgram_sendmsg Tracing 1 functions for "unix_dgram_sendmsg"... Hit Ctrl-C to end. ^C nsecs : count distribution [...] 524288 -> 1048575 : 0 | | 1048576 -> 2097151 : 3881 |****************************************| 2097152 -> 4194303 : 214 |** | 4194304 -> 8388607 : 1 | | avg = 1825567 nsecs, total: 7477526027 nsecs, count: 4096 With series: the sane sendmsg() can finish much faster. $ sudo /usr/share/bcc/tools/funclatency -p 8702 unix_dgram_sendmsg Tracing 1 functions for "unix_dgram_sendmsg"... Hit Ctrl-C to end. ^C nsecs : count distribution [...] 128 -> 255 : 0 | | 256 -> 511 : 4092 |****************************************| 512 -> 1023 : 2 | | 1024 -> 2047 : 0 | | 2048 -> 4095 : 0 | | 4096 -> 8191 : 1 | | 8192 -> 16383 : 1 | | avg = 410 nsecs, total: 1680510 nsecs, count: 4096 Signed-off-by: Kuniyuki Iwashima Link: https://lore.kernel.org/r/20240123170856.41348-6-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- include/net/af_unix.h | 12 ++++++++++-- include/net/scm.h | 1 + net/core/scm.c | 5 +++++ net/unix/af_unix.c | 6 ++++-- net/unix/garbage.c | 10 +++++++++- 5 files changed, 29 insertions(+), 5 deletions(-) diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 7a00d7ed527b..865e2f7bd67c 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -8,13 +8,21 @@ #include #include +#if IS_ENABLED(CONFIG_UNIX) +struct unix_sock *unix_get_socket(struct file *filp); +#else +static inline struct unix_sock *unix_get_socket(struct file *filp) +{ + return NULL; +} +#endif + void unix_inflight(struct user_struct *user, struct file *fp); void unix_notinflight(struct user_struct *user, struct file *fp); void unix_destruct_scm(struct sk_buff *skb); void io_uring_destruct_scm(struct sk_buff *skb); void unix_gc(void); -void wait_for_unix_gc(void); -struct unix_sock *unix_get_socket(struct file *filp); +void wait_for_unix_gc(struct scm_fp_list *fpl); struct sock *unix_peer_get(struct sock *sk); #define UNIX_HASH_MOD (256 - 1) diff --git a/include/net/scm.h b/include/net/scm.h index e8c76b4be2fe..1ff6a2855064 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -24,6 +24,7 @@ struct scm_creds { struct scm_fp_list { short count; + short count_unix; short max; struct user_struct *user; struct file *fp[SCM_MAX_FD]; diff --git a/net/core/scm.c b/net/core/scm.c index 737917c7ac62..574607b1c2d9 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -36,6 +36,7 @@ #include #include #include +#include /* @@ -85,6 +86,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp) return -ENOMEM; *fplp = fpl; fpl->count = 0; + fpl->count_unix = 0; fpl->max = SCM_MAX_FD; fpl->user = NULL; } @@ -109,6 +111,9 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp) fput(file); return -EINVAL; } + if (unix_get_socket(file)) + fpl->count_unix++; + *fpp++ = file; fpl->count++; } diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index ab23c8d72122..bb92b1ed94aa 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1885,11 +1885,12 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, long timeo; int err; - wait_for_unix_gc(); err = scm_send(sock, msg, &scm, false); if (err < 0) return err; + wait_for_unix_gc(scm.fp); + err = -EOPNOTSUPP; if (msg->msg_flags&MSG_OOB) goto out; @@ -2157,11 +2158,12 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg, bool fds_sent = false; int data_len; - wait_for_unix_gc(); err = scm_send(sock, msg, &scm, false); if (err < 0) return err; + wait_for_unix_gc(scm.fp); + err = -EOPNOTSUPP; if (msg->msg_flags & MSG_OOB) { #if IS_ENABLED(CONFIG_AF_UNIX_OOB) diff --git a/net/unix/garbage.c b/net/unix/garbage.c index a2a8543613a5..96cc6b767433 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -335,8 +335,9 @@ void unix_gc(void) } #define UNIX_INFLIGHT_TRIGGER_GC 16000 +#define UNIX_INFLIGHT_SANE_USER (SCM_MAX_FD * 8) -void wait_for_unix_gc(void) +void wait_for_unix_gc(struct scm_fp_list *fpl) { /* If number of inflight sockets is insane, * force a garbage collect right now. @@ -348,6 +349,13 @@ void wait_for_unix_gc(void) !READ_ONCE(gc_in_progress)) unix_gc(); + /* Penalise users who want to send AF_UNIX sockets + * but whose sockets have not been received yet. + */ + if (!fpl || !fpl->count_unix || + READ_ONCE(fpl->user->unix_inflight) < UNIX_INFLIGHT_SANE_USER) + return; + if (READ_ONCE(gc_in_progress)) flush_work(&unix_gc_work); } From 36f1f6ac53889b2ca8ee2d8e4345a96ac814cef7 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:12 +0000 Subject: [PATCH 002/971] af_unix: Replace BUG_ON() with WARN_ON_ONCE(). commit d0f6dc26346863e1f4a23117f5468614e54df064 upstream. This is a prep patch for the last patch in this series so that checkpatch will not warn about BUG_ON(). Signed-off-by: Kuniyuki Iwashima Acked-by: Jens Axboe Link: https://lore.kernel.org/r/20240129190435.57228-2-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- net/unix/garbage.c | 8 ++++---- net/unix/scm.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 96cc6b767433..b4bf7f753882 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -145,7 +145,7 @@ static void scan_children(struct sock *x, void (*func)(struct unix_sock *), /* An embryo cannot be in-flight, so it's safe * to use the list link. */ - BUG_ON(!list_empty(&u->link)); + WARN_ON_ONCE(!list_empty(&u->link)); list_add_tail(&u->link, &embryos); } spin_unlock(&x->sk_receive_queue.lock); @@ -224,8 +224,8 @@ static void __unix_gc(struct work_struct *work) total_refs = file_count(sk->sk_socket->file); - BUG_ON(!u->inflight); - BUG_ON(total_refs < u->inflight); + WARN_ON_ONCE(!u->inflight); + WARN_ON_ONCE(total_refs < u->inflight); if (total_refs == u->inflight) { list_move_tail(&u->link, &gc_candidates); __set_bit(UNIX_GC_CANDIDATE, &u->gc_flags); @@ -318,7 +318,7 @@ static void __unix_gc(struct work_struct *work) list_move_tail(&u->link, &gc_inflight_list); /* All candidates should have been detached by now. */ - BUG_ON(!list_empty(&gc_candidates)); + WARN_ON_ONCE(!list_empty(&gc_candidates)); /* Paired with READ_ONCE() in wait_for_unix_gc(). */ WRITE_ONCE(gc_in_progress, false); diff --git a/net/unix/scm.c b/net/unix/scm.c index b5ae5ab16777..505e56cf02a2 100644 --- a/net/unix/scm.c +++ b/net/unix/scm.c @@ -51,10 +51,10 @@ void unix_inflight(struct user_struct *user, struct file *fp) if (u) { if (!u->inflight) { - BUG_ON(!list_empty(&u->link)); + WARN_ON_ONCE(!list_empty(&u->link)); list_add_tail(&u->link, &gc_inflight_list); } else { - BUG_ON(list_empty(&u->link)); + WARN_ON_ONCE(list_empty(&u->link)); } u->inflight++; /* Paired with READ_ONCE() in wait_for_unix_gc() */ @@ -71,8 +71,8 @@ void unix_notinflight(struct user_struct *user, struct file *fp) spin_lock(&unix_gc_lock); if (u) { - BUG_ON(!u->inflight); - BUG_ON(list_empty(&u->link)); + WARN_ON_ONCE(!u->inflight); + WARN_ON_ONCE(list_empty(&u->link)); u->inflight--; if (!u->inflight) From c0d56c028d90f9d371de067a5653fba8be780c72 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:13 +0000 Subject: [PATCH 003/971] af_unix: Remove io_uring code for GC. commit 11498715f266a3fb4caabba9dd575636cbcaa8f1 upstream. Since commit 705318a99a13 ("io_uring/af_unix: disable sending io_uring over sockets"), io_uring's unix socket cannot be passed via SCM_RIGHTS, so it does not contribute to cyclic reference and no longer be candidate for garbage collection. Also, commit 6e5e6d274956 ("io_uring: drop any code related to SCM_RIGHTS") cleaned up SCM_RIGHTS code in io_uring. Let's do it in AF_UNIX as well by reverting commit 0091bfc81741 ("io_uring/af_unix: defer registered files gc to io_uring release") and commit 10369080454d ("net: reclaim skb->scm_io_uring bit"). Signed-off-by: Kuniyuki Iwashima Acked-by: Jens Axboe Link: https://lore.kernel.org/r/20240129190435.57228-3-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- include/net/af_unix.h | 1 - net/unix/garbage.c | 25 ++----------------------- net/unix/scm.c | 6 ------ 3 files changed, 2 insertions(+), 30 deletions(-) diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 865e2f7bd67c..4d35204c0857 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -20,7 +20,6 @@ static inline struct unix_sock *unix_get_socket(struct file *filp) void unix_inflight(struct user_struct *user, struct file *fp); void unix_notinflight(struct user_struct *user, struct file *fp); void unix_destruct_scm(struct sk_buff *skb); -void io_uring_destruct_scm(struct sk_buff *skb); void unix_gc(void); void wait_for_unix_gc(struct scm_fp_list *fpl); struct sock *unix_peer_get(struct sock *sk); diff --git a/net/unix/garbage.c b/net/unix/garbage.c index b4bf7f753882..c04f82489abb 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -184,12 +184,10 @@ static bool gc_in_progress; static void __unix_gc(struct work_struct *work) { - struct sk_buff *next_skb, *skb; - struct unix_sock *u; - struct unix_sock *next; struct sk_buff_head hitlist; - struct list_head cursor; + struct unix_sock *u, *next; LIST_HEAD(not_cycle_list); + struct list_head cursor; spin_lock(&unix_gc_lock); @@ -293,30 +291,11 @@ static void __unix_gc(struct work_struct *work) spin_unlock(&unix_gc_lock); - /* We need io_uring to clean its registered files, ignore all io_uring - * originated skbs. It's fine as io_uring doesn't keep references to - * other io_uring instances and so killing all other files in the cycle - * will put all io_uring references forcing it to go through normal - * release.path eventually putting registered files. - */ - skb_queue_walk_safe(&hitlist, skb, next_skb) { - if (skb->destructor == io_uring_destruct_scm) { - __skb_unlink(skb, &hitlist); - skb_queue_tail(&skb->sk->sk_receive_queue, skb); - } - } - /* Here we are. Hitlist is filled. Die. */ __skb_queue_purge(&hitlist); spin_lock(&unix_gc_lock); - /* There could be io_uring registered files, just push them back to - * the inflight list - */ - list_for_each_entry_safe(u, next, &gc_candidates, link) - list_move_tail(&u->link, &gc_inflight_list); - /* All candidates should have been detached by now. */ WARN_ON_ONCE(!list_empty(&gc_candidates)); diff --git a/net/unix/scm.c b/net/unix/scm.c index 505e56cf02a2..db65b0ab5947 100644 --- a/net/unix/scm.c +++ b/net/unix/scm.c @@ -148,9 +148,3 @@ void unix_destruct_scm(struct sk_buff *skb) sock_wfree(skb); } EXPORT_SYMBOL(unix_destruct_scm); - -void io_uring_destruct_scm(struct sk_buff *skb) -{ - unix_destruct_scm(skb); -} -EXPORT_SYMBOL(io_uring_destruct_scm); From 8eb55b667a0e2dba4b2409cfffc87080724d54a6 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:14 +0000 Subject: [PATCH 004/971] af_unix: Remove CONFIG_UNIX_SCM. commit 99a7a5b9943ea2d05fb0dee38e4ae2290477ed83 upstream. Originally, the code related to garbage collection was all in garbage.c. Commit f4e65870e5ce ("net: split out functions related to registering inflight socket files") moved some functions to scm.c for io_uring and added CONFIG_UNIX_SCM just in case AF_UNIX was built as module. However, since commit 97154bcf4d1b ("af_unix: Kconfig: make CONFIG_UNIX bool"), AF_UNIX is no longer built separately. Also, io_uring does not support SCM_RIGHTS now. Let's move the functions back to garbage.c Signed-off-by: Kuniyuki Iwashima Acked-by: Jens Axboe Link: https://lore.kernel.org/r/20240129190435.57228-4-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- include/net/af_unix.h | 7 +- net/Makefile | 2 +- net/unix/Kconfig | 5 -- net/unix/Makefile | 2 - net/unix/af_unix.c | 63 +++++++++++++++++- net/unix/garbage.c | 73 +++++++++++++++++++- net/unix/scm.c | 150 ------------------------------------------ net/unix/scm.h | 10 --- 8 files changed, 137 insertions(+), 175 deletions(-) delete mode 100644 net/unix/scm.c delete mode 100644 net/unix/scm.h diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 4d35204c0857..3dee0b2721aa 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -17,19 +17,20 @@ static inline struct unix_sock *unix_get_socket(struct file *filp) } #endif +extern spinlock_t unix_gc_lock; +extern unsigned int unix_tot_inflight; + void unix_inflight(struct user_struct *user, struct file *fp); void unix_notinflight(struct user_struct *user, struct file *fp); -void unix_destruct_scm(struct sk_buff *skb); void unix_gc(void); void wait_for_unix_gc(struct scm_fp_list *fpl); + struct sock *unix_peer_get(struct sock *sk); #define UNIX_HASH_MOD (256 - 1) #define UNIX_HASH_SIZE (256 * 2) #define UNIX_HASH_BITS 8 -extern unsigned int unix_tot_inflight; - struct unix_address { refcount_t refcnt; int len; diff --git a/net/Makefile b/net/Makefile index 4c4dc535453d..45f3fbaae644 100644 --- a/net/Makefile +++ b/net/Makefile @@ -17,7 +17,7 @@ obj-$(CONFIG_NETFILTER) += netfilter/ obj-$(CONFIG_INET) += ipv4/ obj-$(CONFIG_TLS) += tls/ obj-$(CONFIG_XFRM) += xfrm/ -obj-$(CONFIG_UNIX_SCM) += unix/ +obj-$(CONFIG_UNIX) += unix/ obj-y += ipv6/ obj-$(CONFIG_BPFILTER) += bpfilter/ obj-$(CONFIG_PACKET) += packet/ diff --git a/net/unix/Kconfig b/net/unix/Kconfig index 28b232f281ab..8b5d04210d7c 100644 --- a/net/unix/Kconfig +++ b/net/unix/Kconfig @@ -16,11 +16,6 @@ config UNIX Say Y unless you know what you are doing. -config UNIX_SCM - bool - depends on UNIX - default y - config AF_UNIX_OOB bool depends on UNIX diff --git a/net/unix/Makefile b/net/unix/Makefile index 20491825b4d0..4ddd125c4642 100644 --- a/net/unix/Makefile +++ b/net/unix/Makefile @@ -11,5 +11,3 @@ unix-$(CONFIG_BPF_SYSCALL) += unix_bpf.o obj-$(CONFIG_UNIX_DIAG) += unix_diag.o unix_diag-y := diag.o - -obj-$(CONFIG_UNIX_SCM) += scm.o diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index bb92b1ed94aa..78758af2c6f3 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -117,8 +117,6 @@ #include #include -#include "scm.h" - static atomic_long_t unix_nr_socks; static struct hlist_head bsd_socket_buckets[UNIX_HASH_SIZE / 2]; static spinlock_t bsd_socket_locks[UNIX_HASH_SIZE / 2]; @@ -1752,6 +1750,52 @@ out: return err; } +/* The "user->unix_inflight" variable is protected by the garbage + * collection lock, and we just read it locklessly here. If you go + * over the limit, there might be a tiny race in actually noticing + * it across threads. Tough. + */ +static inline bool too_many_unix_fds(struct task_struct *p) +{ + struct user_struct *user = current_user(); + + if (unlikely(READ_ONCE(user->unix_inflight) > task_rlimit(p, RLIMIT_NOFILE))) + return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN); + return false; +} + +static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) +{ + int i; + + if (too_many_unix_fds(current)) + return -ETOOMANYREFS; + + /* Need to duplicate file references for the sake of garbage + * collection. Otherwise a socket in the fps might become a + * candidate for GC while the skb is not yet queued. + */ + UNIXCB(skb).fp = scm_fp_dup(scm->fp); + if (!UNIXCB(skb).fp) + return -ENOMEM; + + for (i = scm->fp->count - 1; i >= 0; i--) + unix_inflight(scm->fp->user, scm->fp->fp[i]); + + return 0; +} + +static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb) +{ + int i; + + scm->fp = UNIXCB(skb).fp; + UNIXCB(skb).fp = NULL; + + for (i = scm->fp->count - 1; i >= 0; i--) + unix_notinflight(scm->fp->user, scm->fp->fp[i]); +} + static void unix_peek_fds(struct scm_cookie *scm, struct sk_buff *skb) { scm->fp = scm_fp_dup(UNIXCB(skb).fp); @@ -1799,6 +1843,21 @@ static void unix_peek_fds(struct scm_cookie *scm, struct sk_buff *skb) spin_unlock(&unix_gc_lock); } +static void unix_destruct_scm(struct sk_buff *skb) +{ + struct scm_cookie scm; + + memset(&scm, 0, sizeof(scm)); + scm.pid = UNIXCB(skb).pid; + if (UNIXCB(skb).fp) + unix_detach_fds(&scm, skb); + + /* Alas, it calls VFS */ + /* So fscking what? fput() had been SMP-safe since the last Summer */ + scm_destroy(&scm); + sock_wfree(skb); +} + static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds) { int err = 0; diff --git a/net/unix/garbage.c b/net/unix/garbage.c index c04f82489abb..0104be9d4704 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -81,11 +81,80 @@ #include #include -#include "scm.h" +struct unix_sock *unix_get_socket(struct file *filp) +{ + struct inode *inode = file_inode(filp); -/* Internal data structures and random procedures: */ + /* Socket ? */ + if (S_ISSOCK(inode->i_mode) && !(filp->f_mode & FMODE_PATH)) { + struct socket *sock = SOCKET_I(inode); + const struct proto_ops *ops; + struct sock *sk = sock->sk; + ops = READ_ONCE(sock->ops); + + /* PF_UNIX ? */ + if (sk && ops && ops->family == PF_UNIX) + return unix_sk(sk); + } + + return NULL; +} + +DEFINE_SPINLOCK(unix_gc_lock); +unsigned int unix_tot_inflight; static LIST_HEAD(gc_candidates); +static LIST_HEAD(gc_inflight_list); + +/* Keep the number of times in flight count for the file + * descriptor if it is for an AF_UNIX socket. + */ +void unix_inflight(struct user_struct *user, struct file *filp) +{ + struct unix_sock *u = unix_get_socket(filp); + + spin_lock(&unix_gc_lock); + + if (u) { + if (!u->inflight) { + WARN_ON_ONCE(!list_empty(&u->link)); + list_add_tail(&u->link, &gc_inflight_list); + } else { + WARN_ON_ONCE(list_empty(&u->link)); + } + u->inflight++; + + /* Paired with READ_ONCE() in wait_for_unix_gc() */ + WRITE_ONCE(unix_tot_inflight, unix_tot_inflight + 1); + } + + WRITE_ONCE(user->unix_inflight, user->unix_inflight + 1); + + spin_unlock(&unix_gc_lock); +} + +void unix_notinflight(struct user_struct *user, struct file *filp) +{ + struct unix_sock *u = unix_get_socket(filp); + + spin_lock(&unix_gc_lock); + + if (u) { + WARN_ON_ONCE(!u->inflight); + WARN_ON_ONCE(list_empty(&u->link)); + + u->inflight--; + if (!u->inflight) + list_del_init(&u->link); + + /* Paired with READ_ONCE() in wait_for_unix_gc() */ + WRITE_ONCE(unix_tot_inflight, unix_tot_inflight - 1); + } + + WRITE_ONCE(user->unix_inflight, user->unix_inflight - 1); + + spin_unlock(&unix_gc_lock); +} static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *), struct sk_buff_head *hitlist) diff --git a/net/unix/scm.c b/net/unix/scm.c deleted file mode 100644 index db65b0ab5947..000000000000 --- a/net/unix/scm.c +++ /dev/null @@ -1,150 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "scm.h" - -unsigned int unix_tot_inflight; -EXPORT_SYMBOL(unix_tot_inflight); - -LIST_HEAD(gc_inflight_list); -EXPORT_SYMBOL(gc_inflight_list); - -DEFINE_SPINLOCK(unix_gc_lock); -EXPORT_SYMBOL(unix_gc_lock); - -struct unix_sock *unix_get_socket(struct file *filp) -{ - struct inode *inode = file_inode(filp); - - /* Socket ? */ - if (S_ISSOCK(inode->i_mode) && !(filp->f_mode & FMODE_PATH)) { - struct socket *sock = SOCKET_I(inode); - const struct proto_ops *ops = READ_ONCE(sock->ops); - struct sock *s = sock->sk; - - /* PF_UNIX ? */ - if (s && ops && ops->family == PF_UNIX) - return unix_sk(s); - } - - return NULL; -} -EXPORT_SYMBOL(unix_get_socket); - -/* Keep the number of times in flight count for the file - * descriptor if it is for an AF_UNIX socket. - */ -void unix_inflight(struct user_struct *user, struct file *fp) -{ - struct unix_sock *u = unix_get_socket(fp); - - spin_lock(&unix_gc_lock); - - if (u) { - if (!u->inflight) { - WARN_ON_ONCE(!list_empty(&u->link)); - list_add_tail(&u->link, &gc_inflight_list); - } else { - WARN_ON_ONCE(list_empty(&u->link)); - } - u->inflight++; - /* Paired with READ_ONCE() in wait_for_unix_gc() */ - WRITE_ONCE(unix_tot_inflight, unix_tot_inflight + 1); - } - WRITE_ONCE(user->unix_inflight, user->unix_inflight + 1); - spin_unlock(&unix_gc_lock); -} - -void unix_notinflight(struct user_struct *user, struct file *fp) -{ - struct unix_sock *u = unix_get_socket(fp); - - spin_lock(&unix_gc_lock); - - if (u) { - WARN_ON_ONCE(!u->inflight); - WARN_ON_ONCE(list_empty(&u->link)); - - u->inflight--; - if (!u->inflight) - list_del_init(&u->link); - /* Paired with READ_ONCE() in wait_for_unix_gc() */ - WRITE_ONCE(unix_tot_inflight, unix_tot_inflight - 1); - } - WRITE_ONCE(user->unix_inflight, user->unix_inflight - 1); - spin_unlock(&unix_gc_lock); -} - -/* - * The "user->unix_inflight" variable is protected by the garbage - * collection lock, and we just read it locklessly here. If you go - * over the limit, there might be a tiny race in actually noticing - * it across threads. Tough. - */ -static inline bool too_many_unix_fds(struct task_struct *p) -{ - struct user_struct *user = current_user(); - - if (unlikely(READ_ONCE(user->unix_inflight) > task_rlimit(p, RLIMIT_NOFILE))) - return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN); - return false; -} - -int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) -{ - int i; - - if (too_many_unix_fds(current)) - return -ETOOMANYREFS; - - /* - * Need to duplicate file references for the sake of garbage - * collection. Otherwise a socket in the fps might become a - * candidate for GC while the skb is not yet queued. - */ - UNIXCB(skb).fp = scm_fp_dup(scm->fp); - if (!UNIXCB(skb).fp) - return -ENOMEM; - - for (i = scm->fp->count - 1; i >= 0; i--) - unix_inflight(scm->fp->user, scm->fp->fp[i]); - return 0; -} -EXPORT_SYMBOL(unix_attach_fds); - -void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb) -{ - int i; - - scm->fp = UNIXCB(skb).fp; - UNIXCB(skb).fp = NULL; - - for (i = scm->fp->count-1; i >= 0; i--) - unix_notinflight(scm->fp->user, scm->fp->fp[i]); -} -EXPORT_SYMBOL(unix_detach_fds); - -void unix_destruct_scm(struct sk_buff *skb) -{ - struct scm_cookie scm; - - memset(&scm, 0, sizeof(scm)); - scm.pid = UNIXCB(skb).pid; - if (UNIXCB(skb).fp) - unix_detach_fds(&scm, skb); - - /* Alas, it calls VFS */ - /* So fscking what? fput() had been SMP-safe since the last Summer */ - scm_destroy(&scm); - sock_wfree(skb); -} -EXPORT_SYMBOL(unix_destruct_scm); diff --git a/net/unix/scm.h b/net/unix/scm.h deleted file mode 100644 index 5a255a477f16..000000000000 --- a/net/unix/scm.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef NET_UNIX_SCM_H -#define NET_UNIX_SCM_H - -extern struct list_head gc_inflight_list; -extern spinlock_t unix_gc_lock; - -int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb); -void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb); - -#endif From 9e98ba0c735292cde35696ac841cbf7beceb306b Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:15 +0000 Subject: [PATCH 005/971] af_unix: Allocate struct unix_vertex for each inflight AF_UNIX fd. commit 1fbfdfaa590248c1d86407f578e40e5c65136330 upstream. We will replace the garbage collection algorithm for AF_UNIX, where we will consider each inflight AF_UNIX socket as a vertex and its file descriptor as an edge in a directed graph. This patch introduces a new struct unix_vertex representing a vertex in the graph and adds its pointer to struct unix_sock. When we send a fd using the SCM_RIGHTS message, we allocate struct scm_fp_list to struct scm_cookie in scm_fp_copy(). Then, we bump each refcount of the inflight fds' struct file and save them in scm_fp_list.fp. After that, unix_attach_fds() inexplicably clones scm_fp_list of scm_cookie and sets it to skb. (We will remove this part after replacing GC.) Here, we add a new function call in unix_attach_fds() to preallocate struct unix_vertex per inflight AF_UNIX fd and link each vertex to skb's scm_fp_list.vertices. When sendmsg() succeeds later, if the socket of the inflight fd is still not inflight yet, we will set the preallocated vertex to struct unix_sock.vertex and link it to a global list unix_unvisited_vertices under spin_lock(&unix_gc_lock). If the socket is already inflight, we free the preallocated vertex. This is to avoid taking the lock unnecessarily when sendmsg() could fail later. In the following patch, we will similarly allocate another struct per edge, which will finally be linked to the inflight socket's unix_vertex.edges. And then, we will count the number of edges as unix_vertex.out_degree. Signed-off-by: Kuniyuki Iwashima Acked-by: Paolo Abeni Link: https://lore.kernel.org/r/20240325202425.60930-2-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- include/net/af_unix.h | 9 +++++++++ include/net/scm.h | 3 +++ net/core/scm.c | 7 +++++++ net/unix/af_unix.c | 6 ++++++ net/unix/garbage.c | 38 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+) diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 3dee0b2721aa..07f0f698c949 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -22,9 +22,17 @@ extern unsigned int unix_tot_inflight; void unix_inflight(struct user_struct *user, struct file *fp); void unix_notinflight(struct user_struct *user, struct file *fp); +int unix_prepare_fpl(struct scm_fp_list *fpl); +void unix_destroy_fpl(struct scm_fp_list *fpl); void unix_gc(void); void wait_for_unix_gc(struct scm_fp_list *fpl); +struct unix_vertex { + struct list_head edges; + struct list_head entry; + unsigned long out_degree; +}; + struct sock *unix_peer_get(struct sock *sk); #define UNIX_HASH_MOD (256 - 1) @@ -62,6 +70,7 @@ struct unix_sock { struct path path; struct mutex iolock, bindlock; struct sock *peer; + struct unix_vertex *vertex; struct list_head link; unsigned long inflight; spinlock_t lock; diff --git a/include/net/scm.h b/include/net/scm.h index 1ff6a2855064..11e86e55f332 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -26,6 +26,9 @@ struct scm_fp_list { short count; short count_unix; short max; +#ifdef CONFIG_UNIX + struct list_head vertices; +#endif struct user_struct *user; struct file *fp[SCM_MAX_FD]; }; diff --git a/net/core/scm.c b/net/core/scm.c index 574607b1c2d9..27e5634c958e 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -89,6 +89,9 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp) fpl->count_unix = 0; fpl->max = SCM_MAX_FD; fpl->user = NULL; +#if IS_ENABLED(CONFIG_UNIX) + INIT_LIST_HEAD(&fpl->vertices); +#endif } fpp = &fpl->fp[fpl->count]; @@ -376,8 +379,12 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl) if (new_fpl) { for (i = 0; i < fpl->count; i++) get_file(fpl->fp[i]); + new_fpl->max = new_fpl->count; new_fpl->user = get_uid(fpl->user); +#if IS_ENABLED(CONFIG_UNIX) + INIT_LIST_HEAD(&new_fpl->vertices); +#endif } return new_fpl; } diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 78758af2c6f3..6d62fa5b0e68 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -979,6 +979,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern, sk->sk_destruct = unix_sock_destructor; u = unix_sk(sk); u->inflight = 0; + u->vertex = NULL; u->path.dentry = NULL; u->path.mnt = NULL; spin_lock_init(&u->lock); @@ -1782,6 +1783,9 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) for (i = scm->fp->count - 1; i >= 0; i--) unix_inflight(scm->fp->user, scm->fp->fp[i]); + if (unix_prepare_fpl(UNIXCB(skb).fp)) + return -ENOMEM; + return 0; } @@ -1792,6 +1796,8 @@ static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb) scm->fp = UNIXCB(skb).fp; UNIXCB(skb).fp = NULL; + unix_destroy_fpl(scm->fp); + for (i = scm->fp->count - 1; i >= 0; i--) unix_notinflight(scm->fp->user, scm->fp->fp[i]); } diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 0104be9d4704..8ea7640e032e 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -101,6 +101,44 @@ struct unix_sock *unix_get_socket(struct file *filp) return NULL; } +static void unix_free_vertices(struct scm_fp_list *fpl) +{ + struct unix_vertex *vertex, *next_vertex; + + list_for_each_entry_safe(vertex, next_vertex, &fpl->vertices, entry) { + list_del(&vertex->entry); + kfree(vertex); + } +} + +int unix_prepare_fpl(struct scm_fp_list *fpl) +{ + struct unix_vertex *vertex; + int i; + + if (!fpl->count_unix) + return 0; + + for (i = 0; i < fpl->count_unix; i++) { + vertex = kmalloc(sizeof(*vertex), GFP_KERNEL); + if (!vertex) + goto err; + + list_add(&vertex->entry, &fpl->vertices); + } + + return 0; + +err: + unix_free_vertices(fpl); + return -ENOMEM; +} + +void unix_destroy_fpl(struct scm_fp_list *fpl) +{ + unix_free_vertices(fpl); +} + DEFINE_SPINLOCK(unix_gc_lock); unsigned int unix_tot_inflight; static LIST_HEAD(gc_candidates); From 4fc7df1c6da14aef3ad9d2ea39565c020ec09aaa Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:16 +0000 Subject: [PATCH 006/971] af_unix: Allocate struct unix_edge for each inflight AF_UNIX fd. commit 29b64e354029cfcf1eea4d91b146c7b769305930 upstream. As with the previous patch, we preallocate to skb's scm_fp_list an array of struct unix_edge in the number of inflight AF_UNIX fds. There we just preallocate memory and do not use immediately because sendmsg() could fail after this point. The actual use will be in the next patch. When we queue skb with inflight edges, we will set the inflight socket's unix_sock as unix_edge->predecessor and the receiver's unix_sock as successor, and then we will link the edge to the inflight socket's unix_vertex.edges. Note that we set NULL to cloned scm_fp_list.edges in scm_fp_dup() so that MSG_PEEK does not change the shape of the directed graph. Signed-off-by: Kuniyuki Iwashima Acked-by: Paolo Abeni Link: https://lore.kernel.org/r/20240325202425.60930-3-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- include/net/af_unix.h | 6 ++++++ include/net/scm.h | 5 +++++ net/core/scm.c | 2 ++ net/unix/garbage.c | 6 ++++++ 4 files changed, 19 insertions(+) diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 07f0f698c949..dd5750daf0b9 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -33,6 +33,12 @@ struct unix_vertex { unsigned long out_degree; }; +struct unix_edge { + struct unix_sock *predecessor; + struct unix_sock *successor; + struct list_head vertex_entry; +}; + struct sock *unix_peer_get(struct sock *sk); #define UNIX_HASH_MOD (256 - 1) diff --git a/include/net/scm.h b/include/net/scm.h index 11e86e55f332..915c4c94306e 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -22,12 +22,17 @@ struct scm_creds { kgid_t gid; }; +#ifdef CONFIG_UNIX +struct unix_edge; +#endif + struct scm_fp_list { short count; short count_unix; short max; #ifdef CONFIG_UNIX struct list_head vertices; + struct unix_edge *edges; #endif struct user_struct *user; struct file *fp[SCM_MAX_FD]; diff --git a/net/core/scm.c b/net/core/scm.c index 27e5634c958e..96e3d2785e50 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -90,6 +90,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp) fpl->max = SCM_MAX_FD; fpl->user = NULL; #if IS_ENABLED(CONFIG_UNIX) + fpl->edges = NULL; INIT_LIST_HEAD(&fpl->vertices); #endif } @@ -383,6 +384,7 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl) new_fpl->max = new_fpl->count; new_fpl->user = get_uid(fpl->user); #if IS_ENABLED(CONFIG_UNIX) + new_fpl->edges = NULL; INIT_LIST_HEAD(&new_fpl->vertices); #endif } diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 8ea7640e032e..912b7945692c 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -127,6 +127,11 @@ int unix_prepare_fpl(struct scm_fp_list *fpl) list_add(&vertex->entry, &fpl->vertices); } + fpl->edges = kvmalloc_array(fpl->count_unix, sizeof(*fpl->edges), + GFP_KERNEL_ACCOUNT); + if (!fpl->edges) + goto err; + return 0; err: @@ -136,6 +141,7 @@ err: void unix_destroy_fpl(struct scm_fp_list *fpl) { + kvfree(fpl->edges); unix_free_vertices(fpl); } From d2d9f382e2db634f9d499e749c668f631ea76e10 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:17 +0000 Subject: [PATCH 007/971] af_unix: Link struct unix_edge when queuing skb. commit 42f298c06b30bfe0a8cbee5d38644e618699e26e upstream. Just before queuing skb with inflight fds, we call scm_stat_add(), which is a good place to set up the preallocated struct unix_vertex and struct unix_edge in UNIXCB(skb).fp. Then, we call unix_add_edges() and construct the directed graph as follows: 1. Set the inflight socket's unix_sock to unix_edge.predecessor. 2. Set the receiver's unix_sock to unix_edge.successor. 3. Set the preallocated vertex to inflight socket's unix_sock.vertex. 4. Link inflight socket's unix_vertex.entry to unix_unvisited_vertices. 5. Link unix_edge.vertex_entry to the inflight socket's unix_vertex.edges. Let's say we pass the fd of AF_UNIX socket A to B and the fd of B to C. The graph looks like this: +-------------------------+ | unix_unvisited_vertices | <-------------------------. +-------------------------+ | + | | +--------------+ +--------------+ | +--------------+ | | unix_sock A | <---. .---> | unix_sock B | <-|-. .---> | unix_sock C | | +--------------+ | | +--------------+ | | | +--------------+ | .-+ | vertex | | | .-+ | vertex | | | | | vertex | | | +--------------+ | | | +--------------+ | | | +--------------+ | | | | | | | | | | +--------------+ | | | +--------------+ | | | | '-> | unix_vertex | | | '-> | unix_vertex | | | | | +--------------+ | | +--------------+ | | | `---> | entry | +---------> | entry | +-' | | |--------------| | | |--------------| | | | edges | <-. | | | edges | <-. | | +--------------+ | | | +--------------+ | | | | | | | | | .----------------------' | | .----------------------' | | | | | | | | | +--------------+ | | | +--------------+ | | | | unix_edge | | | | | unix_edge | | | | +--------------+ | | | +--------------+ | | `-> | vertex_entry | | | `-> | vertex_entry | | | |--------------| | | |--------------| | | | predecessor | +---' | | predecessor | +---' | |--------------| | |--------------| | | successor | +-----' | successor | +-----' +--------------+ +--------------+ Henceforth, we denote such a graph as A -> B (-> C). Now, we can express all inflight fd graphs that do not contain embryo sockets. We will support the particular case later. Signed-off-by: Kuniyuki Iwashima Acked-by: Paolo Abeni Link: https://lore.kernel.org/r/20240325202425.60930-4-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- include/net/af_unix.h | 2 + include/net/scm.h | 1 + net/core/scm.c | 2 + net/unix/af_unix.c | 8 +++- net/unix/garbage.c | 90 ++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 100 insertions(+), 3 deletions(-) diff --git a/include/net/af_unix.h b/include/net/af_unix.h index dd5750daf0b9..affcb990f95e 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -22,6 +22,8 @@ extern unsigned int unix_tot_inflight; void unix_inflight(struct user_struct *user, struct file *fp); void unix_notinflight(struct user_struct *user, struct file *fp); +void unix_add_edges(struct scm_fp_list *fpl, struct unix_sock *receiver); +void unix_del_edges(struct scm_fp_list *fpl); int unix_prepare_fpl(struct scm_fp_list *fpl); void unix_destroy_fpl(struct scm_fp_list *fpl); void unix_gc(void); diff --git a/include/net/scm.h b/include/net/scm.h index 915c4c94306e..07d66c41cc33 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -31,6 +31,7 @@ struct scm_fp_list { short count_unix; short max; #ifdef CONFIG_UNIX + bool inflight; struct list_head vertices; struct unix_edge *edges; #endif diff --git a/net/core/scm.c b/net/core/scm.c index 96e3d2785e50..1e47788379c2 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -90,6 +90,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp) fpl->max = SCM_MAX_FD; fpl->user = NULL; #if IS_ENABLED(CONFIG_UNIX) + fpl->inflight = false; fpl->edges = NULL; INIT_LIST_HEAD(&fpl->vertices); #endif @@ -384,6 +385,7 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl) new_fpl->max = new_fpl->count; new_fpl->user = get_uid(fpl->user); #if IS_ENABLED(CONFIG_UNIX) + new_fpl->inflight = false; new_fpl->edges = NULL; INIT_LIST_HEAD(&new_fpl->vertices); #endif diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 6d62fa5b0e68..e54f54f9d994 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1920,8 +1920,10 @@ static void scm_stat_add(struct sock *sk, struct sk_buff *skb) struct scm_fp_list *fp = UNIXCB(skb).fp; struct unix_sock *u = unix_sk(sk); - if (unlikely(fp && fp->count)) + if (unlikely(fp && fp->count)) { atomic_add(fp->count, &u->scm_stat.nr_fds); + unix_add_edges(fp, u); + } } static void scm_stat_del(struct sock *sk, struct sk_buff *skb) @@ -1929,8 +1931,10 @@ static void scm_stat_del(struct sock *sk, struct sk_buff *skb) struct scm_fp_list *fp = UNIXCB(skb).fp; struct unix_sock *u = unix_sk(sk); - if (unlikely(fp && fp->count)) + if (unlikely(fp && fp->count)) { atomic_sub(fp->count, &u->scm_stat.nr_fds); + unix_del_edges(fp); + } } /* diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 912b7945692c..b5b4a200dbf3 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -101,6 +101,38 @@ struct unix_sock *unix_get_socket(struct file *filp) return NULL; } +static LIST_HEAD(unix_unvisited_vertices); + +static void unix_add_edge(struct scm_fp_list *fpl, struct unix_edge *edge) +{ + struct unix_vertex *vertex = edge->predecessor->vertex; + + if (!vertex) { + vertex = list_first_entry(&fpl->vertices, typeof(*vertex), entry); + vertex->out_degree = 0; + INIT_LIST_HEAD(&vertex->edges); + + list_move_tail(&vertex->entry, &unix_unvisited_vertices); + edge->predecessor->vertex = vertex; + } + + vertex->out_degree++; + list_add_tail(&edge->vertex_entry, &vertex->edges); +} + +static void unix_del_edge(struct scm_fp_list *fpl, struct unix_edge *edge) +{ + struct unix_vertex *vertex = edge->predecessor->vertex; + + list_del(&edge->vertex_entry); + vertex->out_degree--; + + if (!vertex->out_degree) { + edge->predecessor->vertex = NULL; + list_move_tail(&vertex->entry, &fpl->vertices); + } +} + static void unix_free_vertices(struct scm_fp_list *fpl) { struct unix_vertex *vertex, *next_vertex; @@ -111,6 +143,60 @@ static void unix_free_vertices(struct scm_fp_list *fpl) } } +DEFINE_SPINLOCK(unix_gc_lock); + +void unix_add_edges(struct scm_fp_list *fpl, struct unix_sock *receiver) +{ + int i = 0, j = 0; + + spin_lock(&unix_gc_lock); + + if (!fpl->count_unix) + goto out; + + do { + struct unix_sock *inflight = unix_get_socket(fpl->fp[j++]); + struct unix_edge *edge; + + if (!inflight) + continue; + + edge = fpl->edges + i++; + edge->predecessor = inflight; + edge->successor = receiver; + + unix_add_edge(fpl, edge); + } while (i < fpl->count_unix); + +out: + spin_unlock(&unix_gc_lock); + + fpl->inflight = true; + + unix_free_vertices(fpl); +} + +void unix_del_edges(struct scm_fp_list *fpl) +{ + int i = 0; + + spin_lock(&unix_gc_lock); + + if (!fpl->count_unix) + goto out; + + do { + struct unix_edge *edge = fpl->edges + i++; + + unix_del_edge(fpl, edge); + } while (i < fpl->count_unix); + +out: + spin_unlock(&unix_gc_lock); + + fpl->inflight = false; +} + int unix_prepare_fpl(struct scm_fp_list *fpl) { struct unix_vertex *vertex; @@ -141,11 +227,13 @@ err: void unix_destroy_fpl(struct scm_fp_list *fpl) { + if (fpl->inflight) + unix_del_edges(fpl); + kvfree(fpl->edges); unix_free_vertices(fpl); } -DEFINE_SPINLOCK(unix_gc_lock); unsigned int unix_tot_inflight; static LIST_HEAD(gc_candidates); static LIST_HEAD(gc_inflight_list); From 494accabb56e299f4c547ab0ad877256d1394b12 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:18 +0000 Subject: [PATCH 008/971] af_unix: Bulk update unix_tot_inflight/unix_inflight when queuing skb. commit 22c3c0c52d32f41cc38cd936ea0c93f22ced3315 upstream. Currently, we track the number of inflight sockets in two variables. unix_tot_inflight is the total number of inflight AF_UNIX sockets on the host, and user->unix_inflight is the number of inflight fds per user. We update them one by one in unix_inflight(), which can be done once in batch. Also, sendmsg() could fail even after unix_inflight(), then we need to acquire unix_gc_lock only to decrement the counters. Let's bulk update the counters in unix_add_edges() and unix_del_edges(), which is called only for successfully passed fds. Signed-off-by: Kuniyuki Iwashima Acked-by: Paolo Abeni Link: https://lore.kernel.org/r/20240325202425.60930-5-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- net/unix/garbage.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/net/unix/garbage.c b/net/unix/garbage.c index b5b4a200dbf3..f7041fc23000 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -144,6 +144,7 @@ static void unix_free_vertices(struct scm_fp_list *fpl) } DEFINE_SPINLOCK(unix_gc_lock); +unsigned int unix_tot_inflight; void unix_add_edges(struct scm_fp_list *fpl, struct unix_sock *receiver) { @@ -168,7 +169,10 @@ void unix_add_edges(struct scm_fp_list *fpl, struct unix_sock *receiver) unix_add_edge(fpl, edge); } while (i < fpl->count_unix); + WRITE_ONCE(unix_tot_inflight, unix_tot_inflight + fpl->count_unix); out: + WRITE_ONCE(fpl->user->unix_inflight, fpl->user->unix_inflight + fpl->count); + spin_unlock(&unix_gc_lock); fpl->inflight = true; @@ -191,7 +195,10 @@ void unix_del_edges(struct scm_fp_list *fpl) unix_del_edge(fpl, edge); } while (i < fpl->count_unix); + WRITE_ONCE(unix_tot_inflight, unix_tot_inflight - fpl->count_unix); out: + WRITE_ONCE(fpl->user->unix_inflight, fpl->user->unix_inflight - fpl->count); + spin_unlock(&unix_gc_lock); fpl->inflight = false; @@ -234,7 +241,6 @@ void unix_destroy_fpl(struct scm_fp_list *fpl) unix_free_vertices(fpl); } -unsigned int unix_tot_inflight; static LIST_HEAD(gc_candidates); static LIST_HEAD(gc_inflight_list); @@ -255,13 +261,8 @@ void unix_inflight(struct user_struct *user, struct file *filp) WARN_ON_ONCE(list_empty(&u->link)); } u->inflight++; - - /* Paired with READ_ONCE() in wait_for_unix_gc() */ - WRITE_ONCE(unix_tot_inflight, unix_tot_inflight + 1); } - WRITE_ONCE(user->unix_inflight, user->unix_inflight + 1); - spin_unlock(&unix_gc_lock); } @@ -278,13 +279,8 @@ void unix_notinflight(struct user_struct *user, struct file *filp) u->inflight--; if (!u->inflight) list_del_init(&u->link); - - /* Paired with READ_ONCE() in wait_for_unix_gc() */ - WRITE_ONCE(unix_tot_inflight, unix_tot_inflight - 1); } - WRITE_ONCE(user->unix_inflight, user->unix_inflight - 1); - spin_unlock(&unix_gc_lock); } From 856aacbe2c52054249acfc2321471cbccd4e2958 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:19 +0000 Subject: [PATCH 009/971] af_unix: Iterate all vertices by DFS. commit 6ba76fd2848e107594ea4f03b737230f74bc23ea upstream. The new GC will use a depth first search graph algorithm to find cyclic references. The algorithm visits every vertex exactly once. Here, we implement the DFS part without recursion so that no one can abuse it. unix_walk_scc() marks every vertex unvisited by initialising index as UNIX_VERTEX_INDEX_UNVISITED and iterates inflight vertices in unix_unvisited_vertices and call __unix_walk_scc() to start DFS from an arbitrary vertex. __unix_walk_scc() iterates all edges starting from the vertex and explores the neighbour vertices with DFS using edge_stack. After visiting all neighbours, __unix_walk_scc() moves the visited vertex to unix_visited_vertices so that unix_walk_scc() will not restart DFS from the visited vertex. Signed-off-by: Kuniyuki Iwashima Acked-by: Paolo Abeni Link: https://lore.kernel.org/r/20240325202425.60930-6-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- include/net/af_unix.h | 2 ++ net/unix/garbage.c | 74 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/include/net/af_unix.h b/include/net/af_unix.h index affcb990f95e..9198735a6acb 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -33,12 +33,14 @@ struct unix_vertex { struct list_head edges; struct list_head entry; unsigned long out_degree; + unsigned long index; }; struct unix_edge { struct unix_sock *predecessor; struct unix_sock *successor; struct list_head vertex_entry; + struct list_head stack_entry; }; struct sock *unix_peer_get(struct sock *sk); diff --git a/net/unix/garbage.c b/net/unix/garbage.c index f7041fc23000..295dd1a7b8e0 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -103,6 +103,11 @@ struct unix_sock *unix_get_socket(struct file *filp) static LIST_HEAD(unix_unvisited_vertices); +enum unix_vertex_index { + UNIX_VERTEX_INDEX_UNVISITED, + UNIX_VERTEX_INDEX_START, +}; + static void unix_add_edge(struct scm_fp_list *fpl, struct unix_edge *edge) { struct unix_vertex *vertex = edge->predecessor->vertex; @@ -241,6 +246,73 @@ void unix_destroy_fpl(struct scm_fp_list *fpl) unix_free_vertices(fpl); } +static LIST_HEAD(unix_visited_vertices); + +static void __unix_walk_scc(struct unix_vertex *vertex) +{ + unsigned long index = UNIX_VERTEX_INDEX_START; + struct unix_edge *edge; + LIST_HEAD(edge_stack); + +next_vertex: + vertex->index = index; + index++; + + /* Explore neighbour vertices (receivers of the current vertex's fd). */ + list_for_each_entry(edge, &vertex->edges, vertex_entry) { + struct unix_vertex *next_vertex = edge->successor->vertex; + + if (!next_vertex) + continue; + + if (next_vertex->index == UNIX_VERTEX_INDEX_UNVISITED) { + /* Iterative deepening depth first search + * + * 1. Push a forward edge to edge_stack and set + * the successor to vertex for the next iteration. + */ + list_add(&edge->stack_entry, &edge_stack); + + vertex = next_vertex; + goto next_vertex; + + /* 2. Pop the edge directed to the current vertex + * and restore the ancestor for backtracking. + */ +prev_vertex: + edge = list_first_entry(&edge_stack, typeof(*edge), stack_entry); + list_del_init(&edge->stack_entry); + + vertex = edge->predecessor->vertex; + } + } + + /* Don't restart DFS from this vertex in unix_walk_scc(). */ + list_move_tail(&vertex->entry, &unix_visited_vertices); + + /* Need backtracking ? */ + if (!list_empty(&edge_stack)) + goto prev_vertex; +} + +static void unix_walk_scc(void) +{ + struct unix_vertex *vertex; + + list_for_each_entry(vertex, &unix_unvisited_vertices, entry) + vertex->index = UNIX_VERTEX_INDEX_UNVISITED; + + /* Visit every vertex exactly once. + * __unix_walk_scc() moves visited vertices to unix_visited_vertices. + */ + while (!list_empty(&unix_unvisited_vertices)) { + vertex = list_first_entry(&unix_unvisited_vertices, typeof(*vertex), entry); + __unix_walk_scc(vertex); + } + + list_replace_init(&unix_visited_vertices, &unix_unvisited_vertices); +} + static LIST_HEAD(gc_candidates); static LIST_HEAD(gc_inflight_list); @@ -388,6 +460,8 @@ static void __unix_gc(struct work_struct *work) spin_lock(&unix_gc_lock); + unix_walk_scc(); + /* First, select candidates for garbage collection. Only * in-flight sockets are considered, and from those only ones * which don't have any external reference. From 3ee9b24bd6f705bf5ee5ca24861d3a9dc9aaf7cc Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:20 +0000 Subject: [PATCH 010/971] af_unix: Detect Strongly Connected Components. commit 3484f063172dd88776b062046d721d7c2ae1af7c upstream. In the new GC, we use a simple graph algorithm, Tarjan's Strongly Connected Components (SCC) algorithm, to find cyclic references. The algorithm visits every vertex exactly once using depth-first search (DFS). DFS starts by pushing an input vertex to a stack and assigning it a unique number. Two fields, index and lowlink, are initialised with the number, but lowlink could be updated later during DFS. If a vertex has an edge to an unvisited inflight vertex, we visit it and do the same processing. So, we will have vertices in the stack in the order they appear and number them consecutively in the same order. If a vertex has a back-edge to a visited vertex in the stack, we update the predecessor's lowlink with the successor's index. After iterating edges from the vertex, we check if its index equals its lowlink. If the lowlink is different from the index, it shows there was a back-edge. Then, we go backtracking and propagate the lowlink to its predecessor and resume the previous edge iteration from the next edge. If the lowlink is the same as the index, we pop vertices before and including the vertex from the stack. Then, the set of vertices is SCC, possibly forming a cycle. At the same time, we move the vertices to unix_visited_vertices. When we finish the algorithm, all vertices in each SCC will be linked via unix_vertex.scc_entry. Let's take an example. We have a graph including five inflight vertices (F is not inflight): A -> B -> C -> D -> E (-> F) ^ | `---------' Suppose that we start DFS from C. We will visit C, D, and B first and initialise their index and lowlink. Then, the stack looks like this: > B = (3, 3) (index, lowlink) D = (2, 2) C = (1, 1) When checking B's edge to C, we update B's lowlink with C's index and propagate it to D. B = (3, 1) (index, lowlink) > D = (2, 1) C = (1, 1) Next, we visit E, which has no edge to an inflight vertex. > E = (4, 4) (index, lowlink) B = (3, 1) D = (2, 1) C = (1, 1) When we leave from E, its index and lowlink are the same, so we pop E from the stack as single-vertex SCC. Next, we leave from B and D but do nothing because their lowlink are different from their index. B = (3, 1) (index, lowlink) D = (2, 1) > C = (1, 1) Then, we leave from C, whose index and lowlink are the same, so we pop B, D and C as SCC. Last, we do DFS for the rest of vertices, A, which is also a single-vertex SCC. Finally, each unix_vertex.scc_entry is linked as follows: A -. B -> C -> D E -. ^ | ^ | ^ | `--' `---------' `--' We use SCC later to decide whether we can garbage-collect the sockets. Note that we still cannot detect SCC properly if an edge points to an embryo socket. The following two patches will sort it out. Signed-off-by: Kuniyuki Iwashima Acked-by: Paolo Abeni Link: https://lore.kernel.org/r/20240325202425.60930-7-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- include/net/af_unix.h | 3 +++ net/unix/garbage.c | 46 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 9198735a6acb..37171943fb54 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -32,8 +32,11 @@ void wait_for_unix_gc(struct scm_fp_list *fpl); struct unix_vertex { struct list_head edges; struct list_head entry; + struct list_head scc_entry; unsigned long out_degree; unsigned long index; + unsigned long lowlink; + bool on_stack; }; struct unix_edge { diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 295dd1a7b8e0..cdeff548e130 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -251,11 +251,19 @@ static LIST_HEAD(unix_visited_vertices); static void __unix_walk_scc(struct unix_vertex *vertex) { unsigned long index = UNIX_VERTEX_INDEX_START; + LIST_HEAD(vertex_stack); struct unix_edge *edge; LIST_HEAD(edge_stack); next_vertex: + /* Push vertex to vertex_stack. + * The vertex will be popped when finalising SCC later. + */ + vertex->on_stack = true; + list_add(&vertex->scc_entry, &vertex_stack); + vertex->index = index; + vertex->lowlink = index; index++; /* Explore neighbour vertices (receivers of the current vertex's fd). */ @@ -283,12 +291,46 @@ prev_vertex: edge = list_first_entry(&edge_stack, typeof(*edge), stack_entry); list_del_init(&edge->stack_entry); + next_vertex = vertex; vertex = edge->predecessor->vertex; + + /* If the successor has a smaller lowlink, two vertices + * are in the same SCC, so propagate the smaller lowlink + * to skip SCC finalisation. + */ + vertex->lowlink = min(vertex->lowlink, next_vertex->lowlink); + } else if (next_vertex->on_stack) { + /* Loop detected by a back/cross edge. + * + * The successor is on vertex_stack, so two vertices are + * in the same SCC. If the successor has a smaller index, + * propagate it to skip SCC finalisation. + */ + vertex->lowlink = min(vertex->lowlink, next_vertex->index); + } else { + /* The successor was already grouped as another SCC */ } } - /* Don't restart DFS from this vertex in unix_walk_scc(). */ - list_move_tail(&vertex->entry, &unix_visited_vertices); + if (vertex->index == vertex->lowlink) { + struct list_head scc; + + /* SCC finalised. + * + * If the lowlink was not updated, all the vertices above on + * vertex_stack are in the same SCC. Group them using scc_entry. + */ + __list_cut_position(&scc, &vertex_stack, &vertex->scc_entry); + + list_for_each_entry_reverse(vertex, &scc, scc_entry) { + /* Don't restart DFS from this vertex in unix_walk_scc(). */ + list_move_tail(&vertex->entry, &unix_visited_vertices); + + vertex->on_stack = false; + } + + list_del(&scc); + } /* Need backtracking ? */ if (!list_empty(&edge_stack)) From 36f924e4bf4e72fc6dbb240c1ed6a53d7a664b0f Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:21 +0000 Subject: [PATCH 011/971] af_unix: Save listener for embryo socket. commit aed6ecef55d70de3762ce41c561b7f547dbaf107 upstream. This is a prep patch for the following change, where we need to fetch the listening socket from the successor embryo socket during GC. We add a new field to struct unix_sock to save a pointer to a listening socket. We set it when connect() creates a new socket, and clear it when accept() is called. Signed-off-by: Kuniyuki Iwashima Acked-by: Paolo Abeni Link: https://lore.kernel.org/r/20240325202425.60930-8-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- include/net/af_unix.h | 1 + net/unix/af_unix.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 37171943fb54..d6b755b254a1 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -83,6 +83,7 @@ struct unix_sock { struct path path; struct mutex iolock, bindlock; struct sock *peer; + struct sock *listener; struct unix_vertex *vertex; struct list_head link; unsigned long inflight; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index e54f54f9d994..4d4c035ba626 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -978,6 +978,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern, sk->sk_max_ack_backlog = READ_ONCE(net->unx.sysctl_max_dgram_qlen); sk->sk_destruct = unix_sock_destructor; u = unix_sk(sk); + u->listener = NULL; u->inflight = 0; u->vertex = NULL; u->path.dentry = NULL; @@ -1582,6 +1583,7 @@ restart: newsk->sk_type = sk->sk_type; init_peercred(newsk); newu = unix_sk(newsk); + newu->listener = other; RCU_INIT_POINTER(newsk->sk_wq, &newu->peer_wq); otheru = unix_sk(other); @@ -1677,8 +1679,8 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags, bool kern) { struct sock *sk = sock->sk; - struct sock *tsk; struct sk_buff *skb; + struct sock *tsk; int err; err = -EOPNOTSUPP; @@ -1703,6 +1705,7 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags, } tsk = skb->sk; + unix_sk(tsk)->listener = NULL; skb_free_datagram(sk, skb); wake_up_interruptible(&unix_sk(sk)->peer_wait); From 27a07364cefdf97c5ed54654b9b5582f79fd5ecb Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:22 +0000 Subject: [PATCH 012/971] af_unix: Fix up unix_edge.successor for embryo socket. commit dcf70df2048d27c5d186f013f101a4aefd63aa41 upstream. To garbage collect inflight AF_UNIX sockets, we must define the cyclic reference appropriately. This is a bit tricky if the loop consists of embryo sockets. Suppose that the fd of AF_UNIX socket A is passed to D and the fd B to C and that C and D are embryo sockets of A and B, respectively. It may appear that there are two separate graphs, A (-> D) and B (-> C), but this is not correct. A --. .-- B X C <-' `-> D Now, D holds A's refcount, and C has B's refcount, so unix_release() will never be called for A and B when we close() them. However, no one can call close() for D and C to free skbs holding refcounts of A and B because C/D is in A/B's receive queue, which should have been purged by unix_release() for A and B. So, here's another type of cyclic reference. When a fd of an AF_UNIX socket is passed to an embryo socket, the reference is indirectly held by its parent listening socket. .-> A .-> B | `- sk_receive_queue | `- sk_receive_queue | `- skb | `- skb | `- sk == C | `- sk == D | `- sk_receive_queue | `- sk_receive_queue | `- skb +---------' `- skb +-. | | `---------------------------------------------------------' Technically, the graph must be denoted as A <-> B instead of A (-> D) and B (-> C) to find such a cyclic reference without touching each socket's receive queue. .-> A --. .-- B <-. | X | == A <-> B `-- C <-' `-> D --' We apply this fixup during GC by fetching the real successor by unix_edge_successor(). When we call accept(), we clear unix_sock.listener under unix_gc_lock not to confuse GC. Signed-off-by: Kuniyuki Iwashima Acked-by: Paolo Abeni Link: https://lore.kernel.org/r/20240325202425.60930-9-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- include/net/af_unix.h | 1 + net/unix/af_unix.c | 2 +- net/unix/garbage.c | 20 +++++++++++++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/include/net/af_unix.h b/include/net/af_unix.h index d6b755b254a1..9d92dd608fc4 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -24,6 +24,7 @@ void unix_inflight(struct user_struct *user, struct file *fp); void unix_notinflight(struct user_struct *user, struct file *fp); void unix_add_edges(struct scm_fp_list *fpl, struct unix_sock *receiver); void unix_del_edges(struct scm_fp_list *fpl); +void unix_update_edges(struct unix_sock *receiver); int unix_prepare_fpl(struct scm_fp_list *fpl); void unix_destroy_fpl(struct scm_fp_list *fpl); void unix_gc(void); diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 4d4c035ba626..93316e9efc53 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1705,7 +1705,7 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags, } tsk = skb->sk; - unix_sk(tsk)->listener = NULL; + unix_update_edges(unix_sk(tsk)); skb_free_datagram(sk, skb); wake_up_interruptible(&unix_sk(sk)->peer_wait); diff --git a/net/unix/garbage.c b/net/unix/garbage.c index cdeff548e130..6ff7e0b5c544 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -101,6 +101,17 @@ struct unix_sock *unix_get_socket(struct file *filp) return NULL; } +static struct unix_vertex *unix_edge_successor(struct unix_edge *edge) +{ + /* If an embryo socket has a fd, + * the listener indirectly holds the fd's refcnt. + */ + if (edge->successor->listener) + return unix_sk(edge->successor->listener)->vertex; + + return edge->successor->vertex; +} + static LIST_HEAD(unix_unvisited_vertices); enum unix_vertex_index { @@ -209,6 +220,13 @@ out: fpl->inflight = false; } +void unix_update_edges(struct unix_sock *receiver) +{ + spin_lock(&unix_gc_lock); + receiver->listener = NULL; + spin_unlock(&unix_gc_lock); +} + int unix_prepare_fpl(struct scm_fp_list *fpl) { struct unix_vertex *vertex; @@ -268,7 +286,7 @@ next_vertex: /* Explore neighbour vertices (receivers of the current vertex's fd). */ list_for_each_entry(edge, &vertex->edges, vertex_entry) { - struct unix_vertex *next_vertex = edge->successor->vertex; + struct unix_vertex *next_vertex = unix_edge_successor(edge); if (!next_vertex) continue; From e0e23fc4999202fc68e36264288489a6e3f8e347 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:23 +0000 Subject: [PATCH 013/971] af_unix: Save O(n) setup of Tarjan's algo. commit ba31b4a4e1018f5844c6eb31734976e2184f2f9a upstream. Before starting Tarjan's algorithm, we need to mark all vertices as unvisited. We can save this O(n) setup by reserving two special indices (0, 1) and using two variables. The first time we link a vertex to unix_unvisited_vertices, we set unix_vertex_unvisited_index to index. During DFS, we can see that the index of unvisited vertices is the same as unix_vertex_unvisited_index. When we finalise SCC later, we set unix_vertex_grouped_index to each vertex's index. Then, we can know (i) that the vertex is on the stack if the index of a visited vertex is >= 2 and (ii) that it is not on the stack and belongs to a different SCC if the index is unix_vertex_grouped_index. After the whole algorithm, all indices of vertices are set as unix_vertex_grouped_index. Next time we start DFS, we know that all unvisited vertices have unix_vertex_grouped_index, and we can use unix_vertex_unvisited_index as the not-on-stack marker. To use the same variable in __unix_walk_scc(), we can swap unix_vertex_(grouped|unvisited)_index at the end of Tarjan's algorithm. Signed-off-by: Kuniyuki Iwashima Acked-by: Paolo Abeni Link: https://lore.kernel.org/r/20240325202425.60930-10-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- include/net/af_unix.h | 1 - net/unix/garbage.c | 26 +++++++++++++++----------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 9d92dd608fc4..053f67adb9f1 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -37,7 +37,6 @@ struct unix_vertex { unsigned long out_degree; unsigned long index; unsigned long lowlink; - bool on_stack; }; struct unix_edge { diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 6ff7e0b5c544..feae6c17b291 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -115,16 +115,20 @@ static struct unix_vertex *unix_edge_successor(struct unix_edge *edge) static LIST_HEAD(unix_unvisited_vertices); enum unix_vertex_index { - UNIX_VERTEX_INDEX_UNVISITED, + UNIX_VERTEX_INDEX_MARK1, + UNIX_VERTEX_INDEX_MARK2, UNIX_VERTEX_INDEX_START, }; +static unsigned long unix_vertex_unvisited_index = UNIX_VERTEX_INDEX_MARK1; + static void unix_add_edge(struct scm_fp_list *fpl, struct unix_edge *edge) { struct unix_vertex *vertex = edge->predecessor->vertex; if (!vertex) { vertex = list_first_entry(&fpl->vertices, typeof(*vertex), entry); + vertex->index = unix_vertex_unvisited_index; vertex->out_degree = 0; INIT_LIST_HEAD(&vertex->edges); @@ -265,6 +269,7 @@ void unix_destroy_fpl(struct scm_fp_list *fpl) } static LIST_HEAD(unix_visited_vertices); +static unsigned long unix_vertex_grouped_index = UNIX_VERTEX_INDEX_MARK2; static void __unix_walk_scc(struct unix_vertex *vertex) { @@ -274,10 +279,10 @@ static void __unix_walk_scc(struct unix_vertex *vertex) LIST_HEAD(edge_stack); next_vertex: - /* Push vertex to vertex_stack. + /* Push vertex to vertex_stack and mark it as on-stack + * (index >= UNIX_VERTEX_INDEX_START). * The vertex will be popped when finalising SCC later. */ - vertex->on_stack = true; list_add(&vertex->scc_entry, &vertex_stack); vertex->index = index; @@ -291,7 +296,7 @@ next_vertex: if (!next_vertex) continue; - if (next_vertex->index == UNIX_VERTEX_INDEX_UNVISITED) { + if (next_vertex->index == unix_vertex_unvisited_index) { /* Iterative deepening depth first search * * 1. Push a forward edge to edge_stack and set @@ -317,7 +322,7 @@ prev_vertex: * to skip SCC finalisation. */ vertex->lowlink = min(vertex->lowlink, next_vertex->lowlink); - } else if (next_vertex->on_stack) { + } else if (next_vertex->index != unix_vertex_grouped_index) { /* Loop detected by a back/cross edge. * * The successor is on vertex_stack, so two vertices are @@ -344,7 +349,8 @@ prev_vertex: /* Don't restart DFS from this vertex in unix_walk_scc(). */ list_move_tail(&vertex->entry, &unix_visited_vertices); - vertex->on_stack = false; + /* Mark vertex as off-stack. */ + vertex->index = unix_vertex_grouped_index; } list_del(&scc); @@ -357,20 +363,18 @@ prev_vertex: static void unix_walk_scc(void) { - struct unix_vertex *vertex; - - list_for_each_entry(vertex, &unix_unvisited_vertices, entry) - vertex->index = UNIX_VERTEX_INDEX_UNVISITED; - /* Visit every vertex exactly once. * __unix_walk_scc() moves visited vertices to unix_visited_vertices. */ while (!list_empty(&unix_unvisited_vertices)) { + struct unix_vertex *vertex; + vertex = list_first_entry(&unix_unvisited_vertices, typeof(*vertex), entry); __unix_walk_scc(vertex); } list_replace_init(&unix_visited_vertices, &unix_unvisited_vertices); + swap(unix_vertex_unvisited_index, unix_vertex_grouped_index); } static LIST_HEAD(gc_candidates); From cdaa3499a85199ad2b8a185d2ea0cfff2d466003 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:24 +0000 Subject: [PATCH 014/971] af_unix: Skip GC if no cycle exists. commit 77e5593aebba823bcbcf2c4b58b07efcd63933b8 upstream. We do not need to run GC if there is no possible cyclic reference. We use unix_graph_maybe_cyclic to decide if we should run GC. If a fd of an AF_UNIX socket is passed to an already inflight AF_UNIX socket, they could form a cyclic reference. Then, we set true to unix_graph_maybe_cyclic and later run Tarjan's algorithm to group them into SCC. Once we run Tarjan's algorithm, we are 100% sure whether cyclic references exist or not. If there is no cycle, we set false to unix_graph_maybe_cyclic and can skip the entire garbage collection next time. When finalising SCC, we set true to unix_graph_maybe_cyclic if SCC consists of multiple vertices. Even if SCC is a single vertex, a cycle might exist as self-fd passing. Given the corner case is rare, we detect it by checking all edges of the vertex and set true to unix_graph_maybe_cyclic. With this change, __unix_gc() is just a spin_lock() dance in the normal usage. Signed-off-by: Kuniyuki Iwashima Acked-by: Paolo Abeni Link: https://lore.kernel.org/r/20240325202425.60930-11-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- net/unix/garbage.c | 48 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/net/unix/garbage.c b/net/unix/garbage.c index feae6c17b291..8f0dc39bb72f 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -112,6 +112,19 @@ static struct unix_vertex *unix_edge_successor(struct unix_edge *edge) return edge->successor->vertex; } +static bool unix_graph_maybe_cyclic; + +static void unix_update_graph(struct unix_vertex *vertex) +{ + /* If the receiver socket is not inflight, no cyclic + * reference could be formed. + */ + if (!vertex) + return; + + unix_graph_maybe_cyclic = true; +} + static LIST_HEAD(unix_unvisited_vertices); enum unix_vertex_index { @@ -138,12 +151,16 @@ static void unix_add_edge(struct scm_fp_list *fpl, struct unix_edge *edge) vertex->out_degree++; list_add_tail(&edge->vertex_entry, &vertex->edges); + + unix_update_graph(unix_edge_successor(edge)); } static void unix_del_edge(struct scm_fp_list *fpl, struct unix_edge *edge) { struct unix_vertex *vertex = edge->predecessor->vertex; + unix_update_graph(unix_edge_successor(edge)); + list_del(&edge->vertex_entry); vertex->out_degree--; @@ -227,6 +244,7 @@ out: void unix_update_edges(struct unix_sock *receiver) { spin_lock(&unix_gc_lock); + unix_update_graph(unix_sk(receiver->listener)->vertex); receiver->listener = NULL; spin_unlock(&unix_gc_lock); } @@ -268,6 +286,26 @@ void unix_destroy_fpl(struct scm_fp_list *fpl) unix_free_vertices(fpl); } +static bool unix_scc_cyclic(struct list_head *scc) +{ + struct unix_vertex *vertex; + struct unix_edge *edge; + + /* SCC containing multiple vertices ? */ + if (!list_is_singular(scc)) + return true; + + vertex = list_first_entry(scc, typeof(*vertex), scc_entry); + + /* Self-reference or a embryo-listener circle ? */ + list_for_each_entry(edge, &vertex->edges, vertex_entry) { + if (unix_edge_successor(edge) == vertex) + return true; + } + + return false; +} + static LIST_HEAD(unix_visited_vertices); static unsigned long unix_vertex_grouped_index = UNIX_VERTEX_INDEX_MARK2; @@ -353,6 +391,9 @@ prev_vertex: vertex->index = unix_vertex_grouped_index; } + if (!unix_graph_maybe_cyclic) + unix_graph_maybe_cyclic = unix_scc_cyclic(&scc); + list_del(&scc); } @@ -363,6 +404,8 @@ prev_vertex: static void unix_walk_scc(void) { + unix_graph_maybe_cyclic = false; + /* Visit every vertex exactly once. * __unix_walk_scc() moves visited vertices to unix_visited_vertices. */ @@ -524,6 +567,9 @@ static void __unix_gc(struct work_struct *work) spin_lock(&unix_gc_lock); + if (!unix_graph_maybe_cyclic) + goto skip_gc; + unix_walk_scc(); /* First, select candidates for garbage collection. Only @@ -633,7 +679,7 @@ static void __unix_gc(struct work_struct *work) /* All candidates should have been detached by now. */ WARN_ON_ONCE(!list_empty(&gc_candidates)); - +skip_gc: /* Paired with READ_ONCE() in wait_for_unix_gc(). */ WRITE_ONCE(gc_in_progress, false); From d23802221f6755e104606864067c71af8cdb6788 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:25 +0000 Subject: [PATCH 015/971] af_unix: Avoid Tarjan's algorithm if unnecessary. commit ad081928a8b0f57f269df999a28087fce6f2b6ce upstream. Once a cyclic reference is formed, we need to run GC to check if there is dead SCC. However, we do not need to run Tarjan's algorithm if we know that the shape of the inflight graph has not been changed. If an edge is added/updated/deleted and the edge's successor is inflight, we set false to unix_graph_grouped, which means we need to re-classify SCC. Once we finalise SCC, we set true to unix_graph_grouped. While unix_graph_grouped is true, we can iterate the grouped SCC using vertex->scc_entry in unix_walk_scc_fast(). list_add() and list_for_each_entry_reverse() uses seem weird, but they are to keep the vertex order consistent and make writing test easier. Signed-off-by: Kuniyuki Iwashima Acked-by: Paolo Abeni Link: https://lore.kernel.org/r/20240325202425.60930-12-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- net/unix/garbage.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 8f0dc39bb72f..d25841ab2de4 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -113,6 +113,7 @@ static struct unix_vertex *unix_edge_successor(struct unix_edge *edge) } static bool unix_graph_maybe_cyclic; +static bool unix_graph_grouped; static void unix_update_graph(struct unix_vertex *vertex) { @@ -123,6 +124,7 @@ static void unix_update_graph(struct unix_vertex *vertex) return; unix_graph_maybe_cyclic = true; + unix_graph_grouped = false; } static LIST_HEAD(unix_unvisited_vertices); @@ -144,6 +146,7 @@ static void unix_add_edge(struct scm_fp_list *fpl, struct unix_edge *edge) vertex->index = unix_vertex_unvisited_index; vertex->out_degree = 0; INIT_LIST_HEAD(&vertex->edges); + INIT_LIST_HEAD(&vertex->scc_entry); list_move_tail(&vertex->entry, &unix_unvisited_vertices); edge->predecessor->vertex = vertex; @@ -418,6 +421,26 @@ static void unix_walk_scc(void) list_replace_init(&unix_visited_vertices, &unix_unvisited_vertices); swap(unix_vertex_unvisited_index, unix_vertex_grouped_index); + + unix_graph_grouped = true; +} + +static void unix_walk_scc_fast(void) +{ + while (!list_empty(&unix_unvisited_vertices)) { + struct unix_vertex *vertex; + struct list_head scc; + + vertex = list_first_entry(&unix_unvisited_vertices, typeof(*vertex), entry); + list_add(&scc, &vertex->scc_entry); + + list_for_each_entry_reverse(vertex, &scc, scc_entry) + list_move_tail(&vertex->entry, &unix_visited_vertices); + + list_del(&scc); + } + + list_replace_init(&unix_visited_vertices, &unix_unvisited_vertices); } static LIST_HEAD(gc_candidates); @@ -570,7 +593,10 @@ static void __unix_gc(struct work_struct *work) if (!unix_graph_maybe_cyclic) goto skip_gc; - unix_walk_scc(); + if (unix_graph_grouped) + unix_walk_scc_fast(); + else + unix_walk_scc(); /* First, select candidates for garbage collection. Only * in-flight sockets are considered, and from those only ones From 324005012f65ef5ec4d3c7916ece3b9626af72bb Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:26 +0000 Subject: [PATCH 016/971] af_unix: Assign a unique index to SCC. commit bfdb01283ee8f2f3089656c3ff8f62bb072dabb2 upstream. The definition of the lowlink in Tarjan's algorithm is the smallest index of a vertex that is reachable with at most one back-edge in SCC. This is not useful for a cross-edge. If we start traversing from A in the following graph, the final lowlink of D is 3. The cross-edge here is one between D and C. A -> B -> D D = (4, 3) (index, lowlink) ^ | | C = (3, 1) | V | B = (2, 1) `--- C <--' A = (1, 1) This is because the lowlink of D is updated with the index of C. In the following patch, we detect a dead SCC by checking two conditions for each vertex. 1) vertex has no edge directed to another SCC (no bridge) 2) vertex's out_degree is the same as the refcount of its file If 1) is false, there is a receiver of all fds of the SCC and its ancestor SCC. To evaluate 1), we need to assign a unique index to each SCC and assign it to all vertices in the SCC. This patch changes the lowlink update logic for cross-edge so that in the example above, the lowlink of D is updated with the lowlink of C. A -> B -> D D = (4, 1) (index, lowlink) ^ | | C = (3, 1) | V | B = (2, 1) `--- C <--' A = (1, 1) Then, all vertices in the same SCC have the same lowlink, and we can quickly find the bridge connecting to different SCC if exists. However, it is no longer called lowlink, so we rename it to scc_index. (It's sometimes called lowpoint.) Also, we add a global variable to hold the last index used in DFS so that we do not reset the initial index in each DFS. This patch can be squashed to the SCC detection patch but is split deliberately for anyone wondering why lowlink is not used as used in the original Tarjan's algorithm and many reference implementations. Signed-off-by: Kuniyuki Iwashima Acked-by: Paolo Abeni Link: https://lore.kernel.org/r/20240325202425.60930-13-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- include/net/af_unix.h | 2 +- net/unix/garbage.c | 29 +++++++++++++++-------------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 053f67adb9f1..bb7f10aa0129 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -36,7 +36,7 @@ struct unix_vertex { struct list_head scc_entry; unsigned long out_degree; unsigned long index; - unsigned long lowlink; + unsigned long scc_index; }; struct unix_edge { diff --git a/net/unix/garbage.c b/net/unix/garbage.c index d25841ab2de4..2e66b57f3f0f 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -312,9 +312,8 @@ static bool unix_scc_cyclic(struct list_head *scc) static LIST_HEAD(unix_visited_vertices); static unsigned long unix_vertex_grouped_index = UNIX_VERTEX_INDEX_MARK2; -static void __unix_walk_scc(struct unix_vertex *vertex) +static void __unix_walk_scc(struct unix_vertex *vertex, unsigned long *last_index) { - unsigned long index = UNIX_VERTEX_INDEX_START; LIST_HEAD(vertex_stack); struct unix_edge *edge; LIST_HEAD(edge_stack); @@ -326,9 +325,9 @@ next_vertex: */ list_add(&vertex->scc_entry, &vertex_stack); - vertex->index = index; - vertex->lowlink = index; - index++; + vertex->index = *last_index; + vertex->scc_index = *last_index; + (*last_index)++; /* Explore neighbour vertices (receivers of the current vertex's fd). */ list_for_each_entry(edge, &vertex->edges, vertex_entry) { @@ -358,30 +357,30 @@ prev_vertex: next_vertex = vertex; vertex = edge->predecessor->vertex; - /* If the successor has a smaller lowlink, two vertices - * are in the same SCC, so propagate the smaller lowlink + /* If the successor has a smaller scc_index, two vertices + * are in the same SCC, so propagate the smaller scc_index * to skip SCC finalisation. */ - vertex->lowlink = min(vertex->lowlink, next_vertex->lowlink); + vertex->scc_index = min(vertex->scc_index, next_vertex->scc_index); } else if (next_vertex->index != unix_vertex_grouped_index) { /* Loop detected by a back/cross edge. * - * The successor is on vertex_stack, so two vertices are - * in the same SCC. If the successor has a smaller index, + * The successor is on vertex_stack, so two vertices are in + * the same SCC. If the successor has a smaller *scc_index*, * propagate it to skip SCC finalisation. */ - vertex->lowlink = min(vertex->lowlink, next_vertex->index); + vertex->scc_index = min(vertex->scc_index, next_vertex->scc_index); } else { /* The successor was already grouped as another SCC */ } } - if (vertex->index == vertex->lowlink) { + if (vertex->index == vertex->scc_index) { struct list_head scc; /* SCC finalised. * - * If the lowlink was not updated, all the vertices above on + * If the scc_index was not updated, all the vertices above on * vertex_stack are in the same SCC. Group them using scc_entry. */ __list_cut_position(&scc, &vertex_stack, &vertex->scc_entry); @@ -407,6 +406,8 @@ prev_vertex: static void unix_walk_scc(void) { + unsigned long last_index = UNIX_VERTEX_INDEX_START; + unix_graph_maybe_cyclic = false; /* Visit every vertex exactly once. @@ -416,7 +417,7 @@ static void unix_walk_scc(void) struct unix_vertex *vertex; vertex = list_first_entry(&unix_unvisited_vertices, typeof(*vertex), entry); - __unix_walk_scc(vertex); + __unix_walk_scc(vertex, &last_index); } list_replace_init(&unix_visited_vertices, &unix_unvisited_vertices); From 2c2d0c662d842db1fccab5e4423fbe765769a8f7 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:27 +0000 Subject: [PATCH 017/971] af_unix: Detect dead SCC. commit a15702d8b3aad8ce5268c565bd29f0e02fd2db83 upstream. When iterating SCC, we call unix_vertex_dead() for each vertex to check if the vertex is close()d and has no bridge to another SCC. If both conditions are true for every vertex in SCC, we can execute garbage collection for all skb in the SCC. The actual garbage collection is done in the following patch, replacing the old implementation. Signed-off-by: Kuniyuki Iwashima Acked-by: Paolo Abeni Link: https://lore.kernel.org/r/20240325202425.60930-14-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- net/unix/garbage.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 2e66b57f3f0f..1f53c25fc71b 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -289,6 +289,39 @@ void unix_destroy_fpl(struct scm_fp_list *fpl) unix_free_vertices(fpl); } +static bool unix_vertex_dead(struct unix_vertex *vertex) +{ + struct unix_edge *edge; + struct unix_sock *u; + long total_ref; + + list_for_each_entry(edge, &vertex->edges, vertex_entry) { + struct unix_vertex *next_vertex = unix_edge_successor(edge); + + /* The vertex's fd can be received by a non-inflight socket. */ + if (!next_vertex) + return false; + + /* The vertex's fd can be received by an inflight socket in + * another SCC. + */ + if (next_vertex->scc_index != vertex->scc_index) + return false; + } + + /* No receiver exists out of the same SCC. */ + + edge = list_first_entry(&vertex->edges, typeof(*edge), vertex_entry); + u = edge->predecessor; + total_ref = file_count(u->sk.sk_socket->file); + + /* If not close()d, total_ref > out_degree. */ + if (total_ref != vertex->out_degree) + return false; + + return true; +} + static bool unix_scc_cyclic(struct list_head *scc) { struct unix_vertex *vertex; @@ -377,6 +410,7 @@ prev_vertex: if (vertex->index == vertex->scc_index) { struct list_head scc; + bool scc_dead = true; /* SCC finalised. * @@ -391,6 +425,9 @@ prev_vertex: /* Mark vertex as off-stack. */ vertex->index = unix_vertex_grouped_index; + + if (scc_dead) + scc_dead = unix_vertex_dead(vertex); } if (!unix_graph_maybe_cyclic) @@ -431,13 +468,18 @@ static void unix_walk_scc_fast(void) while (!list_empty(&unix_unvisited_vertices)) { struct unix_vertex *vertex; struct list_head scc; + bool scc_dead = true; vertex = list_first_entry(&unix_unvisited_vertices, typeof(*vertex), entry); list_add(&scc, &vertex->scc_entry); - list_for_each_entry_reverse(vertex, &scc, scc_entry) + list_for_each_entry_reverse(vertex, &scc, scc_entry) { list_move_tail(&vertex->entry, &unix_visited_vertices); + if (scc_dead) + scc_dead = unix_vertex_dead(vertex); + } + list_del(&scc); } From de7921631ff323369aa63a4324695ab54ea4047e Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:28 +0000 Subject: [PATCH 018/971] af_unix: Replace garbage collection algorithm. commit 4090fa373f0e763c43610853d2774b5979915959 upstream. If we find a dead SCC during iteration, we call unix_collect_skb() to splice all skb in the SCC to the global sk_buff_head, hitlist. After iterating all SCC, we unlock unix_gc_lock and purge the queue. Signed-off-by: Kuniyuki Iwashima Acked-by: Paolo Abeni Link: https://lore.kernel.org/r/20240325202425.60930-15-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- include/net/af_unix.h | 8 -- net/unix/af_unix.c | 12 -- net/unix/garbage.c | 318 +++++++++--------------------------------- 3 files changed, 64 insertions(+), 274 deletions(-) diff --git a/include/net/af_unix.h b/include/net/af_unix.h index bb7f10aa0129..d88ca51a9081 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -19,9 +19,6 @@ static inline struct unix_sock *unix_get_socket(struct file *filp) extern spinlock_t unix_gc_lock; extern unsigned int unix_tot_inflight; - -void unix_inflight(struct user_struct *user, struct file *fp); -void unix_notinflight(struct user_struct *user, struct file *fp); void unix_add_edges(struct scm_fp_list *fpl, struct unix_sock *receiver); void unix_del_edges(struct scm_fp_list *fpl); void unix_update_edges(struct unix_sock *receiver); @@ -85,12 +82,7 @@ struct unix_sock { struct sock *peer; struct sock *listener; struct unix_vertex *vertex; - struct list_head link; - unsigned long inflight; spinlock_t lock; - unsigned long gc_flags; -#define UNIX_GC_CANDIDATE 0 -#define UNIX_GC_MAYBE_CYCLE 1 struct socket_wq peer_wq; wait_queue_entry_t peer_wake; struct scm_stat scm_stat; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 93316e9efc53..eee0bccd7877 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -979,12 +979,10 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern, sk->sk_destruct = unix_sock_destructor; u = unix_sk(sk); u->listener = NULL; - u->inflight = 0; u->vertex = NULL; u->path.dentry = NULL; u->path.mnt = NULL; spin_lock_init(&u->lock); - INIT_LIST_HEAD(&u->link); mutex_init(&u->iolock); /* single task reading lock */ mutex_init(&u->bindlock); /* single task binding lock */ init_waitqueue_head(&u->peer_wait); @@ -1770,8 +1768,6 @@ static inline bool too_many_unix_fds(struct task_struct *p) static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) { - int i; - if (too_many_unix_fds(current)) return -ETOOMANYREFS; @@ -1783,9 +1779,6 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) if (!UNIXCB(skb).fp) return -ENOMEM; - for (i = scm->fp->count - 1; i >= 0; i--) - unix_inflight(scm->fp->user, scm->fp->fp[i]); - if (unix_prepare_fpl(UNIXCB(skb).fp)) return -ENOMEM; @@ -1794,15 +1787,10 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb) { - int i; - scm->fp = UNIXCB(skb).fp; UNIXCB(skb).fp = NULL; unix_destroy_fpl(scm->fp); - - for (i = scm->fp->count - 1; i >= 0; i--) - unix_notinflight(scm->fp->user, scm->fp->fp[i]); } static void unix_peek_fds(struct scm_cookie *scm, struct sk_buff *skb) diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 1f53c25fc71b..89ea71d9297b 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -322,6 +322,52 @@ 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_skb(struct list_head *scc, struct sk_buff_head *hitlist) +{ + struct unix_vertex *vertex; + + list_for_each_entry_reverse(vertex, scc, scc_entry) { + struct sk_buff_head *queue; + struct unix_edge *edge; + struct unix_sock *u; + + edge = list_first_entry(&vertex->edges, typeof(*edge), vertex_entry); + u = edge->predecessor; + queue = &u->sk.sk_receive_queue; + + spin_lock(&queue->lock); + + if (u->sk.sk_state == TCP_LISTEN) { + struct sk_buff *skb; + + 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); + skb_queue_splice_init(embryo_queue, hitlist); + spin_unlock(&embryo_queue->lock); + } + } else { + skb_queue_splice_init(queue, hitlist); + +#if IS_ENABLED(CONFIG_AF_UNIX_OOB) + if (u->oob_skb) { + kfree_skb(u->oob_skb); + u->oob_skb = NULL; + } +#endif + } + + spin_unlock(&queue->lock); + } +} + static bool unix_scc_cyclic(struct list_head *scc) { struct unix_vertex *vertex; @@ -345,7 +391,8 @@ static bool unix_scc_cyclic(struct list_head *scc) static LIST_HEAD(unix_visited_vertices); static unsigned long unix_vertex_grouped_index = UNIX_VERTEX_INDEX_MARK2; -static void __unix_walk_scc(struct unix_vertex *vertex, unsigned long *last_index) +static void __unix_walk_scc(struct unix_vertex *vertex, unsigned long *last_index, + struct sk_buff_head *hitlist) { LIST_HEAD(vertex_stack); struct unix_edge *edge; @@ -430,7 +477,9 @@ prev_vertex: scc_dead = unix_vertex_dead(vertex); } - if (!unix_graph_maybe_cyclic) + if (scc_dead) + unix_collect_skb(&scc, hitlist); + else if (!unix_graph_maybe_cyclic) unix_graph_maybe_cyclic = unix_scc_cyclic(&scc); list_del(&scc); @@ -441,7 +490,7 @@ prev_vertex: goto prev_vertex; } -static void unix_walk_scc(void) +static void unix_walk_scc(struct sk_buff_head *hitlist) { unsigned long last_index = UNIX_VERTEX_INDEX_START; @@ -454,7 +503,7 @@ static void unix_walk_scc(void) struct unix_vertex *vertex; vertex = list_first_entry(&unix_unvisited_vertices, typeof(*vertex), entry); - __unix_walk_scc(vertex, &last_index); + __unix_walk_scc(vertex, &last_index, hitlist); } list_replace_init(&unix_visited_vertices, &unix_unvisited_vertices); @@ -463,7 +512,7 @@ static void unix_walk_scc(void) unix_graph_grouped = true; } -static void unix_walk_scc_fast(void) +static void unix_walk_scc_fast(struct sk_buff_head *hitlist) { while (!list_empty(&unix_unvisited_vertices)) { struct unix_vertex *vertex; @@ -480,279 +529,40 @@ static void unix_walk_scc_fast(void) scc_dead = unix_vertex_dead(vertex); } + if (scc_dead) + unix_collect_skb(&scc, hitlist); + list_del(&scc); } list_replace_init(&unix_visited_vertices, &unix_unvisited_vertices); } -static LIST_HEAD(gc_candidates); -static LIST_HEAD(gc_inflight_list); - -/* Keep the number of times in flight count for the file - * descriptor if it is for an AF_UNIX socket. - */ -void unix_inflight(struct user_struct *user, struct file *filp) -{ - struct unix_sock *u = unix_get_socket(filp); - - spin_lock(&unix_gc_lock); - - if (u) { - if (!u->inflight) { - WARN_ON_ONCE(!list_empty(&u->link)); - list_add_tail(&u->link, &gc_inflight_list); - } else { - WARN_ON_ONCE(list_empty(&u->link)); - } - u->inflight++; - } - - spin_unlock(&unix_gc_lock); -} - -void unix_notinflight(struct user_struct *user, struct file *filp) -{ - struct unix_sock *u = unix_get_socket(filp); - - spin_lock(&unix_gc_lock); - - if (u) { - WARN_ON_ONCE(!u->inflight); - WARN_ON_ONCE(list_empty(&u->link)); - - u->inflight--; - if (!u->inflight) - list_del_init(&u->link); - } - - spin_unlock(&unix_gc_lock); -} - -static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *), - struct sk_buff_head *hitlist) -{ - struct sk_buff *skb; - struct sk_buff *next; - - spin_lock(&x->sk_receive_queue.lock); - skb_queue_walk_safe(&x->sk_receive_queue, skb, next) { - /* Do we have file descriptors ? */ - if (UNIXCB(skb).fp) { - bool hit = false; - /* Process the descriptors of this socket */ - int nfd = UNIXCB(skb).fp->count; - struct file **fp = UNIXCB(skb).fp->fp; - - while (nfd--) { - /* Get the socket the fd matches if it indeed does so */ - struct unix_sock *u = unix_get_socket(*fp++); - - /* Ignore non-candidates, they could have been added - * to the queues after starting the garbage collection - */ - if (u && test_bit(UNIX_GC_CANDIDATE, &u->gc_flags)) { - hit = true; - - func(u); - } - } - if (hit && hitlist != NULL) { - __skb_unlink(skb, &x->sk_receive_queue); - __skb_queue_tail(hitlist, skb); - } - } - } - spin_unlock(&x->sk_receive_queue.lock); -} - -static void scan_children(struct sock *x, void (*func)(struct unix_sock *), - struct sk_buff_head *hitlist) -{ - if (x->sk_state != TCP_LISTEN) { - scan_inflight(x, func, hitlist); - } else { - struct sk_buff *skb; - struct sk_buff *next; - struct unix_sock *u; - LIST_HEAD(embryos); - - /* For a listening socket collect the queued embryos - * and perform a scan on them as well. - */ - spin_lock(&x->sk_receive_queue.lock); - skb_queue_walk_safe(&x->sk_receive_queue, skb, next) { - u = unix_sk(skb->sk); - - /* An embryo cannot be in-flight, so it's safe - * to use the list link. - */ - WARN_ON_ONCE(!list_empty(&u->link)); - list_add_tail(&u->link, &embryos); - } - spin_unlock(&x->sk_receive_queue.lock); - - while (!list_empty(&embryos)) { - u = list_entry(embryos.next, struct unix_sock, link); - scan_inflight(&u->sk, func, hitlist); - list_del_init(&u->link); - } - } -} - -static void dec_inflight(struct unix_sock *usk) -{ - usk->inflight--; -} - -static void inc_inflight(struct unix_sock *usk) -{ - usk->inflight++; -} - -static void inc_inflight_move_tail(struct unix_sock *u) -{ - u->inflight++; - - /* If this still might be part of a cycle, move it to the end - * of the list, so that it's checked even if it was already - * passed over - */ - if (test_bit(UNIX_GC_MAYBE_CYCLE, &u->gc_flags)) - list_move_tail(&u->link, &gc_candidates); -} - static bool gc_in_progress; static void __unix_gc(struct work_struct *work) { struct sk_buff_head hitlist; - struct unix_sock *u, *next; - LIST_HEAD(not_cycle_list); - struct list_head cursor; spin_lock(&unix_gc_lock); - if (!unix_graph_maybe_cyclic) + if (!unix_graph_maybe_cyclic) { + spin_unlock(&unix_gc_lock); goto skip_gc; + } + + __skb_queue_head_init(&hitlist); if (unix_graph_grouped) - unix_walk_scc_fast(); + unix_walk_scc_fast(&hitlist); else - unix_walk_scc(); - - /* First, select candidates for garbage collection. Only - * in-flight sockets are considered, and from those only ones - * which don't have any external reference. - * - * Holding unix_gc_lock will protect these candidates from - * being detached, and hence from gaining an external - * reference. Since there are no possible receivers, all - * buffers currently on the candidates' queues stay there - * during the garbage collection. - * - * We also know that no new candidate can be added onto the - * receive queues. Other, non candidate sockets _can_ be - * added to queue, so we must make sure only to touch - * candidates. - * - * Embryos, though never candidates themselves, affect which - * candidates are reachable by the garbage collector. Before - * being added to a listener's queue, an embryo may already - * receive data carrying SCM_RIGHTS, potentially making the - * passed socket a candidate that is not yet reachable by the - * collector. It becomes reachable once the embryo is - * enqueued. Therefore, we must ensure that no SCM-laden - * embryo appears in a (candidate) listener's queue between - * consecutive scan_children() calls. - */ - list_for_each_entry_safe(u, next, &gc_inflight_list, link) { - struct sock *sk = &u->sk; - long total_refs; - - total_refs = file_count(sk->sk_socket->file); - - WARN_ON_ONCE(!u->inflight); - WARN_ON_ONCE(total_refs < u->inflight); - if (total_refs == u->inflight) { - list_move_tail(&u->link, &gc_candidates); - __set_bit(UNIX_GC_CANDIDATE, &u->gc_flags); - __set_bit(UNIX_GC_MAYBE_CYCLE, &u->gc_flags); - - if (sk->sk_state == TCP_LISTEN) { - unix_state_lock_nested(sk, U_LOCK_GC_LISTENER); - unix_state_unlock(sk); - } - } - } - - /* Now remove all internal in-flight reference to children of - * the candidates. - */ - list_for_each_entry(u, &gc_candidates, link) - scan_children(&u->sk, dec_inflight, NULL); - - /* Restore the references for children of all candidates, - * which have remaining references. Do this recursively, so - * only those remain, which form cyclic references. - * - * Use a "cursor" link, to make the list traversal safe, even - * though elements might be moved about. - */ - list_add(&cursor, &gc_candidates); - while (cursor.next != &gc_candidates) { - u = list_entry(cursor.next, struct unix_sock, link); - - /* Move cursor to after the current position. */ - list_move(&cursor, &u->link); - - if (u->inflight) { - list_move_tail(&u->link, ¬_cycle_list); - __clear_bit(UNIX_GC_MAYBE_CYCLE, &u->gc_flags); - scan_children(&u->sk, inc_inflight_move_tail, NULL); - } - } - list_del(&cursor); - - /* Now gc_candidates contains only garbage. Restore original - * inflight counters for these as well, and remove the skbuffs - * which are creating the cycle(s). - */ - skb_queue_head_init(&hitlist); - list_for_each_entry(u, &gc_candidates, link) { - scan_children(&u->sk, inc_inflight, &hitlist); - -#if IS_ENABLED(CONFIG_AF_UNIX_OOB) - if (u->oob_skb) { - kfree_skb(u->oob_skb); - u->oob_skb = NULL; - } -#endif - } - - /* not_cycle_list contains those sockets which do not make up a - * cycle. Restore these to the inflight list. - */ - while (!list_empty(¬_cycle_list)) { - u = list_entry(not_cycle_list.next, struct unix_sock, link); - __clear_bit(UNIX_GC_CANDIDATE, &u->gc_flags); - list_move_tail(&u->link, &gc_inflight_list); - } + unix_walk_scc(&hitlist); spin_unlock(&unix_gc_lock); - /* Here we are. Hitlist is filled. Die. */ __skb_queue_purge(&hitlist); - - spin_lock(&unix_gc_lock); - - /* All candidates should have been detached by now. */ - WARN_ON_ONCE(!list_empty(&gc_candidates)); skip_gc: - /* Paired with READ_ONCE() in wait_for_unix_gc(). */ WRITE_ONCE(gc_in_progress, false); - - spin_unlock(&unix_gc_lock); } static DECLARE_WORK(unix_gc_work, __unix_gc); From 7b1ffbd3b22e755d481d49647dcb7c5cfbde5844 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:29 +0000 Subject: [PATCH 019/971] af_unix: Remove lock dance in unix_peek_fds(). commit 118f457da9ed58a79e24b73c2ef0aa1987241f0e upstream. In the previous GC implementation, the shape of the inflight socket graph was not expected to change while GC was in progress. MSG_PEEK was tricky because it could install inflight fd silently and transform the graph. Let's say we peeked a fd, which was a listening socket, and accept()ed some embryo sockets from it. The garbage collection algorithm would have been confused because the set of sockets visited in scan_inflight() would change within the same GC invocation. That's why we placed spin_lock(&unix_gc_lock) and spin_unlock() in unix_peek_fds() with a fat comment. In the new GC implementation, we no longer garbage-collect the socket if it exists in another queue, that is, if it has a bridge to another SCC. Also, accept() will require the lock if it has edges. Thus, we need not do the complicated lock dance. Signed-off-by: Kuniyuki Iwashima Link: https://lore.kernel.org/r/20240401173125.92184-3-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- include/net/af_unix.h | 1 - net/unix/af_unix.c | 42 ------------------------------------------ net/unix/garbage.c | 2 +- 3 files changed, 1 insertion(+), 44 deletions(-) diff --git a/include/net/af_unix.h b/include/net/af_unix.h index d88ca51a9081..47042de4a2a9 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -17,7 +17,6 @@ static inline struct unix_sock *unix_get_socket(struct file *filp) } #endif -extern spinlock_t unix_gc_lock; extern unsigned int unix_tot_inflight; void unix_add_edges(struct scm_fp_list *fpl, struct unix_sock *receiver); void unix_del_edges(struct scm_fp_list *fpl); diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index eee0bccd7877..df70d8a7ee83 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1796,48 +1796,6 @@ static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb) static void unix_peek_fds(struct scm_cookie *scm, struct sk_buff *skb) { scm->fp = scm_fp_dup(UNIXCB(skb).fp); - - /* - * Garbage collection of unix sockets starts by selecting a set of - * candidate sockets which have reference only from being in flight - * (total_refs == inflight_refs). This condition is checked once during - * the candidate collection phase, and candidates are marked as such, so - * that non-candidates can later be ignored. While inflight_refs is - * protected by unix_gc_lock, total_refs (file count) is not, hence this - * is an instantaneous decision. - * - * Once a candidate, however, the socket must not be reinstalled into a - * file descriptor while the garbage collection is in progress. - * - * If the above conditions are met, then the directed graph of - * candidates (*) does not change while unix_gc_lock is held. - * - * Any operations that changes the file count through file descriptors - * (dup, close, sendmsg) does not change the graph since candidates are - * not installed in fds. - * - * Dequeing a candidate via recvmsg would install it into an fd, but - * that takes unix_gc_lock to decrement the inflight count, so it's - * serialized with garbage collection. - * - * MSG_PEEK is special in that it does not change the inflight count, - * yet does install the socket into an fd. The following lock/unlock - * pair is to ensure serialization with garbage collection. It must be - * done between incrementing the file count and installing the file into - * an fd. - * - * If garbage collection starts after the barrier provided by the - * lock/unlock, then it will see the elevated refcount and not mark this - * as a candidate. If a garbage collection is already in progress - * before the file count was incremented, then the lock/unlock pair will - * ensure that garbage collection is finished before progressing to - * installing the fd. - * - * (*) A -> B where B is on the queue of A or B is on the queue of C - * which is on the queue of listening socket A. - */ - spin_lock(&unix_gc_lock); - spin_unlock(&unix_gc_lock); } static void unix_destruct_scm(struct sk_buff *skb) diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 89ea71d9297b..12a4ec27e0d4 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -183,7 +183,7 @@ static void unix_free_vertices(struct scm_fp_list *fpl) } } -DEFINE_SPINLOCK(unix_gc_lock); +static DEFINE_SPINLOCK(unix_gc_lock); unsigned int unix_tot_inflight; void unix_add_edges(struct scm_fp_list *fpl, struct unix_sock *receiver) From 3600729b7fc0564ccb1ceec493fa446858b6d95b Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:30 +0000 Subject: [PATCH 020/971] af_unix: Try not to hold unix_gc_lock during accept(). commit fd86344823b521149bb31d91eba900ba3525efa6 upstream. Commit dcf70df2048d ("af_unix: Fix up unix_edge.successor for embryo socket.") added spin_lock(&unix_gc_lock) in accept() path, and it caused regression in a stress test as reported by kernel test robot. If the embryo socket is not part of the inflight graph, we need not hold the lock. To decide that in O(1) time and avoid the regression in the normal use case, 1. add a new stat unix_sk(sk)->scm_stat.nr_unix_fds 2. count the number of inflight AF_UNIX sockets in the receive queue under unix_state_lock() 3. move unix_update_edges() call under unix_state_lock() 4. avoid locking if nr_unix_fds is 0 in unix_update_edges() Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-lkp/202404101427.92a08551-oliver.sang@intel.com Signed-off-by: Kuniyuki Iwashima Link: https://lore.kernel.org/r/20240413021928.20946-1-kuniyu@amazon.com Signed-off-by: Paolo Abeni Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- include/net/af_unix.h | 1 + net/unix/af_unix.c | 2 +- net/unix/garbage.c | 20 ++++++++++++++++---- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 47042de4a2a9..b6eedf7650da 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -67,6 +67,7 @@ struct unix_skb_parms { struct scm_stat { atomic_t nr_fds; + unsigned long nr_unix_fds; }; #define UNIXCB(skb) (*(struct unix_skb_parms *)&((skb)->cb)) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index df70d8a7ee83..236a2cd2bc93 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1703,12 +1703,12 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags, } tsk = skb->sk; - unix_update_edges(unix_sk(tsk)); skb_free_datagram(sk, skb); wake_up_interruptible(&unix_sk(sk)->peer_wait); /* attach accepted sock to socket */ unix_state_lock(tsk); + unix_update_edges(unix_sk(tsk)); newsock->state = SS_CONNECTED; unix_sock_inherit_flags(sock, newsock); sock_graft(tsk, newsock); diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 12a4ec27e0d4..95240a59808f 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -209,6 +209,7 @@ void unix_add_edges(struct scm_fp_list *fpl, struct unix_sock *receiver) unix_add_edge(fpl, edge); } while (i < fpl->count_unix); + receiver->scm_stat.nr_unix_fds += fpl->count_unix; WRITE_ONCE(unix_tot_inflight, unix_tot_inflight + fpl->count_unix); out: WRITE_ONCE(fpl->user->unix_inflight, fpl->user->unix_inflight + fpl->count); @@ -222,6 +223,7 @@ out: void unix_del_edges(struct scm_fp_list *fpl) { + struct unix_sock *receiver; int i = 0; spin_lock(&unix_gc_lock); @@ -235,6 +237,8 @@ void unix_del_edges(struct scm_fp_list *fpl) unix_del_edge(fpl, edge); } while (i < fpl->count_unix); + receiver = fpl->edges[0].successor; + receiver->scm_stat.nr_unix_fds -= fpl->count_unix; WRITE_ONCE(unix_tot_inflight, unix_tot_inflight - fpl->count_unix); out: WRITE_ONCE(fpl->user->unix_inflight, fpl->user->unix_inflight - fpl->count); @@ -246,10 +250,18 @@ out: void unix_update_edges(struct unix_sock *receiver) { - spin_lock(&unix_gc_lock); - unix_update_graph(unix_sk(receiver->listener)->vertex); - receiver->listener = NULL; - spin_unlock(&unix_gc_lock); + /* nr_unix_fds is only updated under unix_state_lock(). + * If it's 0 here, the embryo socket is not part of the + * inflight graph, and GC will not see it, so no lock needed. + */ + if (!receiver->scm_stat.nr_unix_fds) { + receiver->listener = NULL; + } else { + spin_lock(&unix_gc_lock); + unix_update_graph(unix_sk(receiver->listener)->vertex); + receiver->listener = NULL; + spin_unlock(&unix_gc_lock); + } } int unix_prepare_fpl(struct scm_fp_list *fpl) From a288920ff9dab3202965f86af817fd4e982ef186 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:31 +0000 Subject: [PATCH 021/971] af_unix: Don't access successor in unix_del_edges() during GC. commit 1af2dface5d286dd1f2f3405a0d6fa9f2c8fb998 upstream. syzbot reported use-after-free in unix_del_edges(). [0] What the repro does is basically repeat the following quickly. 1. pass a fd of an AF_UNIX socket to itself socketpair(AF_UNIX, SOCK_DGRAM, 0, [3, 4]) = 0 sendmsg(3, {..., msg_control=[{cmsg_len=20, cmsg_level=SOL_SOCKET, cmsg_type=SCM_RIGHTS, cmsg_data=[4]}], ...}, 0) = 0 2. pass other fds of AF_UNIX sockets to the socket above socketpair(AF_UNIX, SOCK_SEQPACKET, 0, [5, 6]) = 0 sendmsg(3, {..., msg_control=[{cmsg_len=48, cmsg_level=SOL_SOCKET, cmsg_type=SCM_RIGHTS, cmsg_data=[5, 6]}], ...}, 0) = 0 3. close all sockets Here, two skb are created, and every unix_edge->successor is the first socket. Then, __unix_gc() will garbage-collect the two skb: (a) free skb with self-referencing fd (b) free skb holding other sockets After (a), the self-referencing socket will be scheduled to be freed later by the delayed_fput() task. syzbot repeated the sequences above (1. ~ 3.) quickly and triggered the task concurrently while GC was running. So, at (b), the socket was already freed, and accessing it was illegal. unix_del_edges() accesses the receiver socket as edge->successor to optimise GC. However, we should not do it during GC. Garbage-collecting sockets does not change the shape of the rest of the graph, so we need not call unix_update_graph() to update unix_graph_grouped when we purge skb. However, if we clean up all loops in the unix_walk_scc_fast() path, unix_graph_maybe_cyclic remains unchanged (true), and __unix_gc() will call unix_walk_scc_fast() continuously even though there is no socket to garbage-collect. To keep that optimisation while fixing UAF, let's add the same updating logic of unix_graph_maybe_cyclic in unix_walk_scc_fast() as done in unix_walk_scc() and __unix_walk_scc(). Note that when unix_del_edges() is called from other places, the receiver socket is always alive: - sendmsg: the successor's sk_refcnt is bumped by sock_hold() unix_find_other() for SOCK_DGRAM, connect() for SOCK_STREAM - recvmsg: the successor is the receiver, and its fd is alive [0]: BUG: KASAN: slab-use-after-free in unix_edge_successor net/unix/garbage.c:109 [inline] BUG: KASAN: slab-use-after-free in unix_del_edge net/unix/garbage.c:165 [inline] BUG: KASAN: slab-use-after-free in unix_del_edges+0x148/0x630 net/unix/garbage.c:237 Read of size 8 at addr ffff888079c6e640 by task kworker/u8:6/1099 CPU: 0 PID: 1099 Comm: kworker/u8:6 Not tainted 6.9.0-rc4-next-20240418-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/27/2024 Workqueue: events_unbound __unix_gc Call Trace: __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x241/0x360 lib/dump_stack.c:114 print_address_description mm/kasan/report.c:377 [inline] print_report+0x169/0x550 mm/kasan/report.c:488 kasan_report+0x143/0x180 mm/kasan/report.c:601 unix_edge_successor net/unix/garbage.c:109 [inline] unix_del_edge net/unix/garbage.c:165 [inline] unix_del_edges+0x148/0x630 net/unix/garbage.c:237 unix_destroy_fpl+0x59/0x210 net/unix/garbage.c:298 unix_detach_fds net/unix/af_unix.c:1811 [inline] unix_destruct_scm+0x13e/0x210 net/unix/af_unix.c:1826 skb_release_head_state+0x100/0x250 net/core/skbuff.c:1127 skb_release_all net/core/skbuff.c:1138 [inline] __kfree_skb net/core/skbuff.c:1154 [inline] kfree_skb_reason+0x16d/0x3b0 net/core/skbuff.c:1190 __skb_queue_purge_reason include/linux/skbuff.h:3251 [inline] __skb_queue_purge include/linux/skbuff.h:3256 [inline] __unix_gc+0x1732/0x1830 net/unix/garbage.c:575 process_one_work kernel/workqueue.c:3218 [inline] process_scheduled_works+0xa2c/0x1830 kernel/workqueue.c:3299 worker_thread+0x86d/0xd70 kernel/workqueue.c:3380 kthread+0x2f0/0x390 kernel/kthread.c:389 ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 Allocated by task 14427: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x3f/0x80 mm/kasan/common.c:68 unpoison_slab_object mm/kasan/common.c:312 [inline] __kasan_slab_alloc+0x66/0x80 mm/kasan/common.c:338 kasan_slab_alloc include/linux/kasan.h:201 [inline] slab_post_alloc_hook mm/slub.c:3897 [inline] slab_alloc_node mm/slub.c:3957 [inline] kmem_cache_alloc_noprof+0x135/0x290 mm/slub.c:3964 sk_prot_alloc+0x58/0x210 net/core/sock.c:2074 sk_alloc+0x38/0x370 net/core/sock.c:2133 unix_create1+0xb4/0x770 unix_create+0x14e/0x200 net/unix/af_unix.c:1034 __sock_create+0x490/0x920 net/socket.c:1571 sock_create net/socket.c:1622 [inline] __sys_socketpair+0x33e/0x720 net/socket.c:1773 __do_sys_socketpair net/socket.c:1822 [inline] __se_sys_socketpair net/socket.c:1819 [inline] __x64_sys_socketpair+0x9b/0xb0 net/socket.c:1819 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf5/0x240 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 1805: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x3f/0x80 mm/kasan/common.c:68 kasan_save_free_info+0x40/0x50 mm/kasan/generic.c:579 poison_slab_object+0xe0/0x150 mm/kasan/common.c:240 __kasan_slab_free+0x37/0x60 mm/kasan/common.c:256 kasan_slab_free include/linux/kasan.h:184 [inline] slab_free_hook mm/slub.c:2190 [inline] slab_free mm/slub.c:4393 [inline] kmem_cache_free+0x145/0x340 mm/slub.c:4468 sk_prot_free net/core/sock.c:2114 [inline] __sk_destruct+0x467/0x5f0 net/core/sock.c:2208 sock_put include/net/sock.h:1948 [inline] unix_release_sock+0xa8b/0xd20 net/unix/af_unix.c:665 unix_release+0x91/0xc0 net/unix/af_unix.c:1049 __sock_release net/socket.c:659 [inline] sock_close+0xbc/0x240 net/socket.c:1421 __fput+0x406/0x8b0 fs/file_table.c:422 delayed_fput+0x59/0x80 fs/file_table.c:445 process_one_work kernel/workqueue.c:3218 [inline] process_scheduled_works+0xa2c/0x1830 kernel/workqueue.c:3299 worker_thread+0x86d/0xd70 kernel/workqueue.c:3380 kthread+0x2f0/0x390 kernel/kthread.c:389 ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 The buggy address belongs to the object at ffff888079c6e000 which belongs to the cache UNIX of size 1920 The buggy address is located 1600 bytes inside of freed 1920-byte region [ffff888079c6e000, ffff888079c6e780) Reported-by: syzbot+f3f3eef1d2100200e593@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=f3f3eef1d2100200e593 Fixes: 77e5593aebba ("af_unix: Skip GC if no cycle exists.") Fixes: fd86344823b5 ("af_unix: Try not to hold unix_gc_lock during accept().") Signed-off-by: Kuniyuki Iwashima Link: https://lore.kernel.org/r/20240419235102.31707-1-kuniyu@amazon.com Signed-off-by: Paolo Abeni Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- net/unix/garbage.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 95240a59808f..d76450133e4f 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -158,11 +158,14 @@ static void unix_add_edge(struct scm_fp_list *fpl, struct unix_edge *edge) unix_update_graph(unix_edge_successor(edge)); } +static bool gc_in_progress; + static void unix_del_edge(struct scm_fp_list *fpl, struct unix_edge *edge) { struct unix_vertex *vertex = edge->predecessor->vertex; - unix_update_graph(unix_edge_successor(edge)); + if (!gc_in_progress) + unix_update_graph(unix_edge_successor(edge)); list_del(&edge->vertex_entry); vertex->out_degree--; @@ -237,8 +240,10 @@ void unix_del_edges(struct scm_fp_list *fpl) unix_del_edge(fpl, edge); } while (i < fpl->count_unix); - receiver = fpl->edges[0].successor; - receiver->scm_stat.nr_unix_fds -= fpl->count_unix; + if (!gc_in_progress) { + receiver = fpl->edges[0].successor; + receiver->scm_stat.nr_unix_fds -= fpl->count_unix; + } WRITE_ONCE(unix_tot_inflight, unix_tot_inflight - fpl->count_unix); out: WRITE_ONCE(fpl->user->unix_inflight, fpl->user->unix_inflight - fpl->count); @@ -526,6 +531,8 @@ static void unix_walk_scc(struct sk_buff_head *hitlist) static void unix_walk_scc_fast(struct sk_buff_head *hitlist) { + unix_graph_maybe_cyclic = false; + while (!list_empty(&unix_unvisited_vertices)) { struct unix_vertex *vertex; struct list_head scc; @@ -543,6 +550,8 @@ static void unix_walk_scc_fast(struct sk_buff_head *hitlist) if (scc_dead) unix_collect_skb(&scc, hitlist); + else if (!unix_graph_maybe_cyclic) + unix_graph_maybe_cyclic = unix_scc_cyclic(&scc); list_del(&scc); } @@ -550,8 +559,6 @@ static void unix_walk_scc_fast(struct sk_buff_head *hitlist) list_replace_init(&unix_visited_vertices, &unix_unvisited_vertices); } -static bool gc_in_progress; - static void __unix_gc(struct work_struct *work) { struct sk_buff_head hitlist; From abf3ffaeef6037568282b95c8a31946cf94f451a Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Wed, 12 Feb 2025 18:03:52 +0100 Subject: [PATCH 022/971] arm64: dts: qcom: ipq9574: Add missing properties for cryptobam commit b4cd966edb2deb5c75fe356191422e127445b830 upstream. num-channels and qcom,num-ees are required for BAM nodes without clock, because the driver cannot ensure the hardware is powered on when trying to obtain the information from the hardware registers. Specifying the node without these properties is unsafe and has caused early boot crashes for other SoCs before [1, 2]. Add the missing information from the hardware registers to ensure the driver can probe successfully without causing crashes. [1]: https://lore.kernel.org/r/CY01EKQVWE36.B9X5TDXAREPF@fairphone.com/ [2]: https://lore.kernel.org/r/20230626145959.646747-1-krzysztof.kozlowski@linaro.org/ Cc: stable@vger.kernel.org Tested-by: Md Sadre Alam Fixes: ffadc79ed99f ("arm64: dts: qcom: ipq9574: Enable crypto nodes") Signed-off-by: Stephan Gerhold Link: https://lore.kernel.org/r/20250212-bam-dma-fixes-v1-6-f560889e65d8@linaro.org Signed-off-by: Bjorn Andersson Signed-off-by: Greg Kroah-Hartman --- arch/arm64/boot/dts/qcom/ipq9574.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/ipq9574.dtsi b/arch/arm64/boot/dts/qcom/ipq9574.dtsi index 8a72ad4afd03..82e4fd5eb388 100644 --- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi @@ -231,6 +231,8 @@ interrupts = ; #dma-cells = <1>; qcom,ee = <1>; + qcom,num-ees = <4>; + num-channels = <16>; qcom,controlled-remotely; }; From 5dd982ff67d1e89753b995f342c1c3cd0b3b89e5 Mon Sep 17 00:00:00 2001 From: Alok Tiwari Date: Wed, 14 May 2025 04:46:51 -0700 Subject: [PATCH 023/971] arm64: dts: qcom: sm8350: Fix typo in pil_camera_mem node commit 295217420a44403a33c30f99d8337fe7b07eb02b upstream. There is a typo in sm8350.dts where the node label mmeory@85200000 should be memory@85200000. This patch corrects the typo for clarity and consistency. Fixes: b7e8f433a673 ("arm64: dts: qcom: Add basic devicetree support for SM8350 SoC") Cc: stable@vger.kernel.org Signed-off-by: Alok Tiwari Link: https://lore.kernel.org/r/20250514114656.2307828-1-alok.a.tiwari@oracle.com Signed-off-by: Bjorn Andersson Signed-off-by: Greg Kroah-Hartman --- arch/arm64/boot/dts/qcom/sm8350.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi index 2a4d950ac02b..5376c0a00fab 100644 --- a/arch/arm64/boot/dts/qcom/sm8350.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi @@ -442,7 +442,7 @@ no-map; }; - pil_camera_mem: mmeory@85200000 { + pil_camera_mem: memory@85200000 { reg = <0x0 0x85200000 0x0 0x500000>; no-map; }; From feadf31790331977bc368f9536bca28aa9e456f1 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Wed, 12 Feb 2025 18:03:48 +0100 Subject: [PATCH 024/971] arm64: dts: qcom: sm8450: Add missing properties for cryptobam commit 0fe6357229cb15a64b6413c62f1c3d4de68ce55f upstream. num-channels and qcom,num-ees are required for BAM nodes without clock, because the driver cannot ensure the hardware is powered on when trying to obtain the information from the hardware registers. Specifying the node without these properties is unsafe and has caused early boot crashes for other SoCs before [1, 2]. Add the missing information from the hardware registers to ensure the driver can probe successfully without causing crashes. [1]: https://lore.kernel.org/r/CY01EKQVWE36.B9X5TDXAREPF@fairphone.com/ [2]: https://lore.kernel.org/r/20230626145959.646747-1-krzysztof.kozlowski@linaro.org/ Cc: stable@vger.kernel.org Fixes: b92b0d2f7582 ("arm64: dts: qcom: sm8450: add crypto nodes") Signed-off-by: Stephan Gerhold Link: https://lore.kernel.org/r/20250212-bam-dma-fixes-v1-2-f560889e65d8@linaro.org Signed-off-by: Bjorn Andersson Signed-off-by: Greg Kroah-Hartman --- arch/arm64/boot/dts/qcom/sm8450.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi index 3b4d78823008..c1ed39cac8c5 100644 --- a/arch/arm64/boot/dts/qcom/sm8450.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi @@ -4233,6 +4233,8 @@ interrupts = ; #dma-cells = <1>; qcom,ee = <0>; + qcom,num-ees = <4>; + num-channels = <16>; qcom,controlled-remotely; iommus = <&apps_smmu 0x584 0x11>, <&apps_smmu 0x588 0x0>, From cf27046208bd8e84e4345040e5c04231255cd653 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Wed, 12 Feb 2025 18:03:49 +0100 Subject: [PATCH 025/971] arm64: dts: qcom: sm8550: Add missing properties for cryptobam commit 663cd2cad36da23cf1a3db7868fce9f1a19b2d61 upstream. num-channels and qcom,num-ees are required for BAM nodes without clock, because the driver cannot ensure the hardware is powered on when trying to obtain the information from the hardware registers. Specifying the node without these properties is unsafe and has caused early boot crashes for other SoCs before [1, 2]. Add the missing information from the hardware registers to ensure the driver can probe successfully without causing crashes. [1]: https://lore.kernel.org/r/CY01EKQVWE36.B9X5TDXAREPF@fairphone.com/ [2]: https://lore.kernel.org/r/20230626145959.646747-1-krzysztof.kozlowski@linaro.org/ Cc: stable@vger.kernel.org Fixes: 433477c3bf0b ("arm64: dts: qcom: sm8550: add QCrypto nodes") Signed-off-by: Stephan Gerhold Link: https://lore.kernel.org/r/20250212-bam-dma-fixes-v1-3-f560889e65d8@linaro.org Signed-off-by: Bjorn Andersson Signed-off-by: Greg Kroah-Hartman --- arch/arm64/boot/dts/qcom/sm8550.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi index bc9a1fca2db3..c14c6f8583d5 100644 --- a/arch/arm64/boot/dts/qcom/sm8550.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi @@ -1866,6 +1866,8 @@ interrupts = ; #dma-cells = <1>; qcom,ee = <0>; + qcom,num-ees = <4>; + num-channels = <20>; qcom,controlled-remotely; iommus = <&apps_smmu 0x480 0x0>, <&apps_smmu 0x481 0x0>; From ee1209b9f57ba796575bd8b2be3e78acc25e8b39 Mon Sep 17 00:00:00 2001 From: Yemike Abhilash Chandra Date: Tue, 15 Apr 2025 16:43:23 +0530 Subject: [PATCH 026/971] arm64: dts: ti: k3-am68-sk: Fix regulator hierarchy commit 7edf0a4d3bb7f5cd84f172b76c380c4259bb4ef8 upstream. Update the vin-supply of the TLV71033 regulator from LM5141 (vsys_3v3) to LM61460 (vsys_5v0) to match the schematics. Add a fixed regulator node for the LM61460 5V supply to support this change. AM68-SK schematics: https://www.ti.com/lit/zip/sprr463 Fixes: a266c180b398 ("arm64: dts: ti: k3-am68-sk: Add support for AM68 SK base board") Cc: stable@vger.kernel.org Signed-off-by: Yemike Abhilash Chandra Reviewed-by: Neha Malcom Francis Reviewed-by: Udit Kumar Link: https://lore.kernel.org/r/20250415111328.3847502-3-y-abhilashchandra@ti.com Signed-off-by: Nishanth Menon Signed-off-by: Greg Kroah-Hartman --- arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts b/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts index 5df5946687b3..2e92f4174b3c 100644 --- a/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts +++ b/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts @@ -43,6 +43,17 @@ regulator-boot-on; }; + vsys_5v0: regulator-vsys5v0 { + /* Output of LM61460 */ + compatible = "regulator-fixed"; + regulator-name = "vsys_5v0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vusb_main>; + regulator-always-on; + regulator-boot-on; + }; + vsys_3v3: regulator-vsys3v3 { /* Output of LM5141 */ compatible = "regulator-fixed"; @@ -75,7 +86,7 @@ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <3300000>; regulator-boot-on; - vin-supply = <&vsys_3v3>; + vin-supply = <&vsys_5v0>; gpios = <&main_gpio0 49 GPIO_ACTIVE_HIGH>; states = <1800000 0x0>, <3300000 0x1>; From 295f7c579b07b5b7cf2dffe485f71cc2f27647cb Mon Sep 17 00:00:00 2001 From: Pedro Tammela Date: Thu, 22 May 2025 15:14:47 -0300 Subject: [PATCH 027/971] net_sched: hfsc: Address reentrant enqueue adding class to eltree twice commit ac9fe7dd8e730a103ae4481147395cc73492d786 upstream. Savino says: "We are writing to report that this recent patch (141d34391abbb315d68556b7c67ad97885407547) [1] can be bypassed, and a UAF can still occur when HFSC is utilized with NETEM. The patch only checks the cl->cl_nactive field to determine whether it is the first insertion or not [2], but this field is only incremented by init_vf [3]. By using HFSC_RSC (which uses init_ed) [4], it is possible to bypass the check and insert the class twice in the eltree. Under normal conditions, this would lead to an infinite loop in hfsc_dequeue for the reasons we already explained in this report [5]. However, if TBF is added as root qdisc and it is configured with a very low rate, it can be utilized to prevent packets from being dequeued. This behavior can be exploited to perform subsequent insertions in the HFSC eltree and cause a UAF." To fix both the UAF and the infinite loop, with netem as an hfsc child, check explicitly in hfsc_enqueue whether the class is already in the eltree whenever the HFSC_RSC flag is set. [1] https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=141d34391abbb315d68556b7c67ad97885407547 [2] https://elixir.bootlin.com/linux/v6.15-rc5/source/net/sched/sch_hfsc.c#L1572 [3] https://elixir.bootlin.com/linux/v6.15-rc5/source/net/sched/sch_hfsc.c#L677 [4] https://elixir.bootlin.com/linux/v6.15-rc5/source/net/sched/sch_hfsc.c#L1574 [5] https://lore.kernel.org/netdev/8DuRWwfqjoRDLDmBMlIfbrsZg9Gx50DHJc1ilxsEBNe2D6NMoigR_eIRIG0LOjMc3r10nUUZtArXx4oZBIdUfZQrwjcQhdinnMis_0G7VEk=@willsroot.io/T/#u Fixes: 37d9cf1a3ce3 ("sched: Fix detection of empty queues in child qdiscs") Reported-by: Savino Dicanosa Reported-by: William Liu Acked-by: Jamal Hadi Salim Tested-by: Victor Nogueira Signed-off-by: Pedro Tammela Link: https://patch.msgid.link/20250522181448.1439717-2-pctammela@mojatatu.com Signed-off-by: Paolo Abeni Signed-off-by: Greg Kroah-Hartman --- net/sched/sch_hfsc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index 1bf4fd698c41..afcb83d469ff 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -175,6 +175,11 @@ struct hfsc_sched { #define HT_INFINITY 0xffffffffffffffffULL /* infinite time value */ +static bool cl_in_el_or_vttree(struct hfsc_class *cl) +{ + return ((cl->cl_flags & HFSC_FSC) && cl->cl_nactive) || + ((cl->cl_flags & HFSC_RSC) && !RB_EMPTY_NODE(&cl->el_node)); +} /* * eligible tree holds backlogged classes being sorted by their eligible times. @@ -1040,6 +1045,8 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (cl == NULL) return -ENOBUFS; + RB_CLEAR_NODE(&cl->el_node); + err = tcf_block_get(&cl->block, &cl->filter_list, sch, extack); if (err) { kfree(cl); @@ -1573,7 +1580,7 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) sch->qstats.backlog += len; sch->q.qlen++; - if (first && !cl->cl_nactive) { + if (first && !cl_in_el_or_vttree(cl)) { if (cl->cl_flags & HFSC_RSC) init_ed(cl, len); if (cl->cl_flags & HFSC_FSC) From 10778e2f49a2c9f84b60ce1c906a024b1f2f8be4 Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Thu, 8 May 2025 16:16:40 +0100 Subject: [PATCH 028/971] perf/arm-cmn: Fix REQ2/SNP2 mixup commit 11b0f576e0cbde6a12258f2af6753b17b8df342b upstream. Somehow the encodings for REQ2/SNP2 channels in XP events got mixed up... Unmix them. CC: stable@vger.kernel.org Fixes: 23760a014417 ("perf/arm-cmn: Add CMN-700 support") Signed-off-by: Robin Murphy Link: https://lore.kernel.org/r/087023e9737ac93d7ec7a841da904758c254cb01.1746717400.git.robin.murphy@arm.com Signed-off-by: Will Deacon Signed-off-by: Greg Kroah-Hartman --- drivers/perf/arm-cmn.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c index 7bd1733d7977..fdbc57f23614 100644 --- a/drivers/perf/arm-cmn.c +++ b/drivers/perf/arm-cmn.c @@ -684,8 +684,8 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj, if ((chan == 5 && cmn->rsp_vc_num < 2) || (chan == 6 && cmn->dat_vc_num < 2) || - (chan == 7 && cmn->snp_vc_num < 2) || - (chan == 8 && cmn->req_vc_num < 2)) + (chan == 7 && cmn->req_vc_num < 2) || + (chan == 8 && cmn->snp_vc_num < 2)) return 0; } @@ -841,8 +841,8 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj, _CMN_EVENT_XP(pub_##_name, (_event) | (4 << 5)), \ _CMN_EVENT_XP(rsp2_##_name, (_event) | (5 << 5)), \ _CMN_EVENT_XP(dat2_##_name, (_event) | (6 << 5)), \ - _CMN_EVENT_XP(snp2_##_name, (_event) | (7 << 5)), \ - _CMN_EVENT_XP(req2_##_name, (_event) | (8 << 5)) + _CMN_EVENT_XP(req2_##_name, (_event) | (7 << 5)), \ + _CMN_EVENT_XP(snp2_##_name, (_event) | (8 << 5)) #define CMN_EVENT_XP_DAT(_name, _event) \ _CMN_EVENT_XP_PORT(dat_##_name, (_event) | (3 << 5)), \ From 0ec1e98bf5366ce892febc575d25f6c9212bb4c0 Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Mon, 12 May 2025 18:11:54 +0100 Subject: [PATCH 029/971] perf/arm-cmn: Initialise cmn->cpu earlier commit 597704e201068db3d104de3c7a4d447ff8209127 upstream. For all the complexity of handling affinity for CPU hotplug, what we've apparently managed to overlook is that arm_cmn_init_irqs() has in fact always been setting the *initial* affinity of all IRQs to CPU 0, not the CPU we subsequently choose for event scheduling. Oh dear. Cc: stable@vger.kernel.org Fixes: 0ba64770a2f2 ("perf: Add Arm CMN-600 PMU driver") Signed-off-by: Robin Murphy Reviewed-by: Ilkka Koskinen Link: https://lore.kernel.org/r/b12fccba6b5b4d2674944f59e4daad91cd63420b.1747069914.git.robin.murphy@arm.com Signed-off-by: Will Deacon Signed-off-by: Greg Kroah-Hartman --- drivers/perf/arm-cmn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c index fdbc57f23614..77aa37de5988 100644 --- a/drivers/perf/arm-cmn.c +++ b/drivers/perf/arm-cmn.c @@ -2443,6 +2443,7 @@ static int arm_cmn_probe(struct platform_device *pdev) cmn->dev = &pdev->dev; cmn->part = (unsigned long)device_get_match_data(cmn->dev); + cmn->cpu = cpumask_local_spread(0, dev_to_node(cmn->dev)); platform_set_drvdata(pdev, cmn); if (cmn->part == PART_CMN600 && has_acpi_companion(cmn->dev)) { @@ -2470,7 +2471,6 @@ static int arm_cmn_probe(struct platform_device *pdev) if (err) return err; - cmn->cpu = cpumask_local_spread(0, dev_to_node(cmn->dev)); cmn->pmu = (struct pmu) { .module = THIS_MODULE, .attr_groups = arm_cmn_attr_groups, From c0c8d419dade95e70ca80c68d34e7b05934e3f32 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 21 May 2025 14:45:32 +0000 Subject: [PATCH 030/971] af_unix: Add dead flag to struct scm_fp_list. commit 7172dc93d621d5dc302d007e95ddd1311ec64283 upstream. Commit 1af2dface5d2 ("af_unix: Don't access successor in unix_del_edges() during GC.") fixed use-after-free by avoid accessing edge->successor while GC is in progress. However, there could be a small race window where another process could call unix_del_edges() while gc_in_progress is true and __skb_queue_purge() is on the way. So, we need another marker for struct scm_fp_list which indicates if the skb is garbage-collected. This patch adds dead flag in struct scm_fp_list and set it true before calling __skb_queue_purge(). Fixes: 1af2dface5d2 ("af_unix: Don't access successor in unix_del_edges() during GC.") Signed-off-by: Kuniyuki Iwashima Acked-by: Paolo Abeni Link: https://lore.kernel.org/r/20240508171150.50601-1-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- include/net/scm.h | 1 + net/core/scm.c | 1 + net/unix/garbage.c | 14 ++++++++++---- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/include/net/scm.h b/include/net/scm.h index 07d66c41cc33..059e287745dc 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -32,6 +32,7 @@ struct scm_fp_list { short max; #ifdef CONFIG_UNIX bool inflight; + bool dead; struct list_head vertices; struct unix_edge *edges; #endif diff --git a/net/core/scm.c b/net/core/scm.c index 1e47788379c2..431bfb3ea392 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -91,6 +91,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp) fpl->user = NULL; #if IS_ENABLED(CONFIG_UNIX) fpl->inflight = false; + fpl->dead = false; fpl->edges = NULL; INIT_LIST_HEAD(&fpl->vertices); #endif diff --git a/net/unix/garbage.c b/net/unix/garbage.c index d76450133e4f..1f8b8cdfcdc8 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -158,13 +158,11 @@ static void unix_add_edge(struct scm_fp_list *fpl, struct unix_edge *edge) unix_update_graph(unix_edge_successor(edge)); } -static bool gc_in_progress; - static void unix_del_edge(struct scm_fp_list *fpl, struct unix_edge *edge) { struct unix_vertex *vertex = edge->predecessor->vertex; - if (!gc_in_progress) + if (!fpl->dead) unix_update_graph(unix_edge_successor(edge)); list_del(&edge->vertex_entry); @@ -240,7 +238,7 @@ void unix_del_edges(struct scm_fp_list *fpl) unix_del_edge(fpl, edge); } while (i < fpl->count_unix); - if (!gc_in_progress) { + if (!fpl->dead) { receiver = fpl->edges[0].successor; receiver->scm_stat.nr_unix_fds -= fpl->count_unix; } @@ -559,9 +557,12 @@ static void unix_walk_scc_fast(struct sk_buff_head *hitlist) list_replace_init(&unix_visited_vertices, &unix_unvisited_vertices); } +static bool gc_in_progress; + static void __unix_gc(struct work_struct *work) { struct sk_buff_head hitlist; + struct sk_buff *skb; spin_lock(&unix_gc_lock); @@ -579,6 +580,11 @@ static void __unix_gc(struct work_struct *work) spin_unlock(&unix_gc_lock); + skb_queue_walk(&hitlist, skb) { + if (UNIXCB(skb).fp) + UNIXCB(skb).fp->dead = true; + } + __skb_queue_purge(&hitlist); skip_gc: WRITE_ONCE(gc_in_progress, false); From 1846a7b92b863c194e549860d046e0b33ff37a24 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Mon, 14 Apr 2025 15:55:06 +0200 Subject: [PATCH 031/971] coredump: fix error handling for replace_fd() commit 95c5f43181fe9c1b5e5a4bd3281c857a5259991f upstream. The replace_fd() helper returns the file descriptor number on success and a negative error code on failure. The current error handling in umh_pipe_setup() only works because the file descriptor that is replaced is zero but that's pretty volatile. Explicitly check for a negative error code. Link: https://lore.kernel.org/20250414-work-coredump-v2-2-685bf231f828@kernel.org Tested-by: Luca Boccassi Reviewed-by: Oleg Nesterov Signed-off-by: Christian Brauner Signed-off-by: Greg Kroah-Hartman --- fs/coredump.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/coredump.c b/fs/coredump.c index 9d235fa14ab9..f342f352b478 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -502,7 +502,9 @@ static int umh_pipe_setup(struct subprocess_info *info, struct cred *new) { struct file *files[2]; struct coredump_params *cp = (struct coredump_params *)info->data; - int err = create_pipe_files(files, 0); + int err; + + err = create_pipe_files(files, 0); if (err) return err; @@ -510,10 +512,13 @@ static int umh_pipe_setup(struct subprocess_info *info, struct cred *new) err = replace_fd(0, files[0], 0); fput(files[0]); + if (err < 0) + return err; + /* and disallow core files too */ current->signal->rlim[RLIMIT_CORE] = (struct rlimit){1, 1}; - return err; + return 0; } void do_coredump(const kernel_siginfo_t *siginfo) From ed14f8ae9bcf7dde123a0e26dafa767225882923 Mon Sep 17 00:00:00 2001 From: Michal Luczaj Date: Wed, 21 May 2025 14:45:33 +0000 Subject: [PATCH 032/971] af_unix: Fix garbage collection of embryos carrying OOB with SCM_RIGHTS commit 041933a1ec7b4173a8e638cae4f8e394331d7e54 upstream. GC attempts to explicitly drop oob_skb's reference before purging the hit list. The problem is with embryos: kfree_skb(u->oob_skb) is never called on an embryo socket. The python script below [0] sends a listener's fd to its embryo as OOB data. While GC does collect the embryo's queue, it fails to drop the OOB skb's refcount. The skb which was in embryo's receive queue stays as unix_sk(sk)->oob_skb and keeps the listener's refcount [1]. Tell GC to dispose embryo's oob_skb. [0]: from array import array from socket import * addr = '\x00unix-oob' lis = socket(AF_UNIX, SOCK_STREAM) lis.bind(addr) lis.listen(1) s = socket(AF_UNIX, SOCK_STREAM) s.connect(addr) scm = (SOL_SOCKET, SCM_RIGHTS, array('i', [lis.fileno()])) s.sendmsg([b'x'], [scm], MSG_OOB) lis.close() [1] $ grep unix-oob /proc/net/unix $ ./unix-oob.py $ grep unix-oob /proc/net/unix 0000000000000000: 00000002 00000000 00000000 0001 02 0 @unix-oob 0000000000000000: 00000002 00000000 00010000 0001 01 6072 @unix-oob Fixes: 4090fa373f0e ("af_unix: Replace garbage collection algorithm.") Signed-off-by: Michal Luczaj Reviewed-by: Kuniyuki Iwashima Signed-off-by: Paolo Abeni Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- net/unix/garbage.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 1f8b8cdfcdc8..dfe94a90ece4 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -342,6 +342,18 @@ enum unix_recv_queue_lock_class { U_RECVQ_LOCK_EMBRYO, }; +static void unix_collect_queue(struct unix_sock *u, struct sk_buff_head *hitlist) +{ + skb_queue_splice_init(&u->sk.sk_receive_queue, hitlist); + +#if IS_ENABLED(CONFIG_AF_UNIX_OOB) + if (u->oob_skb) { + WARN_ON_ONCE(skb_unref(u->oob_skb)); + u->oob_skb = NULL; + } +#endif +} + static void unix_collect_skb(struct list_head *scc, struct sk_buff_head *hitlist) { struct unix_vertex *vertex; @@ -365,18 +377,11 @@ static void unix_collect_skb(struct list_head *scc, struct sk_buff_head *hitlist /* listener -> embryo order, the inversion never happens. */ spin_lock_nested(&embryo_queue->lock, U_RECVQ_LOCK_EMBRYO); - skb_queue_splice_init(embryo_queue, hitlist); + unix_collect_queue(unix_sk(skb->sk), hitlist); spin_unlock(&embryo_queue->lock); } } else { - skb_queue_splice_init(queue, hitlist); - -#if IS_ENABLED(CONFIG_AF_UNIX_OOB) - if (u->oob_skb) { - kfree_skb(u->oob_skb); - u->oob_skb = NULL; - } -#endif + unix_collect_queue(u, hitlist); } spin_unlock(&queue->lock); From cdb61a705f5f3ca2453130daab925e021bda814e Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Mon, 14 Apr 2025 15:55:07 +0200 Subject: [PATCH 033/971] coredump: hand a pidfd to the usermode coredump helper commit b5325b2a270fcaf7b2a9a0f23d422ca8a5a8bdea upstream. Give userspace a way to instruct the kernel to install a pidfd into the usermode helper process. This makes coredump handling a lot more reliable for userspace. In parallel with this commit we already have systemd adding support for this in [1]. We create a pidfs file for the coredumping process when we process the corename pattern. When the usermode helper process is forked we then install the pidfs file as file descriptor three into the usermode helpers file descriptor table so it's available to the exec'd program. Since usermode helpers are either children of the system_unbound_wq workqueue or kthreadd we know that the file descriptor table is empty and can thus always use three as the file descriptor number. Note, that we'll install a pidfd for the thread-group leader even if a subthread is calling do_coredump(). We know that task linkage hasn't been removed due to delay_group_leader() and even if this @current isn't the actual thread-group leader we know that the thread-group leader cannot be reaped until @current has exited. [brauner: This is a backport for the v6.6 series. Upsteam has significantly changed and backporting all that infra is a non-starter. So simply use the pidfd_prepare() helper and waste the file descriptor we allocated. Then we minimally massage the umh coredump setup code.] Link: https://github.com/systemd/systemd/pull/37125 [1] Link: https://lore.kernel.org/20250414-work-coredump-v2-3-685bf231f828@kernel.org Tested-by: Luca Boccassi Reviewed-by: Oleg Nesterov Signed-off-by: Christian Brauner Signed-off-by: Greg Kroah-Hartman --- fs/coredump.c | 78 ++++++++++++++++++++++++++++++++++++---- include/linux/coredump.h | 1 + 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/fs/coredump.c b/fs/coredump.c index f342f352b478..d3a4f5dc2e36 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -56,6 +57,13 @@ static bool dump_vma_snapshot(struct coredump_params *cprm); static void free_vma_snapshot(struct coredump_params *cprm); +/* + * File descriptor number for the pidfd for the thread-group leader of + * the coredumping task installed into the usermode helper's file + * descriptor table. + */ +#define COREDUMP_PIDFD_NUMBER 3 + static int core_uses_pid; static unsigned int core_pipe_limit; static char core_pattern[CORENAME_MAX_SIZE] = "core"; @@ -332,6 +340,27 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm, case 'C': err = cn_printf(cn, "%d", cprm->cpu); break; + /* pidfd number */ + case 'F': { + /* + * Installing a pidfd only makes sense if + * we actually spawn a usermode helper. + */ + if (!ispipe) + break; + + /* + * Note that we'll install a pidfd for the + * thread-group leader. We know that task + * linkage hasn't been removed yet and even if + * this @current isn't the actual thread-group + * leader we know that the thread-group leader + * cannot be reaped until @current has exited. + */ + cprm->pid = task_tgid(current); + err = cn_printf(cn, "%d", COREDUMP_PIDFD_NUMBER); + break; + } default: break; } @@ -488,7 +517,7 @@ static void wait_for_dump_helpers(struct file *file) } /* - * umh_pipe_setup + * umh_coredump_setup * helper function to customize the process used * to collect the core in userspace. Specifically * it sets up a pipe and installs it as fd 0 (stdin) @@ -498,27 +527,62 @@ static void wait_for_dump_helpers(struct file *file) * is a special value that we use to trap recursive * core dumps */ -static int umh_pipe_setup(struct subprocess_info *info, struct cred *new) +static int umh_coredump_setup(struct subprocess_info *info, struct cred *new) { struct file *files[2]; + struct file *pidfs_file = NULL; struct coredump_params *cp = (struct coredump_params *)info->data; int err; + if (cp->pid) { + int fd; + + fd = pidfd_prepare(cp->pid, 0, &pidfs_file); + if (fd < 0) + return fd; + + /* + * We don't care about the fd. We also cannot simply + * replace it below because dup2() will refuse to close + * this file descriptor if its in a larval state. So + * close it! + */ + put_unused_fd(fd); + + /* + * Usermode helpers are childen of either + * system_unbound_wq or of kthreadd. So we know that + * we're starting off with a clean file descriptor + * table. So we should always be able to use + * COREDUMP_PIDFD_NUMBER as our file descriptor value. + */ + err = replace_fd(COREDUMP_PIDFD_NUMBER, pidfs_file, 0); + if (err < 0) + goto out_fail; + + pidfs_file = NULL; + } + err = create_pipe_files(files, 0); if (err) - return err; + goto out_fail; cp->file = files[1]; err = replace_fd(0, files[0], 0); fput(files[0]); if (err < 0) - return err; + goto out_fail; /* and disallow core files too */ current->signal->rlim[RLIMIT_CORE] = (struct rlimit){1, 1}; - return 0; + err = 0; + +out_fail: + if (pidfs_file) + fput(pidfs_file); + return err; } void do_coredump(const kernel_siginfo_t *siginfo) @@ -594,7 +658,7 @@ void do_coredump(const kernel_siginfo_t *siginfo) } if (cprm.limit == 1) { - /* See umh_pipe_setup() which sets RLIMIT_CORE = 1. + /* See umh_coredump_setup() which sets RLIMIT_CORE = 1. * * Normally core limits are irrelevant to pipes, since * we're not writing to the file system, but we use @@ -639,7 +703,7 @@ void do_coredump(const kernel_siginfo_t *siginfo) retval = -ENOMEM; sub_info = call_usermodehelper_setup(helper_argv[0], helper_argv, NULL, GFP_KERNEL, - umh_pipe_setup, NULL, &cprm); + umh_coredump_setup, NULL, &cprm); if (sub_info) retval = call_usermodehelper_exec(sub_info, UMH_WAIT_EXEC); diff --git a/include/linux/coredump.h b/include/linux/coredump.h index d3eba4360150..c1b4c8c70cae 100644 --- a/include/linux/coredump.h +++ b/include/linux/coredump.h @@ -28,6 +28,7 @@ struct coredump_params { int vma_count; size_t vma_data_size; struct core_vma_metadata *vma_meta; + struct pid *pid; }; /* From ea61eda1f4b454aaa5883b24984f0b7b1a2fb8d7 Mon Sep 17 00:00:00 2001 From: Shigeru Yoshida Date: Wed, 21 May 2025 14:45:34 +0000 Subject: [PATCH 034/971] af_unix: Fix uninit-value in __unix_walk_scc() commit 927fa5b3e4f52e0967bfc859afc98ad1c523d2d5 upstream. KMSAN reported uninit-value access in __unix_walk_scc() [1]. In the list_for_each_entry_reverse() loop, when the vertex's index equals it's scc_index, the loop uses the variable vertex as a temporary variable that points to a vertex in scc. And when the loop is finished, the variable vertex points to the list head, in this case scc, which is a local variable on the stack (more precisely, it's not even scc and might underflow the call stack of __unix_walk_scc(): container_of(&scc, struct unix_vertex, scc_entry)). However, the variable vertex is used under the label prev_vertex. So if the edge_stack is not empty and the function jumps to the prev_vertex label, the function will access invalid data on the stack. This causes the uninit-value access issue. Fix this by introducing a new temporary variable for the loop. [1] BUG: KMSAN: uninit-value in __unix_walk_scc net/unix/garbage.c:478 [inline] BUG: KMSAN: uninit-value in unix_walk_scc net/unix/garbage.c:526 [inline] BUG: KMSAN: uninit-value in __unix_gc+0x2589/0x3c20 net/unix/garbage.c:584 __unix_walk_scc net/unix/garbage.c:478 [inline] unix_walk_scc net/unix/garbage.c:526 [inline] __unix_gc+0x2589/0x3c20 net/unix/garbage.c:584 process_one_work kernel/workqueue.c:3231 [inline] process_scheduled_works+0xade/0x1bf0 kernel/workqueue.c:3312 worker_thread+0xeb6/0x15b0 kernel/workqueue.c:3393 kthread+0x3c4/0x530 kernel/kthread.c:389 ret_from_fork+0x6e/0x90 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 Uninit was stored to memory at: unix_walk_scc net/unix/garbage.c:526 [inline] __unix_gc+0x2adf/0x3c20 net/unix/garbage.c:584 process_one_work kernel/workqueue.c:3231 [inline] process_scheduled_works+0xade/0x1bf0 kernel/workqueue.c:3312 worker_thread+0xeb6/0x15b0 kernel/workqueue.c:3393 kthread+0x3c4/0x530 kernel/kthread.c:389 ret_from_fork+0x6e/0x90 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 Local variable entries created at: ref_tracker_free+0x48/0xf30 lib/ref_tracker.c:222 netdev_tracker_free include/linux/netdevice.h:4058 [inline] netdev_put include/linux/netdevice.h:4075 [inline] dev_put include/linux/netdevice.h:4101 [inline] update_gid_event_work_handler+0xaa/0x1b0 drivers/infiniband/core/roce_gid_mgmt.c:813 CPU: 1 PID: 12763 Comm: kworker/u8:31 Not tainted 6.10.0-rc4-00217-g35bb670d65fc #32 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-2.fc40 04/01/2014 Workqueue: events_unbound __unix_gc Fixes: 3484f063172d ("af_unix: Detect Strongly Connected Components.") Reported-by: syzkaller Signed-off-by: Shigeru Yoshida Reviewed-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20240702160428.10153-1-syoshida@redhat.com Signed-off-by: Jakub Kicinski Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- net/unix/garbage.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/net/unix/garbage.c b/net/unix/garbage.c index dfe94a90ece4..23efb78fe9ef 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -476,6 +476,7 @@ prev_vertex: } if (vertex->index == vertex->scc_index) { + struct unix_vertex *v; struct list_head scc; bool scc_dead = true; @@ -486,15 +487,15 @@ prev_vertex: */ __list_cut_position(&scc, &vertex_stack, &vertex->scc_entry); - list_for_each_entry_reverse(vertex, &scc, scc_entry) { + list_for_each_entry_reverse(v, &scc, scc_entry) { /* Don't restart DFS from this vertex in unix_walk_scc(). */ - list_move_tail(&vertex->entry, &unix_visited_vertices); + list_move_tail(&v->entry, &unix_visited_vertices); /* Mark vertex as off-stack. */ - vertex->index = unix_vertex_grouped_index; + v->index = unix_vertex_grouped_index; if (scc_dead) - scc_dead = unix_vertex_dead(vertex); + scc_dead = unix_vertex_dead(v); } if (scc_dead) From 46a6ce48125558d425c285391b0de53f8f2b125e Mon Sep 17 00:00:00 2001 From: Purva Yeshi Date: Thu, 10 Apr 2025 16:32:16 +0530 Subject: [PATCH 035/971] dmaengine: idxd: cdev: Fix uninitialized use of sva in idxd_cdev_open [ Upstream commit 97994333de2b8062d2df4e6ce0dc65c2dc0f40dc ] Fix Smatch-detected issue: drivers/dma/idxd/cdev.c:321 idxd_cdev_open() error: uninitialized symbol 'sva'. 'sva' pointer may be used uninitialized in error handling paths. Specifically, if PASID support is enabled and iommu_sva_bind_device() returns an error, the code jumps to the cleanup label and attempts to call iommu_sva_unbind_device(sva) without ensuring that sva was successfully assigned. This triggers a Smatch warning about an uninitialized symbol. Initialize sva to NULL at declaration and add a check using IS_ERR_OR_NULL() before unbinding the device. This ensures the function does not use an invalid or uninitialized pointer during cleanup. Signed-off-by: Purva Yeshi Reviewed-by: Dave Jiang Acked-by: Vinicius Costa Gomes Link: https://lore.kernel.org/r/20250410110216.21592-1-purvayeshi550@gmail.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/dma/idxd/cdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/dma/idxd/cdev.c b/drivers/dma/idxd/cdev.c index 6cfcef3cf4cd..7e3a67f9f0a6 100644 --- a/drivers/dma/idxd/cdev.c +++ b/drivers/dma/idxd/cdev.c @@ -225,7 +225,7 @@ static int idxd_cdev_open(struct inode *inode, struct file *filp) struct idxd_wq *wq; struct device *dev, *fdev; int rc = 0; - struct iommu_sva *sva; + struct iommu_sva *sva = NULL; unsigned int pasid; struct idxd_cdev *idxd_cdev; @@ -322,7 +322,7 @@ failed_set_pasid: if (device_user_pasid_enabled(idxd)) idxd_xa_pasid_remove(ctx); failed_get_pasid: - if (device_user_pasid_enabled(idxd)) + if (device_user_pasid_enabled(idxd) && !IS_ERR_OR_NULL(sva)) iommu_sva_unbind_device(sva); failed: mutex_unlock(&wq->wq_lock); From 98f7c351a11a10ab3154a9bd815e06450df70a30 Mon Sep 17 00:00:00 2001 From: Milton Barrera Date: Wed, 9 Apr 2025 00:04:28 -0600 Subject: [PATCH 036/971] HID: quirks: Add ADATA XPG alpha wireless mouse support [ Upstream commit fa9fdeea1b7d6440c22efa6d59a769eae8bc89f1 ] This patch adds HID_QUIRK_ALWAYS_POLL for the ADATA XPG wireless gaming mouse (USB ID 125f:7505) and its USB dongle (USB ID 125f:7506). Without this quirk, the device does not generate input events properly. Signed-off-by: Milton Barrera Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin --- drivers/hid/hid-ids.h | 4 ++++ drivers/hid/hid-quirks.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 8e721ec3faaf..a8665d57094b 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -41,6 +41,10 @@ #define USB_VENDOR_ID_ACTIONSTAR 0x2101 #define USB_DEVICE_ID_ACTIONSTAR_1011 0x1011 +#define USB_VENDOR_ID_ADATA_XPG 0x125f +#define USB_VENDOR_ID_ADATA_XPG_WL_GAMING_MOUSE 0x7505 +#define USB_VENDOR_ID_ADATA_XPG_WL_GAMING_MOUSE_DONGLE 0x7506 + #define USB_VENDOR_ID_ADS_TECH 0x06e1 #define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155 diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 5d7a418ccdbe..73979643315b 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -27,6 +27,8 @@ static const struct hid_device_id hid_quirks[] = { { HID_USB_DEVICE(USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD), HID_QUIRK_BADPAD }, { HID_USB_DEVICE(USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR), HID_QUIRK_BADPAD }, + { HID_USB_DEVICE(USB_VENDOR_ID_ADATA_XPG, USB_VENDOR_ID_ADATA_XPG_WL_GAMING_MOUSE), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_ADATA_XPG, USB_VENDOR_ID_ADATA_XPG_WL_GAMING_MOUSE_DONGLE), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016), HID_QUIRK_FULLSPEED_INTERVAL }, { HID_USB_DEVICE(USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_AKAI_09E8, USB_DEVICE_ID_AKAI_09E8_MIDIMIX), HID_QUIRK_NO_INIT_REPORTS }, From 764f8cd8aadcd98e7fd1112f81e8c7507a153cd5 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Thu, 10 Apr 2025 16:42:03 -0400 Subject: [PATCH 037/971] nfs: don't share pNFS DS connections between net namespaces [ Upstream commit 6b9785dc8b13d9fb75ceec8cf4ea7ec3f3b1edbc ] Currently, different NFS clients can share the same DS connections, even when they are in different net namespaces. If a containerized client creates a DS connection, another container can find and use it. When the first client exits, the connection will close which can lead to stalls in other clients. Add a net namespace pointer to struct nfs4_pnfs_ds, and compare those value to the caller's netns in _data_server_lookup_locked() when searching for a nfs4_pnfs_ds to match. Reported-by: Omar Sandoval Reported-by: Sargun Dillon Closes: https://lore.kernel.org/linux-nfs/Z_ArpQC_vREh_hEA@telecaster/ Tested-by: Sargun Dillon Signed-off-by: Jeff Layton Reviewed-by: Benjamin Coddington Link: https://lore.kernel.org/r/20250410-nfs-ds-netns-v2-1-f80b7979ba80@kernel.org Signed-off-by: Trond Myklebust Signed-off-by: Sasha Levin --- fs/nfs/filelayout/filelayoutdev.c | 6 +++--- fs/nfs/flexfilelayout/flexfilelayoutdev.c | 6 +++--- fs/nfs/pnfs.h | 4 +++- fs/nfs/pnfs_nfs.c | 9 +++++---- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/fs/nfs/filelayout/filelayoutdev.c b/fs/nfs/filelayout/filelayoutdev.c index acf4b88889dc..d5f1fbfd9a0c 100644 --- a/fs/nfs/filelayout/filelayoutdev.c +++ b/fs/nfs/filelayout/filelayoutdev.c @@ -75,6 +75,7 @@ nfs4_fl_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev, struct page *scratch; struct list_head dsaddrs; struct nfs4_pnfs_ds_addr *da; + struct net *net = server->nfs_client->cl_net; /* set up xdr stream */ scratch = alloc_page(gfp_flags); @@ -158,8 +159,7 @@ nfs4_fl_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev, mp_count = be32_to_cpup(p); /* multipath count */ for (j = 0; j < mp_count; j++) { - da = nfs4_decode_mp_ds_addr(server->nfs_client->cl_net, - &stream, gfp_flags); + da = nfs4_decode_mp_ds_addr(net, &stream, gfp_flags); if (da) list_add_tail(&da->da_node, &dsaddrs); } @@ -169,7 +169,7 @@ nfs4_fl_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev, goto out_err_free_deviceid; } - dsaddr->ds_list[i] = nfs4_pnfs_ds_add(&dsaddrs, gfp_flags); + dsaddr->ds_list[i] = nfs4_pnfs_ds_add(net, &dsaddrs, gfp_flags); if (!dsaddr->ds_list[i]) goto out_err_drain_dsaddrs; diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c index e028f5a0ef5f..d21c5ecfbf1c 100644 --- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c +++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c @@ -49,6 +49,7 @@ nfs4_ff_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev, struct nfs4_pnfs_ds_addr *da; struct nfs4_ff_layout_ds *new_ds = NULL; struct nfs4_ff_ds_version *ds_versions = NULL; + struct net *net = server->nfs_client->cl_net; u32 mp_count; u32 version_count; __be32 *p; @@ -80,8 +81,7 @@ nfs4_ff_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev, for (i = 0; i < mp_count; i++) { /* multipath ds */ - da = nfs4_decode_mp_ds_addr(server->nfs_client->cl_net, - &stream, gfp_flags); + da = nfs4_decode_mp_ds_addr(net, &stream, gfp_flags); if (da) list_add_tail(&da->da_node, &dsaddrs); } @@ -149,7 +149,7 @@ nfs4_ff_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev, new_ds->ds_versions = ds_versions; new_ds->ds_versions_cnt = version_count; - new_ds->ds = nfs4_pnfs_ds_add(&dsaddrs, gfp_flags); + new_ds->ds = nfs4_pnfs_ds_add(net, &dsaddrs, gfp_flags); if (!new_ds->ds) goto out_err_drain_dsaddrs; diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index d886c8226d8f..79996d7dad0f 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h @@ -59,6 +59,7 @@ struct nfs4_pnfs_ds { struct list_head ds_node; /* nfs4_pnfs_dev_hlist dev_dslist */ char *ds_remotestr; /* comma sep list of addrs */ struct list_head ds_addrs; + const struct net *ds_net; struct nfs_client *ds_clp; refcount_t ds_count; unsigned long ds_state; @@ -405,7 +406,8 @@ int pnfs_generic_commit_pagelist(struct inode *inode, int pnfs_generic_scan_commit_lists(struct nfs_commit_info *cinfo, int max); void pnfs_generic_write_commit_done(struct rpc_task *task, void *data); void nfs4_pnfs_ds_put(struct nfs4_pnfs_ds *ds); -struct nfs4_pnfs_ds *nfs4_pnfs_ds_add(struct list_head *dsaddrs, +struct nfs4_pnfs_ds *nfs4_pnfs_ds_add(const struct net *net, + struct list_head *dsaddrs, gfp_t gfp_flags); void nfs4_pnfs_v3_ds_connect_unload(void); int nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c index 88e061bd711b..1b317c44da12 100644 --- a/fs/nfs/pnfs_nfs.c +++ b/fs/nfs/pnfs_nfs.c @@ -651,12 +651,12 @@ _same_data_server_addrs_locked(const struct list_head *dsaddrs1, * Lookup DS by addresses. nfs4_ds_cache_lock is held */ static struct nfs4_pnfs_ds * -_data_server_lookup_locked(const struct list_head *dsaddrs) +_data_server_lookup_locked(const struct net *net, const struct list_head *dsaddrs) { struct nfs4_pnfs_ds *ds; list_for_each_entry(ds, &nfs4_data_server_cache, ds_node) - if (_same_data_server_addrs_locked(&ds->ds_addrs, dsaddrs)) + if (ds->ds_net == net && _same_data_server_addrs_locked(&ds->ds_addrs, dsaddrs)) return ds; return NULL; } @@ -763,7 +763,7 @@ out_err: * uncached and return cached struct nfs4_pnfs_ds. */ struct nfs4_pnfs_ds * -nfs4_pnfs_ds_add(struct list_head *dsaddrs, gfp_t gfp_flags) +nfs4_pnfs_ds_add(const struct net *net, struct list_head *dsaddrs, gfp_t gfp_flags) { struct nfs4_pnfs_ds *tmp_ds, *ds = NULL; char *remotestr; @@ -781,13 +781,14 @@ nfs4_pnfs_ds_add(struct list_head *dsaddrs, gfp_t gfp_flags) remotestr = nfs4_pnfs_remotestr(dsaddrs, gfp_flags); spin_lock(&nfs4_ds_cache_lock); - tmp_ds = _data_server_lookup_locked(dsaddrs); + tmp_ds = _data_server_lookup_locked(net, dsaddrs); if (tmp_ds == NULL) { INIT_LIST_HEAD(&ds->ds_addrs); list_splice_init(dsaddrs, &ds->ds_addrs); ds->ds_remotestr = remotestr; refcount_set(&ds->ds_count, 1); INIT_LIST_HEAD(&ds->ds_node); + ds->ds_net = net; ds->ds_clp = NULL; list_add(&ds->ds_node, &nfs4_data_server_cache); dprintk("%s add new data server %s\n", __func__, From af288d8e140589116eaea1678ba023970793c6b9 Mon Sep 17 00:00:00 2001 From: John Chau Date: Mon, 5 May 2025 01:55:13 +0900 Subject: [PATCH 038/971] platform/x86: thinkpad_acpi: Support also NEC Lavie X1475JAS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit a032f29a15412fab9f4352e0032836d51420a338 ] Change get_thinkpad_model_data() to check for additional vendor name "NEC" in order to support NEC Lavie X1475JAS notebook (and perhaps more). The reason of this works with minimal changes is because NEC Lavie X1475JAS is a Thinkpad inside. ACPI dumps reveals its OEM ID to be "LENOVO", BIOS version "R2PET30W" matches typical Lenovo BIOS version, the existence of HKEY of LEN0268, with DMI fw string is "R2PHT24W". I compiled and tested with my own machine, attached the dmesg below as proof of work: [ 6.288932] thinkpad_acpi: ThinkPad ACPI Extras v0.26 [ 6.288937] thinkpad_acpi: http://ibm-acpi.sf.net/ [ 6.288938] thinkpad_acpi: ThinkPad BIOS R2PET30W (1.11 ), EC R2PHT24W [ 6.307000] thinkpad_acpi: radio switch found; radios are enabled [ 6.307030] thinkpad_acpi: This ThinkPad has standard ACPI backlight brightness control, supported by the ACPI video driver [ 6.307033] thinkpad_acpi: Disabling thinkpad-acpi brightness events by default... [ 6.320322] thinkpad_acpi: rfkill switch tpacpi_bluetooth_sw: radio is unblocked [ 6.371963] thinkpad_acpi: secondary fan control detected & enabled [ 6.391922] thinkpad_acpi: battery 1 registered (start 0, stop 85, behaviours: 0x7) [ 6.398375] input: ThinkPad Extra Buttons as /devices/platform/thinkpad_acpi/input/input13 Signed-off-by: John Chau Link: https://lore.kernel.org/r/20250504165513.295135-1-johnchau@0atlas.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin --- drivers/platform/x86/thinkpad_acpi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index cde5f845cf25..bcb0689101e2 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -11315,6 +11315,8 @@ static int __must_check __init get_thinkpad_model_data( tp->vendor = PCI_VENDOR_ID_IBM; else if (dmi_name_in_vendors("LENOVO")) tp->vendor = PCI_VENDOR_ID_LENOVO; + else if (dmi_name_in_vendors("NEC")) + tp->vendor = PCI_VENDOR_ID_LENOVO; else return 0; From 4728d56dc56f07a54f5ccaf2b6d6f53ad7284a26 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 7 May 2025 16:49:33 +0900 Subject: [PATCH 039/971] um: let 'make clean' properly clean underlying SUBARCH as well [ Upstream commit ab09da75700e9d25c7dfbc7f7934920beb5e39b9 ] Building the kernel with O= is affected by stale in-tree build artifacts. So, if the source tree is not clean, Kbuild displays the following: $ make ARCH=um O=build defconfig make[1]: Entering directory '/.../linux/build' *** *** The source tree is not clean, please run 'make ARCH=um mrproper' *** in /.../linux *** make[2]: *** [/.../linux/Makefile:673: outputmakefile] Error 1 make[1]: *** [/.../linux/Makefile:248: __sub-make] Error 2 make[1]: Leaving directory '/.../linux/build' make: *** [Makefile:248: __sub-make] Error 2 Usually, running 'make mrproper' is sufficient for cleaning the source tree for out-of-tree builds. However, building UML generates build artifacts not only in arch/um/, but also in the SUBARCH directory (i.e., arch/x86/). If in-tree stale files remain under arch/x86/, Kbuild will reuse them instead of creating new ones under the specified build directory. This commit makes 'make ARCH=um clean' recurse into the SUBARCH directory. Reported-by: Shuah Khan Closes: https://lore.kernel.org/lkml/20250502172459.14175-1-skhan@linuxfoundation.org/ Signed-off-by: Masahiro Yamada Acked-by: Johannes Berg Reviewed-by: David Gow Reviewed-by: Shuah Khan Signed-off-by: Sasha Levin --- arch/um/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/um/Makefile b/arch/um/Makefile index 34957dcb88b9..744c5d0bdeb8 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -151,5 +151,6 @@ MRPROPER_FILES += $(HOST_DIR)/include/generated archclean: @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ -o -name '*.gcov' \) -type f -print | xargs rm -f + $(Q)$(MAKE) -f $(srctree)/Makefile ARCH=$(HEADER_ARCH) clean export HEADER_ARCH SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING DEV_NULL_PATH From eae121397e278775df97e3e8790481969eae3066 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 24 Apr 2025 10:02:59 -0400 Subject: [PATCH 040/971] drm/amd/display: fix link_set_dpms_off multi-display MST corner case [ Upstream commit 3c1a467372e0c356b1d3c59f6d199ed5a6612dd1 ] [Why & How] When MST config is unplugged/replugged too quickly, it can potentially result in a scenario where previous DC state has not been reset before the HPD link detection sequence begins. In this case, driver will disable the streams/link prior to re-enabling the link for link training. There is a bug in the current logic that does not account for the fact that current_state can be released and cleared prior to swapping to a new state (resulting in the pipe_ctx stream pointers to be cleared) in between disabling streams. To resolve this, cache the original streams prior to committing any stream updates. Reviewed-by: Wenjing Liu Signed-off-by: George Shen Signed-off-by: Ray Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher (cherry picked from commit 1561782686ccc36af844d55d31b44c938dd412dc) Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/display/dc/link/link_dpms.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c index 4901e27f678b..9b470812d96a 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c @@ -145,6 +145,7 @@ void link_blank_dp_stream(struct dc_link *link, bool hw_init) void link_set_all_streams_dpms_off_for_link(struct dc_link *link) { struct pipe_ctx *pipes[MAX_PIPES]; + struct dc_stream_state *streams[MAX_PIPES]; struct dc_state *state = link->dc->current_state; uint8_t count; int i; @@ -157,10 +158,18 @@ void link_set_all_streams_dpms_off_for_link(struct dc_link *link) link_get_master_pipes_with_dpms_on(link, state, &count, pipes); + /* The subsequent call to dc_commit_updates_for_stream for a full update + * will release the current state and swap to a new state. Releasing the + * current state results in the stream pointers in the pipe_ctx structs + * to be zero'd. Hence, cache all streams prior to dc_commit_updates_for_stream. + */ + for (i = 0; i < count; i++) + streams[i] = pipes[i]->stream; + for (i = 0; i < count; i++) { - stream_update.stream = pipes[i]->stream; + stream_update.stream = streams[i]; dc_commit_updates_for_stream(link->ctx->dc, NULL, 0, - pipes[i]->stream, &stream_update, + streams[i], &stream_update, state); } From b8435b76971dc65fee707cae209e0003c357f88d Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Tue, 22 Apr 2025 18:12:44 +0800 Subject: [PATCH 041/971] phy: starfive: jh7110-usb: Fix USB 2.0 host occasional detection failure [ Upstream commit 3f097adb9b6c804636bcf8d01e0e7bc037bee0d3 ] JH7110 USB 2.0 host fails to detect USB 2.0 devices occasionally. With a long time of debugging and testing, we found that setting Rx clock gating control signal to normal power consumption mode can solve this problem. Signed-off-by: Hal Feng Link: https://lore.kernel.org/r/20250422101244.51686-1-hal.feng@starfivetech.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/phy/starfive/phy-jh7110-usb.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/phy/starfive/phy-jh7110-usb.c b/drivers/phy/starfive/phy-jh7110-usb.c index 633912f8a05d..bf52b41110db 100644 --- a/drivers/phy/starfive/phy-jh7110-usb.c +++ b/drivers/phy/starfive/phy-jh7110-usb.c @@ -16,6 +16,8 @@ #include #define USB_125M_CLK_RATE 125000000 +#define USB_CLK_MODE_OFF 0x0 +#define USB_CLK_MODE_RX_NORMAL_PWR BIT(1) #define USB_LS_KEEPALIVE_OFF 0x4 #define USB_LS_KEEPALIVE_ENABLE BIT(4) @@ -68,6 +70,7 @@ static int jh7110_usb2_phy_init(struct phy *_phy) { struct jh7110_usb2_phy *phy = phy_get_drvdata(_phy); int ret; + unsigned int val; ret = clk_set_rate(phy->usb_125m_clk, USB_125M_CLK_RATE); if (ret) @@ -77,6 +80,10 @@ static int jh7110_usb2_phy_init(struct phy *_phy) if (ret) return ret; + val = readl(phy->regs + USB_CLK_MODE_OFF); + val |= USB_CLK_MODE_RX_NORMAL_PWR; + writel(val, phy->regs + USB_CLK_MODE_OFF); + return 0; } From e99de950330510b0da9cb4a1e326ac3930c30a23 Mon Sep 17 00:00:00 2001 From: Alessandro Grassi Date: Fri, 2 May 2025 11:55:20 +0200 Subject: [PATCH 042/971] spi: spi-sun4i: fix early activation [ Upstream commit fb98bd0a13de2c9d96cb5c00c81b5ca118ac9d71 ] The SPI interface is activated before the CPOL setting is applied. In that moment, the clock idles high and CS goes low. After a short delay, CPOL and other settings are applied, which may cause the clock to change state and idle low. This transition is not part of a clock cycle, and it can confuse the receiving device. To prevent this unexpected transition, activate the interface while CPOL and the other settings are being applied. Signed-off-by: Alessandro Grassi Link: https://patch.msgid.link/20250502095520.13825-1-alessandro.grassi@mailbox.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-sun4i.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c index b8947265d329..5b2cb225a419 100644 --- a/drivers/spi/spi-sun4i.c +++ b/drivers/spi/spi-sun4i.c @@ -263,6 +263,9 @@ static int sun4i_spi_transfer_one(struct spi_master *master, else reg |= SUN4I_CTL_DHB; + /* Now that the settings are correct, enable the interface */ + reg |= SUN4I_CTL_ENABLE; + sun4i_spi_write(sspi, SUN4I_CTL_REG, reg); /* Ensure that we have a parent clock fast enough */ @@ -403,7 +406,7 @@ static int sun4i_spi_runtime_resume(struct device *dev) } sun4i_spi_write(sspi, SUN4I_CTL_REG, - SUN4I_CTL_ENABLE | SUN4I_CTL_MASTER | SUN4I_CTL_TP); + SUN4I_CTL_MASTER | SUN4I_CTL_TP); return 0; From f83097445b7ec6efc1b89bb51215fd9994f59fc3 Mon Sep 17 00:00:00 2001 From: Ilya Guterman Date: Sat, 10 May 2025 19:21:30 +0900 Subject: [PATCH 043/971] nvme-pci: add NVME_QUIRK_NO_DEEPEST_PS quirk for SOLIDIGM P44 Pro [ Upstream commit e765bf89f42b5c82132a556b630affeb82b2a21f ] This commit adds the NVME_QUIRK_NO_DEEPEST_PS quirk for device [126f:2262], which belongs to device SOLIDIGM P44 Pro SSDPFKKW020X7 The device frequently have trouble exiting the deepest power state (5), resulting in the entire disk being unresponsive. Verified by setting nvme_core.default_ps_max_latency_us=10000 and observing the expected behavior. Signed-off-by: Ilya Guterman Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin --- drivers/nvme/host/pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 1a33be577397..97ab91a479d1 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -3541,6 +3541,8 @@ static const struct pci_device_id nvme_id_table[] = { .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, { PCI_DEVICE(0x1e49, 0x0041), /* ZHITAI TiPro7000 NVMe SSD */ .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, + { PCI_DEVICE(0x025e, 0xf1ac), /* SOLIDIGM P44 pro SSDPFKKW020X7 */ + .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, { PCI_DEVICE(0xc0a9, 0x540a), /* Crucial P2 */ .driver_data = NVME_QUIRK_BOGUS_NID, }, { PCI_DEVICE(0x1d97, 0x2263), /* Lexar NM610 */ From af7243148f2eba8d351afbc5afbe8903a03b8945 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 27 Apr 2025 18:21:06 -0400 Subject: [PATCH 044/971] NFS: Avoid flushing data while holding directory locks in nfs_rename() [ Upstream commit dcd21b609d4abc7303f8683bce4f35d78d7d6830 ] The Linux client assumes that all filehandles are non-volatile for renames within the same directory (otherwise sillyrename cannot work). However, the existence of the Linux 'subtree_check' export option has meant that nfs_rename() has always assumed it needs to flush writes before attempting to rename. Since NFSv4 does allow the client to query whether or not the server exhibits this behaviour, and since knfsd does actually set the appropriate flag when 'subtree_check' is enabled on an export, it should be OK to optimise away the write flushing behaviour in the cases where it is clearly not needed. Signed-off-by: Trond Myklebust Reviewed-by: Jeff Layton Signed-off-by: Sasha Levin --- fs/nfs/client.c | 2 ++ fs/nfs/dir.c | 15 ++++++++++++++- include/linux/nfs_fs_sb.h | 12 +++++++++--- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 62607d52bfa5..aa09f930eeaf 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -1080,6 +1080,8 @@ struct nfs_server *nfs_create_server(struct fs_context *fc) if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN) server->namelen = NFS2_MAXNAMLEN; } + /* Linux 'subtree_check' borkenness mandates this setting */ + server->fh_expire_type = NFS_FH_VOL_RENAME; if (!(fattr->valid & NFS_ATTR_FATTR)) { error = ctx->nfs_mod->rpc_ops->getattr(server, ctx->mntfh, diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 39f7549afcf5..389186384235 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -2642,6 +2642,18 @@ nfs_unblock_rename(struct rpc_task *task, struct nfs_renamedata *data) unblock_revalidate(new_dentry); } +static bool nfs_rename_is_unsafe_cross_dir(struct dentry *old_dentry, + struct dentry *new_dentry) +{ + struct nfs_server *server = NFS_SB(old_dentry->d_sb); + + if (old_dentry->d_parent != new_dentry->d_parent) + return false; + if (server->fh_expire_type & NFS_FH_RENAME_UNSAFE) + return !(server->fh_expire_type & NFS_FH_NOEXPIRE_WITH_OPEN); + return true; +} + /* * RENAME * FIXME: Some nfsds, like the Linux user space nfsd, may generate a @@ -2729,7 +2741,8 @@ int nfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, } - if (S_ISREG(old_inode->i_mode)) + if (S_ISREG(old_inode->i_mode) && + nfs_rename_is_unsafe_cross_dir(old_dentry, new_dentry)) nfs_sync_inode(old_inode); task = nfs_async_rename(old_dir, new_dir, old_dentry, new_dentry, must_unblock ? nfs_unblock_rename : NULL); diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 86d96e00c2e3..374b1b208bd8 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -199,6 +199,15 @@ struct nfs_server { char *fscache_uniq; /* Uniquifier (or NULL) */ #endif + /* The following #defines numerically match the NFSv4 equivalents */ +#define NFS_FH_NOEXPIRE_WITH_OPEN (0x1) +#define NFS_FH_VOLATILE_ANY (0x2) +#define NFS_FH_VOL_MIGRATION (0x4) +#define NFS_FH_VOL_RENAME (0x8) +#define NFS_FH_RENAME_UNSAFE (NFS_FH_VOLATILE_ANY | NFS_FH_VOL_RENAME) + u32 fh_expire_type; /* V4 bitmask representing file + handle volatility type for + this filesystem */ u32 pnfs_blksize; /* layout_blksize attr */ #if IS_ENABLED(CONFIG_NFS_V4) u32 attr_bitmask[3];/* V4 bitmask representing the set @@ -222,9 +231,6 @@ struct nfs_server { u32 acl_bitmask; /* V4 bitmask representing the ACEs that are supported on this filesystem */ - u32 fh_expire_type; /* V4 bitmask representing file - handle volatility type for - this filesystem */ struct pnfs_layoutdriver_type *pnfs_curr_ld; /* Active layout driver */ struct rpc_wait_queue roc_rpcwaitq; void *pnfs_ld_data; /* per mount point data */ From 871e44494f5d57377b0f75a961d2c4e085b6f40e Mon Sep 17 00:00:00 2001 From: Valtteri Koskivuori Date: Fri, 9 May 2025 21:42:49 +0300 Subject: [PATCH 045/971] platform/x86: fujitsu-laptop: Support Lifebook S2110 hotkeys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit a7e255ff9fe4d9b8b902023aaf5b7a673786bb50 ] The S2110 has an additional set of media playback control keys enabled by a hardware toggle button that switches the keys between "Application" and "Player" modes. Toggling "Player" mode just shifts the scancode of each hotkey up by 4. Add defines for new scancodes, and a keymap and dmi id for the S2110. Tested on a Fujitsu Lifebook S2110. Signed-off-by: Valtteri Koskivuori Acked-by: Jonathan Woithe Link: https://lore.kernel.org/r/20250509184251.713003-1-vkoskiv@gmail.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin --- drivers/platform/x86/fujitsu-laptop.c | 33 +++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index 085e044e888e..d7ef4f046d99 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -17,13 +17,13 @@ /* * fujitsu-laptop.c - Fujitsu laptop support, providing access to additional * features made available on a range of Fujitsu laptops including the - * P2xxx/P5xxx/S6xxx/S7xxx series. + * P2xxx/P5xxx/S2xxx/S6xxx/S7xxx series. * * This driver implements a vendor-specific backlight control interface for * Fujitsu laptops and provides support for hotkeys present on certain Fujitsu * laptops. * - * This driver has been tested on a Fujitsu Lifebook S6410, S7020 and + * This driver has been tested on a Fujitsu Lifebook S2110, S6410, S7020 and * P8010. It should work on most P-series and S-series Lifebooks, but * YMMV. * @@ -102,7 +102,11 @@ #define KEY2_CODE 0x411 #define KEY3_CODE 0x412 #define KEY4_CODE 0x413 -#define KEY5_CODE 0x420 +#define KEY5_CODE 0x414 +#define KEY6_CODE 0x415 +#define KEY7_CODE 0x416 +#define KEY8_CODE 0x417 +#define KEY9_CODE 0x420 /* Hotkey ringbuffer limits */ #define MAX_HOTKEY_RINGBUFFER_SIZE 100 @@ -450,7 +454,7 @@ static const struct key_entry keymap_default[] = { { KE_KEY, KEY2_CODE, { KEY_PROG2 } }, { KE_KEY, KEY3_CODE, { KEY_PROG3 } }, { KE_KEY, KEY4_CODE, { KEY_PROG4 } }, - { KE_KEY, KEY5_CODE, { KEY_RFKILL } }, + { KE_KEY, KEY9_CODE, { KEY_RFKILL } }, /* Soft keys read from status flags */ { KE_KEY, FLAG_RFKILL, { KEY_RFKILL } }, { KE_KEY, FLAG_TOUCHPAD_TOGGLE, { KEY_TOUCHPAD_TOGGLE } }, @@ -474,6 +478,18 @@ static const struct key_entry keymap_p8010[] = { { KE_END, 0 } }; +static const struct key_entry keymap_s2110[] = { + { KE_KEY, KEY1_CODE, { KEY_PROG1 } }, /* "A" */ + { KE_KEY, KEY2_CODE, { KEY_PROG2 } }, /* "B" */ + { KE_KEY, KEY3_CODE, { KEY_WWW } }, /* "Internet" */ + { KE_KEY, KEY4_CODE, { KEY_EMAIL } }, /* "E-mail" */ + { KE_KEY, KEY5_CODE, { KEY_STOPCD } }, + { KE_KEY, KEY6_CODE, { KEY_PLAYPAUSE } }, + { KE_KEY, KEY7_CODE, { KEY_PREVIOUSSONG } }, + { KE_KEY, KEY8_CODE, { KEY_NEXTSONG } }, + { KE_END, 0 } +}; + static const struct key_entry *keymap = keymap_default; static int fujitsu_laptop_dmi_keymap_override(const struct dmi_system_id *id) @@ -511,6 +527,15 @@ static const struct dmi_system_id fujitsu_laptop_dmi_table[] = { }, .driver_data = (void *)keymap_p8010 }, + { + .callback = fujitsu_laptop_dmi_keymap_override, + .ident = "Fujitsu LifeBook S2110", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK S2110"), + }, + .driver_data = (void *)keymap_s2110 + }, {} }; From 513b27dbd126b8a838b601754cb3ae9cd91d2e95 Mon Sep 17 00:00:00 2001 From: Mark Pearson Date: Fri, 16 May 2025 22:33:37 -0400 Subject: [PATCH 046/971] platform/x86: thinkpad_acpi: Ignore battery threshold change event notification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 29e4e6b4235fefa5930affb531fe449cac330a72 ] If user modifies the battery charge threshold an ACPI event is generated. Confirmed with Lenovo FW team this is only generated on user event. As no action is needed, ignore the event and prevent spurious kernel logs. Reported-by: Derek Barbosa Closes: https://lore.kernel.org/platform-driver-x86/7e9a1c47-5d9c-4978-af20-3949d53fb5dc@app.fastmail.com/T/#m5f5b9ae31d3fbf30d7d9a9d76c15fb3502dfd903 Signed-off-by: Mark Pearson Reviewed-by: Hans de Goede Reviewed-by: Armin Wolf Link: https://lore.kernel.org/r/20250517023348.2962591-1-mpearson-lenovo@squebb.ca Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin --- drivers/platform/x86/thinkpad_acpi.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index bcb0689101e2..8de0d3232e48 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -212,6 +212,7 @@ enum tpacpi_hkey_event_t { /* Thermal events */ TP_HKEY_EV_ALARM_BAT_HOT = 0x6011, /* battery too hot */ TP_HKEY_EV_ALARM_BAT_XHOT = 0x6012, /* battery critically hot */ + TP_HKEY_EV_ALARM_BAT_LIM_CHANGE = 0x6013, /* battery charge limit changed*/ TP_HKEY_EV_ALARM_SENSOR_HOT = 0x6021, /* sensor too hot */ TP_HKEY_EV_ALARM_SENSOR_XHOT = 0x6022, /* sensor critically hot */ TP_HKEY_EV_THM_TABLE_CHANGED = 0x6030, /* windows; thermal table changed */ @@ -3942,6 +3943,10 @@ static bool hotkey_notify_6xxx(const u32 hkey, pr_alert("THERMAL EMERGENCY: battery is extremely hot!\n"); /* recommended action: immediate sleep/hibernate */ break; + case TP_HKEY_EV_ALARM_BAT_LIM_CHANGE: + pr_debug("Battery Info: battery charge threshold changed\n"); + /* User changed charging threshold. No action needed */ + return true; case TP_HKEY_EV_ALARM_SENSOR_HOT: pr_crit("THERMAL ALARM: a sensor reports something is too hot!\n"); /* recommended action: warn user through gui, that */ From 106451492d74c01dc9e2c78fc7508228b68b1d05 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Fri, 16 May 2025 07:26:55 -0500 Subject: [PATCH 047/971] net: ethernet: ti: am65-cpsw: Lower random mac address error print to info [ Upstream commit 50980d8da71a0c2e045e85bba93c0099ab73a209 ] Using random mac address is not an error since the driver continues to function, it should be informative that the system has not assigned a MAC address. This is inline with other drivers such as ax88796c, dm9051 etc. Drop the error level to info level. Signed-off-by: Nishanth Menon Reviewed-by: Simon Horman Reviewed-by: Roger Quadros Link: https://patch.msgid.link/20250516122655.442808-1-nm@ti.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/ti/am65-cpsw-nuss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c index 9c8376b27189..c379a958380c 100644 --- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c +++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c @@ -2095,7 +2095,7 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common) port->slave.mac_addr); if (!is_valid_ether_addr(port->slave.mac_addr)) { eth_random_addr(port->slave.mac_addr); - dev_err(dev, "Use random MAC address\n"); + dev_info(dev, "Use random MAC address\n"); } } } From c78abb646ff823e7d22faad4cc0703d4484da9e8 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Tue, 20 May 2025 09:25:03 +0900 Subject: [PATCH 048/971] ksmbd: use list_first_entry_or_null for opinfo_get_list() [ Upstream commit 10379171f346e6f61d30d9949500a8de4336444a ] The list_first_entry() macro never returns NULL. If the list is empty then it returns an invalid pointer. Use list_first_entry_or_null() to check if the list is empty. Reported-by: kernel test robot Reported-by: Dan Carpenter Closes: https://lore.kernel.org/r/202505080231.7OXwq4Te-lkp@intel.com/ Signed-off-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/smb/server/oplock.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c index 72294764d4c2..e564432643ea 100644 --- a/fs/smb/server/oplock.c +++ b/fs/smb/server/oplock.c @@ -146,12 +146,9 @@ static struct oplock_info *opinfo_get_list(struct ksmbd_inode *ci) { struct oplock_info *opinfo; - if (list_empty(&ci->m_op_list)) - return NULL; - down_read(&ci->m_lock); - opinfo = list_first_entry(&ci->m_op_list, struct oplock_info, - op_entry); + opinfo = list_first_entry_or_null(&ci->m_op_list, struct oplock_info, + op_entry); if (opinfo) { if (opinfo->conn == NULL || !atomic_inc_not_zero(&opinfo->refcount)) From c2603c511feb427b2b09f74b57816a81272932a1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 4 Jun 2025 14:42:26 +0200 Subject: [PATCH 049/971] Linux 6.6.93 Link: https://lore.kernel.org/r/20250602134340.906731340@linuxfoundation.org Tested-by: Peter Schneider Tested-by: Florian Fainelli Tested-by: Harshit Mogalapalli Tested-by: Ron Economos Tested-by: Linux Kernel Functional Testing Tested-by: Shuah Khan Tested-by: Mark Brown Tested-by: Miguel Ojeda Tested-by: Hardik Garg Tested-by: Jon Hunter Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 51d975b35551..c9a1e2286b3a 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 6 PATCHLEVEL = 6 -SUBLEVEL = 92 +SUBLEVEL = 93 EXTRAVERSION = NAME = Pinguïn Aangedreven From 4afa9d57ed5e34ead5b51ce7b9dfa3b862fbcb00 Mon Sep 17 00:00:00 2001 From: Pan Taixi Date: Mon, 26 May 2025 09:37:31 +0800 Subject: [PATCH 050/971] tracing: Fix compilation warning on arm32 commit 2fbdb6d8e03b70668c0876e635506540ae92ab05 upstream. On arm32, size_t is defined to be unsigned int, while PAGE_SIZE is unsigned long. This hence triggers a compilation warning as min() asserts the type of two operands to be equal. Casting PAGE_SIZE to size_t solves this issue and works on other target architectures as well. Compilation warning details: kernel/trace/trace.c: In function 'tracing_splice_read_pipe': ./include/linux/minmax.h:20:28: warning: comparison of distinct pointer types lacks a cast (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1))) ^ ./include/linux/minmax.h:26:4: note: in expansion of macro '__typecheck' (__typecheck(x, y) && __no_side_effects(x, y)) ^~~~~~~~~~~ ... kernel/trace/trace.c:6771:8: note: in expansion of macro 'min' min((size_t)trace_seq_used(&iter->seq), ^~~ Cc: stable@vger.kernel.org Link: https://lore.kernel.org/20250526013731.1198030-1-pantaixi@huaweicloud.com Fixes: f5178c41bb43 ("tracing: Fix oob write in trace_seq_to_buffer()") Reviewed-by: Jeongjun Park Signed-off-by: Pan Taixi Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 43d19b69c635..946350c98b53 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -7023,7 +7023,7 @@ static ssize_t tracing_splice_read_pipe(struct file *filp, ret = trace_seq_to_buffer(&iter->seq, page_address(spd.pages[i]), min((size_t)trace_seq_used(&iter->seq), - PAGE_SIZE)); + (size_t)PAGE_SIZE)); if (ret < 0) { __free_page(spd.pages[i]); break; From 8f0f45a312151a52aae920a091ea4b454ac97caf Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Wed, 14 May 2025 21:18:32 +0200 Subject: [PATCH 051/971] pinctrl: armada-37xx: use correct OUTPUT_VAL register for GPIOs > 31 commit 947c93eb29c2a581c0b0b6d5f21af3c2b7ff6d25 upstream. The controller has two consecutive OUTPUT_VAL registers and both holds output value for 32 GPIOs. Due to a missing adjustment, the current code always uses the first register while setting the output value whereas it should use the second one for GPIOs > 31. Add the missing armada_37xx_update_reg() call to adjust the register according to the 'offset' parameter of the function to fix the issue. Cc: stable@vger.kernel.org Fixes: 6702abb3bf23 ("pinctrl: armada-37xx: Fix direction_output() callback behavior") Signed-off-by: Imre Kaloz Reviewed-by: Andrew Lunn Signed-off-by: Gabor Juhos Link: https://lore.kernel.org/20250514-pinctrl-a37xx-fixes-v2-1-07e9ac1ab737@gmail.com Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index c34719b7506d..a20e7d37633e 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -417,6 +417,7 @@ static int armada_37xx_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int value) { struct armada_37xx_pinctrl *info = gpiochip_get_data(chip); + unsigned int val_offset = offset; unsigned int reg = OUTPUT_EN; unsigned int mask, val, ret; @@ -429,6 +430,8 @@ static int armada_37xx_gpio_direction_output(struct gpio_chip *chip, return ret; reg = OUTPUT_VAL; + armada_37xx_update_reg(®, &val_offset); + val = value ? mask : 0; regmap_update_bits(info->regmap, reg, mask, val); From 39ed85ae485d991ffb24d25629a679c0b22e2d8f Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Wed, 14 May 2025 21:18:33 +0200 Subject: [PATCH 052/971] pinctrl: armada-37xx: set GPIO output value before setting direction commit e6ebd4942981f8ad37189bbb36a3c8495e21ef4c upstream. Changing the direction before updating the output value in the OUTPUT_VAL register may result in a glitch on the output line if the previous value in the OUTPUT_VAL register is different from the one we want to set. In order to avoid that, update the output value before changing the direction. Cc: stable@vger.kernel.org Fixes: 6702abb3bf23 ("pinctrl: armada-37xx: Fix direction_output() callback behavior") Signed-off-by: Imre Kaloz Reviewed-by: Andrew Lunn Signed-off-by: Gabor Juhos Link: https://lore.kernel.org/20250514-pinctrl-a37xx-fixes-v2-2-07e9ac1ab737@gmail.com Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index a20e7d37633e..1a39fd97a900 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -417,23 +417,22 @@ static int armada_37xx_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int value) { struct armada_37xx_pinctrl *info = gpiochip_get_data(chip); - unsigned int val_offset = offset; - unsigned int reg = OUTPUT_EN; + unsigned int en_offset = offset; + unsigned int reg = OUTPUT_VAL; unsigned int mask, val, ret; armada_37xx_update_reg(®, &offset); mask = BIT(offset); + val = value ? mask : 0; - ret = regmap_update_bits(info->regmap, reg, mask, mask); - + ret = regmap_update_bits(info->regmap, reg, mask, val); if (ret) return ret; - reg = OUTPUT_VAL; - armada_37xx_update_reg(®, &val_offset); + reg = OUTPUT_EN; + armada_37xx_update_reg(®, &en_offset); - val = value ? mask : 0; - regmap_update_bits(info->regmap, reg, mask, val); + regmap_update_bits(info->regmap, reg, mask, mask); return 0; } From dbd568a30597a705dced78a8c97aaf78824f1552 Mon Sep 17 00:00:00 2001 From: "Gautham R. Shenoy" Date: Thu, 29 May 2025 14:21:43 +0530 Subject: [PATCH 053/971] acpi-cpufreq: Fix nominal_freq units to KHz in get_max_boost_ratio() commit cb6a85f38f456b086c366e346ebb67ffa70c7243 upstream. commit 083466754596 ("cpufreq: ACPI: Fix max-frequency computation") modified get_max_boost_ratio() to return the nominal_freq advertised in the _CPC object. This was for the purposes of computing the maximum frequency. The frequencies advertised in _CPC objects are in MHz. However, cpufreq expects the frequency to be in KHz. Since the nominal_freq returned by get_max_boost_ratio() was not in KHz but instead in MHz,the cpuinfo_max_frequency that was computed using this nominal_freq was incorrect and an invalid value which resulted in cpufreq reporting the P0 frequency as the cpuinfo_max_freq. Fix this by converting the nominal_freq to KHz before returning the same from get_max_boost_ratio(). Reported-by: Manu Bretelle Closes: https://lore.kernel.org/lkml/aDaB63tDvbdcV0cg@HQ-GR2X1W2P57/ Fixes: 083466754596 ("cpufreq: ACPI: Fix max-frequency computation") Signed-off-by: Gautham R. Shenoy Cc: 6.14+ # 6.14+ Link: https://patch.msgid.link/20250529085143.709-1-gautham.shenoy@amd.com Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/cpufreq/acpi-cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 0615e7fa20ad..0bfced81cc17 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -659,7 +659,7 @@ static u64 get_max_boost_ratio(unsigned int cpu, u64 *nominal_freq) nominal_perf = perf_caps.nominal_perf; if (nominal_freq) - *nominal_freq = perf_caps.nominal_freq; + *nominal_freq = perf_caps.nominal_freq * 1000; if (!highest_perf || !nominal_perf) { pr_debug("CPU%d: highest or nominal performance missing\n", cpu); From b836d94be852e2d989e6ca36d863e3a28fc2c67a Mon Sep 17 00:00:00 2001 From: Alexandre Mergnat Date: Mon, 28 Apr 2025 12:06:47 +0200 Subject: [PATCH 054/971] rtc: Make rtc_time64_to_tm() support dates before 1970 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 7df4cfef8b351fec3156160bedfc7d6d29de4cce upstream. Conversion of dates before 1970 is still relevant today because these dates are reused on some hardwares to store dates bigger than the maximal date that is representable in the device's native format. This prominently and very soon affects the hardware covered by the rtc-mt6397 driver that can only natively store dates in the interval 1900-01-01 up to 2027-12-31. So to store the date 2028-01-01 00:00:00 to such a device, rtc_time64_to_tm() must do the right thing for time=-2208988800. Signed-off-by: Alexandre Mergnat Reviewed-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20250428-enable-rtc-v4-1-2b2f7e3f9349@baylibre.com Signed-off-by: Alexandre Belloni Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/lib.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/rtc/lib.c b/drivers/rtc/lib.c index fe361652727a..13b5b1f20465 100644 --- a/drivers/rtc/lib.c +++ b/drivers/rtc/lib.c @@ -46,24 +46,38 @@ EXPORT_SYMBOL(rtc_year_days); * rtc_time64_to_tm - converts time64_t to rtc_time. * * @time: The number of seconds since 01-01-1970 00:00:00. - * (Must be positive.) + * Works for values since at least 1900 * @tm: Pointer to the struct rtc_time. */ void rtc_time64_to_tm(time64_t time, struct rtc_time *tm) { - unsigned int secs; - int days; + int days, secs; u64 u64tmp; u32 u32tmp, udays, century, day_of_century, year_of_century, year, day_of_year, month, day; bool is_Jan_or_Feb, is_leap_year; - /* time must be positive */ + /* + * Get days and seconds while preserving the sign to + * handle negative time values (dates before 1970-01-01) + */ days = div_s64_rem(time, 86400, &secs); + /* + * We need 0 <= secs < 86400 which isn't given for negative + * values of time. Fixup accordingly. + */ + if (secs < 0) { + days -= 1; + secs += 86400; + } + /* day of the week, 1970-01-01 was a Thursday */ tm->tm_wday = (days + 4) % 7; + /* Ensure tm_wday is always positive */ + if (tm->tm_wday < 0) + tm->tm_wday += 7; /* * The following algorithm is, basically, Proposition 6.3 of Neri @@ -93,7 +107,7 @@ void rtc_time64_to_tm(time64_t time, struct rtc_time *tm) * thus, is slightly different from [1]. */ - udays = ((u32) days) + 719468; + udays = days + 719468; u32tmp = 4 * udays + 3; century = u32tmp / 146097; From 32a5f643ce54475fa7eddc336e52c232699a5735 Mon Sep 17 00:00:00 2001 From: Alexandre Mergnat Date: Mon, 28 Apr 2025 12:06:48 +0200 Subject: [PATCH 055/971] rtc: Fix offset calculation for .start_secs < 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit fe9f5f96cfe8b82d0f24cbfa93718925560f4f8d upstream. The comparison rtc->start_secs > rtc->range_max has a signed left-hand side and an unsigned right-hand side. So the comparison might become true for negative start_secs which is interpreted as a (possibly very large) positive value. As a negative value can never be bigger than an unsigned value the correct representation of the (mathematical) comparison rtc->start_secs > rtc->range_max in C is: rtc->start_secs >= 0 && rtc->start_secs > rtc->range_max Use that to fix the offset calculation currently used in the rtc-mt6397 driver. Fixes: 989515647e783 ("rtc: Add one offset seconds to expand RTC range") Signed-off-by: Alexandre Mergnat Reviewed-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20250428-enable-rtc-v4-2-2b2f7e3f9349@baylibre.com Signed-off-by: Alexandre Belloni Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/class.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index edfd942f8c54..af10850fbac2 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -323,7 +323,7 @@ static void rtc_device_get_offset(struct rtc_device *rtc) * * Otherwise the offset seconds should be 0. */ - if (rtc->start_secs > rtc->range_max || + if ((rtc->start_secs >= 0 && rtc->start_secs > rtc->range_max) || rtc->start_secs + range_secs - 1 < rtc->range_min) rtc->offset_secs = rtc->start_secs - rtc->range_min; else if (rtc->start_secs > rtc->range_min) From 73c50fa3ff02acc42b67128827ab7c989570d483 Mon Sep 17 00:00:00 2001 From: Jiayi Li Date: Thu, 8 May 2025 13:59:47 +0800 Subject: [PATCH 056/971] usb: quirks: Add NO_LPM quirk for SanDisk Extreme 55AE commit 19f795591947596b5b9efa86fd4b9058e45786e9 upstream. This device exhibits I/O errors during file transfers due to unstable link power management (LPM) behavior. The kernel logs show repeated warm resets and eventual disconnection when LPM is enabled: [ 3467.810740] hub 2-0:1.0: state 7 ports 6 chg 0000 evt 0020 [ 3467.810740] usb usb2-port5: do warm reset [ 3467.866444] usb usb2-port5: not warm reset yet, waiting 50ms [ 3467.907407] sd 0:0:0:0: [sda] tag#12 sense submit err -19 [ 3467.994423] usb usb2-port5: status 02c0, change 0001, 10.0 Gb/s [ 3467.994453] usb 2-5: USB disconnect, device number 4 The error -19 (ENODEV) occurs when the device disappears during write operations. Adding USB_QUIRK_NO_LPM disables link power management for this specific device, resolving the stability issues. Signed-off-by: Jiayi Li Cc: stable Link: https://lore.kernel.org/r/20250508055947.764538-1-lijiayi@kylinos.cn Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 4903c733d37a..c979ecd0169a 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -372,6 +372,9 @@ static const struct usb_device_id usb_quirk_list[] = { /* SanDisk Corp. SanDisk 3.2Gen1 */ { USB_DEVICE(0x0781, 0x55a3), .driver_info = USB_QUIRK_DELAY_INIT }, + /* SanDisk Extreme 55AE */ + { USB_DEVICE(0x0781, 0x55ae), .driver_info = USB_QUIRK_NO_LPM }, + /* Realforce 87U Keyboard */ { USB_DEVICE(0x0853, 0x011b), .driver_info = USB_QUIRK_NO_LPM }, From ff835ab115f0fbec9397d6f0848612a6254a7e5c Mon Sep 17 00:00:00 2001 From: Hongyu Xie Date: Mon, 19 May 2025 10:33:28 +0800 Subject: [PATCH 057/971] usb: storage: Ignore UAS driver for SanDisk 3.2 Gen2 storage device commit a541acceedf4f639f928f41fbb676b75946dc295 upstream. SanDisk 3.2 Gen2 storage device(0781:55e8) doesn't work well with UAS. Log says, [ 6.507865][ 3] [ T159] usb 2-1.4: new SuperSpeed Gen 1 USB device number 4 using xhci_hcd [ 6.540314][ 3] [ T159] usb 2-1.4: New USB device found, idVendor=0781, idProduct=55e8, bcdDevice= 0.01 [ 6.576304][ 3] [ T159] usb 2-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [ 6.584727][ 3] [ T159] usb 2-1.4: Product: SanDisk 3.2 Gen2 [ 6.590459][ 3] [ T159] usb 2-1.4: Manufacturer: SanDisk [ 6.595845][ 3] [ T159] usb 2-1.4: SerialNumber: 03021707022525140940 [ 7.230852][ 0] [ T265] usbcore: registered new interface driver usb-storage [ 7.251247][ 0] [ T265] scsi host3: uas [ 7.255280][ 0] [ T265] usbcore: registered new interface driver uas [ 7.270498][ 1] [ T192] scsi 3:0:0:0: Direct-Access SanDisk Extreme Pro DDE1 0110 PQ: 0 ANSI: 6 [ 7.299588][ 3] [ T192] scsi 3:0:0:1: Enclosure SanDisk SES Device 0110 PQ: 0 ANSI: 6 [ 7.321681][ 3] [ T192] sd 3:0:0:0: Attached scsi generic sg1 type 0 [ 7.328185][ 3] [ T192] scsi 3:0:0:1: Attached scsi generic sg2 type 13 [ 7.328804][ 0] [ T191] sd 3:0:0:0: [sda] 976773168 512-byte logical blocks: (500 GB/466 GiB) [ 7.343486][ 0] [ T191] sd 3:0:0:0: [sda] 4096-byte physical blocks [ 7.364611][ 0] [ T191] sd 3:0:0:0: [sda] Write Protect is off [ 7.370524][ 0] [ T191] sd 3:0:0:0: [sda] Mode Sense: 3d 00 10 00 [ 7.390655][ 0] [ T191] sd 3:0:0:0: [sda] Write cache: enabled, read cache: enabled, supports DPO and FUA [ 7.401363][ 0] [ T191] sd 3:0:0:0: [sda] Optimal transfer size 1048576 bytes [ 7.436010][ 0] [ T191] sda: sda1 [ 7.450850][ 0] [ T191] sd 3:0:0:0: [sda] Attached SCSI disk [ 7.470218][ 4] [ T262] scsi 3:0:0:1: Failed to get diagnostic page 0x1 [ 7.474869][ 0] [ C0] sd 3:0:0:0: [sda] tag#0 data cmplt err -75 uas-tag 2 inflight: CMD [ 7.476911][ 4] [ T262] scsi 3:0:0:1: Failed to bind enclosure -19 [ 7.485330][ 0] [ C0] sd 3:0:0:0: [sda] tag#0 CDB: Read(10) 28 00 00 00 00 28 00 00 10 00 [ 7.491593][ 4] [ T262] ses 3:0:0:1: Attached Enclosure device [ 38.066980][ 4] [ T192] sd 3:0:0:0: [sda] tag#4 uas_eh_abort_handler 0 uas-tag 5 inflight: CMD IN [ 38.076012][ 4] [ T192] sd 3:0:0:0: [sda] tag#4 CDB: Read(10) 28 00 00 00 01 08 00 00 f8 00 [ 38.086485][ 4] [ T192] sd 3:0:0:0: [sda] tag#3 uas_eh_abort_handler 0 uas-tag 1 inflight: CMD IN [ 38.095515][ 4] [ T192] sd 3:0:0:0: [sda] tag#3 CDB: Read(10) 28 00 00 00 00 10 00 00 08 00 [ 38.104122][ 4] [ T192] sd 3:0:0:0: [sda] tag#2 uas_eh_abort_handler 0 uas-tag 4 inflight: CMD IN [ 38.113152][ 4] [ T192] sd 3:0:0:0: [sda] tag#2 CDB: Read(10) 28 00 00 00 00 88 00 00 78 00 [ 38.121761][ 4] [ T192] sd 3:0:0:0: [sda] tag#1 uas_eh_abort_handler 0 uas-tag 3 inflight: CMD IN [ 38.130791][ 4] [ T192] sd 3:0:0:0: [sda] tag#1 CDB: Read(10) 28 00 00 00 00 48 00 00 30 00 [ 38.139401][ 4] [ T192] sd 3:0:0:0: [sda] tag#0 uas_eh_abort_handler 0 uas-tag 2 inflight: CMD [ 38.148170][ 4] [ T192] sd 3:0:0:0: [sda] tag#0 CDB: Read(10) 28 00 00 00 00 28 00 00 10 00 [ 38.178980][ 2] [ T304] scsi host3: uas_eh_device_reset_handler start [ 38.901540][ 2] [ T304] usb 2-1.4: reset SuperSpeed Gen 1 USB device number 4 using xhci_hcd [ 38.936791][ 2] [ T304] scsi host3: uas_eh_device_reset_handler success Device decriptor is below, Bus 002 Device 006: ID 0781:55e8 SanDisk Corp. SanDisk 3.2 Gen2 Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 3.20 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 9 idVendor 0x0781 SanDisk Corp. idProduct 0x55e8 bcdDevice 0.01 iManufacturer 1 SanDisk iProduct 2 SanDisk 3.2 Gen2 iSerial 3 03021707022525140940 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 0x0079 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 896mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 8 Mass Storage bInterfaceSubClass 6 SCSI bInterfaceProtocol 80 Bulk-Only iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0400 1x 1024 bytes bInterval 0 bMaxBurst 15 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x01 EP 1 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0400 1x 1024 bytes bInterval 0 bMaxBurst 15 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 1 bNumEndpoints 4 bInterfaceClass 8 Mass Storage bInterfaceSubClass 6 SCSI bInterfaceProtocol 98 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x01 EP 1 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0400 1x 1024 bytes bInterval 0 bMaxBurst 0 Command pipe (0x01) Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0400 1x 1024 bytes bInterval 0 bMaxBurst 15 MaxStreams 32 Status pipe (0x02) Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0400 1x 1024 bytes bInterval 0 bMaxBurst 15 MaxStreams 32 Data-in pipe (0x03) Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x03 EP 3 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0400 1x 1024 bytes bInterval 0 bMaxBurst 15 MaxStreams 32 Data-out pipe (0x04) Binary Object Store Descriptor: bLength 5 bDescriptorType 15 wTotalLength 0x002a bNumDeviceCaps 3 USB 2.0 Extension Device Capability: bLength 7 bDescriptorType 16 bDevCapabilityType 2 bmAttributes 0x0000f41e BESL Link Power Management (LPM) Supported BESL value 1024 us Deep BESL value 61440 us SuperSpeed USB Device Capability: bLength 10 bDescriptorType 16 bDevCapabilityType 3 bmAttributes 0x00 wSpeedsSupported 0x000e Device can operate at Full Speed (12Mbps) Device can operate at High Speed (480Mbps) Device can operate at SuperSpeed (5Gbps) bFunctionalitySupport 1 Lowest fully-functional device speed is Full Speed (12Mbps) bU1DevExitLat 10 micro seconds bU2DevExitLat 2047 micro seconds SuperSpeedPlus USB Device Capability: bLength 20 bDescriptorType 16 bDevCapabilityType 10 bmAttributes 0x00000001 Sublink Speed Attribute count 1 Sublink Speed ID count 0 wFunctionalitySupport 0x1100 bmSublinkSpeedAttr[0] 0x000a4030 Speed Attribute ID: 0 10Gb/s Symmetric RX SuperSpeedPlus bmSublinkSpeedAttr[1] 0x000a40b0 Speed Attribute ID: 0 10Gb/s Symmetric TX SuperSpeedPlus Device Status: 0x0000 (Bus Powered) So ignore UAS driver for this device. Signed-off-by: Hongyu Xie Cc: stable Link: https://lore.kernel.org/r/20250519023328.1498856-1-xiehongyu1@kylinos.cn Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_uas.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index d460d71b4257..1477e31d7763 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h @@ -52,6 +52,13 @@ UNUSUAL_DEV(0x059f, 0x1061, 0x0000, 0x9999, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NO_REPORT_OPCODES | US_FL_NO_SAME), +/* Reported-by: Zhihong Zhou */ +UNUSUAL_DEV(0x0781, 0x55e8, 0x0000, 0x9999, + "SanDisk", + "", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_UAS), + /* Reported-by: Hongling Zeng */ UNUSUAL_DEV(0x090c, 0x2000, 0x0000, 0x9999, "Hiksemi", From 5ec1200da929d1871f12f29cd13f5a29327b203b Mon Sep 17 00:00:00 2001 From: Charles Yeh Date: Wed, 21 May 2025 21:23:54 +0800 Subject: [PATCH 058/971] USB: serial: pl2303: add new chip PL2303GC-Q20 and PL2303GT-2AB commit d3a889482bd5abf2bbdc1ec3d2d49575aa160c9c upstream. Add new bcd (0x905) to support PL2303GT-2AB (TYPE_HXN). Add new bcd (0x1005) to support PL2303GC-Q20 (TYPE_HXN). Signed-off-by: Charles Yeh Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/pl2303.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 8e327fcb222f..1ba2287d4d45 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -457,6 +457,8 @@ static int pl2303_detect_type(struct usb_serial *serial) case 0x605: case 0x700: /* GR */ case 0x705: + case 0x905: /* GT-2AB */ + case 0x1005: /* GC-Q20 */ return TYPE_HXN; } break; From b63f23fb0ad28987e177587a6bbd9436e03a29a8 Mon Sep 17 00:00:00 2001 From: Qasim Ijaz Date: Tue, 22 Apr 2025 14:47:17 +0100 Subject: [PATCH 059/971] usb: typec: ucsi: fix Clang -Wsign-conversion warning commit f4239ace2dd8606f6824757f192965a95746da05 upstream. debugfs.c emits the following warnings when compiling with the -Wsign-conversion flag with clang 15: drivers/usb/typec/ucsi/debugfs.c:58:27: warning: implicit conversion changes signedness: 'int' to 'u32' (aka 'unsigned int') [-Wsign-conversion] ucsi->debugfs->status = ret; ~ ^~~ drivers/usb/typec/ucsi/debugfs.c:71:25: warning: implicit conversion changes signedness: 'u32' (aka 'unsigned int') to 'int' [-Wsign-conversion] return ucsi->debugfs->status; ~~~~~~ ~~~~~~~~~~~~~~~^~~~~~ During ucsi_cmd() we see: if (ret < 0) { ucsi->debugfs->status = ret; return ret; } But "status" is u32 meaning unsigned wrap-around occurs when assigning a value which is < 0 to it, this obscures the real status. To fix this make the "status" of type int since ret is also of type int. Fixes: df0383ffad64 ("usb: typec: ucsi: Add debugfs for ucsi commands") Cc: stable@vger.kernel.org Signed-off-by: Qasim Ijaz Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20250422134717.66218-1-qasdev00@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/ucsi/ucsi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h index 3bb23a2ea547..7706f4e95125 100644 --- a/drivers/usb/typec/ucsi/ucsi.h +++ b/drivers/usb/typec/ucsi/ucsi.h @@ -302,7 +302,7 @@ struct ucsi_debugfs_entry { u64 low; u64 high; } response; - u32 status; + int status; struct dentry *dentry; }; From e2e38c5211b1d1970544e3d9292938d926b88da9 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Tue, 27 May 2025 09:47:37 +0200 Subject: [PATCH 060/971] Bluetooth: hci_qca: move the SoC type check to the right place commit 0fb410c914eb03c7e9d821e26d03bac0a239e5db upstream. Commit 3d05fc82237a ("Bluetooth: qca: set power_ctrl_enabled on NULL returned by gpiod_get_optional()") accidentally changed the prevous behavior where power control would be disabled without the BT_EN GPIO only on QCA_WCN6750 and QCA_WCN6855 while also getting the error check wrong. We should treat every IS_ERR() return value from devm_gpiod_get_optional() as a reason to bail-out while we should only set power_ctrl_enabled to false on the two models mentioned above. While at it: use dev_err_probe() to save a LOC. Cc: stable@vger.kernel.org Fixes: 3d05fc82237a ("Bluetooth: qca: set power_ctrl_enabled on NULL returned by gpiod_get_optional()") Signed-off-by: Bartosz Golaszewski Reviewed-by: Krzysztof Kozlowski Tested-by: Hsin-chen Chuang Reviewed-by: Hsin-chen Chuang Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Greg Kroah-Hartman --- drivers/bluetooth/hci_qca.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 7a552387129e..9c6f79d86053 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -2307,14 +2307,14 @@ static int qca_serdev_probe(struct serdev_device *serdev) qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", GPIOD_OUT_LOW); - if (IS_ERR(qcadev->bt_en) && - (data->soc_type == QCA_WCN6750 || - data->soc_type == QCA_WCN6855)) { - dev_err(&serdev->dev, "failed to acquire BT_EN gpio\n"); - return PTR_ERR(qcadev->bt_en); - } + if (IS_ERR(qcadev->bt_en)) + return dev_err_probe(&serdev->dev, + PTR_ERR(qcadev->bt_en), + "failed to acquire BT_EN gpio\n"); - if (!qcadev->bt_en) + if (!qcadev->bt_en && + (data->soc_type == QCA_WCN6750 || + data->soc_type == QCA_WCN6855)) power_ctrl_enabled = false; qcadev->sw_ctrl = devm_gpiod_get_optional(&serdev->dev, "swctrl", From 3258d7ff8ebfa451426662b23e8f2b51b129afe1 Mon Sep 17 00:00:00 2001 From: Dustin Lundquist Date: Tue, 6 May 2025 11:18:45 -0700 Subject: [PATCH 061/971] serial: jsm: fix NPE during jsm_uart_port_init commit e3975aa899c0a3bbc10d035e699b142cd1373a71 upstream. No device was set which caused serial_base_ctrl_add to crash. BUG: kernel NULL pointer dereference, address: 0000000000000050 Oops: Oops: 0000 [#1] PREEMPT SMP NOPTI CPU: 16 UID: 0 PID: 368 Comm: (udev-worker) Not tainted 6.12.25-amd64 #1 Debian 6.12.25-1 RIP: 0010:serial_base_ctrl_add+0x96/0x120 Call Trace: serial_core_register_port+0x1a0/0x580 ? __setup_irq+0x39c/0x660 ? __kmalloc_cache_noprof+0x111/0x310 jsm_uart_port_init+0xe8/0x180 [jsm] jsm_probe_one+0x1f4/0x410 [jsm] local_pci_probe+0x42/0x90 pci_device_probe+0x22f/0x270 really_probe+0xdb/0x340 ? pm_runtime_barrier+0x54/0x90 ? __pfx___driver_attach+0x10/0x10 __driver_probe_device+0x78/0x110 driver_probe_device+0x1f/0xa0 __driver_attach+0xba/0x1c0 bus_for_each_dev+0x8c/0xe0 bus_add_driver+0x112/0x1f0 driver_register+0x72/0xd0 jsm_init_module+0x36/0xff0 [jsm] ? __pfx_jsm_init_module+0x10/0x10 [jsm] do_one_initcall+0x58/0x310 do_init_module+0x60/0x230 Tested with Digi Neo PCIe 8 port card. Fixes: 84a9582fd203 ("serial: core: Start managing serial controllers to enable runtime PM") Cc: stable Signed-off-by: Dustin Lundquist Link: https://lore.kernel.org/r/3f31d4f75863614655c4673027a208be78d022ec.camel@null-ptr.net Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/jsm/jsm_tty.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c index 222afc270c88..1bee624bd484 100644 --- a/drivers/tty/serial/jsm/jsm_tty.c +++ b/drivers/tty/serial/jsm/jsm_tty.c @@ -451,6 +451,7 @@ int jsm_uart_port_init(struct jsm_board *brd) if (!brd->channels[i]) continue; + brd->channels[i]->uart_port.dev = &brd->pci_dev->dev; brd->channels[i]->uart_port.irq = brd->irq; brd->channels[i]->uart_port.uartclk = 14745600; brd->channels[i]->uart_port.type = PORT_JSM; From 259e4d6e10cddb377112063c2fcb3d65a72c76cf Mon Sep 17 00:00:00 2001 From: Dave Penkler Date: Wed, 21 May 2025 14:16:56 +0200 Subject: [PATCH 062/971] usb: usbtmc: Fix timeout value in get_stb commit 342e4955a1f1ce28c70a589999b76365082dbf10 upstream. wait_event_interruptible_timeout requires a timeout argument in units of jiffies. It was being called in usbtmc_get_stb with the usb timeout value which is in units of milliseconds. Pass the timeout argument converted to jiffies. Fixes: 048c6d88a021 ("usb: usbtmc: Add ioctls to set/get usb timeout") Cc: stable@vger.kernel.org Signed-off-by: Dave Penkler Link: https://lore.kernel.org/r/20250521121656.18174-4-dpenkler@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/usbtmc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 2f92905e05ca..629ef749dafc 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -483,6 +483,7 @@ static int usbtmc_get_stb(struct usbtmc_file_data *file_data, __u8 *stb) u8 tag; int rv; long wait_rv; + unsigned long expire; dev_dbg(dev, "Enter ioctl_read_stb iin_ep_present: %d\n", data->iin_ep_present); @@ -512,10 +513,11 @@ static int usbtmc_get_stb(struct usbtmc_file_data *file_data, __u8 *stb) } if (data->iin_ep_present) { + expire = msecs_to_jiffies(file_data->timeout); wait_rv = wait_event_interruptible_timeout( data->waitq, atomic_read(&data->iin_data_valid) != 0, - file_data->timeout); + expire); if (wait_rv < 0) { dev_dbg(dev, "wait interrupted %ld\n", wait_rv); rv = wait_rv; From 5a057f261539720165d03d85024da2b52e67f63d Mon Sep 17 00:00:00 2001 From: Sergey Senozhatsky Date: Fri, 28 Mar 2025 00:03:50 +0900 Subject: [PATCH 063/971] thunderbolt: Do not double dequeue a configuration request commit 0f73628e9da1ee39daf5f188190cdbaee5e0c98c upstream. Some of our devices crash in tb_cfg_request_dequeue(): general protection fault, probably for non-canonical address 0xdead000000000122 CPU: 6 PID: 91007 Comm: kworker/6:2 Tainted: G U W 6.6.65 RIP: 0010:tb_cfg_request_dequeue+0x2d/0xa0 Call Trace: ? tb_cfg_request_dequeue+0x2d/0xa0 tb_cfg_request_work+0x33/0x80 worker_thread+0x386/0x8f0 kthread+0xed/0x110 ret_from_fork+0x38/0x50 ret_from_fork_asm+0x1b/0x30 The circumstances are unclear, however, the theory is that tb_cfg_request_work() can be scheduled twice for a request: first time via frame.callback from ring_work() and second time from tb_cfg_request(). Both times kworkers will execute tb_cfg_request_dequeue(), which results in double list_del() from the ctl->request_queue (the list poison deference hints at it: 0xdead000000000122). Do not dequeue requests that don't have TB_CFG_REQUEST_ACTIVE bit set. Signed-off-by: Sergey Senozhatsky Cc: stable@vger.kernel.org Signed-off-by: Mika Westerberg Signed-off-by: Greg Kroah-Hartman --- drivers/thunderbolt/ctl.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/thunderbolt/ctl.c b/drivers/thunderbolt/ctl.c index d997a4c545f7..a60d7afc041f 100644 --- a/drivers/thunderbolt/ctl.c +++ b/drivers/thunderbolt/ctl.c @@ -143,6 +143,11 @@ static void tb_cfg_request_dequeue(struct tb_cfg_request *req) struct tb_ctl *ctl = req->ctl; mutex_lock(&ctl->request_queue_lock); + if (!test_bit(TB_CFG_REQUEST_ACTIVE, &req->flags)) { + mutex_unlock(&ctl->request_queue_lock); + return; + } + list_del(&req->list); clear_bit(TB_CFG_REQUEST_ACTIVE, &req->flags); if (test_bit(TB_CFG_REQUEST_CANCELED, &req->flags)) From 68c50424373711dfc14e487ac596dde84bca60ce Mon Sep 17 00:00:00 2001 From: Lukasz Czechowski Date: Fri, 25 Apr 2025 17:18:07 +0200 Subject: [PATCH 064/971] dt-bindings: usb: cypress,hx3: Add support for all variants commit 1ad4b5a7de16806afc1aeaf012337e62af04e001 upstream. The Cypress HX3 hubs use different default PID value depending on the variant. Update compatibles list. Becasuse all hub variants use the same driver data, allow the dt node to have two compatibles: leftmost which matches the HW exactly, and the second one as fallback. Fixes: 1eca51f58a10 ("dt-bindings: usb: Add binding for Cypress HX3 USB 3.0 family") Cc: stable@vger.kernel.org # 6.6 Cc: stable@vger.kernel.org # Backport of the patch ("dt-bindings: usb: usb-device: relax compatible pattern to a contains") from list: https://lore.kernel.org/linux-usb/20250418-dt-binding-usb-device-compatibles-v2-1-b3029f14e800@cherry.de/ Cc: stable@vger.kernel.org # Backport of the patch in this series fixing product ID in onboard_dev_id_table in drivers/usb/misc/onboard_usb_dev.c driver Signed-off-by: Lukasz Czechowski Reviewed-by: "Rob Herring (Arm)" Link: https://lore.kernel.org/r/20250425-onboard_usb_dev-v2-2-4a76a474a010@thaumatec.com [taken with Greg's blessing] Signed-off-by: Heiko Stuebner Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/usb/cypress,hx3.yaml | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/cypress,hx3.yaml b/Documentation/devicetree/bindings/usb/cypress,hx3.yaml index 47add0d85fb8..02349bbb0d46 100644 --- a/Documentation/devicetree/bindings/usb/cypress,hx3.yaml +++ b/Documentation/devicetree/bindings/usb/cypress,hx3.yaml @@ -14,9 +14,22 @@ allOf: properties: compatible: - enum: - - usb4b4,6504 - - usb4b4,6506 + oneOf: + - enum: + - usb4b4,6504 + - usb4b4,6506 + - items: + - enum: + - usb4b4,6500 + - usb4b4,6508 + - const: usb4b4,6504 + - items: + - enum: + - usb4b4,6502 + - usb4b4,6503 + - usb4b4,6507 + - usb4b4,650a + - const: usb4b4,6506 reg: true From 9f837b359d1c82d71aa4159f5128681e0b93303e Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Wed, 30 Apr 2025 17:44:59 +0800 Subject: [PATCH 065/971] dt-bindings: phy: imx8mq-usb: fix fsl,phy-tx-vboost-level-microvolt property commit 5b3a91b207c00a8d27f75ce8aaa9860844da72c8 upstream. The ticket TKT0676370 shows the description of TX_VBOOST_LVL is wrong in register PHY_CTRL3 bit[31:29]. 011: Corresponds to a launch amplitude of 1.12 V. 010: Corresponds to a launch amplitude of 1.04 V. 000: Corresponds to a launch amplitude of 0.88 V. After updated: 011: Corresponds to a launch amplitude of 0.844 V. 100: Corresponds to a launch amplitude of 1.008 V. 101: Corresponds to a launch amplitude of 1.156 V. This will correct it accordingly. Fixes: b2e75563dc39 ("dt-bindings: phy: imx8mq-usb: add phy tuning properties") Cc: stable@vger.kernel.org Reviewed-by: Jun Li Signed-off-by: Xu Yang Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250430094502.2723983-1-xu.yang_2@nxp.com Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml index dc3a3f709fea..bac4d0b51d8a 100644 --- a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml +++ b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml @@ -58,8 +58,7 @@ properties: fsl,phy-tx-vboost-level-microvolt: description: Adjust the boosted transmit launch pk-pk differential amplitude - minimum: 880 - maximum: 1120 + enum: [844, 1008, 1156] fsl,phy-comp-dis-tune-percent: description: From e9019e2214fac6a73d5247467672d1663ec0421a Mon Sep 17 00:00:00 2001 From: Aurabindo Pillai Date: Wed, 21 May 2025 16:05:39 -0400 Subject: [PATCH 066/971] Revert "drm/amd/display: more liberal vmin/vmax update for freesync" commit 1b824eef269db44d068bbc0de74c94a8e8f9ce02 upstream. This reverts commit cfb2d41831ee5647a4ae0ea7c24971a92d5dfa0d since it causes regressions on certain configs. Revert until the issue can be isolated and debugged. Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4238 Signed-off-by: Aurabindo Pillai Acked-by: Alex Deucher Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 9189864c236a..d4edddaa23dd 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -610,21 +610,15 @@ static void dm_crtc_high_irq(void *interrupt_params) spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); if (acrtc->dm_irq_params.stream && - acrtc->dm_irq_params.vrr_params.supported) { - bool replay_en = acrtc->dm_irq_params.stream->link->replay_settings.replay_feature_enabled; - bool psr_en = acrtc->dm_irq_params.stream->link->psr_settings.psr_feature_enabled; - bool fs_active_var_en = acrtc->dm_irq_params.freesync_config.state == VRR_STATE_ACTIVE_VARIABLE; - + acrtc->dm_irq_params.vrr_params.supported && + acrtc->dm_irq_params.freesync_config.state == + VRR_STATE_ACTIVE_VARIABLE) { mod_freesync_handle_v_update(adev->dm.freesync_module, acrtc->dm_irq_params.stream, &acrtc->dm_irq_params.vrr_params); - /* update vmin_vmax only if freesync is enabled, or only if PSR and REPLAY are disabled */ - if (fs_active_var_en || (!fs_active_var_en && !replay_en && !psr_en)) { - dc_stream_adjust_vmin_vmax(adev->dm.dc, - acrtc->dm_irq_params.stream, - &acrtc->dm_irq_params.vrr_params.adjust); - } + dc_stream_adjust_vmin_vmax(adev->dm.dc, acrtc->dm_irq_params.stream, + &acrtc->dm_irq_params.vrr_params.adjust); } /* From cc5cd8a1719e475890c374a38bfc2192608fb055 Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Mon, 24 Mar 2025 15:20:22 +0100 Subject: [PATCH 067/971] tools/x86/kcpuid: Fix error handling [ Upstream commit 116edfe173d0c59ec2aa87fb91f2f31d477b61b3 ] Error handling in kcpuid is unreliable. On malloc() failures, the code prints an error then just goes on. The error messages are also printed to standard output instead of standard error. Use err() and errx() from to direct all error messages to standard error and automatically exit the program. Use err() to include the errno information, and errx() otherwise. Use warnx() for warnings. While at it, alphabetically reorder the header includes. [ mingo: Fix capitalization in the help text while at it. ] Fixes: c6b2f240bf8d ("tools/x86: Add a kcpuid tool to show raw CPU features") Reported-by: Remington Brasga Signed-off-by: Ahmed S. Darwish Signed-off-by: Ingo Molnar Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Josh Poimboeuf Link: https://lore.kernel.org/r/20250324142042.29010-2-darwi@linutronix.de Closes: https://lkml.kernel.org/r/20240926223557.2048-1-rbrasga@uci.edu Signed-off-by: Sasha Levin --- tools/arch/x86/kcpuid/kcpuid.c | 47 +++++++++++++++++----------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/tools/arch/x86/kcpuid/kcpuid.c b/tools/arch/x86/kcpuid/kcpuid.c index b7965dfff33a..8c2644f3497e 100644 --- a/tools/arch/x86/kcpuid/kcpuid.c +++ b/tools/arch/x86/kcpuid/kcpuid.c @@ -1,11 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 #define _GNU_SOURCE -#include +#include +#include #include +#include #include #include -#include #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #define min(a, b) (((a) < (b)) ? (a) : (b)) @@ -156,14 +157,14 @@ static bool cpuid_store(struct cpuid_range *range, u32 f, int subleaf, if (!func->leafs) { func->leafs = malloc(sizeof(struct subleaf)); if (!func->leafs) - perror("malloc func leaf"); + err(EXIT_FAILURE, NULL); func->nr = 1; } else { s = func->nr; func->leafs = realloc(func->leafs, (s + 1) * sizeof(*leaf)); if (!func->leafs) - perror("realloc f->leafs"); + err(EXIT_FAILURE, NULL); func->nr++; } @@ -222,7 +223,7 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax) range = malloc(sizeof(struct cpuid_range)); if (!range) - perror("malloc range"); + err(EXIT_FAILURE, NULL); if (input_eax & 0x80000000) range->is_ext = true; @@ -231,7 +232,7 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax) range->funcs = malloc(sizeof(struct cpuid_func) * idx_func); if (!range->funcs) - perror("malloc range->funcs"); + err(EXIT_FAILURE, NULL); range->nr = idx_func; memset(range->funcs, 0, sizeof(struct cpuid_func) * idx_func); @@ -387,8 +388,8 @@ static int parse_line(char *line) return 0; err_exit: - printf("Warning: wrong line format:\n"); - printf("\tline[%d]: %s\n", flines, line); + warnx("Wrong line format:\n" + "\tline[%d]: %s", flines, line); return -1; } @@ -410,10 +411,8 @@ static void parse_text(void) file = fopen("./cpuid.csv", "r"); } - if (!file) { - printf("Fail to open '%s'\n", filename); - return; - } + if (!file) + err(EXIT_FAILURE, "%s", filename); while (1) { ret = getline(&line, &len, file); @@ -521,7 +520,7 @@ static inline struct cpuid_func *index_to_func(u32 index) func_idx = index & 0xffff; if ((func_idx + 1) > (u32)range->nr) { - printf("ERR: invalid input index (0x%x)\n", index); + warnx("Invalid input index (0x%x)", index); return NULL; } return &range->funcs[func_idx]; @@ -553,7 +552,7 @@ static void show_info(void) return; } - printf("ERR: invalid input subleaf (0x%x)\n", user_sub); + warnx("Invalid input subleaf (0x%x)", user_sub); } show_func(func); @@ -584,15 +583,15 @@ static void setup_platform_cpuid(void) static void usage(void) { - printf("kcpuid [-abdfhr] [-l leaf] [-s subleaf]\n" - "\t-a|--all Show both bit flags and complex bit fields info\n" - "\t-b|--bitflags Show boolean flags only\n" - "\t-d|--detail Show details of the flag/fields (default)\n" - "\t-f|--flags Specify the cpuid csv file\n" - "\t-h|--help Show usage info\n" - "\t-l|--leaf=index Specify the leaf you want to check\n" - "\t-r|--raw Show raw cpuid data\n" - "\t-s|--subleaf=sub Specify the subleaf you want to check\n" + warnx("kcpuid [-abdfhr] [-l leaf] [-s subleaf]\n" + "\t-a|--all Show both bit flags and complex bit fields info\n" + "\t-b|--bitflags Show boolean flags only\n" + "\t-d|--detail Show details of the flag/fields (default)\n" + "\t-f|--flags Specify the CPUID CSV file\n" + "\t-h|--help Show usage info\n" + "\t-l|--leaf=index Specify the leaf you want to check\n" + "\t-r|--raw Show raw CPUID data\n" + "\t-s|--subleaf=sub Specify the subleaf you want to check" ); } @@ -643,7 +642,7 @@ static int parse_options(int argc, char *argv[]) user_sub = strtoul(optarg, NULL, 0); break; default: - printf("%s: Invalid option '%c'\n", argv[0], optopt); + warnx("Invalid option '%c'", optopt); return -1; } From 5dea6398f2dd6ad9a9bc4c1225efb9656087cb72 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Wed, 2 Apr 2025 18:24:58 +0100 Subject: [PATCH 068/971] x86/idle: Remove MFENCEs for X86_BUG_CLFLUSH_MONITOR in mwait_idle_with_hints() and prefer_mwait_c1_over_halt() [ Upstream commit 1f13c60d84e880df6698441026e64f84c7110c49 ] The following commit, 12 years ago: 7e98b7192046 ("x86, idle: Use static_cpu_has() for CLFLUSH workaround, add barriers") added barriers around the CLFLUSH in mwait_idle_with_hints(), justified with: ... and add memory barriers around it since the documentation is explicit that CLFLUSH is only ordered with respect to MFENCE. This also triggered, 11 years ago, the same adjustment in: f8e617f45829 ("sched/idle/x86: Optimize unnecessary mwait_idle() resched IPIs") during development, although it failed to get the static_cpu_has_bug() treatment. X86_BUG_CLFLUSH_MONITOR (a.k.a the AAI65 errata) is specific to Intel CPUs, and the SDM currently states: Executions of the CLFLUSH instruction are ordered with respect to each other and with respect to writes, locked read-modify-write instructions, and fence instructions[1]. With footnote 1 reading: Earlier versions of this manual specified that executions of the CLFLUSH instruction were ordered only by the MFENCE instruction. All processors implementing the CLFLUSH instruction also order it relative to the other operations enumerated above. i.e. The SDM was incorrect at the time, and barriers should not have been inserted. Double checking the original AAI65 errata (not available from intel.com any more) shows no mention of barriers either. Note: If this were a general codepath, the MFENCEs would be needed, because AMD CPUs of the same vintage do sport otherwise-unordered CLFLUSHs. Remove the unnecessary barriers. Furthermore, use a plain alternative(), rather than static_cpu_has_bug() and/or no optimisation. The workaround is a single instruction. Use an explicit %rax pointer rather than a general memory operand, because MONITOR takes the pointer implicitly in the same way. [ mingo: Cleaned up the commit a bit. ] Fixes: 7e98b7192046 ("x86, idle: Use static_cpu_has() for CLFLUSH workaround, add barriers") Signed-off-by: Andrew Cooper Signed-off-by: Ingo Molnar Acked-by: Dave Hansen Acked-by: Borislav Petkov (AMD) Cc: "H. Peter Anvin" Cc: Peter Zijlstra Cc: Rik van Riel Cc: Linus Torvalds Cc: Andy Lutomirski Cc: Brian Gerst Cc: Juergen Gross Cc: Rafael J. Wysocki Link: https://lore.kernel.org/r/20250402172458.1378112-1-andrew.cooper3@citrix.com Signed-off-by: Sasha Levin --- arch/x86/include/asm/mwait.h | 9 +++------ arch/x86/kernel/process.c | 9 +++------ 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h index bae83810505b..a541411d9226 100644 --- a/arch/x86/include/asm/mwait.h +++ b/arch/x86/include/asm/mwait.h @@ -108,13 +108,10 @@ static __always_inline void __sti_mwait(unsigned long eax, unsigned long ecx) static __always_inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) { if (static_cpu_has_bug(X86_BUG_MONITOR) || !current_set_polling_and_test()) { - if (static_cpu_has_bug(X86_BUG_CLFLUSH_MONITOR)) { - mb(); - clflush((void *)¤t_thread_info()->flags); - mb(); - } + const void *addr = ¤t_thread_info()->flags; - __monitor((void *)¤t_thread_info()->flags, 0, 0); + alternative_input("", "clflush (%[addr])", X86_BUG_CLFLUSH_MONITOR, [addr] "a" (addr)); + __monitor(addr, 0, 0); if (!need_resched()) { if (ecx & 1) { diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 419353904173..8a398acfdea2 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -923,13 +923,10 @@ static int prefer_mwait_c1_over_halt(const struct cpuinfo_x86 *c) static __cpuidle void mwait_idle(void) { if (!current_set_polling_and_test()) { - if (this_cpu_has(X86_BUG_CLFLUSH_MONITOR)) { - mb(); /* quirk */ - clflush((void *)¤t_thread_info()->flags); - mb(); /* quirk */ - } + const void *addr = ¤t_thread_info()->flags; - __monitor((void *)¤t_thread_info()->flags, 0, 0); + alternative_input("", "clflush (%[addr])", X86_BUG_CLFLUSH_MONITOR, [addr] "a" (addr)); + __monitor(addr, 0, 0); if (!need_resched()) { __sti_mwait(0, 0); raw_local_irq_disable(); From 76c7b1407a7ae5a0382cb646357be985bf84e19f Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Tue, 1 Apr 2025 22:23:16 +0300 Subject: [PATCH 069/971] crypto: sun8i-ce-hash - fix error handling in sun8i_ce_hash_run() [ Upstream commit ea4dd134ef332bd9e3e734c1ba0a1521f436b678 ] Rework error handling in sun8i_ce_hash_run() to unmap the dma buffers in case of failure. Currently, the dma unmap functions are not called if the function errors out at various points. Fixes: 56f6d5aee88d1 ("crypto: sun8i-ce - support hash algorithms") Signed-off-by: Ovidiu Panait Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- .../crypto/allwinner/sun8i-ce/sun8i-ce-hash.c | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c index d358334e5981..ebc857ed10e1 100644 --- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c @@ -343,9 +343,8 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq) u32 common; u64 byte_count; __le32 *bf; - void *buf = NULL; + void *buf, *result; int j, i, todo; - void *result = NULL; u64 bs; int digestsize; dma_addr_t addr_res, addr_pad; @@ -365,14 +364,14 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq) buf = kzalloc(bs * 2, GFP_KERNEL | GFP_DMA); if (!buf) { err = -ENOMEM; - goto theend; + goto err_out; } bf = (__le32 *)buf; result = kzalloc(digestsize, GFP_KERNEL | GFP_DMA); if (!result) { err = -ENOMEM; - goto theend; + goto err_free_buf; } flow = rctx->flow; @@ -398,7 +397,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq) if (nr_sgs <= 0 || nr_sgs > MAX_SG) { dev_err(ce->dev, "Invalid sg number %d\n", nr_sgs); err = -EINVAL; - goto theend; + goto err_free_result; } len = areq->nbytes; @@ -411,7 +410,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq) if (len > 0) { dev_err(ce->dev, "remaining len %d\n", len); err = -EINVAL; - goto theend; + goto err_unmap_src; } addr_res = dma_map_single(ce->dev, result, digestsize, DMA_FROM_DEVICE); cet->t_dst[0].addr = cpu_to_le32(addr_res); @@ -419,7 +418,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq) if (dma_mapping_error(ce->dev, addr_res)) { dev_err(ce->dev, "DMA map dest\n"); err = -EINVAL; - goto theend; + goto err_unmap_src; } byte_count = areq->nbytes; @@ -441,7 +440,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq) } if (!j) { err = -EINVAL; - goto theend; + goto err_unmap_result; } addr_pad = dma_map_single(ce->dev, buf, j * 4, DMA_TO_DEVICE); @@ -450,7 +449,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq) if (dma_mapping_error(ce->dev, addr_pad)) { dev_err(ce->dev, "DMA error on padding SG\n"); err = -EINVAL; - goto theend; + goto err_unmap_result; } if (ce->variant->hash_t_dlen_in_bits) @@ -463,16 +462,25 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq) err = sun8i_ce_run_task(ce, flow, crypto_ahash_alg_name(tfm)); dma_unmap_single(ce->dev, addr_pad, j * 4, DMA_TO_DEVICE); - dma_unmap_sg(ce->dev, areq->src, ns, DMA_TO_DEVICE); + +err_unmap_result: dma_unmap_single(ce->dev, addr_res, digestsize, DMA_FROM_DEVICE); + if (!err) + memcpy(areq->result, result, algt->alg.hash.base.halg.digestsize); +err_unmap_src: + dma_unmap_sg(ce->dev, areq->src, ns, DMA_TO_DEVICE); - memcpy(areq->result, result, algt->alg.hash.base.halg.digestsize); -theend: - kfree(buf); +err_free_result: kfree(result); + +err_free_buf: + kfree(buf); + +err_out: local_bh_disable(); crypto_finalize_hash_request(engine, breq, err); local_bh_enable(); + return 0; } From eec0dd17db02ae1f8e431b60da3b29e7b7dfaee9 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Fri, 18 Apr 2025 16:40:58 +0200 Subject: [PATCH 070/971] gfs2: gfs2_create_inode error handling fix [ Upstream commit af4044fd0b77e915736527dd83011e46e6415f01 ] When gfs2_create_inode() finds a directory, make sure to return -EISDIR. Fixes: 571a4b57975a ("GFS2: bugger off early if O_CREAT open finds a directory") Signed-off-by: Andreas Gruenbacher Signed-off-by: Sasha Levin --- fs/gfs2/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 29085643ad10..1cb5ce63fbf6 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -658,7 +658,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, if (!IS_ERR(inode)) { if (S_ISDIR(inode->i_mode)) { iput(inode); - inode = ERR_PTR(-EISDIR); + inode = NULL; + error = -EISDIR; goto fail_gunlock; } d_instantiate(dentry, inode); From 6ce08b3ba52c1f92325fb9f487021ae1c2f779e9 Mon Sep 17 00:00:00 2001 From: Qing Wang Date: Sat, 5 Apr 2025 22:16:35 +0800 Subject: [PATCH 071/971] perf/core: Fix broken throttling when max_samples_per_tick=1 [ Upstream commit f51972e6f8b9a737b2b3eb588069acb538fa72de ] According to the throttling mechanism, the pmu interrupts number can not exceed the max_samples_per_tick in one tick. But this mechanism is ineffective when max_samples_per_tick=1, because the throttling check is skipped during the first interrupt and only performed when the second interrupt arrives. Perhaps this bug may cause little influence in one tick, but if in a larger time scale, the problem can not be underestimated. When max_samples_per_tick = 1: Allowed-interrupts-per-second max-samples-per-second default-HZ ARCH 200 100 100 X86 500 250 250 ARM64 ... Obviously, the pmu interrupt number far exceed the user's expect. Fixes: e050e3f0a71b ("perf: Fix broken interrupt rate throttling") Signed-off-by: Qing Wang Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/20250405141635.243786-3-wangqing7171@gmail.com Signed-off-by: Sasha Levin --- kernel/events/core.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 5dd6424e62fa..6460f79280ed 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -9553,14 +9553,14 @@ __perf_event_account_interrupt(struct perf_event *event, int throttle) hwc->interrupts = 1; } else { hwc->interrupts++; - if (unlikely(throttle && - hwc->interrupts > max_samples_per_tick)) { - __this_cpu_inc(perf_throttled_count); - tick_dep_set_cpu(smp_processor_id(), TICK_DEP_BIT_PERF_EVENTS); - hwc->interrupts = MAX_INTERRUPTS; - perf_log_throttle(event, 0); - ret = 1; - } + } + + if (unlikely(throttle && hwc->interrupts >= max_samples_per_tick)) { + __this_cpu_inc(perf_throttled_count); + tick_dep_set_cpu(smp_processor_id(), TICK_DEP_BIT_PERF_EVENTS); + hwc->interrupts = MAX_INTERRUPTS; + perf_log_throttle(event, 0); + ret = 1; } if (event->attr.freq) { From c62b79c1c51303dbcb6edfa4de0ee176f4934c52 Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Fri, 25 Apr 2025 15:45:14 +0300 Subject: [PATCH 072/971] crypto: sun8i-ce-cipher - fix error handling in sun8i_ce_cipher_prepare() [ Upstream commit f31adc3e356f7350d4a4d68c98d3f60f2f6e26b3 ] Fix two DMA cleanup issues on the error path in sun8i_ce_cipher_prepare(): 1] If dma_map_sg() fails for areq->dst, the device driver would try to free DMA memory it has not allocated in the first place. To fix this, on the "theend_sgs" error path, call dma unmap only if the corresponding dma map was successful. 2] If the dma_map_single() call for the IV fails, the device driver would try to free an invalid DMA memory address on the "theend_iv" path: ------------[ cut here ]------------ DMA-API: sun8i-ce 1904000.crypto: device driver tries to free an invalid DMA memory address WARNING: CPU: 2 PID: 69 at kernel/dma/debug.c:968 check_unmap+0x123c/0x1b90 Modules linked in: skcipher_example(O+) CPU: 2 UID: 0 PID: 69 Comm: 1904000.crypto- Tainted: G O 6.15.0-rc3+ #24 PREEMPT Tainted: [O]=OOT_MODULE Hardware name: OrangePi Zero2 (DT) pc : check_unmap+0x123c/0x1b90 lr : check_unmap+0x123c/0x1b90 ... Call trace: check_unmap+0x123c/0x1b90 (P) debug_dma_unmap_page+0xac/0xc0 dma_unmap_page_attrs+0x1f4/0x5fc sun8i_ce_cipher_do_one+0x1bd4/0x1f40 crypto_pump_work+0x334/0x6e0 kthread_worker_fn+0x21c/0x438 kthread+0x374/0x664 ret_from_fork+0x10/0x20 ---[ end trace 0000000000000000 ]--- To fix this, check for !dma_mapping_error() before calling dma_unmap_single() on the "theend_iv" path. Fixes: 06f751b61329 ("crypto: allwinner - Add sun8i-ce Crypto Engine") Signed-off-by: Ovidiu Panait Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c index d2cf9619018b..70434601f99b 100644 --- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c @@ -275,13 +275,16 @@ theend_sgs: } else { if (nr_sgs > 0) dma_unmap_sg(ce->dev, areq->src, ns, DMA_TO_DEVICE); - dma_unmap_sg(ce->dev, areq->dst, nd, DMA_FROM_DEVICE); + + if (nr_sgd > 0) + dma_unmap_sg(ce->dev, areq->dst, nd, DMA_FROM_DEVICE); } theend_iv: if (areq->iv && ivsize > 0) { - if (rctx->addr_iv) + if (!dma_mapping_error(ce->dev, rctx->addr_iv)) dma_unmap_single(ce->dev, rctx->addr_iv, rctx->ivlen, DMA_TO_DEVICE); + offset = areq->cryptlen - ivsize; if (rctx->op_dir & CE_DECRYPTION) { memcpy(areq->iv, chan->backup_iv, ivsize); From cb1e26f53e598a3946dd9b3014d6bcddd8609a47 Mon Sep 17 00:00:00 2001 From: Corentin Labbe Date: Sun, 27 Apr 2025 13:12:36 +0200 Subject: [PATCH 073/971] crypto: sun8i-ss - do not use sg_dma_len before calling DMA functions [ Upstream commit 2dfc7cd74a5e062a5405560447517e7aab1c7341 ] When testing sun8i-ss with multi_v7_defconfig, all CBC algorithm fail crypto selftests. This is strange since on sunxi_defconfig, everything was ok. The problem was in the IV setup loop which never run because sg_dma_len was 0. Fixes: 359e893e8af4 ("crypto: sun8i-ss - rework handling of IV") Signed-off-by: Corentin Labbe Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c index 7fa359725ec7..9b18fb46a2c8 100644 --- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c @@ -141,7 +141,7 @@ static int sun8i_ss_setup_ivs(struct skcipher_request *areq) /* we need to copy all IVs from source in case DMA is bi-directionnal */ while (sg && len) { - if (sg_dma_len(sg) == 0) { + if (sg->length == 0) { sg = sg_next(sg); continue; } From fdc39b3ad8a7791792408212507683bfae9f2dc5 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 17 Apr 2025 12:53:05 +0200 Subject: [PATCH 074/971] powerpc: do not build ppc_save_regs.o always [ Upstream commit 497b7794aef03d525a5be05ae78dd7137c6861a5 ] The Fixes commit below tried to add CONFIG_PPC_BOOK3S to one of the conditions to enable the build of ppc_save_regs.o. But it failed to do so, in fact. The commit omitted to add a dollar sign. Therefore, ppc_save_regs.o is built always these days (as "(CONFIG_PPC_BOOK3S)" is never an empty string). Fix this by adding the missing dollar sign. Signed-off-by: Jiri Slaby (SUSE) Fixes: fc2a5a6161a2 ("powerpc/64s: ppc_save_regs is now needed for all 64s builds") Acked-by: Stephen Rothwell Signed-off-by: Madhavan Srinivasan Link: https://patch.msgid.link/20250417105305.397128-1-jirislaby@kernel.org Signed-off-by: Sasha Levin --- arch/powerpc/kernel/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 2919433be355..b7629122680b 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -165,7 +165,7 @@ endif obj64-$(CONFIG_PPC_TRANSACTIONAL_MEM) += tm.o -ifneq ($(CONFIG_XMON)$(CONFIG_KEXEC_CORE)(CONFIG_PPC_BOOK3S),) +ifneq ($(CONFIG_XMON)$(CONFIG_KEXEC_CORE)$(CONFIG_PPC_BOOK3S),) obj-y += ppc_save_regs.o endif From 4fb22310892c9bba3a170d0873e95886fbadf064 Mon Sep 17 00:00:00 2001 From: Eddie James Date: Tue, 11 Feb 2025 10:20:54 -0600 Subject: [PATCH 075/971] powerpc/crash: Fix non-smp kexec preparation [ Upstream commit 882b25af265de8e05c66f72b9a29f6047102958f ] In non-smp configurations, crash_kexec_prepare is never called in the crash shutdown path. One result of this is that the crashing_cpu variable is never set, preventing crash_save_cpu from storing the NT_PRSTATUS elf note in the core dump. Fixes: c7255058b543 ("powerpc/crash: save cpu register data in crash_smp_send_stop()") Signed-off-by: Eddie James Reviewed-by: Hari Bathini Signed-off-by: Madhavan Srinivasan Link: https://patch.msgid.link/20250211162054.857762-1-eajames@linux.ibm.com Signed-off-by: Sasha Levin --- arch/powerpc/kexec/crash.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kexec/crash.c b/arch/powerpc/kexec/crash.c index ef5c2d25ec39..61552bbb1ea8 100644 --- a/arch/powerpc/kexec/crash.c +++ b/arch/powerpc/kexec/crash.c @@ -356,7 +356,10 @@ void default_machine_crash_shutdown(struct pt_regs *regs) if (TRAP(regs) == INTERRUPT_SYSTEM_RESET) is_via_system_reset = 1; - crash_smp_send_stop(); + if (IS_ENABLED(CONFIG_SMP)) + crash_smp_send_stop(); + else + crash_kexec_prepare(); crash_save_cpu(regs, crashing_cpu); From ce167ff4cd172bb85b834d671f37151b0f7f734a Mon Sep 17 00:00:00 2001 From: Annie Li Date: Wed, 30 Apr 2025 05:34:24 +0000 Subject: [PATCH 076/971] x86/microcode/AMD: Do not return error when microcode update is not necessary [ Upstream commit b43dc4ab097859c24e2a6993119c927cffc856aa ] After 6f059e634dcd("x86/microcode: Clarify the late load logic"), if the load is up-to-date, the AMD side returns UCODE_OK which leads to load_late_locked() returning -EBADFD. Handle UCODE_OK in the switch case to avoid this error. [ bp: Massage commit message. ] Fixes: 6f059e634dcd ("x86/microcode: Clarify the late load logic") Signed-off-by: Annie Li Signed-off-by: Borislav Petkov (AMD) Link: https://lore.kernel.org/20250430053424.77438-1-jiayanli@google.com Signed-off-by: Sasha Levin --- arch/x86/kernel/cpu/microcode/core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index 5b47c320f17a..fc539346599c 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -703,6 +703,8 @@ static int load_late_locked(void) return load_late_stop_cpus(true); case UCODE_NFOUND: return -ENOENT; + case UCODE_OK: + return 0; default: return -EBADFD; } From 62af7780054fa2fe5c7aa012dfd5d37e76f4d9dc Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Tue, 6 May 2025 07:04:13 +0200 Subject: [PATCH 077/971] x86/cpu: Sanitize CPUID(0x80000000) output [ Upstream commit cc663ba3fe383a628a812f893cc98aafff39ab04 ] CPUID(0x80000000).EAX returns the max extended CPUID leaf available. On x86-32 machines without an extended CPUID range, a CPUID(0x80000000) query will just repeat the output of the last valid standard CPUID leaf on the CPU; i.e., a garbage values. Current tip:x86/cpu code protects against this by doing: eax = cpuid_eax(0x80000000); c->extended_cpuid_level = eax; if ((eax & 0xffff0000) == 0x80000000) { // CPU has an extended CPUID range. Check for 0x80000001 if (eax >= 0x80000001) { cpuid(0x80000001, ...); } } This is correct so far. Afterwards though, the same possibly broken EAX value is used to check the availability of other extended CPUID leaves: if (c->extended_cpuid_level >= 0x80000007) ... if (c->extended_cpuid_level >= 0x80000008) ... if (c->extended_cpuid_level >= 0x8000000a) ... if (c->extended_cpuid_level >= 0x8000001f) ... which is invalid. Fix this by immediately setting the CPU's max extended CPUID leaf to zero if CPUID(0x80000000).EAX doesn't indicate a valid CPUID extended range. While at it, add a comment, similar to kernel/head_32.S, clarifying the CPUID(0x80000000) sanity check. References: 8a50e5135af0 ("x86-32: Use symbolic constants, safer CPUID when enabling EFER.NX") Fixes: 3da99c977637 ("x86: make (early)_identify_cpu more the same between 32bit and 64 bit") Signed-off-by: Ahmed S. Darwish Signed-off-by: Ingo Molnar Cc: Andrew Cooper Cc: H. Peter Anvin Cc: John Ogness Cc: x86-cpuid@lists.linux.dev Link: https://lore.kernel.org/r/20250506050437.10264-3-darwi@linutronix.de Signed-off-by: Sasha Levin --- arch/x86/kernel/cpu/common.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 067e31fb9e16..b6e43dad577a 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1066,17 +1066,18 @@ void get_cpu_cap(struct cpuinfo_x86 *c) c->x86_capability[CPUID_D_1_EAX] = eax; } - /* AMD-defined flags: level 0x80000001 */ + /* + * Check if extended CPUID leaves are implemented: Max extended + * CPUID leaf must be in the 0x80000001-0x8000ffff range. + */ eax = cpuid_eax(0x80000000); - c->extended_cpuid_level = eax; + c->extended_cpuid_level = ((eax & 0xffff0000) == 0x80000000) ? eax : 0; - if ((eax & 0xffff0000) == 0x80000000) { - if (eax >= 0x80000001) { - cpuid(0x80000001, &eax, &ebx, &ecx, &edx); + if (c->extended_cpuid_level >= 0x80000001) { + cpuid(0x80000001, &eax, &ebx, &ecx, &edx); - c->x86_capability[CPUID_8000_0001_ECX] = ecx; - c->x86_capability[CPUID_8000_0001_EDX] = edx; - } + c->x86_capability[CPUID_8000_0001_ECX] = ecx; + c->x86_capability[CPUID_8000_0001_EDX] = edx; } if (c->extended_cpuid_level >= 0x80000007) { From 5e9666ac8b94c978690f937d59170c5237bd2c45 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sat, 10 May 2025 18:41:31 +0800 Subject: [PATCH 078/971] crypto: marvell/cesa - Handle zero-length skcipher requests [ Upstream commit 8a4e047c6cc07676f637608a9dd675349b5de0a7 ] Do not access random memory for zero-length skcipher requests. Just return 0. Fixes: f63601fd616a ("crypto: marvell/cesa - add a new driver for Marvell's CESA") Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/marvell/cesa/cipher.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/crypto/marvell/cesa/cipher.c b/drivers/crypto/marvell/cesa/cipher.c index 0f37dfd42d85..3876e3ce822f 100644 --- a/drivers/crypto/marvell/cesa/cipher.c +++ b/drivers/crypto/marvell/cesa/cipher.c @@ -459,6 +459,9 @@ static int mv_cesa_skcipher_queue_req(struct skcipher_request *req, struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); struct mv_cesa_engine *engine; + if (!req->cryptlen) + return 0; + ret = mv_cesa_skcipher_req_init(req, tmpl); if (ret) return ret; From 3cf4d9cae4356c2a0610d82c13c957e4a88d6d94 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sat, 10 May 2025 18:43:33 +0800 Subject: [PATCH 079/971] crypto: marvell/cesa - Avoid empty transfer descriptor [ Upstream commit 1bafd82d9a40cf09c6c40f1c09cc35b7050b1a9f ] The user may set req->src even if req->nbytes == 0. If there is no data to hash from req->src, do not generate an empty TDMA descriptor. Fixes: db509a45339f ("crypto: marvell/cesa - add TDMA support") Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/marvell/cesa/hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/marvell/cesa/hash.c b/drivers/crypto/marvell/cesa/hash.c index f150861ceaf6..6815eddc9068 100644 --- a/drivers/crypto/marvell/cesa/hash.c +++ b/drivers/crypto/marvell/cesa/hash.c @@ -663,7 +663,7 @@ static int mv_cesa_ahash_dma_req_init(struct ahash_request *req) if (ret) goto err_free_tdma; - if (iter.src.sg) { + if (iter.base.len > iter.src.op_offset) { /* * Add all the new data, inserting an operation block and * launch command between each full SRAM block-worth of From 7cfb9086b6d32017ef93e552f9aa412ec7d825f7 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Thu, 1 May 2025 08:37:54 +0930 Subject: [PATCH 080/971] btrfs: scrub: update device stats when an error is detected [ Upstream commit ec1f3a207cdf314eae4d4ae145f1ffdb829f0652 ] [BUG] Since the migration to the new scrub_stripe interface, scrub no longer updates the device stats when hitting an error, no matter if it's a read or checksum mismatch error. E.g: BTRFS info (device dm-2): scrub: started on devid 1 BTRFS error (device dm-2): unable to fixup (regular) error at logical 13631488 on dev /dev/mapper/test-scratch1 physical 13631488 BTRFS warning (device dm-2): checksum error at logical 13631488 on dev /dev/mapper/test-scratch1, physical 13631488, root 5, inode 257, offset 0, length 4096, links 1 (path: file) BTRFS error (device dm-2): unable to fixup (regular) error at logical 13631488 on dev /dev/mapper/test-scratch1 physical 13631488 BTRFS warning (device dm-2): checksum error at logical 13631488 on dev /dev/mapper/test-scratch1, physical 13631488, root 5, inode 257, offset 0, length 4096, links 1 (path: file) BTRFS info (device dm-2): scrub: finished on devid 1 with status: 0 Note there is no line showing the device stats error update. [CAUSE] In the migration to the new scrub_stripe interface, we no longer call btrfs_dev_stat_inc_and_print(). [FIX] - Introduce a new bitmap for metadata generation errors * A new bitmap @meta_gen_error_bitmap is introduced to record which blocks have metadata generation mismatch errors. * A new counter for that bitmap @init_nr_meta_gen_errors, is also introduced to store the number of generation mismatch errors that are found during the initial read. This is for the error reporting at scrub_stripe_report_errors(). * New dedicated error message for unrepaired generation mismatches * Update @meta_gen_error_bitmap if a transid mismatch is hit - Add btrfs_dev_stat_inc_and_print() calls to the following call sites * scrub_stripe_report_errors() * scrub_write_endio() This is only for the write errors. This means there is a minor behavior change: - The timing of device stats error message Since we concentrate the error messages at scrub_stripe_report_errors(), the device stats error messages will all show up in one go, after the detailed scrub error messages: BTRFS error (device dm-2): unable to fixup (regular) error at logical 13631488 on dev /dev/mapper/test-scratch1 physical 13631488 BTRFS warning (device dm-2): checksum error at logical 13631488 on dev /dev/mapper/test-scratch1, physical 13631488, root 5, inode 257, offset 0, length 4096, links 1 (path: file) BTRFS error (device dm-2): unable to fixup (regular) error at logical 13631488 on dev /dev/mapper/test-scratch1 physical 13631488 BTRFS warning (device dm-2): checksum error at logical 13631488 on dev /dev/mapper/test-scratch1, physical 13631488, root 5, inode 257, offset 0, length 4096, links 1 (path: file) BTRFS error (device dm-2): bdev /dev/mapper/test-scratch1 errs: wr 0, rd 0, flush 0, corrupt 1, gen 0 BTRFS error (device dm-2): bdev /dev/mapper/test-scratch1 errs: wr 0, rd 0, flush 0, corrupt 2, gen 0 Fixes: e02ee89baa66 ("btrfs: scrub: switch scrub_simple_mirror() to scrub_stripe infrastructure") Reviewed-by: Filipe Manana Signed-off-by: Qu Wenruo Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/scrub.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index da49bdb70375..97c17025b31e 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c @@ -153,12 +153,14 @@ struct scrub_stripe { unsigned int init_nr_io_errors; unsigned int init_nr_csum_errors; unsigned int init_nr_meta_errors; + unsigned int init_nr_meta_gen_errors; /* * The following error bitmaps are all for the current status. * Every time we submit a new read, these bitmaps may be updated. * - * error_bitmap = io_error_bitmap | csum_error_bitmap | meta_error_bitmap; + * error_bitmap = io_error_bitmap | csum_error_bitmap | + * meta_error_bitmap | meta_generation_bitmap; * * IO and csum errors can happen for both metadata and data. */ @@ -166,6 +168,7 @@ struct scrub_stripe { unsigned long io_error_bitmap; unsigned long csum_error_bitmap; unsigned long meta_error_bitmap; + unsigned long meta_gen_error_bitmap; /* For writeback (repair or replace) error reporting. */ unsigned long write_error_bitmap; @@ -673,7 +676,7 @@ static void scrub_verify_one_metadata(struct scrub_stripe *stripe, int sector_nr } if (stripe->sectors[sector_nr].generation != btrfs_stack_header_generation(header)) { - bitmap_set(&stripe->meta_error_bitmap, sector_nr, sectors_per_tree); + bitmap_set(&stripe->meta_gen_error_bitmap, sector_nr, sectors_per_tree); bitmap_set(&stripe->error_bitmap, sector_nr, sectors_per_tree); btrfs_warn_rl(fs_info, "tree block %llu mirror %u has bad generation, has %llu want %llu", @@ -685,6 +688,7 @@ static void scrub_verify_one_metadata(struct scrub_stripe *stripe, int sector_nr bitmap_clear(&stripe->error_bitmap, sector_nr, sectors_per_tree); bitmap_clear(&stripe->csum_error_bitmap, sector_nr, sectors_per_tree); bitmap_clear(&stripe->meta_error_bitmap, sector_nr, sectors_per_tree); + bitmap_clear(&stripe->meta_gen_error_bitmap, sector_nr, sectors_per_tree); } static void scrub_verify_one_sector(struct scrub_stripe *stripe, int sector_nr) @@ -973,8 +977,22 @@ skip: if (__ratelimit(&rs) && dev) scrub_print_common_warning("header error", dev, false, stripe->logical, physical); + if (test_bit(sector_nr, &stripe->meta_gen_error_bitmap)) + if (__ratelimit(&rs) && dev) + scrub_print_common_warning("generation error", dev, false, + stripe->logical, physical); } + /* Update the device stats. */ + for (int i = 0; i < stripe->init_nr_io_errors; i++) + btrfs_dev_stat_inc_and_print(stripe->dev, BTRFS_DEV_STAT_READ_ERRS); + for (int i = 0; i < stripe->init_nr_csum_errors; i++) + btrfs_dev_stat_inc_and_print(stripe->dev, BTRFS_DEV_STAT_CORRUPTION_ERRS); + /* Generation mismatch error is based on each metadata, not each block. */ + for (int i = 0; i < stripe->init_nr_meta_gen_errors; + i += (fs_info->nodesize >> fs_info->sectorsize_bits)) + btrfs_dev_stat_inc_and_print(stripe->dev, BTRFS_DEV_STAT_GENERATION_ERRS); + spin_lock(&sctx->stat_lock); sctx->stat.data_extents_scrubbed += stripe->nr_data_extents; sctx->stat.tree_extents_scrubbed += stripe->nr_meta_extents; @@ -983,7 +1001,8 @@ skip: sctx->stat.no_csum += nr_nodatacsum_sectors; sctx->stat.read_errors += stripe->init_nr_io_errors; sctx->stat.csum_errors += stripe->init_nr_csum_errors; - sctx->stat.verify_errors += stripe->init_nr_meta_errors; + sctx->stat.verify_errors += stripe->init_nr_meta_errors + + stripe->init_nr_meta_gen_errors; sctx->stat.uncorrectable_errors += bitmap_weight(&stripe->error_bitmap, stripe->nr_sectors); sctx->stat.corrected_errors += nr_repaired_sectors; @@ -1029,6 +1048,8 @@ static void scrub_stripe_read_repair_worker(struct work_struct *work) stripe->nr_sectors); stripe->init_nr_meta_errors = bitmap_weight(&stripe->meta_error_bitmap, stripe->nr_sectors); + stripe->init_nr_meta_gen_errors = bitmap_weight(&stripe->meta_gen_error_bitmap, + stripe->nr_sectors); if (bitmap_empty(&stripe->init_error_bitmap, stripe->nr_sectors)) goto out; @@ -1143,6 +1164,9 @@ static void scrub_write_endio(struct btrfs_bio *bbio) bitmap_set(&stripe->write_error_bitmap, sector_nr, bio_size >> fs_info->sectorsize_bits); spin_unlock_irqrestore(&stripe->write_error_lock, flags); + for (int i = 0; i < (bio_size >> fs_info->sectorsize_bits); i++) + btrfs_dev_stat_inc_and_print(stripe->dev, + BTRFS_DEV_STAT_WRITE_ERRS); } bio_put(&bbio->bio); @@ -1505,10 +1529,12 @@ static void scrub_stripe_reset_bitmaps(struct scrub_stripe *stripe) stripe->init_nr_io_errors = 0; stripe->init_nr_csum_errors = 0; stripe->init_nr_meta_errors = 0; + stripe->init_nr_meta_gen_errors = 0; stripe->error_bitmap = 0; stripe->io_error_bitmap = 0; stripe->csum_error_bitmap = 0; stripe->meta_error_bitmap = 0; + stripe->meta_gen_error_bitmap = 0; } /* From 402fd6a6fe575872220d25d168f15a7bed711500 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Mon, 5 May 2025 18:56:18 +0930 Subject: [PATCH 081/971] btrfs: scrub: fix a wrong error type when metadata bytenr mismatches [ Upstream commit f2c19541e421b3235efc515dad88b581f00592ae ] When the bytenr doesn't match for a metadata tree block, we will report it as an csum error, which is incorrect and should be reported as a metadata error instead. Fixes: a3ddbaebc7c9 ("btrfs: scrub: introduce a helper to verify one metadata block") Signed-off-by: Qu Wenruo Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/scrub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index 97c17025b31e..7632d652a125 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c @@ -620,7 +620,7 @@ static void scrub_verify_one_metadata(struct scrub_stripe *stripe, int sector_nr memcpy(on_disk_csum, header->csum, fs_info->csum_size); if (logical != btrfs_stack_header_bytenr(header)) { - bitmap_set(&stripe->csum_error_bitmap, sector_nr, sectors_per_tree); + bitmap_set(&stripe->meta_error_bitmap, sector_nr, sectors_per_tree); bitmap_set(&stripe->error_bitmap, sector_nr, sectors_per_tree); btrfs_warn_rl(fs_info, "tree block %llu mirror %u has bad bytenr, has %llu want %llu", From ec91ab135cf0a4249e848112ce1dc6bf60e5a18e Mon Sep 17 00:00:00 2001 From: Yongliang Gao Date: Sun, 16 Feb 2025 16:41:09 +0800 Subject: [PATCH 082/971] rcu/cpu_stall_cputime: fix the hardirq count for x86 architecture [ Upstream commit da6b85598af30e9fec34d82882d7e1e39f3da769 ] When counting the number of hardirqs in the x86 architecture, it is essential to add arch_irq_stat_cpu to ensure accuracy. For example, a CPU loop within the rcu_read_lock function. Before: [ 70.910184] rcu: INFO: rcu_preempt self-detected stall on CPU [ 70.910436] rcu: 3-....: (4999 ticks this GP) idle=*** [ 70.910711] rcu: hardirqs softirqs csw/system [ 70.910870] rcu: number: 0 657 0 [ 70.911024] rcu: cputime: 0 0 2498 ==> 2498(ms) [ 70.911278] rcu: (t=5001 jiffies g=3677 q=29 ncpus=8) After: [ 68.046132] rcu: INFO: rcu_preempt self-detected stall on CPU [ 68.046354] rcu: 2-....: (4999 ticks this GP) idle=*** [ 68.046628] rcu: hardirqs softirqs csw/system [ 68.046793] rcu: number: 2498 663 0 [ 68.046951] rcu: cputime: 0 0 2496 ==> 2496(ms) [ 68.047244] rcu: (t=5000 jiffies g=3825 q=4 ncpus=8) Fixes: be42f00b73a0 ("rcu: Add RCU stall diagnosis information") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202501090842.SfI6QPGS-lkp@intel.com/ Signed-off-by: Yongliang Gao Reviewed-by: Neeraj Upadhyay Link: https://lore.kernel.org/r/20250216084109.3109837-1-leonylgao@gmail.com Signed-off-by: Boqun Feng Signed-off-by: Joel Fernandes Signed-off-by: Sasha Levin --- kernel/rcu/tree.c | 10 +++++++--- kernel/rcu/tree.h | 2 +- kernel/rcu/tree_stall.h | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index fda08520c75c..1fb3b7a0ed5d 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -754,6 +754,10 @@ static int dyntick_save_progress_counter(struct rcu_data *rdp) return 0; } +#ifndef arch_irq_stat_cpu +#define arch_irq_stat_cpu(cpu) 0 +#endif + /* * Returns positive if the specified CPU has passed through a quiescent state * by virtue of being in or having passed through an dynticks idle state since @@ -889,9 +893,9 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp) rsrp->cputime_irq = kcpustat_field(kcsp, CPUTIME_IRQ, cpu); rsrp->cputime_softirq = kcpustat_field(kcsp, CPUTIME_SOFTIRQ, cpu); rsrp->cputime_system = kcpustat_field(kcsp, CPUTIME_SYSTEM, cpu); - rsrp->nr_hardirqs = kstat_cpu_irqs_sum(rdp->cpu); - rsrp->nr_softirqs = kstat_cpu_softirqs_sum(rdp->cpu); - rsrp->nr_csw = nr_context_switches_cpu(rdp->cpu); + rsrp->nr_hardirqs = kstat_cpu_irqs_sum(cpu) + arch_irq_stat_cpu(cpu); + rsrp->nr_softirqs = kstat_cpu_softirqs_sum(cpu); + rsrp->nr_csw = nr_context_switches_cpu(cpu); rsrp->jiffies = jiffies; rsrp->gp_seq = rdp->gp_seq; } diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h index 9eb43b501ff5..ac8cc756920d 100644 --- a/kernel/rcu/tree.h +++ b/kernel/rcu/tree.h @@ -169,7 +169,7 @@ struct rcu_snap_record { u64 cputime_irq; /* Accumulated cputime of hard irqs */ u64 cputime_softirq;/* Accumulated cputime of soft irqs */ u64 cputime_system; /* Accumulated cputime of kernel tasks */ - unsigned long nr_hardirqs; /* Accumulated number of hard irqs */ + u64 nr_hardirqs; /* Accumulated number of hard irqs */ unsigned int nr_softirqs; /* Accumulated number of soft irqs */ unsigned long long nr_csw; /* Accumulated number of task switches */ unsigned long jiffies; /* Track jiffies value */ diff --git a/kernel/rcu/tree_stall.h b/kernel/rcu/tree_stall.h index 11a1fac3a589..aab91040b83b 100644 --- a/kernel/rcu/tree_stall.h +++ b/kernel/rcu/tree_stall.h @@ -452,8 +452,8 @@ static void print_cpu_stat_info(int cpu) rsr.cputime_system = kcpustat_field(kcsp, CPUTIME_SYSTEM, cpu); pr_err("\t hardirqs softirqs csw/system\n"); - pr_err("\t number: %8ld %10d %12lld\n", - kstat_cpu_irqs_sum(cpu) - rsrp->nr_hardirqs, + pr_err("\t number: %8lld %10d %12lld\n", + kstat_cpu_irqs_sum(cpu) + arch_irq_stat_cpu(cpu) - rsrp->nr_hardirqs, kstat_cpu_softirqs_sum(cpu) - rsrp->nr_softirqs, nr_context_switches_cpu(cpu) - rsrp->nr_csw); pr_err("\tcputime: %8lld %10lld %12lld ==> %d(ms)\n", From ba2af6855c4dde0f5bbafb1e3346c1626341b69f Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 15 May 2025 16:28:08 +0800 Subject: [PATCH 083/971] crypto: lrw - Only add ecb if it is not already there [ Upstream commit 3d73909bddc2ebb3224a8bc2e5ce00e9df70c15d ] Only add ecb to the cipher name if it isn't already ecb. Also use memcmp instead of strncmp since these strings are all stored in an array of length CRYPTO_MAX_ALG_NAME. Fixes: 700cb3f5fe75 ("crypto: lrw - Convert to skcipher") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-lkp/202505151503.d8a6cf10-lkp@intel.com Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- crypto/lrw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crypto/lrw.c b/crypto/lrw.c index 59260aefed28..5536ec7bf18f 100644 --- a/crypto/lrw.c +++ b/crypto/lrw.c @@ -322,7 +322,7 @@ static int lrw_create(struct crypto_template *tmpl, struct rtattr **tb) err = crypto_grab_skcipher(spawn, skcipher_crypto_instance(inst), cipher_name, 0, mask); - if (err == -ENOENT) { + if (err == -ENOENT && memcmp(cipher_name, "ecb(", 4)) { err = -ENAMETOOLONG; if (snprintf(ecb_name, CRYPTO_MAX_ALG_NAME, "ecb(%s)", cipher_name) >= CRYPTO_MAX_ALG_NAME) @@ -356,7 +356,7 @@ static int lrw_create(struct crypto_template *tmpl, struct rtattr **tb) /* Alas we screwed up the naming so we have to mangle the * cipher name. */ - if (!strncmp(cipher_name, "ecb(", 4)) { + if (!memcmp(cipher_name, "ecb(", 4)) { int len; len = strscpy(ecb_name, cipher_name + 4, sizeof(ecb_name)); From 04a39a3c7d3788874f8d6b52884f7a53b564ba5d Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 15 May 2025 16:34:04 +0800 Subject: [PATCH 084/971] crypto: xts - Only add ecb if it is not already there [ Upstream commit 270b6f13454cb7f2f7058c50df64df409c5dcf55 ] Only add ecb to the cipher name if it isn't already ecb. Also use memcmp instead of strncmp since these strings are all stored in an array of length CRYPTO_MAX_ALG_NAME. Fixes: f1c131b45410 ("crypto: xts - Convert to skcipher") Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- crypto/xts.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crypto/xts.c b/crypto/xts.c index 038f60dd512d..97fd0fb8757c 100644 --- a/crypto/xts.c +++ b/crypto/xts.c @@ -363,7 +363,7 @@ static int xts_create(struct crypto_template *tmpl, struct rtattr **tb) err = crypto_grab_skcipher(&ctx->spawn, skcipher_crypto_instance(inst), cipher_name, 0, mask); - if (err == -ENOENT) { + if (err == -ENOENT && memcmp(cipher_name, "ecb(", 4)) { err = -ENAMETOOLONG; if (snprintf(name, CRYPTO_MAX_ALG_NAME, "ecb(%s)", cipher_name) >= CRYPTO_MAX_ALG_NAME) @@ -397,7 +397,7 @@ static int xts_create(struct crypto_template *tmpl, struct rtattr **tb) /* Alas we screwed up the naming so we have to mangle the * cipher name. */ - if (!strncmp(cipher_name, "ecb(", 4)) { + if (!memcmp(cipher_name, "ecb(", 4)) { int len; len = strscpy(name, cipher_name + 4, sizeof(name)); From 5810e9d402c43a63c16ce949f9d9ff59fe6832e7 Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Fri, 16 May 2025 15:06:56 +0300 Subject: [PATCH 085/971] crypto: sun8i-ce - move fallback ahash_request to the end of the struct [ Upstream commit c822831b426307a6ca426621504d3c7f99765a39 ] 'struct ahash_request' has a flexible array at the end, so it must be the last member in a struct, to avoid overwriting other struct members. Therefore, move 'fallback_req' to the end of the 'sun8i_ce_hash_reqctx' struct. Fixes: 56f6d5aee88d ("crypto: sun8i-ce - support hash algorithms") Signed-off-by: Ovidiu Panait Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h index 93d4985def87..65cc1278ee15 100644 --- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h @@ -293,8 +293,8 @@ struct sun8i_ce_hash_tfm_ctx { * @flow: the flow to use for this request */ struct sun8i_ce_hash_reqctx { - struct ahash_request fallback_req; int flow; + struct ahash_request fallback_req; // keep at the end }; /* From f6941e72d352b35babe3cc269eb5a54abf7b8170 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Tue, 20 May 2025 08:20:49 +0000 Subject: [PATCH 086/971] kunit: Fix wrong parameter to kunit_deactivate_static_stub() [ Upstream commit 772e50a76ee664e75581624f512df4e45582605a ] kunit_deactivate_static_stub() accepts real_fn_addr instead of replacement_addr. In the case, it always passes NULL to kunit_deactivate_static_stub(). Fix it. Link: https://lore.kernel.org/r/20250520082050.2254875-1-tzungbi@kernel.org Fixes: e047c5eaa763 ("kunit: Expose 'static stub' API to redirect functions") Signed-off-by: Tzung-Bi Shih Reviewed-by: David Gow Signed-off-by: Shuah Khan Signed-off-by: Sasha Levin --- lib/kunit/static_stub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/kunit/static_stub.c b/lib/kunit/static_stub.c index 92b2cccd5e76..484fd85251b4 100644 --- a/lib/kunit/static_stub.c +++ b/lib/kunit/static_stub.c @@ -96,7 +96,7 @@ void __kunit_activate_static_stub(struct kunit *test, /* If the replacement address is NULL, deactivate the stub. */ if (!replacement_addr) { - kunit_deactivate_static_stub(test, replacement_addr); + kunit_deactivate_static_stub(test, real_fn_addr); return; } From 8b94e19adae3cae5547def1ec72a3014054344d5 Mon Sep 17 00:00:00 2001 From: Daniil Tatianin Date: Tue, 1 Apr 2025 21:43:11 +0300 Subject: [PATCH 087/971] ACPICA: exserial: don't forget to handle FFixedHW opregions for reading [ Upstream commit 0f8af0356a45547683a216e4921006a3c6a6d922 ] The initial commit that introduced support for FFixedHW operation regions did add a special case in the AcpiExReadSerialBus If, but forgot to actually handle it inside the switch, so add the missing case to prevent reads from failing with AE_AML_INVALID_SPACE_ID. Link: https://github.com/acpica/acpica/pull/998 Fixes: ee64b827a9a ("ACPICA: Add support for FFH Opregion special context data") Signed-off-by: Daniil Tatianin Link: https://patch.msgid.link/20250401184312.599962-1-d-tatianin@yandex-team.ru Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/acpica/exserial.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/acpi/acpica/exserial.c b/drivers/acpi/acpica/exserial.c index 5241f4c01c76..89a4ac447a2b 100644 --- a/drivers/acpi/acpica/exserial.c +++ b/drivers/acpi/acpica/exserial.c @@ -201,6 +201,12 @@ acpi_ex_read_serial_bus(union acpi_operand_object *obj_desc, function = ACPI_READ; break; + case ACPI_ADR_SPACE_FIXED_HARDWARE: + + buffer_length = ACPI_FFH_INPUT_BUFFER_SIZE; + function = ACPI_READ; + break; + default: return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID); } From 4191b7669e00a45f19ddf701020611358b5cfa59 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sun, 6 Apr 2025 09:15:08 +1000 Subject: [PATCH 088/971] ASoC: tas2764: Enable main IRQs [ Upstream commit dd50f0e38563f15819059c923bf142200453e003 ] IRQ handling was added in commit dae191fb957f ("ASoC: tas2764: Add IRQ handling") however that same commit masks all interrupts coming from the chip. Unmask the "main" interrupts so that we can see and deal with a number of errors including clock, voltage, and current. Fixes: dae191fb957f ("ASoC: tas2764: Add IRQ handling") Reviewed-by: Neal Gompa Signed-off-by: Hector Martin Signed-off-by: James Calligeros Link: https://patch.msgid.link/20250406-apple-codec-changes-v5-4-50a00ec850a3@gmail.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/tas2764.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c index 72d6356b8981..054c6f860675 100644 --- a/sound/soc/codecs/tas2764.c +++ b/sound/soc/codecs/tas2764.c @@ -542,7 +542,7 @@ static int tas2764_codec_probe(struct snd_soc_component *component) tas2764_reset(tas2764); if (tas2764->irq) { - ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK0, 0xff); + ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK0, 0x00); if (ret < 0) return ret; From 3f5d0659000923735350da60ad710f8c804544fe Mon Sep 17 00:00:00 2001 From: Qiuxu Zhuo Date: Thu, 17 Apr 2025 23:07:18 +0800 Subject: [PATCH 089/971] EDAC/skx_common: Fix general protection fault [ Upstream commit 20d2d476b3ae18041be423671a8637ed5ffd6958 ] After loading i10nm_edac (which automatically loads skx_edac_common), if unload only i10nm_edac, then reload it and perform error injection testing, a general protection fault may occur: mce: [Hardware Error]: Machine check events logged Oops: general protection fault ... ... Workqueue: events mce_gen_pool_process RIP: 0010:string+0x53/0xe0 ... Call Trace: ? die_addr+0x37/0x90 ? exc_general_protection+0x1e7/0x3f0 ? asm_exc_general_protection+0x26/0x30 ? string+0x53/0xe0 vsnprintf+0x23e/0x4c0 snprintf+0x4d/0x70 skx_adxl_decode+0x16a/0x330 [skx_edac_common] skx_mce_check_error.part.0+0xf8/0x220 [skx_edac_common] skx_mce_check_error+0x17/0x20 [skx_edac_common] ... The issue arose was because the variable 'adxl_component_count' (inside skx_edac_common), which counts the ADXL components, was not reset. During the reloading of i10nm_edac, the count was incremented by the actual number of ADXL components again, resulting in a count that was double the real number of ADXL components. This led to an out-of-bounds reference to the ADXL component array, causing the general protection fault above. Fix this issue by resetting the 'adxl_component_count' in adxl_put(), which is called during the unloading of {skx,i10nm}_edac. Fixes: 123b15863550 ("EDAC, i10nm: make skx_common.o a separate module") Reported-by: Feng Xu Signed-off-by: Qiuxu Zhuo Signed-off-by: Tony Luck Tested-by: Feng Xu Link: https://lore.kernel.org/r/20250417150724.1170168-2-qiuxu.zhuo@intel.com Signed-off-by: Sasha Levin --- drivers/edac/skx_common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c index d47f0055217e..9e43aed72bd9 100644 --- a/drivers/edac/skx_common.c +++ b/drivers/edac/skx_common.c @@ -115,6 +115,7 @@ EXPORT_SYMBOL_GPL(skx_adxl_get); void skx_adxl_put(void) { + adxl_component_count = 0; kfree(adxl_values); kfree(adxl_msg); } From 3ff2422442de73f66d707e3a09e04687ca33c139 Mon Sep 17 00:00:00 2001 From: Qiuxu Zhuo Date: Thu, 17 Apr 2025 23:07:19 +0800 Subject: [PATCH 090/971] EDAC/{skx_common,i10nm}: Fix the loss of saved RRL for HBM pseudo channel 0 [ Upstream commit eeed3e03f4261e5e381a72ae099ff00ccafbb437 ] When enabling the retry_rd_err_log (RRL) feature during the loading of the i10nm_edac driver with the module parameter retry_rd_err_log=2 (Linux RRL control mode), the default values of the control bits of RRL are saved so that they can be restored during the unloading of the driver. In the current code, the RRL of pseudo channel 1 of HBM overwrites pseudo channel 0 during the loading of the driver, resulting in the loss of saved RRL for pseudo channel 0. This causes the RRL of pseudo channel 0 of HBM to be wrongly restored with the values from pseudo channel 1 when unloading the driver. Fix this issue by creating two separate groups of RRL control registers per channel to save default RRL settings of two {sub-,pseudo-}channels. Fixes: acd4cf68fefe ("EDAC/i10nm: Retrieve and print retry_rd_err_log registers for HBM") Signed-off-by: Qiuxu Zhuo Signed-off-by: Tony Luck Tested-by: Feng Xu Link: https://lore.kernel.org/r/20250417150724.1170168-3-qiuxu.zhuo@intel.com Signed-off-by: Sasha Levin --- drivers/edac/i10nm_base.c | 35 +++++++++++++++++++---------------- drivers/edac/skx_common.h | 11 ++++++++--- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c index 67a46abe07da..068597e8fce9 100644 --- a/drivers/edac/i10nm_base.c +++ b/drivers/edac/i10nm_base.c @@ -99,7 +99,7 @@ static u32 offsets_demand2_spr[] = {0x22c70, 0x22d80, 0x22f18, 0x22d58, 0x22c64, static u32 offsets_demand_spr_hbm0[] = {0x2a54, 0x2a60, 0x2b10, 0x2a58, 0x2a5c, 0x0ee0}; static u32 offsets_demand_spr_hbm1[] = {0x2e54, 0x2e60, 0x2f10, 0x2e58, 0x2e5c, 0x0fb0}; -static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable, +static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable, u32 *rrl_ctl, u32 *offsets_scrub, u32 *offsets_demand, u32 *offsets_demand2) { @@ -112,10 +112,10 @@ static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable if (enable) { /* Save default configurations */ - imc->chan[chan].retry_rd_err_log_s = s; - imc->chan[chan].retry_rd_err_log_d = d; + rrl_ctl[0] = s; + rrl_ctl[1] = d; if (offsets_demand2) - imc->chan[chan].retry_rd_err_log_d2 = d2; + rrl_ctl[2] = d2; s &= ~RETRY_RD_ERR_LOG_NOOVER_UC; s |= RETRY_RD_ERR_LOG_EN; @@ -129,25 +129,25 @@ static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable } } else { /* Restore default configurations */ - if (imc->chan[chan].retry_rd_err_log_s & RETRY_RD_ERR_LOG_UC) + if (rrl_ctl[0] & RETRY_RD_ERR_LOG_UC) s |= RETRY_RD_ERR_LOG_UC; - if (imc->chan[chan].retry_rd_err_log_s & RETRY_RD_ERR_LOG_NOOVER) + if (rrl_ctl[0] & RETRY_RD_ERR_LOG_NOOVER) s |= RETRY_RD_ERR_LOG_NOOVER; - if (!(imc->chan[chan].retry_rd_err_log_s & RETRY_RD_ERR_LOG_EN)) + if (!(rrl_ctl[0] & RETRY_RD_ERR_LOG_EN)) s &= ~RETRY_RD_ERR_LOG_EN; - if (imc->chan[chan].retry_rd_err_log_d & RETRY_RD_ERR_LOG_UC) + if (rrl_ctl[1] & RETRY_RD_ERR_LOG_UC) d |= RETRY_RD_ERR_LOG_UC; - if (imc->chan[chan].retry_rd_err_log_d & RETRY_RD_ERR_LOG_NOOVER) + if (rrl_ctl[1] & RETRY_RD_ERR_LOG_NOOVER) d |= RETRY_RD_ERR_LOG_NOOVER; - if (!(imc->chan[chan].retry_rd_err_log_d & RETRY_RD_ERR_LOG_EN)) + if (!(rrl_ctl[1] & RETRY_RD_ERR_LOG_EN)) d &= ~RETRY_RD_ERR_LOG_EN; if (offsets_demand2) { - if (imc->chan[chan].retry_rd_err_log_d2 & RETRY_RD_ERR_LOG_UC) + if (rrl_ctl[2] & RETRY_RD_ERR_LOG_UC) d2 |= RETRY_RD_ERR_LOG_UC; - if (!(imc->chan[chan].retry_rd_err_log_d2 & RETRY_RD_ERR_LOG_NOOVER)) + if (!(rrl_ctl[2] & RETRY_RD_ERR_LOG_NOOVER)) d2 &= ~RETRY_RD_ERR_LOG_NOOVER; - if (!(imc->chan[chan].retry_rd_err_log_d2 & RETRY_RD_ERR_LOG_EN)) + if (!(rrl_ctl[2] & RETRY_RD_ERR_LOG_EN)) d2 &= ~RETRY_RD_ERR_LOG_EN; } } @@ -161,6 +161,7 @@ static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable static void enable_retry_rd_err_log(bool enable) { int i, j, imc_num, chan_num; + struct skx_channel *chan; struct skx_imc *imc; struct skx_dev *d; @@ -175,8 +176,9 @@ static void enable_retry_rd_err_log(bool enable) if (!imc->mbase) continue; + chan = d->imc[i].chan; for (j = 0; j < chan_num; j++) - __enable_retry_rd_err_log(imc, j, enable, + __enable_retry_rd_err_log(imc, j, enable, chan[j].rrl_ctl[0], res_cfg->offsets_scrub, res_cfg->offsets_demand, res_cfg->offsets_demand2); @@ -190,12 +192,13 @@ static void enable_retry_rd_err_log(bool enable) if (!imc->mbase || !imc->hbm_mc) continue; + chan = d->imc[i].chan; for (j = 0; j < chan_num; j++) { - __enable_retry_rd_err_log(imc, j, enable, + __enable_retry_rd_err_log(imc, j, enable, chan[j].rrl_ctl[0], res_cfg->offsets_scrub_hbm0, res_cfg->offsets_demand_hbm0, NULL); - __enable_retry_rd_err_log(imc, j, enable, + __enable_retry_rd_err_log(imc, j, enable, chan[j].rrl_ctl[1], res_cfg->offsets_scrub_hbm1, res_cfg->offsets_demand_hbm1, NULL); diff --git a/drivers/edac/skx_common.h b/drivers/edac/skx_common.h index 5acfef8fd3d3..2ea4d1d1fbef 100644 --- a/drivers/edac/skx_common.h +++ b/drivers/edac/skx_common.h @@ -80,6 +80,9 @@ */ #define MCACOD_EXT_MEM_ERR 0x280 +/* Max RRL register sets per {,sub-,pseudo-}channel. */ +#define NUM_RRL_SET 3 + /* * Each cpu socket contains some pci devices that provide global * information, and also some that are local to each of the two @@ -118,9 +121,11 @@ struct skx_dev { struct skx_channel { struct pci_dev *cdev; struct pci_dev *edev; - u32 retry_rd_err_log_s; - u32 retry_rd_err_log_d; - u32 retry_rd_err_log_d2; + /* + * Two groups of RRL control registers per channel to save default RRL + * settings of two {sub-,pseudo-}channels in Linux RRL control mode. + */ + u32 rrl_ctl[2][NUM_RRL_SET]; struct skx_dimm { u8 close_pg; u8 bank_xor_enable; From 04034d43e9b6044dc875e23a8c8093f78f5b8ddb Mon Sep 17 00:00:00 2001 From: Vishwaroop A Date: Wed, 16 Apr 2025 11:06:01 +0000 Subject: [PATCH 091/971] spi: tegra210-quad: Fix X1_X2_X4 encoding and support x4 transfers [ Upstream commit dcb06c638a1174008a985849fa30fc0da7d08904 ] This patch corrects the QSPI_COMMAND_X1_X2_X4 and QSPI_ADDRESS_X1_X2_X4 macros to properly encode the bus width for x1, x2, and x4 transfers. Although these macros were previously incorrect, they were not being used in the driver, so no functionality was affected. The patch updates tegra_qspi_cmd_config() and tegra_qspi_addr_config() function calls to use the actual bus width from the transfer, instead of hardcoding it to 0 (which implied x1 mode). This change enables proper support for x1, x2, and x4 data transfers by correctly configuring the interface width for commands and addresses. These modifications improve the QSPI driver's flexibility and prepare it for future use cases that may require different bus widths for commands and addresses. Fixes: 1b8342cc4a38 ("spi: tegra210-quad: combined sequence mode") Signed-off-by: Vishwaroop A Link: https://patch.msgid.link/20250416110606.2737315-2-va@nvidia.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-tegra210-quad.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c index e3c236025a7b..78b3a021e915 100644 --- a/drivers/spi/spi-tegra210-quad.c +++ b/drivers/spi/spi-tegra210-quad.c @@ -134,7 +134,7 @@ #define QSPI_COMMAND_VALUE_SET(X) (((x) & 0xFF) << 0) #define QSPI_CMB_SEQ_CMD_CFG 0x1a0 -#define QSPI_COMMAND_X1_X2_X4(x) (((x) & 0x3) << 13) +#define QSPI_COMMAND_X1_X2_X4(x) ((((x) >> 1) & 0x3) << 13) #define QSPI_COMMAND_X1_X2_X4_MASK (0x03 << 13) #define QSPI_COMMAND_SDR_DDR BIT(12) #define QSPI_COMMAND_SIZE_SET(x) (((x) & 0xFF) << 0) @@ -147,7 +147,7 @@ #define QSPI_ADDRESS_VALUE_SET(X) (((x) & 0xFFFF) << 0) #define QSPI_CMB_SEQ_ADDR_CFG 0x1ac -#define QSPI_ADDRESS_X1_X2_X4(x) (((x) & 0x3) << 13) +#define QSPI_ADDRESS_X1_X2_X4(x) ((((x) >> 1) & 0x3) << 13) #define QSPI_ADDRESS_X1_X2_X4_MASK (0x03 << 13) #define QSPI_ADDRESS_SDR_DDR BIT(12) #define QSPI_ADDRESS_SIZE_SET(x) (((x) & 0xFF) << 0) @@ -1036,10 +1036,6 @@ static u32 tegra_qspi_addr_config(bool is_ddr, u8 bus_width, u8 len) { u32 addr_config = 0; - /* Extract Address configuration and value */ - is_ddr = 0; //Only SDR mode supported - bus_width = 0; //X1 mode - if (is_ddr) addr_config |= QSPI_ADDRESS_SDR_DDR; else @@ -1079,13 +1075,13 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, switch (transfer_phase) { case CMD_TRANSFER: /* X1 SDR mode */ - cmd_config = tegra_qspi_cmd_config(false, 0, + cmd_config = tegra_qspi_cmd_config(false, xfer->tx_nbits, xfer->len); cmd_value = *((const u8 *)(xfer->tx_buf)); break; case ADDR_TRANSFER: /* X1 SDR mode */ - addr_config = tegra_qspi_addr_config(false, 0, + addr_config = tegra_qspi_addr_config(false, xfer->tx_nbits, xfer->len); address_value = *((const u32 *)(xfer->tx_buf)); break; From 41de2c9e30b7346c9e1a0208292beb786da0401f Mon Sep 17 00:00:00 2001 From: Vishwaroop A Date: Wed, 16 Apr 2025 11:06:02 +0000 Subject: [PATCH 092/971] spi: tegra210-quad: remove redundant error handling code [ Upstream commit 400d9f1a27cc2fceabdb1ed93eaf0b89b6d32ba5 ] Remove unnecessary error handling code that terminated transfers and executed delay on errors. This code was redundant as error handling is already done at a higher level in the SPI core. Fixes: 1b8342cc4a38 ("spi: tegra210-quad: combined sequence mode") Signed-off-by: Vishwaroop A Link: https://patch.msgid.link/20250416110606.2737315-3-va@nvidia.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-tegra210-quad.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c index 78b3a021e915..7a74164cd954 100644 --- a/drivers/spi/spi-tegra210-quad.c +++ b/drivers/spi/spi-tegra210-quad.c @@ -1175,10 +1175,6 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, exit: msg->status = ret; - if (ret < 0) { - tegra_qspi_transfer_end(spi); - spi_transfer_delay_exec(xfer); - } return ret; } From c6c142267952b51f42e53e5deb8880dda7bdcd2a Mon Sep 17 00:00:00 2001 From: Vishwaroop A Date: Wed, 16 Apr 2025 11:06:03 +0000 Subject: [PATCH 093/971] spi: tegra210-quad: modify chip select (CS) deactivation [ Upstream commit d8966b65413390d1b5b706886987caac05fbe024 ] Modify the chip select (CS) deactivation and inter-transfer delay execution only during the DATA_TRANSFER phase when the cs_change flag is not set. This ensures proper CS handling and timing between transfers while eliminating redundant operations. Fixes: 1b8342cc4a38 ("spi: tegra210-quad: combined sequence mode") Signed-off-by: Vishwaroop A Link: https://patch.msgid.link/20250416110606.2737315-4-va@nvidia.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-tegra210-quad.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c index 7a74164cd954..e9afebd72423 100644 --- a/drivers/spi/spi-tegra210-quad.c +++ b/drivers/spi/spi-tegra210-quad.c @@ -1159,16 +1159,16 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, ret = -EIO; goto exit; } - if (!xfer->cs_change) { - tegra_qspi_transfer_end(spi); - spi_transfer_delay_exec(xfer); - } break; default: ret = -EINVAL; goto exit; } msg->actual_length += xfer->len; + if (!xfer->cs_change && transfer_phase == DATA_TRANSFER) { + tegra_qspi_transfer_end(spi); + spi_transfer_delay_exec(xfer); + } transfer_phase++; } ret = 0; From d46af758f63de42b04444fa7b097717a7c0a0df7 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Fri, 7 Mar 2025 08:38:09 +0300 Subject: [PATCH 094/971] power: reset: at91-reset: Optimize at91_reset() [ Upstream commit 62d48983f215bf1dd48665913318101fa3414dcf ] This patch adds a small optimization to the low-level at91_reset() function, which includes: - Removes the extra branch, since the following store operations already have proper condition checks. - Removes the definition of the clobber register r4, since it is no longer used in the code. Fixes: fcd0532fac2a ("power: reset: at91-reset: make at91sam9g45_restart() generic") Signed-off-by: Alexander Shiyan Reviewed-by: Alexandre Belloni Link: https://lore.kernel.org/r/20250307053809.20245-1-eagle.alexander923@gmail.com Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin --- drivers/power/reset/at91-reset.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index aa9b012d3d00..bafe4cc6fafd 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c @@ -129,12 +129,11 @@ static int at91_reset(struct notifier_block *this, unsigned long mode, " str %4, [%0, %6]\n\t" /* Disable SDRAM1 accesses */ "1: tst %1, #0\n\t" - " beq 2f\n\t" " strne %3, [%1, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t" /* Power down SDRAM1 */ " strne %4, [%1, %6]\n\t" /* Reset CPU */ - "2: str %5, [%2, #" __stringify(AT91_RSTC_CR) "]\n\t" + " str %5, [%2, #" __stringify(AT91_RSTC_CR) "]\n\t" " b .\n\t" : @@ -145,7 +144,7 @@ static int at91_reset(struct notifier_block *this, unsigned long mode, "r" cpu_to_le32(AT91_DDRSDRC_LPCB_POWER_DOWN), "r" (reset->data->reset_args), "r" (reset->ramc_lpr) - : "r4"); + ); return NOTIFY_DONE; } From 5b71469d77fdcb4b2260191ee871c4046064a400 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 25 Apr 2025 23:25:12 -0700 Subject: [PATCH 095/971] ASoC: SOF: ipc4-pcm: Adjust pipeline_list->pipelines allocation type [ Upstream commit 00a371adbbfb46db561db85a9d7b53b2363880a1 ] In preparation for making the kmalloc family of allocators type aware, we need to make sure that the returned type from the allocation matches the type of the variable being assigned. (Before, the allocator would always return "void *", which can be implicitly cast to any pointer type.) The assigned type is "struct snd_sof_pipeline **", but the returned type will be "struct snd_sof_widget **". These are the same size allocation (pointer size) but the types don't match. Adjust the allocation type to match the assignment. Signed-off-by: Kees Cook Fixes: 9c04363d222b ("ASoC: SOF: Introduce struct snd_sof_pipeline") Acked-by: Peter Ujfalusi Link: https://patch.msgid.link/20250426062511.work.859-kees@kernel.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/sof/ipc4-pcm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c index bb5df0d214e3..a29632423ccd 100644 --- a/sound/soc/sof/ipc4-pcm.c +++ b/sound/soc/sof/ipc4-pcm.c @@ -615,7 +615,8 @@ static int sof_ipc4_pcm_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm /* allocate memory for max number of pipeline IDs */ pipeline_list->pipelines = kcalloc(ipc4_data->max_num_pipelines, - sizeof(struct snd_sof_widget *), GFP_KERNEL); + sizeof(*pipeline_list->pipelines), + GFP_KERNEL); if (!pipeline_list->pipelines) { sof_ipc4_pcm_free(sdev, spcm); return -ENOMEM; From 2b5459380613e15625c9cd9178280650f986a809 Mon Sep 17 00:00:00 2001 From: Zijun Hu Date: Mon, 5 May 2025 17:26:51 +0800 Subject: [PATCH 096/971] PM: wakeup: Delete space in the end of string shown by pm_show_wakelocks() [ Upstream commit f0050a3e214aa941b78ad4caf122a735a24d81a6 ] pm_show_wakelocks() is called to generate a string when showing attributes /sys/power/wake_(lock|unlock), but the string ends with an unwanted space that was added back by mistake by commit c9d967b2ce40 ("PM: wakeup: simplify the output logic of pm_show_wakelocks()"). Remove the unwanted space. Fixes: c9d967b2ce40 ("PM: wakeup: simplify the output logic of pm_show_wakelocks()") Signed-off-by: Zijun Hu Link: https://patch.msgid.link/20250505-fix_power-v1-1-0f7f2c2f338c@quicinc.com [ rjw: Changelog edits ] Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- kernel/power/wakelock.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/power/wakelock.c b/kernel/power/wakelock.c index 52571dcad768..4e941999a53b 100644 --- a/kernel/power/wakelock.c +++ b/kernel/power/wakelock.c @@ -49,6 +49,9 @@ ssize_t pm_show_wakelocks(char *buf, bool show_active) len += sysfs_emit_at(buf, len, "%s ", wl->name); } + if (len > 0) + --len; + len += sysfs_emit_at(buf, len, "\n"); mutex_unlock(&wakelocks_lock); From aa7b90057bc3f8d9ddf50e7397facdd613de5610 Mon Sep 17 00:00:00 2001 From: Jiaqing Zhao Date: Fri, 9 May 2025 17:06:33 +0000 Subject: [PATCH 097/971] x86/mtrr: Check if fixed-range MTRRs exist in mtrr_save_fixed_ranges() [ Upstream commit 824c6384e8d9275d4ec7204f3f79a4ac6bc10379 ] When suspending, save_processor_state() calls mtrr_save_fixed_ranges() to save fixed-range MTRRs. On platforms without fixed-range MTRRs like the ACRN hypervisor which has removed fixed-range MTRR emulation, accessing these MSRs will trigger an unchecked MSR access error. Make sure fixed-range MTRRs are supported before access to prevent such error. Since mtrr_state.have_fixed is only set when MTRRs are present and enabled, checking the CPU feature flag in mtrr_save_fixed_ranges() is unnecessary. Fixes: 3ebad5905609 ("[PATCH] x86: Save and restore the fixed-range MTRRs of the BSP when suspending") Signed-off-by: Jiaqing Zhao Signed-off-by: Borislav Petkov (AMD) Link: https://lore.kernel.org/20250509170633.3411169-2-jiaqing.zhao@linux.intel.com Signed-off-by: Sasha Levin --- arch/x86/kernel/cpu/mtrr/generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index 2d6aa5d2e3d7..6839440a4b31 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -582,7 +582,7 @@ static void get_fixed_ranges(mtrr_type *frs) void mtrr_save_fixed_ranges(void *info) { - if (boot_cpu_has(X86_FEATURE_MTRR)) + if (mtrr_state.have_fixed) get_fixed_ranges(mtrr_state.fixed_ranges); } From fca08cfadd45b692df583436582ce314775ce9f9 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 9 May 2025 14:51:47 +0200 Subject: [PATCH 098/971] PM: sleep: Print PM debug messages during hibernation [ Upstream commit 1b17d4525bca3916644c41e01522df8fa0f8b90b ] Commit cdb8c100d8a4 ("include/linux/suspend.h: Only show pm_pr_dbg messages at suspend/resume") caused PM debug messages to only be printed during system-wide suspend and resume in progress, but it forgot about hibernation. Address this by adding a check for hibernation in progress to pm_debug_messages_should_print(). Fixes: cdb8c100d8a4 ("include/linux/suspend.h: Only show pm_pr_dbg messages at suspend/resume") Signed-off-by: Rafael J. Wysocki Reviewed-by: Mario Limonciello Link: https://patch.msgid.link/4998903.GXAFRqVoOG@rjwysocki.net Signed-off-by: Sasha Levin --- kernel/power/hibernate.c | 5 +++++ kernel/power/main.c | 3 ++- kernel/power/power.h | 4 ++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index c2fc58938dee..76dcf2e28427 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -80,6 +80,11 @@ void hibernate_release(void) atomic_inc(&hibernate_atomic); } +bool hibernation_in_progress(void) +{ + return !atomic_read(&hibernate_atomic); +} + bool hibernation_available(void) { return nohibernate == 0 && diff --git a/kernel/power/main.c b/kernel/power/main.c index f6425ae3e8b0..a3543bd2d25a 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -585,7 +585,8 @@ bool pm_debug_messages_on __read_mostly; bool pm_debug_messages_should_print(void) { - return pm_debug_messages_on && pm_suspend_target_state != PM_SUSPEND_ON; + return pm_debug_messages_on && (hibernation_in_progress() || + pm_suspend_target_state != PM_SUSPEND_ON); } EXPORT_SYMBOL_GPL(pm_debug_messages_should_print); diff --git a/kernel/power/power.h b/kernel/power/power.h index a98f95e309a3..62a7cb452a4b 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -66,10 +66,14 @@ extern void enable_restore_image_protection(void); static inline void enable_restore_image_protection(void) {} #endif /* CONFIG_STRICT_KERNEL_RWX */ +extern bool hibernation_in_progress(void); + #else /* !CONFIG_HIBERNATION */ static inline void hibernate_reserved_size_init(void) {} static inline void hibernate_image_size_init(void) {} + +static inline bool hibernation_in_progress(void) { return false; } #endif /* !CONFIG_HIBERNATION */ #define power_attr(_name) \ From 5174ac310ae7aaed7072c9ed91465d33a215a686 Mon Sep 17 00:00:00 2001 From: Armin Wolf Date: Thu, 10 Apr 2025 18:54:54 +0200 Subject: [PATCH 099/971] ACPI: OSI: Stop advertising support for "3.0 _SCP Extensions" [ Upstream commit 8cf4fdac9bdead7bca15fc56fdecdf78d11c3ec6 ] As specified in section 5.7.2 of the ACPI specification the feature group string "3.0 _SCP Extensions" implies that the operating system evaluates the _SCP control method with additional parameters. However the ACPI thermal driver evaluates the _SCP control method without those additional parameters, conflicting with the above feature group string advertised to the firmware thru _OSI. Stop advertising support for this feature string to avoid confusing the ACPI firmware. Fixes: e5f660ebef68 ("ACPI / osi: Collect _OSI handling into one single file") Signed-off-by: Armin Wolf Link: https://patch.msgid.link/20250410165456.4173-2-W_Armin@gmx.de Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/osi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/acpi/osi.c b/drivers/acpi/osi.c index d4405e1ca9b9..ae9620757865 100644 --- a/drivers/acpi/osi.c +++ b/drivers/acpi/osi.c @@ -42,7 +42,6 @@ static struct acpi_osi_entry osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = { {"Module Device", true}, {"Processor Device", true}, - {"3.0 _SCP Extensions", true}, {"Processor Aggregator Device", true}, }; From 42f7dd4bf5e08d4c00b3a65673817ad6ac324082 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 16 May 2025 15:32:06 +0200 Subject: [PATCH 100/971] spi: sh-msiof: Fix maximum DMA transfer size [ Upstream commit 0941d5166629cb766000530945e54b4e49680c68 ] The maximum amount of data to transfer in a single DMA request is calculated from the FIFO sizes (which is technically not 100% correct, but a simplification, as it is limited by the maximum word count values in the Transmit and Control Data Registers). However, in case there is both data to transmit and to receive, the transmit limit is overwritten by the receive limit. Fix this by using the minimum applicable FIFO size instead. Move the calculation outside the loop, so it is not repeated for each individual DMA transfer. As currently tx_fifo_size is always equal to rx_fifo_size, this bug had no real impact. Fixes: fe78d0b7691c0274 ("spi: sh-msiof: Fix FIFO size to 64 word from 256 word") Signed-off-by: Geert Uytterhoeven Link: https://patch.msgid.link/d9961767a97758b2614f2ee8afe1bd56dc900a60.1747401908.git.geert+renesas@glider.be Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-sh-msiof.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 6f12e4fb2e2e..65c11909659c 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -918,6 +918,7 @@ static int sh_msiof_transfer_one(struct spi_controller *ctlr, void *rx_buf = t->rx_buf; unsigned int len = t->len; unsigned int bits = t->bits_per_word; + unsigned int max_wdlen = 256; unsigned int bytes_per_word; unsigned int words; int n; @@ -931,17 +932,17 @@ static int sh_msiof_transfer_one(struct spi_controller *ctlr, if (!spi_controller_is_target(p->ctlr)) sh_msiof_spi_set_clk_regs(p, t); + if (tx_buf) + max_wdlen = min(max_wdlen, p->tx_fifo_size); + if (rx_buf) + max_wdlen = min(max_wdlen, p->rx_fifo_size); + while (ctlr->dma_tx && len > 15) { /* * DMA supports 32-bit words only, hence pack 8-bit and 16-bit * words, with byte resp. word swapping. */ - unsigned int l = 0; - - if (tx_buf) - l = min(round_down(len, 4), p->tx_fifo_size * 4); - if (rx_buf) - l = min(round_down(len, 4), p->rx_fifo_size * 4); + unsigned int l = min(round_down(len, 4), max_wdlen * 4); if (bits <= 8) { copy32 = copy_bswap32; From 8b263e8ab2d3e84a6b0eb4573c21562c5df6144a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Sun, 18 May 2025 20:50:46 +1000 Subject: [PATCH 101/971] ASoC: apple: mca: Constrain channels according to TDM mask MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit e717c661e2d1a660e96c40b0fe9933e23a1d7747 ] We don't (and can't) configure the hardware correctly if the number of channels exceeds the weight of the TDM mask. Report that constraint in startup of FE. Fixes: 3df5d0d97289 ("ASoC: apple: mca: Start new platform driver") Signed-off-by: Martin Povišer Signed-off-by: James Calligeros Link: https://patch.msgid.link/20250518-mca-fixes-v1-1-ee1015a695f6@gmail.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/apple/mca.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/sound/soc/apple/mca.c b/sound/soc/apple/mca.c index ce77934f3eef..0e96caa607fb 100644 --- a/sound/soc/apple/mca.c +++ b/sound/soc/apple/mca.c @@ -464,6 +464,28 @@ err: return -EINVAL; } +static int mca_fe_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mca_cluster *cl = mca_dai_to_cluster(dai); + unsigned int mask, nchannels; + + if (cl->tdm_slots) { + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + mask = cl->tdm_tx_mask; + else + mask = cl->tdm_rx_mask; + + nchannels = hweight32(mask); + } else { + nchannels = 2; + } + + return snd_pcm_hw_constraint_minmax(substream->runtime, + SNDRV_PCM_HW_PARAM_CHANNELS, + 1, nchannels); +} + static int mca_fe_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) { @@ -680,6 +702,7 @@ static int mca_fe_hw_params(struct snd_pcm_substream *substream, } static const struct snd_soc_dai_ops mca_fe_ops = { + .startup = mca_fe_startup, .set_fmt = mca_fe_set_fmt, .set_bclk_ratio = mca_set_bclk_ratio, .set_tdm_slot = mca_fe_set_tdm_slot, From 83cc36371af8ae262df9630013e43943858d8edf Mon Sep 17 00:00:00 2001 From: Ian Forbes Date: Fri, 28 Feb 2025 14:06:33 -0600 Subject: [PATCH 102/971] drm/vmwgfx: Add seqno waiter for sync_files [ Upstream commit 0039a3b35b10d9c15d3d26320532ab56cc566750 ] Because sync_files are passive waiters they do not participate in the processing of fences like the traditional vmw_fence_wait IOCTL. If userspace exclusively uses sync_files for synchronization then nothing in the kernel actually processes fence updates as interrupts for fences are masked and ignored if the kernel does not indicate to the SVGA device that there are active waiters. This oversight results in a bug where the entire GUI can freeze waiting on a sync_file that will never be signalled as we've masked the interrupts to signal its completion. This bug is incredibly racy as any process which interacts with the fencing code via the 3D stack can process the stuck fences on behalf of the stuck process causing it to run again. Even a simple app like eglinfo is enough to resume the stuck process. Usually this bug is seen at a login screen like GDM because there are no other 3D apps running. By adding a seqno waiter we re-enable interrupt based processing of the dma_fences associated with the sync_file which is signalled as part of a dma_fence_callback. This has likely been broken since it was initially added to the kernel in 2017 but has gone unnoticed until mutter recently started using sync_files heavily over the course of 2024 as part of their explicit sync support. Fixes: c906965dee22 ("drm/vmwgfx: Add export fence to file descriptor support") Signed-off-by: Ian Forbes Signed-off-by: Zack Rusin Link: https://patchwork.freedesktop.org/patch/msgid/20250228200633.642417-1-ian.forbes@broadcom.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 26 +++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 5fef0b31c117..b129ce873af3 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -4083,6 +4083,23 @@ static int vmw_execbuf_tie_context(struct vmw_private *dev_priv, return 0; } +/* + * DMA fence callback to remove a seqno_waiter + */ +struct seqno_waiter_rm_context { + struct dma_fence_cb base; + struct vmw_private *dev_priv; +}; + +static void seqno_waiter_rm_cb(struct dma_fence *f, struct dma_fence_cb *cb) +{ + struct seqno_waiter_rm_context *ctx = + container_of(cb, struct seqno_waiter_rm_context, base); + + vmw_seqno_waiter_remove(ctx->dev_priv); + kfree(ctx); +} + int vmw_execbuf_process(struct drm_file *file_priv, struct vmw_private *dev_priv, void __user *user_commands, void *kernel_commands, @@ -4263,6 +4280,15 @@ int vmw_execbuf_process(struct drm_file *file_priv, } else { /* Link the fence with the FD created earlier */ fd_install(out_fence_fd, sync_file->file); + struct seqno_waiter_rm_context *ctx = + kmalloc(sizeof(*ctx), GFP_KERNEL); + ctx->dev_priv = dev_priv; + vmw_seqno_waiter_add(dev_priv); + if (dma_fence_add_callback(&fence->base, &ctx->base, + seqno_waiter_rm_cb) < 0) { + vmw_seqno_waiter_remove(dev_priv); + kfree(ctx); + } } } From 079cc1fa46e0f218ddbf73fb39ec2a071b20de41 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 3 Apr 2025 15:33:30 +0200 Subject: [PATCH 103/971] drm/vc4: tests: Use return instead of assert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 9e26a3740cc08ef8bcdc5e5d824792cd677affce ] The vc4_mock_atomic_add_output() and vc4_mock_atomic_del_output() assert that the functions they are calling didn't fail. Since some of them can return EDEADLK, we can't properly deal with it. Since both functions are expected to return an int, and all caller check the return value, let's just properly propagate the errors when they occur. Fixes: f759f5b53f1c ("drm/vc4: tests: Introduce a mocking infrastructure") Fixes: 76ec18dc5afa ("drm/vc4: tests: Add unit test suite for the PV muxing") Reviewed-by: Maíra Canal Link: https://lore.kernel.org/r/20250403-drm-vc4-kunit-failures-v2-1-e09195cc8840@kernel.org Signed-off-by: Maxime Ripard Signed-off-by: Sasha Levin --- drivers/gpu/drm/vc4/tests/vc4_mock_output.c | 36 ++++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock_output.c b/drivers/gpu/drm/vc4/tests/vc4_mock_output.c index e70d7c3076ac..f0ddc223c1f8 100644 --- a/drivers/gpu/drm/vc4/tests/vc4_mock_output.c +++ b/drivers/gpu/drm/vc4/tests/vc4_mock_output.c @@ -75,24 +75,30 @@ int vc4_mock_atomic_add_output(struct kunit *test, int ret; encoder = vc4_find_encoder_by_type(drm, type); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder); + if (!encoder) + return -ENODEV; crtc = vc4_find_crtc_for_encoder(test, drm, encoder); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc); + if (!crtc) + return -ENODEV; output = encoder_to_vc4_dummy_output(encoder); conn = &output->connector; conn_state = drm_atomic_get_connector_state(state, conn); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + if (IS_ERR(conn_state)) + return PTR_ERR(conn_state); ret = drm_atomic_set_crtc_for_connector(conn_state, crtc); - KUNIT_EXPECT_EQ(test, ret, 0); + if (ret) + return ret; crtc_state = drm_atomic_get_crtc_state(state, crtc); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); ret = drm_atomic_set_mode_for_crtc(crtc_state, &default_mode); - KUNIT_EXPECT_EQ(test, ret, 0); + if (ret) + return ret; crtc_state->active = true; @@ -113,26 +119,32 @@ int vc4_mock_atomic_del_output(struct kunit *test, int ret; encoder = vc4_find_encoder_by_type(drm, type); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder); + if (!encoder) + return -ENODEV; crtc = vc4_find_crtc_for_encoder(test, drm, encoder); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc); + if (!crtc) + return -ENODEV; crtc_state = drm_atomic_get_crtc_state(state, crtc); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); crtc_state->active = false; ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL); - KUNIT_ASSERT_EQ(test, ret, 0); + if (ret) + return ret; output = encoder_to_vc4_dummy_output(encoder); conn = &output->connector; conn_state = drm_atomic_get_connector_state(state, conn); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + if (IS_ERR(conn_state)) + return PTR_ERR(conn_state); ret = drm_atomic_set_crtc_for_connector(conn_state, NULL); - KUNIT_ASSERT_EQ(test, ret, 0); + if (ret) + return ret; return 0; } From cdf7e1ff99ab06ef15d0b5d1aca5258a4fb62b85 Mon Sep 17 00:00:00 2001 From: Charles Han Date: Thu, 27 Mar 2025 12:04:35 +0800 Subject: [PATCH 104/971] drm/amd/pp: Fix potential NULL pointer dereference in atomctrl_initialize_mc_reg_table [ Upstream commit 820116a39f96bdc7d426c33a804b52f53700a919 ] The function atomctrl_initialize_mc_reg_table() and atomctrl_initialize_mc_reg_table_v2_2() does not check the return value of smu_atom_get_data_table(). If smu_atom_get_data_table() fails to retrieve vram_info, it returns NULL which is later dereferenced. Fixes: b3892e2bb519 ("drm/amd/pp: Use atombios api directly in powerplay (v2)") Fixes: 5f92b48cf62c ("drm/amd/pm: add mc register table initialization") Signed-off-by: Charles Han Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c index 1fbd23922082..7e37354a0341 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c @@ -144,6 +144,10 @@ int atomctrl_initialize_mc_reg_table( vram_info = (ATOM_VRAM_INFO_HEADER_V2_1 *) smu_atom_get_data_table(hwmgr->adev, GetIndexIntoMasterTable(DATA, VRAM_Info), &size, &frev, &crev); + if (!vram_info) { + pr_err("Could not retrieve the VramInfo table!"); + return -EINVAL; + } if (module_index >= vram_info->ucNumOfVRAMModule) { pr_err("Invalid VramInfo table."); @@ -181,6 +185,10 @@ int atomctrl_initialize_mc_reg_table_v2_2( vram_info = (ATOM_VRAM_INFO_HEADER_V2_2 *) smu_atom_get_data_table(hwmgr->adev, GetIndexIntoMasterTable(DATA, VRAM_Info), &size, &frev, &crev); + if (!vram_info) { + pr_err("Could not retrieve the VramInfo table!"); + return -EINVAL; + } if (module_index >= vram_info->ucNumOfVRAMModule) { pr_err("Invalid VramInfo table."); From 0d271c53009a6709f14c2c5221f096ee60e3d30b Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Tue, 25 Feb 2025 10:40:33 +0100 Subject: [PATCH 105/971] media: rkvdec: Fix frame size enumeration [ Upstream commit f270005b99fa19fee9a6b4006e8dee37c10f1944 ] The VIDIOC_ENUM_FRAMESIZES ioctl should return all frame sizes (i.e. width and height in pixels) that the device supports for the given pixel format. It doesn't make a lot of sense to return the frame-sizes in a stepwise manner, which is used to enforce hardware alignments requirements for CAPTURE buffers, for coded formats. Instead, applications should receive an indication, about the maximum supported frame size for that hardware decoder, via a continuous frame-size enumeration. Fixes: cd33c830448b ("media: rkvdec: Add the rkvdec driver") Suggested-by: Alex Bee Signed-off-by: Jonas Karlman Reviewed-by: Nicolas Dufresne Signed-off-by: Nicolas Dufresne Signed-off-by: Hans Verkuil Signed-off-by: Sasha Levin --- drivers/staging/media/rkvdec/rkvdec.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c index ac398b5a9736..a1d941b0be00 100644 --- a/drivers/staging/media/rkvdec/rkvdec.c +++ b/drivers/staging/media/rkvdec/rkvdec.c @@ -213,8 +213,14 @@ static int rkvdec_enum_framesizes(struct file *file, void *priv, if (!fmt) return -EINVAL; - fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; - fsize->stepwise = fmt->frmsize; + fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; + fsize->stepwise.min_width = 1; + fsize->stepwise.max_width = fmt->frmsize.max_width; + fsize->stepwise.step_width = 1; + fsize->stepwise.min_height = 1; + fsize->stepwise.max_height = fmt->frmsize.max_height; + fsize->stepwise.step_height = 1; + return 0; } From 8bf6491dab8c1b1d040db79dd0a5908fb6691a65 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Wed, 9 Apr 2025 17:39:58 +0100 Subject: [PATCH 106/971] arm64/fpsimd: Avoid RES0 bits in the SME trap handler [ Upstream commit 95507570fb2f75544af69760cd5d8f48fc5c7f20 ] The SME trap handler consumes RES0 bits from the ESR when determining the reason for the trap, and depends upon those bits reading as zero. This may break in future when those RES0 bits are allocated a meaning and stop reading as zero. For SME traps taken with ESR_ELx.EC == 0b011101, the specific reason for the trap is indicated by ESR_ELx.ISS.SMTC ("SME Trap Code"). This field occupies bits [2:0] of ESR_ELx.ISS, and as of ARM DDI 0487 L.a, bits [24:3] of ESR_ELx.ISS are RES0. ESR_ELx.ISS itself occupies bits [24:0] of ESR_ELx. Extract the SMTC field specifically, matching the way we handle ESR_ELx fields elsewhere, and ensuring that the handler is future-proof. Fixes: 8bd7f91c03d8 ("arm64/sme: Implement traps and syscall handling for SME") Signed-off-by: Mark Rutland Cc: Marc Zyngier Cc: Mark Brown Cc: Will Deacon Reviewed-by: Mark Brown Link: https://lore.kernel.org/r/20250409164010.3480271-2-mark.rutland@arm.com Signed-off-by: Catalin Marinas Signed-off-by: Sasha Levin --- arch/arm64/include/asm/esr.h | 12 +++++++----- arch/arm64/kernel/fpsimd.c | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h index 1cdae1b4f03b..b04575ea3a35 100644 --- a/arch/arm64/include/asm/esr.h +++ b/arch/arm64/include/asm/esr.h @@ -366,12 +366,14 @@ /* * ISS values for SME traps */ +#define ESR_ELx_SME_ISS_SMTC_MASK GENMASK(2, 0) +#define ESR_ELx_SME_ISS_SMTC(esr) ((esr) & ESR_ELx_SME_ISS_SMTC_MASK) -#define ESR_ELx_SME_ISS_SME_DISABLED 0 -#define ESR_ELx_SME_ISS_ILL 1 -#define ESR_ELx_SME_ISS_SM_DISABLED 2 -#define ESR_ELx_SME_ISS_ZA_DISABLED 3 -#define ESR_ELx_SME_ISS_ZT_DISABLED 4 +#define ESR_ELx_SME_ISS_SMTC_SME_DISABLED 0 +#define ESR_ELx_SME_ISS_SMTC_ILL 1 +#define ESR_ELx_SME_ISS_SMTC_SM_DISABLED 2 +#define ESR_ELx_SME_ISS_SMTC_ZA_DISABLED 3 +#define ESR_ELx_SME_ISS_SMTC_ZT_DISABLED 4 /* ISS field definitions for MOPS exceptions */ #define ESR_ELx_MOPS_ISS_MEM_INST (UL(1) << 24) diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index bd4f6c6ee0f3..9f6ea38f5189 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -1514,7 +1514,7 @@ void do_sme_acc(unsigned long esr, struct pt_regs *regs) * If this not a trap due to SME being disabled then something * is being used in the wrong mode, report as SIGILL. */ - if (ESR_ELx_ISS(esr) != ESR_ELx_SME_ISS_SME_DISABLED) { + if (ESR_ELx_SME_ISS_SMTC(esr) != ESR_ELx_SME_ISS_SMTC_SME_DISABLED) { force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc, 0); return; } From 43be952e885476dafb74aa832c0847b2f4f650c6 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 9 Apr 2025 17:40:02 +0100 Subject: [PATCH 107/971] arm64/fpsimd: Discard stale CPU state when handling SME traps [ Upstream commit d3eaab3c70905c5467e5c4ea403053d67505adeb ] The logic for handling SME traps manipulates saved FPSIMD/SVE/SME state incorrectly, and a race with preemption can result in a task having TIF_SME set and TIF_FOREIGN_FPSTATE clear even though the live CPU state is stale (e.g. with SME traps enabled). This can result in warnings from do_sme_acc() where SME traps are not expected while TIF_SME is set: | /* With TIF_SME userspace shouldn't generate any traps */ | if (test_and_set_thread_flag(TIF_SME)) | WARN_ON(1); This is very similar to the SVE issue we fixed in commit: 751ecf6afd6568ad ("arm64/sve: Discard stale CPU state when handling SVE traps") The race can occur when the SME trap handler is preempted before and after manipulating the saved FPSIMD/SVE/SME state, starting and ending on the same CPU, e.g. | void do_sme_acc(unsigned long esr, struct pt_regs *regs) | { | // Trap on CPU 0 with TIF_SME clear, SME traps enabled | // task->fpsimd_cpu is 0. | // per_cpu_ptr(&fpsimd_last_state, 0) is task. | | ... | | // Preempted; migrated from CPU 0 to CPU 1. | // TIF_FOREIGN_FPSTATE is set. | | get_cpu_fpsimd_context(); | | /* With TIF_SME userspace shouldn't generate any traps */ | if (test_and_set_thread_flag(TIF_SME)) | WARN_ON(1); | | if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) { | unsigned long vq_minus_one = | sve_vq_from_vl(task_get_sme_vl(current)) - 1; | sme_set_vq(vq_minus_one); | | fpsimd_bind_task_to_cpu(); | } | | put_cpu_fpsimd_context(); | | // Preempted; migrated from CPU 1 to CPU 0. | // task->fpsimd_cpu is still 0 | // If per_cpu_ptr(&fpsimd_last_state, 0) is still task then: | // - Stale HW state is reused (with SME traps enabled) | // - TIF_FOREIGN_FPSTATE is cleared | // - A return to userspace skips HW state restore | } Fix the case where the state is not live and TIF_FOREIGN_FPSTATE is set by calling fpsimd_flush_task_state() to detach from the saved CPU state. This ensures that a subsequent context switch will not reuse the stale CPU state, and will instead set TIF_FOREIGN_FPSTATE, forcing the new state to be reloaded from memory prior to a return to userspace. Note: this was originallly posted as [1]. Fixes: 8bd7f91c03d8 ("arm64/sme: Implement traps and syscall handling for SME") Reported-by: Mark Rutland Signed-off-by: Mark Brown Link: https://lore.kernel.org/linux-arm-kernel/20241204-arm64-sme-reenable-v2-1-bae87728251d@kernel.org/ [ Rutland: rewrite commit message ] Signed-off-by: Mark Rutland Cc: Marc Zyngier Cc: Will Deacon Link: https://lore.kernel.org/r/20250409164010.3480271-6-mark.rutland@arm.com Signed-off-by: Catalin Marinas Signed-off-by: Sasha Levin --- arch/arm64/kernel/fpsimd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index 9f6ea38f5189..3d482336c066 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -1538,6 +1538,8 @@ void do_sme_acc(unsigned long esr, struct pt_regs *regs) sme_set_vq(vq_minus_one); fpsimd_bind_task_to_cpu(); + } else { + fpsimd_flush_task_state(current); } put_cpu_fpsimd_context(); From 2f6e645ce64e299dd5bbb62aaa4717bcf7586901 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Wed, 9 Apr 2025 17:40:06 +0100 Subject: [PATCH 108/971] arm64/fpsimd: Fix merging of FPSIMD state during signal return [ Upstream commit c94f2f326146a34066a0070ed90b8bc656b1842f ] For backwards compatibility reasons, when a signal return occurs which restores SVE state, the effective lower 128 bits of each of the SVE vector registers are restored from the corresponding FPSIMD vector register in the FPSIMD signal frame, overriding the values in the SVE signal frame. This is intended to be the case regardless of streaming mode. To make this happen, restore_sve_fpsimd_context() uses fpsimd_update_current_state() to merge the lower 128 bits from the FPSIMD signal frame into the SVE register state. Unfortunately, fpsimd_update_current_state() performs this merging dependent upon TIF_SVE, which is not always correct for streaming SVE register state: * When restoring non-streaming SVE register state there is no observable problem, as the signal return code configures TIF_SVE and the saved fp_type to match before calling fpsimd_update_current_state(), which observes either: - TIF_SVE set AND fp_type == FP_STATE_SVE - TIF_SVE clear AND fp_type == FP_STATE_FPSIMD * On systems which have SME but not SVE, TIF_SVE cannot be set. Thus the merging will never happen for the streaming SVE register state. * On systems which have SVE and SME, TIF_SVE can be set and cleared independently of PSTATE.SM. Thus the merging may or may not happen for streaming SVE register state. As TIF_SVE can be cleared non-deterministically during syscalls (including at the start of sigreturn()), the merging may occur non-deterministically from the perspective of userspace. This logic has been broken since its introduction in commit: 85ed24dad2904f7c ("arm64/sme: Implement streaming SVE signal handling") ... at which point both fpsimd_signal_preserve_current_state() and fpsimd_update_current_state() only checked TIF SVE. When PSTATE.SM==1 and TIF_SVE was clear, signal delivery would place stale FPSIMD state into the FPSIMD signal frame, and signal return would not merge this into the restored register state. Subsequently, signal delivery was fixed as part of commit: 61da7c8e2a602f66 ("arm64/signal: Don't assume that TIF_SVE means we saved SVE state") ... but signal restore was not given a corresponding fix, and when TIF_SVE was clear, signal restore would still fail to merge the FPSIMD state into the restored SVE register state. The 'Fixes' tag did not indicate that this had been broken since its introduction. Fix this by merging the FPSIMD state dependent upon the saved fp_type, matching what we (currently) do during signal delivery. As described above, when backporting this commit, it will also be necessary to backport commit: 61da7c8e2a602f66 ("arm64/signal: Don't assume that TIF_SVE means we saved SVE state") ... and prior to commit: baa8515281b30861 ("arm64/fpsimd: Track the saved FPSIMD state type separately to TIF_SVE") ... it will be necessary for fpsimd_signal_preserve_current_state() and fpsimd_update_current_state() to consider both TIF_SVE and thread_sm_enabled(¤t->thread), in place of the saved fp_type. Fixes: 85ed24dad290 ("arm64/sme: Implement streaming SVE signal handling") Signed-off-by: Mark Rutland Cc: Marc Zyngier Cc: Mark Brown Cc: Will Deacon Reviewed-by: Mark Brown Link: https://lore.kernel.org/r/20250409164010.3480271-10-mark.rutland@arm.com Signed-off-by: Catalin Marinas Signed-off-by: Sasha Levin --- arch/arm64/kernel/fpsimd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index 3d482336c066..b86a50646700 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -1805,7 +1805,7 @@ void fpsimd_update_current_state(struct user_fpsimd_state const *state) get_cpu_fpsimd_context(); current->thread.uw.fpsimd_state = *state; - if (test_thread_flag(TIF_SVE)) + if (current->thread.fp_type == FP_STATE_SVE) fpsimd_to_sve(current); task_fpsimd_load(); From 94be75619e8ce7c9a25aaada090fd4b4a91638e6 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Fri, 18 Apr 2025 08:48:16 +0200 Subject: [PATCH 109/971] drm/bridge: lt9611uxc: Fix an error handling path in lt9611uxc_probe() [ Upstream commit b848cd418aebdb313364b4843f41fae82281a823 ] If lt9611uxc_audio_init() fails, some resources still need to be released before returning the error code. Use the existing error handling path. Fixes: 0cbbd5b1a012 ("drm: bridge: add support for lontium LT9611UXC bridge") Signed-off-by: Christophe JAILLET Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/f167608e392c6b4d7d7f6e45e3c21878feb60cbd.1744958833.git.christophe.jaillet@wanadoo.fr Signed-off-by: Dmitry Baryshkov Signed-off-by: Sasha Levin --- drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c index c41ffd0bc049..d458a4f37ac8 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -962,7 +962,11 @@ retry: } } - return lt9611uxc_audio_init(dev, lt9611uxc); + ret = lt9611uxc_audio_init(dev, lt9611uxc); + if (ret) + goto err_remove_bridge; + + return 0; err_remove_bridge: free_irq(client->irq, lt9611uxc); From 701340a25b1ad210e6b8192195be21fd3fcc22c7 Mon Sep 17 00:00:00 2001 From: Andrey Vatoropin Date: Tue, 18 Mar 2025 13:42:18 +0000 Subject: [PATCH 110/971] fs/ntfs3: handle hdr_first_de() return value [ Upstream commit af5cab0e5b6f8edb0be51a9f47f3f620e0b4fd70 ] The hdr_first_de() function returns a pointer to a struct NTFS_DE. This pointer may be NULL. To handle the NULL error effectively, it is important to implement an error handler. This will help manage potential errors consistently. Additionally, error handling for the return value already exists at other points where this function is called. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 82cae269cfa9 ("fs/ntfs3: Add initialization of super block") Signed-off-by: Andrey Vatoropin Signed-off-by: Konstantin Komarov Signed-off-by: Sasha Levin --- fs/ntfs3/index.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c index 28aae6ea1e61..191b91ffadbb 100644 --- a/fs/ntfs3/index.c +++ b/fs/ntfs3/index.c @@ -2184,6 +2184,10 @@ static int indx_get_entry_to_replace(struct ntfs_index *indx, e = hdr_first_de(&n->index->ihdr); fnd_push(fnd, n, e); + if (!e) { + err = -EINVAL; + goto out; + } if (!de_is_last(e)) { /* @@ -2205,6 +2209,10 @@ static int indx_get_entry_to_replace(struct ntfs_index *indx, n = fnd->nodes[level]; te = hdr_first_de(&n->index->ihdr); + if (!te) { + err = -EINVAL; + goto out; + } /* Copy the candidate entry into the replacement entry buffer. */ re = kmalloc(le16_to_cpu(te->size) + sizeof(u64), GFP_NOFS); if (!re) { From 428d865fec68789ec440fc3ac9af8f35e2024c41 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 15 Apr 2025 15:52:49 -0700 Subject: [PATCH 111/971] watchdog: exar: Shorten identity name to fit correctly [ Upstream commit 8e28276a569addb8a2324439ae473848ee52b056 ] The static initializer for struct watchdog_info::identity is too long and gets initialized without a trailing NUL byte. Since the length of "identity" is part of UAPI and tied to ioctls, just shorten the name of the device. Avoids the warning seen with GCC 15's -Wunterminated-string-initialization option: drivers/watchdog/exar_wdt.c:224:27: warning: initializer-string for array of 'unsigned char' truncates NUL terminator but destination lacks 'nonstring' attribute (33 chars into 32 available) [-Wunterminated-string-initialization] 224 | .identity = "Exar/MaxLinear XR28V38x Watchdog", | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Fixes: 81126222bd3a ("watchdog: Exar/MaxLinear XR28V38x driver") Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20250415225246.work.458-kees@kernel.org Signed-off-by: Kees Cook Signed-off-by: Sasha Levin --- drivers/watchdog/exar_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/watchdog/exar_wdt.c b/drivers/watchdog/exar_wdt.c index 7c61ff343271..c2e3bb08df89 100644 --- a/drivers/watchdog/exar_wdt.c +++ b/drivers/watchdog/exar_wdt.c @@ -221,7 +221,7 @@ static const struct watchdog_info exar_wdt_info = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, - .identity = "Exar/MaxLinear XR28V38x Watchdog", + .identity = "Exar XR28V38x Watchdog", }; static const struct watchdog_ops exar_wdt_ops = { From 569829f8fde0946f2598cade8ff23e21a2a012bc Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Thu, 24 Apr 2025 10:07:26 +1000 Subject: [PATCH 112/971] m68k: mac: Fix macintosh_config for Mac II [ Upstream commit 52ae3f5da7e5adbe3d1319573b55dac470abb83c ] When booted on my Mac II, the kernel prints this: Detected Macintosh model: 6 Apple Macintosh Unknown The catch-all entry ("Unknown") is mac_data_table[0] which is only needed in the unlikely event that the bootinfo model ID can't be matched. When model ID is 6, the search should begin and end at mac_data_table[1]. Fix the off-by-one error that causes this problem. Cc: Joshua Thompson Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Finn Thain Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/d0f30a551064ca4810b1c48d5a90954be80634a9.1745453246.git.fthain@linux-m68k.org Signed-off-by: Geert Uytterhoeven Signed-off-by: Sasha Levin --- arch/m68k/mac/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c index 382f656c29ea..9f5603e01a68 100644 --- a/arch/m68k/mac/config.c +++ b/arch/m68k/mac/config.c @@ -801,7 +801,7 @@ static void __init mac_identify(void) } macintosh_config = mac_data_table; - for (m = macintosh_config; m->ident != -1; m++) { + for (m = &mac_data_table[1]; m->ident != -1; m++) { if (m->ident == model) { macintosh_config = m; break; From 0052f10c25e47512f08cfcff43ebec76ad8102b2 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Tue, 18 Mar 2025 23:17:12 +0800 Subject: [PATCH 113/971] firmware: psci: Fix refcount leak in psci_dt_init [ Upstream commit 7ff37d29fd5c27617b9767e1b8946d115cf93a1e ] Fix a reference counter leak in psci_dt_init() where of_node_put(np) was missing after of_find_matching_node_and_match() when np is unavailable. Fixes: d09a0011ec0d ("drivers: psci: Allow PSCI node to be disabled") Signed-off-by: Miaoqian Lin Reviewed-by: Gavin Shan Acked-by: Mark Rutland Link: https://lore.kernel.org/r/20250318151712.28763-1-linmq006@gmail.com Signed-off-by: Will Deacon Signed-off-by: Sasha Levin --- drivers/firmware/psci/psci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c index 2328ca58bba6..d6701d81cf68 100644 --- a/drivers/firmware/psci/psci.c +++ b/drivers/firmware/psci/psci.c @@ -759,8 +759,10 @@ int __init psci_dt_init(void) np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np); - if (!np || !of_device_is_available(np)) + if (!np || !of_device_is_available(np)) { + of_node_put(np); return -ENODEV; + } init_fn = (psci_initcall_t)matched_np->data; ret = init_fn(np); From cf08a1cba0045cb03806686575472ba90c5eb30c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kornel=20Dul=C4=99ba?= Date: Thu, 17 Apr 2025 11:47:54 +0000 Subject: [PATCH 114/971] arm64: Support ARM64_VA_BITS=52 when setting ARCH_MMAP_RND_BITS_MAX MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit f101c56447717c595d803894ba0e215f56c6fba4 ] When the 52-bit virtual addressing was introduced the select like ARCH_MMAP_RND_BITS_MAX logic was never updated to account for it. Because of that the rnd max bits knob is set to the default value of 18 when ARM64_VA_BITS=52. Fix this by setting ARCH_MMAP_RND_BITS_MAX to the same value that would be used if 48-bit addressing was used. Higher values can't used here because 52-bit addressing is used only if the caller provides a hint to mmap, with a fallback to 48-bit. The knob in question is an upper bound for what the user can set in /proc/sys/vm/mmap_rnd_bits, which in turn is used to determine how many random bits can be inserted into the base address used for mmap allocations. Since 48-bit allocations are legal with ARM64_VA_BITS=52, we need to make sure that the base address is small enough to facilitate this. Fixes: b6d00d47e81a ("arm64: mm: Introduce 52-bit Kernel VAs") Signed-off-by: Kornel Dulęba Reviewed-by: Anshuman Khandual Link: https://lore.kernel.org/r/20250417114754.3238273-1-korneld@google.com Signed-off-by: Will Deacon Signed-off-by: Sasha Levin --- arch/arm64/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 658c6a61ab6f..4ecba0690938 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -304,9 +304,9 @@ config ARCH_MMAP_RND_BITS_MAX default 24 if ARM64_VA_BITS=39 default 27 if ARM64_VA_BITS=42 default 30 if ARM64_VA_BITS=47 - default 29 if ARM64_VA_BITS=48 && ARM64_64K_PAGES - default 31 if ARM64_VA_BITS=48 && ARM64_16K_PAGES - default 33 if ARM64_VA_BITS=48 + default 29 if (ARM64_VA_BITS=48 || ARM64_VA_BITS=52) && ARM64_64K_PAGES + default 31 if (ARM64_VA_BITS=48 || ARM64_VA_BITS=52) && ARM64_16K_PAGES + default 33 if (ARM64_VA_BITS=48 || ARM64_VA_BITS=52) default 14 if ARM64_64K_PAGES default 16 if ARM64_16K_PAGES default 18 From 5e99bcff7cb5047c46a640f1909b089d255a0f64 Mon Sep 17 00:00:00 2001 From: Neill Kapron Date: Sun, 27 Apr 2025 09:40:58 +0000 Subject: [PATCH 115/971] selftests/seccomp: fix syscall_restart test for arm compat [ Upstream commit 797002deed03491215a352ace891749b39741b69 ] The inconsistencies in the systcall ABI between arm and arm-compat can can cause a failure in the syscall_restart test due to the logic attempting to work around the differences. The 'machine' field for an ARM64 device running in compat mode can report 'armv8l' or 'armv8b' which matches with the string 'arm' when only examining the first three characters of the string. This change adds additional validation to the workaround logic to make sure we only take the arm path when running natively, not in arm-compat. Fixes: 256d0afb11d6 ("selftests/seccomp: build and pass on arm64") Signed-off-by: Neill Kapron Link: https://lore.kernel.org/r/20250427094103.3488304-2-nkapron@google.com Signed-off-by: Kees Cook Signed-off-by: Sasha Levin --- tools/testing/selftests/seccomp/seccomp_bpf.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index cacf6507f690..15325ca35f1e 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -3154,12 +3154,15 @@ TEST(syscall_restart) ret = get_syscall(_metadata, child_pid); #if defined(__arm__) /* - * FIXME: * - native ARM registers do NOT expose true syscall. * - compat ARM registers on ARM64 DO expose true syscall. + * - values of utsbuf.machine include 'armv8l' or 'armb8b' + * for ARM64 running in compat mode. */ ASSERT_EQ(0, uname(&utsbuf)); - if (strncmp(utsbuf.machine, "arm", 3) == 0) { + if ((strncmp(utsbuf.machine, "arm", 3) == 0) && + (strncmp(utsbuf.machine, "armv8l", 6) != 0) && + (strncmp(utsbuf.machine, "armv8b", 6) != 0)) { EXPECT_EQ(__NR_nanosleep, ret); } else #endif From 4715d2959d3bbc979259ce3275fff8fe42d05b21 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Thu, 16 Nov 2023 12:24:24 +0000 Subject: [PATCH 116/971] drm: rcar-du: Fix memory leak in rcar_du_vsps_init() [ Upstream commit 91e3bf09a90bb4340c0c3c51396e7531555efda4 ] The rcar_du_vsps_init() doesn't free the np allocated by of_parse_phandle_with_fixed_args() for the non-error case. Fix memory leak for the non-error case. While at it, replace the label 'error'->'done' as it applies to non-error case as well and update the error check condition for rcar_du_vsp_init() to avoid breakage in future, if it returns positive value. Fixes: 3e81374e2014 ("drm: rcar-du: Support multiple sources from the same VSP") Signed-off-by: Biju Das Reviewed-by: Laurent Pinchart Link: https://lore.kernel.org/r/20231116122424.80136-1-biju.das.jz@bp.renesas.com Signed-off-by: Tomi Valkeinen Signed-off-by: Sasha Levin --- drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c index 70d8ad065bfa..4c8fe83dd610 100644 --- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c @@ -705,7 +705,7 @@ static int rcar_du_vsps_init(struct rcar_du_device *rcdu) ret = of_parse_phandle_with_fixed_args(np, vsps_prop_name, cells, i, &args); if (ret < 0) - goto error; + goto done; /* * Add the VSP to the list or update the corresponding existing @@ -743,13 +743,11 @@ static int rcar_du_vsps_init(struct rcar_du_device *rcdu) vsp->dev = rcdu; ret = rcar_du_vsp_init(vsp, vsps[i].np, vsps[i].crtcs_mask); - if (ret < 0) - goto error; + if (ret) + goto done; } - return 0; - -error: +done: for (i = 0; i < ARRAY_SIZE(vsps); ++i) of_node_put(vsps[i].np); From 01f73e104288a3b3c651708f110cc41c1277ea4e Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 25 Apr 2025 23:14:32 -0700 Subject: [PATCH 117/971] drm/vkms: Adjust vkms_state->active_planes allocation type [ Upstream commit 258aebf100540d36aba910f545d4d5ddf4ecaf0b ] In preparation for making the kmalloc family of allocators type aware, we need to make sure that the returned type from the allocation matches the type of the variable being assigned. (Before, the allocator would always return "void *", which can be implicitly cast to any pointer type.) The assigned type is "struct vkms_plane_state **", but the returned type will be "struct drm_plane **". These are the same size (pointer size), but the types don't match. Adjust the allocation type to match the assignment. Signed-off-by: Kees Cook Reviewed-by: Louis Chauvet Fixes: 8b1865873651 ("drm/vkms: totally reworked crc data tracking") Link: https://lore.kernel.org/r/20250426061431.work.304-kees@kernel.org Signed-off-by: Louis Chauvet Signed-off-by: Sasha Levin --- drivers/gpu/drm/vkms/vkms_crtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c index 61e500b8c9da..894c484f99e9 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -201,7 +201,7 @@ static int vkms_crtc_atomic_check(struct drm_crtc *crtc, i++; } - vkms_state->active_planes = kcalloc(i, sizeof(plane), GFP_KERNEL); + vkms_state->active_planes = kcalloc(i, sizeof(*vkms_state->active_planes), GFP_KERNEL); if (!vkms_state->active_planes) return -ENOMEM; vkms_state->num_active_planes = i; From 3215e000eff69a613ef60ea00d9888987fe99c59 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 5 Feb 2025 11:21:35 +0000 Subject: [PATCH 118/971] drm/tegra: rgb: Fix the unbound reference count [ Upstream commit 3c3642335065c3bde0742b0edc505b6ea8fdc2b3 ] The of_get_child_by_name() increments the refcount in tegra_dc_rgb_probe, but the driver does not decrement the refcount during unbind. Fix the unbound reference count using devm_add_action_or_reset() helper. Fixes: d8f4a9eda006 ("drm: Add NVIDIA Tegra20 support") Signed-off-by: Biju Das Signed-off-by: Thierry Reding Link: https://lore.kernel.org/r/20250205112137.36055-1-biju.das.jz@bp.renesas.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/tegra/rgb.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c index d6424abd3c45..8930460ba628 100644 --- a/drivers/gpu/drm/tegra/rgb.c +++ b/drivers/gpu/drm/tegra/rgb.c @@ -190,6 +190,11 @@ static const struct drm_encoder_helper_funcs tegra_rgb_encoder_helper_funcs = { .atomic_check = tegra_rgb_encoder_atomic_check, }; +static void tegra_dc_of_node_put(void *data) +{ + of_node_put(data); +} + int tegra_dc_rgb_probe(struct tegra_dc *dc) { struct device_node *np; @@ -197,7 +202,14 @@ int tegra_dc_rgb_probe(struct tegra_dc *dc) int err; np = of_get_child_by_name(dc->dev->of_node, "rgb"); - if (!np || !of_device_is_available(np)) + if (!np) + return -ENODEV; + + err = devm_add_action_or_reset(dc->dev, tegra_dc_of_node_put, np); + if (err < 0) + return err; + + if (!of_device_is_available(np)) return -ENODEV; rgb = devm_kzalloc(dc->dev, sizeof(*rgb), GFP_KERNEL); From 99d4011a0a322e3eb0a7828630145311b8a0b58e Mon Sep 17 00:00:00 2001 From: Huang Yiwei Date: Wed, 7 May 2025 12:57:57 +0800 Subject: [PATCH 119/971] firmware: SDEI: Allow sdei initialization without ACPI_APEI_GHES [ Upstream commit 59529bbe642de4eb2191a541d9b4bae7eb73862e ] SDEI usually initialize with the ACPI table, but on platforms where ACPI is not used, the SDEI feature can still be used to handle specific firmware calls or other customized purposes. Therefore, it is not necessary for ARM_SDE_INTERFACE to depend on ACPI_APEI_GHES. In commit dc4e8c07e9e2 ("ACPI: APEI: explicit init of HEST and GHES in acpi_init()"), to make APEI ready earlier, sdei_init was moved into acpi_ghes_init instead of being a standalone initcall, adding ACPI_APEI_GHES dependency to ARM_SDE_INTERFACE. This restricts the flexibility and usability of SDEI. This patch corrects the dependency in Kconfig and splits sdei_init() into two separate functions: sdei_init() and acpi_sdei_init(). sdei_init() will be called by arch_initcall and will only initialize the platform driver, while acpi_sdei_init() will initialize the device from acpi_ghes_init() when ACPI is ready. This allows the initialization of SDEI without ACPI_APEI_GHES enabled. Fixes: dc4e8c07e9e2 ("ACPI: APEI: explicit init of HEST and GHES in apci_init()") Cc: Shuai Xue Signed-off-by: Huang Yiwei Reviewed-by: Shuai Xue Reviewed-by: Gavin Shan Acked-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/20250507045757.2658795-1-quic_hyiwei@quicinc.com Signed-off-by: Will Deacon Signed-off-by: Sasha Levin --- drivers/acpi/apei/Kconfig | 1 + drivers/acpi/apei/ghes.c | 2 +- drivers/firmware/Kconfig | 1 - drivers/firmware/arm_sdei.c | 11 ++++++++--- include/linux/arm_sdei.h | 4 ++-- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig index 6b18f8bc7be3..71e0d64a7792 100644 --- a/drivers/acpi/apei/Kconfig +++ b/drivers/acpi/apei/Kconfig @@ -23,6 +23,7 @@ config ACPI_APEI_GHES select ACPI_HED select IRQ_WORK select GENERIC_ALLOCATOR + select ARM_SDE_INTERFACE if ARM64 help Generic Hardware Error Source provides a way to report platform hardware errors (such as that from chipset). It diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 3aadc632d7dd..2abf20736702 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -1523,7 +1523,7 @@ void __init acpi_ghes_init(void) { int rc; - sdei_init(); + acpi_sdei_init(); if (acpi_disabled) return; diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index 3f2f22e47bfa..8ecffdce94b1 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -40,7 +40,6 @@ config ARM_SCPI_POWER_DOMAIN config ARM_SDE_INTERFACE bool "ARM Software Delegated Exception Interface (SDEI)" depends on ARM64 - depends on ACPI_APEI_GHES help The Software Delegated Exception Interface (SDEI) is an ARM standard for registering callbacks from the platform firmware diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c index 3e8051fe8296..71e2a9a89f6a 100644 --- a/drivers/firmware/arm_sdei.c +++ b/drivers/firmware/arm_sdei.c @@ -1062,13 +1062,12 @@ static bool __init sdei_present_acpi(void) return true; } -void __init sdei_init(void) +void __init acpi_sdei_init(void) { struct platform_device *pdev; int ret; - ret = platform_driver_register(&sdei_driver); - if (ret || !sdei_present_acpi()) + if (!sdei_present_acpi()) return; pdev = platform_device_register_simple(sdei_driver.driver.name, @@ -1081,6 +1080,12 @@ void __init sdei_init(void) } } +static int __init sdei_init(void) +{ + return platform_driver_register(&sdei_driver); +} +arch_initcall(sdei_init); + int sdei_event_handler(struct pt_regs *regs, struct sdei_registered_event *arg) { diff --git a/include/linux/arm_sdei.h b/include/linux/arm_sdei.h index 255701e1251b..f652a5028b59 100644 --- a/include/linux/arm_sdei.h +++ b/include/linux/arm_sdei.h @@ -46,12 +46,12 @@ int sdei_unregister_ghes(struct ghes *ghes); /* For use by arch code when CPU hotplug notifiers are not appropriate. */ int sdei_mask_local_cpu(void); int sdei_unmask_local_cpu(void); -void __init sdei_init(void); +void __init acpi_sdei_init(void); void sdei_handler_abort(void); #else static inline int sdei_mask_local_cpu(void) { return 0; } static inline int sdei_unmask_local_cpu(void) { return 0; } -static inline void sdei_init(void) { } +static inline void acpi_sdei_init(void) { } static inline void sdei_handler_abort(void) { } #endif /* CONFIG_ARM_SDE_INTERFACE */ From e500dff1e4e55e5eb7f461b50a6fe3a66f25aac9 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Thu, 8 May 2025 14:26:21 +0100 Subject: [PATCH 120/971] arm64/fpsimd: Do not discard modified SVE state [ Upstream commit 398edaa12f9cf2be7902f306fc023c20e3ebd3e4 ] Historically SVE state was discarded deterministically early in the syscall entry path, before ptrace is notified of syscall entry. This permitted ptrace to modify SVE state before and after the "real" syscall logic was executed, with the modified state being retained. This behaviour was changed by commit: 8c845e2731041f0f ("arm64/sve: Leave SVE enabled on syscall if we don't context switch") That commit was intended to speed up workloads that used SVE by opportunistically leaving SVE enabled when returning from a syscall. The syscall entry logic was modified to truncate the SVE state without disabling userspace access to SVE, and fpsimd_save_user_state() was modified to discard userspace SVE state whenever in_syscall(current_pt_regs()) is true, i.e. when current_pt_regs()->syscallno != NO_SYSCALL. Leaving SVE enabled opportunistically resulted in a couple of changes to userspace visible behaviour which weren't described at the time, but are logical consequences of opportunistically leaving SVE enabled: * Signal handlers can observe the type of saved state in the signal's sve_context record. When the kernel only tracks FPSIMD state, the 'vq' field is 0 and there is no space allocated for register contents. When the kernel tracks SVE state, the 'vq' field is non-zero and the register contents are saved into the record. As a result of the above commit, 'vq' (and the presence of SVE register state) is non-deterministically zero or non-zero for a period of time after a syscall. The effective register state is still deterministic. Hopefully no-one relies on this being deterministic. In general, handlers for asynchronous events cannot expect a deterministic state. * Similarly to signal handlers, ptrace requests can observe the type of saved state in the NT_ARM_SVE and NT_ARM_SSVE regsets, as this is exposed in the header flags. As a result of the above commit, this is now in a non-deterministic state after a syscall. The effective register state is still deterministic. Hopefully no-one relies on this being deterministic. In general, debuggers would have to handle this changing at arbitrary points during program flow. Discarding the SVE state within fpsimd_save_user_state() resulted in other changes to userspace visible behaviour which are not desirable: * A ptrace tracer can modify (or create) a tracee's SVE state at syscall entry or syscall exit. As a result of the above commit, the tracee's SVE state can be discarded non-deterministically after modification, rather than being retained as it previously was. Note that for co-operative tracer/tracee pairs, the tracer may (re)initialise the tracee's state arbitrarily after the tracee sends itself an initial SIGSTOP via a syscall, so this affects realistic design patterns. * The current_pt_regs()->syscallno field can be modified via ptrace, and can be altered even when the tracee is not really in a syscall, causing non-deterministic discarding to occur in situations where this was not previously possible. Further, using current_pt_regs()->syscallno in this way is unsound: * There are data races between readers and writers of the current_pt_regs()->syscallno field. The current_pt_regs()->syscallno field is written in interruptible task context using plain C accesses, and is read in irq/softirq context using plain C accesses. These accesses are subject to data races, with the usual concerns with tearing, etc. * Writes to current_pt_regs()->syscallno are subject to compiler reordering. As current_pt_regs()->syscallno is written with plain C accesses, the compiler is free to move those writes arbitrarily relative to anything which doesn't access the same memory location. In theory this could break signal return, where prior to restoring the SVE state, restore_sigframe() calls forget_syscall(). If the write were hoisted after restore of some SVE state, that state could be discarded unexpectedly. In practice that reordering cannot happen in the absence of LTO (as cross compilation-unit function calls happen prevent this reordering), and that reordering appears to be unlikely in the presence of LTO. Additionally, since commit: f130ac0ae4412dbe ("arm64: syscall: unmask DAIF earlier for SVCs") ... DAIF is unmasked before el0_svc_common() sets regs->syscallno to the real syscall number. Consequently state may be saved in SVE format prior to this point. Considering all of the above, current_pt_regs()->syscallno should not be used to infer whether the SVE state can be discarded. Luckily we can instead use cpu_fp_state::to_save to track when it is safe to discard the SVE state: * At syscall entry, after the live SVE register state is truncated, set cpu_fp_state::to_save to FP_STATE_FPSIMD to indicate that only the FPSIMD portion is live and needs to be saved. * At syscall exit, once the task's state is guaranteed to be live, set cpu_fp_state::to_save to FP_STATE_CURRENT to indicate that TIF_SVE must be considered to determine which state needs to be saved. * Whenever state is modified, it must be saved+flushed prior to manipulation. The state will be truncated if necessary when it is saved, and reloading the state will set fp_state::to_save to FP_STATE_CURRENT, preventing subsequent discarding. This permits SVE state to be discarded *only* when it is known to have been truncated (and the non-FPSIMD portions must be zero), and ensures that SVE state is retained after it is explicitly modified. For backporting, note that this fix depends on the following commits: * b2482807fbd4 ("arm64/sme: Optimise SME exit on syscall entry") * f130ac0ae441 ("arm64: syscall: unmask DAIF earlier for SVCs") * 929fa99b1215 ("arm64/fpsimd: signal: Always save+flush state early") Fixes: 8c845e273104 ("arm64/sve: Leave SVE enabled on syscall if we don't context switch") Fixes: f130ac0ae441 ("arm64: syscall: unmask DAIF earlier for SVCs") Signed-off-by: Mark Rutland Cc: Catalin Marinas Cc: Marc Zyngier Cc: Mark Brown Cc: Will Deacon Link: https://lore.kernel.org/r/20250508132644.1395904-2-mark.rutland@arm.com Signed-off-by: Will Deacon Signed-off-by: Sasha Levin --- arch/arm64/include/asm/fpsimd.h | 3 +++ arch/arm64/kernel/entry-common.c | 46 ++++++++++++++++++++++++-------- arch/arm64/kernel/fpsimd.c | 15 ++++++----- 3 files changed, 47 insertions(+), 17 deletions(-) diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h index 7415c63b4187..c4840ea6d137 100644 --- a/arch/arm64/include/asm/fpsimd.h +++ b/arch/arm64/include/asm/fpsimd.h @@ -6,6 +6,7 @@ #define __ASM_FP_H #include +#include #include #include #include @@ -69,6 +70,8 @@ struct cpu_fp_state { enum fp_type to_save; }; +DECLARE_PER_CPU(struct cpu_fp_state, fpsimd_last_state); + extern void fpsimd_bind_state_to_cpu(struct cpu_fp_state *fp_state); extern void fpsimd_flush_task_state(struct task_struct *target); diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c index 0fc94207e69a..5e8204d250b4 100644 --- a/arch/arm64/kernel/entry-common.c +++ b/arch/arm64/kernel/entry-common.c @@ -359,20 +359,16 @@ static bool cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs) * As per the ABI exit SME streaming mode and clear the SVE state not * shared with FPSIMD on syscall entry. */ -static inline void fp_user_discard(void) +static inline void fpsimd_syscall_enter(void) { - /* - * If SME is active then exit streaming mode. If ZA is active - * then flush the SVE registers but leave userspace access to - * both SVE and SME enabled, otherwise disable SME for the - * task and fall through to disabling SVE too. This means - * that after a syscall we never have any streaming mode - * register state to track, if this changes the KVM code will - * need updating. - */ + /* Ensure PSTATE.SM is clear, but leave PSTATE.ZA as-is. */ if (system_supports_sme()) sme_smstop_sm(); + /* + * The CPU is not in streaming mode. If non-streaming SVE is not + * supported, there is no SVE state that needs to be discarded. + */ if (!system_supports_sve()) return; @@ -382,6 +378,33 @@ static inline void fp_user_discard(void) sve_vq_minus_one = sve_vq_from_vl(task_get_sve_vl(current)) - 1; sve_flush_live(true, sve_vq_minus_one); } + + /* + * Any live non-FPSIMD SVE state has been zeroed. Allow + * fpsimd_save_user_state() to lazily discard SVE state until either + * the live state is unbound or fpsimd_syscall_exit() is called. + */ + __this_cpu_write(fpsimd_last_state.to_save, FP_STATE_FPSIMD); +} + +static __always_inline void fpsimd_syscall_exit(void) +{ + if (!system_supports_sve()) + return; + + /* + * The current task's user FPSIMD/SVE/SME state is now bound to this + * CPU. The fpsimd_last_state.to_save value is either: + * + * - FP_STATE_FPSIMD, if the state has not been reloaded on this CPU + * since fpsimd_syscall_enter(). + * + * - FP_STATE_CURRENT, if the state has been reloaded on this CPU at + * any point. + * + * Reset this to FP_STATE_CURRENT to stop lazy discarding. + */ + __this_cpu_write(fpsimd_last_state.to_save, FP_STATE_CURRENT); } UNHANDLED(el1t, 64, sync) @@ -673,10 +696,11 @@ static void noinstr el0_svc(struct pt_regs *regs) { enter_from_user_mode(regs); cortex_a76_erratum_1463225_svc_handler(); - fp_user_discard(); + fpsimd_syscall_enter(); local_daif_restore(DAIF_PROCCTX); do_el0_svc(regs); exit_to_user_mode(regs); + fpsimd_syscall_exit(); } static void noinstr el0_fpac(struct pt_regs *regs, unsigned long esr) diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index b86a50646700..a1e0cc5353fb 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -119,7 +119,7 @@ * whatever is in the FPSIMD registers is not saved to memory, but discarded. */ -static DEFINE_PER_CPU(struct cpu_fp_state, fpsimd_last_state); +DEFINE_PER_CPU(struct cpu_fp_state, fpsimd_last_state); __ro_after_init struct vl_info vl_info[ARM64_VEC_MAX] = { #ifdef CONFIG_ARM64_SVE @@ -473,12 +473,15 @@ static void fpsimd_save(void) return; /* - * If a task is in a syscall the ABI allows us to only - * preserve the state shared with FPSIMD so don't bother - * saving the full SVE state in that case. + * Save SVE state if it is live. + * + * The syscall ABI discards live SVE state at syscall entry. When + * entering a syscall, fpsimd_syscall_enter() sets to_save to + * FP_STATE_FPSIMD to allow the SVE state to be lazily discarded until + * either new SVE state is loaded+bound or fpsimd_syscall_exit() is + * called prior to a return to userspace. */ - if ((last->to_save == FP_STATE_CURRENT && test_thread_flag(TIF_SVE) && - !in_syscall(current_pt_regs())) || + if ((last->to_save == FP_STATE_CURRENT && test_thread_flag(TIF_SVE)) || last->to_save == FP_STATE_SVE) { save_sve_regs = true; save_ffr = true; From ee96502062ec0b91428bd1609d5eb18b90af64e5 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 2 May 2025 15:41:57 -0700 Subject: [PATCH 121/971] scsi: qedf: Use designated initializer for struct qed_fcoe_cb_ops [ Upstream commit d8720235d5b5cad86c1f07f65117ef2a96f8bec7 ] Recent fixes to the randstruct GCC plugin allowed it to notice that this structure is entirely function pointers and is therefore subject to randomization, but doing so requires that it always use designated initializers. Explicitly specify the "common" member as being initialized. Silences: drivers/scsi/qedf/qedf_main.c:702:9: error: positional initialization of field in 'struct' declared with 'designated_init' attribute [-Werror=designated-init] 702 | { | ^ Fixes: 035f7f87b729 ("randstruct: Enable Clang support") Link: https://lore.kernel.org/r/20250502224156.work.617-kees@kernel.org Signed-off-by: Kees Cook Signed-off-by: Sasha Levin --- drivers/scsi/qedf/qedf_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index 9a81d14aef6b..17b19b39699a 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -699,7 +699,7 @@ static u32 qedf_get_login_failures(void *cookie) } static struct qed_fcoe_cb_ops qedf_cb_ops = { - { + .common = { .link_update = qedf_link_update, .bw_update = qedf_bw_update, .schedule_recovery_handler = qedf_schedule_recovery_handler, From 77511c2d2d1cbce8d9b4f50849843dd469d14173 Mon Sep 17 00:00:00 2001 From: Anand Moon Date: Mon, 7 Apr 2025 12:02:03 +0530 Subject: [PATCH 122/971] perf/amlogic: Replace smp_processor_id() with raw_smp_processor_id() in meson_ddr_pmu_create() [ Upstream commit 097469a2b0f12b91b4f27b9e9e4f2c46484cde30 ] The Amlogic DDR PMU driver meson_ddr_pmu_create() function incorrectly uses smp_processor_id(), which assumes disabled preemption. This leads to kernel warnings during module loading because meson_ddr_pmu_create() can be called in a preemptible context. Following kernel warning and stack trace: [ 31.745138] [ T2289] BUG: using smp_processor_id() in preemptible [00000000] code: (udev-worker)/2289 [ 31.745154] [ T2289] caller is debug_smp_processor_id+0x28/0x38 [ 31.745172] [ T2289] CPU: 4 UID: 0 PID: 2289 Comm: (udev-worker) Tainted: GW 6.14.0-0-MANJARO-ARM #1 59519addcbca6ba8de735e151fd7b9e97aac7ff0 [ 31.745181] [ T2289] Tainted: [W]=WARN [ 31.745183] [ T2289] Hardware name: Hardkernel ODROID-N2Plus (DT) [ 31.745188] [ T2289] Call trace: [ 31.745191] [ T2289] show_stack+0x28/0x40 (C) [ 31.745199] [ T2289] dump_stack_lvl+0x4c/0x198 [ 31.745205] [ T2289] dump_stack+0x20/0x50 [ 31.745209] [ T2289] check_preemption_disabled+0xec/0xf0 [ 31.745213] [ T2289] debug_smp_processor_id+0x28/0x38 [ 31.745216] [ T2289] meson_ddr_pmu_create+0x200/0x560 [meson_ddr_pmu_g12 8095101c49676ad138d9961e3eddaee10acca7bd] [ 31.745237] [ T2289] g12_ddr_pmu_probe+0x20/0x38 [meson_ddr_pmu_g12 8095101c49676ad138d9961e3eddaee10acca7bd] [ 31.745246] [ T2289] platform_probe+0x98/0xe0 [ 31.745254] [ T2289] really_probe+0x144/0x3f8 [ 31.745258] [ T2289] __driver_probe_device+0xb8/0x180 [ 31.745261] [ T2289] driver_probe_device+0x54/0x268 [ 31.745264] [ T2289] __driver_attach+0x11c/0x288 [ 31.745267] [ T2289] bus_for_each_dev+0xfc/0x160 [ 31.745274] [ T2289] driver_attach+0x34/0x50 [ 31.745277] [ T2289] bus_add_driver+0x160/0x2b0 [ 31.745281] [ T2289] driver_register+0x78/0x120 [ 31.745285] [ T2289] __platform_driver_register+0x30/0x48 [ 31.745288] [ T2289] init_module+0x30/0xfe0 [meson_ddr_pmu_g12 8095101c49676ad138d9961e3eddaee10acca7bd] [ 31.745298] [ T2289] do_one_initcall+0x11c/0x438 [ 31.745303] [ T2289] do_init_module+0x68/0x228 [ 31.745311] [ T2289] load_module+0x118c/0x13a8 [ 31.745315] [ T2289] __arm64_sys_finit_module+0x274/0x390 [ 31.745320] [ T2289] invoke_syscall+0x74/0x108 [ 31.745326] [ T2289] el0_svc_common+0x90/0xf8 [ 31.745330] [ T2289] do_el0_svc+0x2c/0x48 [ 31.745333] [ T2289] el0_svc+0x60/0x150 [ 31.745337] [ T2289] el0t_64_sync_handler+0x80/0x118 [ 31.745341] [ T2289] el0t_64_sync+0x1b8/0x1c0 Changes replaces smp_processor_id() with raw_smp_processor_id() to ensure safe CPU ID retrieval in preemptible contexts. Cc: Jiucheng Xu Fixes: 2016e2113d35 ("perf/amlogic: Add support for Amlogic meson G12 SoC DDR PMU driver") Signed-off-by: Anand Moon Link: https://lore.kernel.org/r/20250407063206.5211-1-linux.amoon@gmail.com Signed-off-by: Will Deacon Signed-off-by: Sasha Levin --- drivers/perf/amlogic/meson_ddr_pmu_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/perf/amlogic/meson_ddr_pmu_core.c b/drivers/perf/amlogic/meson_ddr_pmu_core.c index bbc7285fd934..5f8699612a9a 100644 --- a/drivers/perf/amlogic/meson_ddr_pmu_core.c +++ b/drivers/perf/amlogic/meson_ddr_pmu_core.c @@ -510,7 +510,7 @@ int meson_ddr_pmu_create(struct platform_device *pdev) fmt_attr_fill(pmu->info.hw_info->fmt_attr); - pmu->cpu = smp_processor_id(); + pmu->cpu = raw_smp_processor_id(); name = devm_kasprintf(&pdev->dev, GFP_KERNEL, DDR_PERF_DEV_NAME); if (!name) From 8126855798b010d65b8de04d6998afd9acb88f6c Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Thu, 3 Apr 2025 12:47:37 +0200 Subject: [PATCH 123/971] drm/mediatek: mtk_drm_drv: Fix kobject put for mtk_mutex device ptr [ Upstream commit 22918591fb747a6d16801e74a170cf98e886f83b ] This driver is taking a kobject for mtk_mutex only once per mmsys device for each drm-mediatek driver instance, differently from the behavior with other components, but it is decrementing the kobj's refcount in a loop and once per mmsys: this is not right and will result in a refcount_t underflow warning when mediatek-drm returns multiple probe deferrals in one boot (or when manually bound and unbound). Besides that, the refcount for mutex_dev was not decremented for error cases in mtk_drm_bind(), causing another refcount_t warning but this time for overflow, when the failure happens not during driver bind but during component bind. In order to fix one of the reasons why this is happening, remove the put_device(xx->mutex_dev) loop from the mtk_drm_kms_init()'s put_mutex_dev label (and drop the label) and add a single call to correctly free the single incremented refcount of mutex_dev to the mtk_drm_unbind() function to fix the refcount_t underflow. Moreover, add the same call to the error cases in mtk_drm_bind() to fix the refcount_t overflow. Fixes: 1ef7ed48356c ("drm/mediatek: Modify mediatek-drm for mt8195 multi mmsys support") Reviewed-by: Chen-Yu Tsai Signed-off-by: AngeloGioacchino Del Regno Link: https://patchwork.kernel.org/project/dri-devel/patch/20250403104741.71045-2-angelogioacchino.delregno@collabora.com/ Signed-off-by: Chun-Kuang Hu Signed-off-by: Sasha Levin --- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 8b41a07c3641..108cab35ce48 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -431,7 +431,7 @@ static int mtk_drm_kms_init(struct drm_device *drm) ret = drmm_mode_config_init(drm); if (ret) - goto put_mutex_dev; + return ret; drm->mode_config.min_width = 64; drm->mode_config.min_height = 64; @@ -450,7 +450,7 @@ static int mtk_drm_kms_init(struct drm_device *drm) drm->dev_private = private->all_drm_private[i]; ret = component_bind_all(private->all_drm_private[i]->dev, drm); if (ret) - goto put_mutex_dev; + return ret; } /* @@ -532,9 +532,6 @@ static int mtk_drm_kms_init(struct drm_device *drm) err_component_unbind: for (i = 0; i < private->data->mmsys_dev_num; i++) component_unbind_all(private->all_drm_private[i]->dev, drm); -put_mutex_dev: - for (i = 0; i < private->data->mmsys_dev_num; i++) - put_device(private->all_drm_private[i]->mutex_dev); return ret; } @@ -608,8 +605,10 @@ static int mtk_drm_bind(struct device *dev) return 0; drm = drm_dev_alloc(&mtk_drm_driver, dev); - if (IS_ERR(drm)) - return PTR_ERR(drm); + if (IS_ERR(drm)) { + ret = PTR_ERR(drm); + goto err_put_dev; + } private->drm_master = true; drm->dev_private = private; @@ -635,6 +634,8 @@ err_free: drm_dev_put(drm); for (i = 0; i < private->data->mmsys_dev_num; i++) private->all_drm_private[i]->drm = NULL; +err_put_dev: + put_device(private->mutex_dev); return ret; } @@ -647,6 +648,8 @@ static void mtk_drm_unbind(struct device *dev) drm_dev_unregister(private->drm); mtk_drm_kms_deinit(private->drm); drm_dev_put(private->drm); + + put_device(private->mutex_dev); } private->mtk_drm_bound = false; private->drm_master = false; From a2502fd0fa9ffa44d3550d692b12779ed0dc02eb Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Thu, 3 Apr 2025 12:47:38 +0200 Subject: [PATCH 124/971] drm/mediatek: Fix kobject put for component sub-drivers [ Upstream commit 80805b62ea5b95eda54c225b989f929ca0691ab0 ] In function mtk_drm_get_all_drm_priv(), this driver is incrementing the refcount for the sub-drivers of mediatek-drm with a call to device_find_child() when taking a reference to all of those child devices. When the component bind fails multiple times this results in a refcount_t overflow, as the reference count is never decremented: fix that by adding a call to put_device() for all of the mmsys devices in a loop, in error cases of mtk_drm_bind() and in the mtk_drm_unbind() callback. Fixes: 1ef7ed48356c ("drm/mediatek: Modify mediatek-drm for mt8195 multi mmsys support") Reviewed-by: Chen-Yu Tsai Signed-off-by: AngeloGioacchino Del Regno Link: https://patchwork.kernel.org/project/dri-devel/patch/20250403104741.71045-3-angelogioacchino.delregno@collabora.com/ Signed-off-by: Chun-Kuang Hu Signed-off-by: Sasha Levin --- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 108cab35ce48..32d66fa75b7c 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -635,6 +635,10 @@ err_free: for (i = 0; i < private->data->mmsys_dev_num; i++) private->all_drm_private[i]->drm = NULL; err_put_dev: + for (i = 0; i < private->data->mmsys_dev_num; i++) { + /* For device_find_child in mtk_drm_get_all_priv() */ + put_device(private->all_drm_private[i]->dev); + } put_device(private->mutex_dev); return ret; } @@ -642,6 +646,7 @@ err_put_dev: static void mtk_drm_unbind(struct device *dev) { struct mtk_drm_private *private = dev_get_drvdata(dev); + int i; /* for multi mmsys dev, unregister drm dev in mmsys master */ if (private->drm_master) { @@ -649,6 +654,10 @@ static void mtk_drm_unbind(struct device *dev) mtk_drm_kms_deinit(private->drm); drm_dev_put(private->drm); + for (i = 0; i < private->data->mmsys_dev_num; i++) { + /* For device_find_child in mtk_drm_get_all_priv() */ + put_device(private->all_drm_private[i]->dev); + } put_device(private->mutex_dev); } private->mtk_drm_bound = false; From 7810600b06cb44976394c20233cb89450cc68669 Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Thu, 3 Apr 2025 12:47:39 +0200 Subject: [PATCH 125/971] drm/mediatek: mtk_drm_drv: Unbind secondary mmsys components on err [ Upstream commit 94c933716567084bfb9e79dcd81eb2b2308e84e1 ] When calling component_bind_all(), if a component that is included in the list fails, all of those that have been successfully bound will be unbound, but this driver has two components lists for two actual devices, as in, each mmsys instance has its own components list. In case mmsys0 (or actually vdosys0) is able to bind all of its components, but the secondary one fails, all of the components of the first are kept bound, while the ones of mmsys1/vdosys1 are correctly cleaned up. This is not right because, in case of a failure, the components are re-bound for all of the mmsys/vdosys instances without caring about the ones that were previously left in a bound state. Fix that by calling component_unbind_all() on all of the previous component masters that succeeded binding all subdevices when any of the other masters errors out. Fixes: 1ef7ed48356c ("drm/mediatek: Modify mediatek-drm for mt8195 multi mmsys support") Reviewed-by: Chen-Yu Tsai Signed-off-by: AngeloGioacchino Del Regno Link: https://patchwork.kernel.org/project/dri-devel/patch/20250403104741.71045-4-angelogioacchino.delregno@collabora.com/ Signed-off-by: Chun-Kuang Hu Signed-off-by: Sasha Levin --- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 32d66fa75b7c..ef4fa70119de 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -449,8 +449,11 @@ static int mtk_drm_kms_init(struct drm_device *drm) for (i = 0; i < private->data->mmsys_dev_num; i++) { drm->dev_private = private->all_drm_private[i]; ret = component_bind_all(private->all_drm_private[i]->dev, drm); - if (ret) + if (ret) { + while (--i >= 0) + component_unbind_all(private->all_drm_private[i]->dev, drm); return ret; + } } /* From 3d6e3849b691b78b851180f6384e9fe530f49520 Mon Sep 17 00:00:00 2001 From: Roger Pau Monne Date: Wed, 14 May 2025 10:04:26 +0200 Subject: [PATCH 126/971] xen/x86: fix initial memory balloon target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 74287971dbb3fe322bb316afd9e7fb5807e23bee ] When adding extra memory regions as ballooned pages also adjust the balloon target, otherwise when the balloon driver is started it will populate memory to match the target value and consume all the extra memory regions added. This made the usage of the Xen `dom0_mem=,max:` command line parameter for dom0 not work as expected, as the target won't be adjusted and when the balloon is started it will populate memory straight to the 'max:' value. It would equally affect domUs that have memory != maxmem. Kernels built with CONFIG_XEN_UNPOPULATED_ALLOC are not affected, because the extra memory regions are consumed by the unpopulated allocation driver, and then balloon_add_regions() becomes a no-op. Reported-by: John Fixes: 87af633689ce ('x86/xen: fix balloon target initialization for PVH dom0') Signed-off-by: Roger Pau Monné Reviewed-by: Juergen Gross Tested-by: Marek Marczykowski-Górecki Message-ID: <20250514080427.28129-1-roger.pau@citrix.com> Signed-off-by: Juergen Gross Signed-off-by: Sasha Levin --- drivers/xen/balloon.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index b0b52fa8fba6..204ec1bcbd52 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -696,15 +696,18 @@ static int __init balloon_add_regions(void) /* * Extra regions are accounted for in the physmap, but need - * decreasing from current_pages to balloon down the initial - * allocation, because they are already accounted for in - * total_pages. + * decreasing from current_pages and target_pages to balloon + * down the initial allocation, because they are already + * accounted for in total_pages. */ - if (extra_pfn_end - start_pfn >= balloon_stats.current_pages) { + pages = extra_pfn_end - start_pfn; + if (pages >= balloon_stats.current_pages || + pages >= balloon_stats.target_pages) { WARN(1, "Extra pages underflow current target"); return -ERANGE; } - balloon_stats.current_pages -= extra_pfn_end - start_pfn; + balloon_stats.current_pages -= pages; + balloon_stats.target_pages -= pages; } return 0; From f50ba7e7b607f2d00618799312e7fdb76a1ff48e Mon Sep 17 00:00:00 2001 From: Stone Zhang Date: Thu, 20 Mar 2025 13:31:45 +0800 Subject: [PATCH 127/971] wifi: ath11k: fix node corruption in ar->arvifs list [ Upstream commit 31e98e277ae47f56632e4d663b1d4fd12ba33ea8 ] In current WLAN recovery code flow, ath11k_core_halt() only reinitializes the "arvifs" list head. This will cause the list node immediately following the list head to become an invalid list node. Because the prev of that node still points to the list head "arvifs", but the next of the list head "arvifs" no longer points to that list node. When a WLAN recovery occurs during the execution of a vif removal, and it happens before the spin_lock_bh(&ar->data_lock) in ath11k_mac_op_remove_interface(), list_del() will detect the previously mentioned situation, thereby triggering a kernel panic. The fix is to remove and reinitialize all vif list nodes from the list head "arvifs" during WLAN halt. The reinitialization is to make the list nodes valid, ensuring that the list_del() in ath11k_mac_op_remove_interface() can execute normally. Call trace: __list_del_entry_valid_or_report+0xb8/0xd0 ath11k_mac_op_remove_interface+0xb0/0x27c [ath11k] drv_remove_interface+0x48/0x194 [mac80211] ieee80211_do_stop+0x6e0/0x844 [mac80211] ieee80211_stop+0x44/0x17c [mac80211] __dev_close_many+0xac/0x150 __dev_change_flags+0x194/0x234 dev_change_flags+0x24/0x6c devinet_ioctl+0x3a0/0x670 inet_ioctl+0x200/0x248 sock_do_ioctl+0x60/0x118 sock_ioctl+0x274/0x35c __arm64_sys_ioctl+0xac/0xf0 invoke_syscall+0x48/0x114 ... Tested-on: QCA6698AQ hw2.1 PCI WLAN.HSP.1.1-04591-QCAHSPSWPL_V1_V2_SILICONZ_IOE-1 Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") Signed-off-by: Stone Zhang Link: https://patch.msgid.link/20250320053145.3445187-1-quic_stonez@quicinc.com Signed-off-by: Jeff Johnson Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath11k/core.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index fc7c4564a715..f9870ba651d8 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -1742,6 +1742,7 @@ err_hal_srng_deinit: void ath11k_core_halt(struct ath11k *ar) { struct ath11k_base *ab = ar->ab; + struct list_head *pos, *n; lockdep_assert_held(&ar->conf_mutex); @@ -1756,7 +1757,12 @@ void ath11k_core_halt(struct ath11k *ar) rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL); synchronize_rcu(); - INIT_LIST_HEAD(&ar->arvifs); + + spin_lock_bh(&ar->data_lock); + list_for_each_safe(pos, n, &ar->arvifs) + list_del_init(pos); + spin_unlock_bh(&ar->data_lock); + idr_init(&ar->txmgmt_idr); } From b524baecb01b41b8460d0202307d5b10fc617d9a Mon Sep 17 00:00:00 2001 From: Jacob Moroni Date: Thu, 20 Feb 2025 17:56:12 +0000 Subject: [PATCH 128/971] IB/cm: use rwlock for MAD agent lock [ Upstream commit 4dab26bed543584577b64b36aadb8b5b165bf44f ] In workloads where there are many processes establishing connections using RDMA CM in parallel (large scale MPI), there can be heavy contention for mad_agent_lock in cm_alloc_msg. This contention can occur while inside of a spin_lock_irq region, leading to interrupts being disabled for extended durations on many cores. Furthermore, it leads to the serialization of rdma_create_ah calls, which has negative performance impacts for NICs which are capable of processing multiple address handle creations in parallel. The end result is the machine becoming unresponsive, hung task warnings, netdev TX timeouts, etc. Since the lock appears to be only for protection from cm_remove_one, it can be changed to a rwlock to resolve these issues. Reproducer: Server: for i in $(seq 1 512); do ucmatose -c 32 -p $((i + 5000)) & done Client: for i in $(seq 1 512); do ucmatose -c 32 -p $((i + 5000)) -s 10.2.0.52 & done Fixes: 76039ac9095f ("IB/cm: Protect cm_dev, cm_ports and mad_agent with kref and lock") Link: https://patch.msgid.link/r/20250220175612.2763122-1-jmoroni@google.com Signed-off-by: Jacob Moroni Acked-by: Eric Dumazet Reviewed-by: Zhu Yanjun Reviewed-by: Jason Gunthorpe Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin --- drivers/infiniband/core/cm.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 07fb8d3c037f..d45e3909dafe 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -166,7 +166,7 @@ struct cm_port { struct cm_device { struct kref kref; struct list_head list; - spinlock_t mad_agent_lock; + rwlock_t mad_agent_lock; struct ib_device *ib_device; u8 ack_delay; int going_down; @@ -284,7 +284,7 @@ static struct ib_mad_send_buf *cm_alloc_msg(struct cm_id_private *cm_id_priv) if (!cm_id_priv->av.port) return ERR_PTR(-EINVAL); - spin_lock(&cm_id_priv->av.port->cm_dev->mad_agent_lock); + read_lock(&cm_id_priv->av.port->cm_dev->mad_agent_lock); mad_agent = cm_id_priv->av.port->mad_agent; if (!mad_agent) { m = ERR_PTR(-EINVAL); @@ -315,7 +315,7 @@ static struct ib_mad_send_buf *cm_alloc_msg(struct cm_id_private *cm_id_priv) m->context[0] = cm_id_priv; out: - spin_unlock(&cm_id_priv->av.port->cm_dev->mad_agent_lock); + read_unlock(&cm_id_priv->av.port->cm_dev->mad_agent_lock); return m; } @@ -1294,10 +1294,10 @@ static __be64 cm_form_tid(struct cm_id_private *cm_id_priv) if (!cm_id_priv->av.port) return cpu_to_be64(low_tid); - spin_lock(&cm_id_priv->av.port->cm_dev->mad_agent_lock); + read_lock(&cm_id_priv->av.port->cm_dev->mad_agent_lock); if (cm_id_priv->av.port->mad_agent) hi_tid = ((u64)cm_id_priv->av.port->mad_agent->hi_tid) << 32; - spin_unlock(&cm_id_priv->av.port->cm_dev->mad_agent_lock); + read_unlock(&cm_id_priv->av.port->cm_dev->mad_agent_lock); return cpu_to_be64(hi_tid | low_tid); } @@ -4374,7 +4374,7 @@ static int cm_add_one(struct ib_device *ib_device) return -ENOMEM; kref_init(&cm_dev->kref); - spin_lock_init(&cm_dev->mad_agent_lock); + rwlock_init(&cm_dev->mad_agent_lock); cm_dev->ib_device = ib_device; cm_dev->ack_delay = ib_device->attrs.local_ca_ack_delay; cm_dev->going_down = 0; @@ -4490,9 +4490,9 @@ static void cm_remove_one(struct ib_device *ib_device, void *client_data) * The above ensures no call paths from the work are running, * the remaining paths all take the mad_agent_lock. */ - spin_lock(&cm_dev->mad_agent_lock); + write_lock(&cm_dev->mad_agent_lock); port->mad_agent = NULL; - spin_unlock(&cm_dev->mad_agent_lock); + write_unlock(&cm_dev->mad_agent_lock); ib_unregister_mad_agent(mad_agent); ib_port_unregister_client_groups(ib_device, i, cm_counter_groups); From 7c969106a8bae90e7a59d8ee922cedd81458821c Mon Sep 17 00:00:00 2001 From: Saket Kumar Bhaskar Date: Wed, 9 Apr 2025 15:26:33 +0530 Subject: [PATCH 129/971] selftests/bpf: Fix bpf_nf selftest failure [ Upstream commit 967e8def1100cb4b08c28a54d27ce69563fdf281 ] For systems with missing iptables-legacy tool this selftest fails. Add check to find if iptables-legacy tool is available and skip the test if the tool is missing. Fixes: de9c8d848d90 ("selftests/bpf: S/iptables/iptables-legacy/ in the bpf_nf and xdp_synproxy test") Signed-off-by: Saket Kumar Bhaskar Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20250409095633.33653-1-skb99@linux.ibm.com Signed-off-by: Sasha Levin --- tools/testing/selftests/bpf/prog_tests/bpf_nf.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_nf.c b/tools/testing/selftests/bpf/prog_tests/bpf_nf.c index b30ff6b3b81a..f80660c00a1a 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_nf.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_nf.c @@ -63,6 +63,12 @@ static void test_bpf_nf_ct(int mode) .repeat = 1, ); + if (SYS_NOFAIL("iptables-legacy --version")) { + fprintf(stdout, "Missing required iptables-legacy tool\n"); + test__skip(); + return; + } + skel = test_bpf_nf__open_and_load(); if (!ASSERT_OK_PTR(skel, "test_bpf_nf__open_and_load")) return; From 2e36a81d388ec9c3f78b6223f7eda2088cd40adb Mon Sep 17 00:00:00 2001 From: Jiayuan Chen Date: Wed, 19 Feb 2025 13:20:14 +0800 Subject: [PATCH 130/971] bpf: fix ktls panic with sockmap [ Upstream commit 54a3ecaeeeae8176da8badbd7d72af1017032c39 ] [ 2172.936997] ------------[ cut here ]------------ [ 2172.936999] kernel BUG at lib/iov_iter.c:629! ...... [ 2172.944996] PKRU: 55555554 [ 2172.945155] Call Trace: [ 2172.945299] [ 2172.945428] ? die+0x36/0x90 [ 2172.945601] ? do_trap+0xdd/0x100 [ 2172.945795] ? iov_iter_revert+0x178/0x180 [ 2172.946031] ? iov_iter_revert+0x178/0x180 [ 2172.946267] ? do_error_trap+0x7d/0x110 [ 2172.946499] ? iov_iter_revert+0x178/0x180 [ 2172.946736] ? exc_invalid_op+0x50/0x70 [ 2172.946961] ? iov_iter_revert+0x178/0x180 [ 2172.947197] ? asm_exc_invalid_op+0x1a/0x20 [ 2172.947446] ? iov_iter_revert+0x178/0x180 [ 2172.947683] ? iov_iter_revert+0x5c/0x180 [ 2172.947913] tls_sw_sendmsg_locked.isra.0+0x794/0x840 [ 2172.948206] tls_sw_sendmsg+0x52/0x80 [ 2172.948420] ? inet_sendmsg+0x1f/0x70 [ 2172.948634] __sys_sendto+0x1cd/0x200 [ 2172.948848] ? find_held_lock+0x2b/0x80 [ 2172.949072] ? syscall_trace_enter+0x140/0x270 [ 2172.949330] ? __lock_release.isra.0+0x5e/0x170 [ 2172.949595] ? find_held_lock+0x2b/0x80 [ 2172.949817] ? syscall_trace_enter+0x140/0x270 [ 2172.950211] ? lockdep_hardirqs_on_prepare+0xda/0x190 [ 2172.950632] ? ktime_get_coarse_real_ts64+0xc2/0xd0 [ 2172.951036] __x64_sys_sendto+0x24/0x30 [ 2172.951382] do_syscall_64+0x90/0x170 ...... After calling bpf_exec_tx_verdict(), the size of msg_pl->sg may increase, e.g., when the BPF program executes bpf_msg_push_data(). If the BPF program sets cork_bytes and sg.size is smaller than cork_bytes, it will return -ENOSPC and attempt to roll back to the non-zero copy logic. However, during rollback, msg->msg_iter is reset, but since msg_pl->sg.size has been increased, subsequent executions will exceed the actual size of msg_iter. ''' iov_iter_revert(&msg->msg_iter, msg_pl->sg.size - orig_size); ''' The changes in this commit are based on the following considerations: 1. When cork_bytes is set, rolling back to non-zero copy logic is pointless and can directly go to zero-copy logic. 2. We can not calculate the correct number of bytes to revert msg_iter. Assume the original data is "abcdefgh" (8 bytes), and after 3 pushes by the BPF program, it becomes 11-byte data: "abc?de?fgh?". Then, we set cork_bytes to 6, which means the first 6 bytes have been processed, and the remaining 5 bytes "?fgh?" will be cached until the length meets the cork_bytes requirement. However, some data in "?fgh?" is not within 'sg->msg_iter' (but in msg_pl instead), especially the data "?" we pushed. So it doesn't seem as simple as just reverting through an offset of msg_iter. 3. For non-TLS sockets in tcp_bpf_sendmsg, when a "cork" situation occurs, the user-space send() doesn't return an error, and the returned length is the same as the input length parameter, even if some data is cached. Additionally, I saw that the current non-zero-copy logic for handling corking is written as: ''' line 1177 else if (ret != -EAGAIN) { if (ret == -ENOSPC) ret = 0; goto send_end; ''' So it's ok to just return 'copied' without error when a "cork" situation occurs. Fixes: fcb14cb1bdac ("new iov_iter flavour - ITER_UBUF") Fixes: d3b18ad31f93 ("tls: add bpf support to sk_msg handling") Signed-off-by: Jiayuan Chen Acked-by: John Fastabend Link: https://lore.kernel.org/r/20250219052015.274405-2-jiayuan.chen@linux.dev Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin --- net/tls/tls_sw.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index 6e30fe879d53..bf445a518883 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -1120,9 +1120,13 @@ alloc_encrypted: num_async++; else if (ret == -ENOMEM) goto wait_for_memory; - else if (ctx->open_rec && ret == -ENOSPC) + else if (ctx->open_rec && ret == -ENOSPC) { + if (msg_pl->cork_bytes) { + ret = 0; + goto send_end; + } goto rollback_iter; - else if (ret != -EAGAIN) + } else if (ret != -EAGAIN) goto send_end; } continue; From 34837ae8cdedebabf2dd8cbcf426738590d43c4b Mon Sep 17 00:00:00 2001 From: Jiayuan Chen Date: Mon, 7 Apr 2025 22:21:21 +0800 Subject: [PATCH 131/971] bpf, sockmap: fix duplicated data transmission [ Upstream commit 3b4f14b794287be137ea2c6158765d1ea1e018a4 ] In the !ingress path under sk_psock_handle_skb(), when sending data to the remote under snd_buf limitations, partial skb data might be transmitted. Although we preserved the partial transmission state (offset/length), the state wasn't properly consumed during retries. This caused the retry path to resend the entire skb data instead of continuing from the previous offset, resulting in data overlap at the receiver side. Fixes: 405df89dd52c ("bpf, sockmap: Improved check for empty queue") Signed-off-by: Jiayuan Chen Link: https://lore.kernel.org/r/20250407142234.47591-3-jiayuan.chen@linux.dev Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin --- net/core/skmsg.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/net/core/skmsg.c b/net/core/skmsg.c index b9b941c487c8..c284c8a3d679 100644 --- a/net/core/skmsg.c +++ b/net/core/skmsg.c @@ -655,11 +655,6 @@ static void sk_psock_backlog(struct work_struct *work) int ret; mutex_lock(&psock->work_mutex); - if (unlikely(state->len)) { - len = state->len; - off = state->off; - } - while ((skb = skb_peek(&psock->ingress_skb))) { len = skb->len; off = 0; @@ -669,6 +664,13 @@ static void sk_psock_backlog(struct work_struct *work) off = stm->offset; len = stm->full_len; } + + /* Resume processing from previous partial state */ + if (unlikely(state->len)) { + len = state->len; + off = state->off; + } + ingress = skb_bpf_ingress(skb); skb_bpf_redirect_clear(skb); do { @@ -696,6 +698,8 @@ static void sk_psock_backlog(struct work_struct *work) len -= ret; } while (len); + /* The entire skb sent, clear state */ + sk_psock_skb_state(psock, state, 0, 0); skb = skb_dequeue(&psock->ingress_skb); kfree_skb(skb); } From db1d15a26f21f97459508c42ae87cabe8d3afc3b Mon Sep 17 00:00:00 2001 From: Jiayuan Chen Date: Mon, 7 Apr 2025 22:21:22 +0800 Subject: [PATCH 132/971] bpf, sockmap: Fix panic when calling skb_linearize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 5ca2e29f6834c64c0e5a9ccf1278c21fb49b827e ] The panic can be reproduced by executing the command: ./bench sockmap -c 2 -p 1 -a --rx-verdict-ingress --rx-strp 100000 Then a kernel panic was captured: ''' [ 657.460555] kernel BUG at net/core/skbuff.c:2178! [ 657.462680] Tainted: [W]=WARN [ 657.463287] Workqueue: events sk_psock_backlog ... [ 657.469610] [ 657.469738] ? die+0x36/0x90 [ 657.469916] ? do_trap+0x1d0/0x270 [ 657.470118] ? pskb_expand_head+0x612/0xf40 [ 657.470376] ? pskb_expand_head+0x612/0xf40 [ 657.470620] ? do_error_trap+0xa3/0x170 [ 657.470846] ? pskb_expand_head+0x612/0xf40 [ 657.471092] ? handle_invalid_op+0x2c/0x40 [ 657.471335] ? pskb_expand_head+0x612/0xf40 [ 657.471579] ? exc_invalid_op+0x2d/0x40 [ 657.471805] ? asm_exc_invalid_op+0x1a/0x20 [ 657.472052] ? pskb_expand_head+0xd1/0xf40 [ 657.472292] ? pskb_expand_head+0x612/0xf40 [ 657.472540] ? lock_acquire+0x18f/0x4e0 [ 657.472766] ? find_held_lock+0x2d/0x110 [ 657.472999] ? __pfx_pskb_expand_head+0x10/0x10 [ 657.473263] ? __kmalloc_cache_noprof+0x5b/0x470 [ 657.473537] ? __pfx___lock_release.isra.0+0x10/0x10 [ 657.473826] __pskb_pull_tail+0xfd/0x1d20 [ 657.474062] ? __kasan_slab_alloc+0x4e/0x90 [ 657.474707] sk_psock_skb_ingress_enqueue+0x3bf/0x510 [ 657.475392] ? __kasan_kmalloc+0xaa/0xb0 [ 657.476010] sk_psock_backlog+0x5cf/0xd70 [ 657.476637] process_one_work+0x858/0x1a20 ''' The panic originates from the assertion BUG_ON(skb_shared(skb)) in skb_linearize(). A previous commit(see Fixes tag) introduced skb_get() to avoid race conditions between skb operations in the backlog and skb release in the recvmsg path. However, this caused the panic to always occur when skb_linearize is executed. The "--rx-strp 100000" parameter forces the RX path to use the strparser module which aggregates data until it reaches 100KB before calling sockmap logic. The 100KB payload exceeds MAX_MSG_FRAGS, triggering skb_linearize. To fix this issue, just move skb_get into sk_psock_skb_ingress_enqueue. ''' sk_psock_backlog: sk_psock_handle_skb skb_get(skb) <== we move it into 'sk_psock_skb_ingress_enqueue' sk_psock_skb_ingress____________ ↓ | | → sk_psock_skb_ingress_self | sk_psock_skb_ingress_enqueue sk_psock_verdict_apply_________________↑ skb_linearize ''' Note that for verdict_apply path, the skb_get operation is unnecessary so we add 'take_ref' param to control it's behavior. Fixes: a454d84ee20b ("bpf, sockmap: Fix skb refcnt race after locking changes") Signed-off-by: Jiayuan Chen Link: https://lore.kernel.org/r/20250407142234.47591-4-jiayuan.chen@linux.dev Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin --- net/core/skmsg.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/net/core/skmsg.c b/net/core/skmsg.c index c284c8a3d679..c7edf77fd6fd 100644 --- a/net/core/skmsg.c +++ b/net/core/skmsg.c @@ -529,16 +529,22 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb, u32 off, u32 len, struct sk_psock *psock, struct sock *sk, - struct sk_msg *msg) + struct sk_msg *msg, + bool take_ref) { int num_sge, copied; + /* skb_to_sgvec will fail when the total number of fragments in + * frag_list and frags exceeds MAX_MSG_FRAGS. For example, the + * caller may aggregate multiple skbs. + */ num_sge = skb_to_sgvec(skb, msg->sg.data, off, len); if (num_sge < 0) { /* skb linearize may fail with ENOMEM, but lets simply try again * later if this happens. Under memory pressure we don't want to * drop the skb. We need to linearize the skb so that the mapping * in skb_to_sgvec can not error. + * Note that skb_linearize requires the skb not to be shared. */ if (skb_linearize(skb)) return -EAGAIN; @@ -555,7 +561,7 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb, msg->sg.start = 0; msg->sg.size = copied; msg->sg.end = num_sge; - msg->skb = skb; + msg->skb = take_ref ? skb_get(skb) : skb; sk_psock_queue_msg(psock, msg); sk_psock_data_ready(sk, psock); @@ -563,7 +569,7 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb, } static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb, - u32 off, u32 len); + u32 off, u32 len, bool take_ref); static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb, u32 off, u32 len) @@ -577,7 +583,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb, * correctly. */ if (unlikely(skb->sk == sk)) - return sk_psock_skb_ingress_self(psock, skb, off, len); + return sk_psock_skb_ingress_self(psock, skb, off, len, true); msg = sk_psock_create_ingress_msg(sk, skb); if (!msg) return -EAGAIN; @@ -589,7 +595,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb, * into user buffers. */ skb_set_owner_r(skb, sk); - err = sk_psock_skb_ingress_enqueue(skb, off, len, psock, sk, msg); + err = sk_psock_skb_ingress_enqueue(skb, off, len, psock, sk, msg, true); if (err < 0) kfree(msg); return err; @@ -600,7 +606,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb, * because the skb is already accounted for here. */ static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb, - u32 off, u32 len) + u32 off, u32 len, bool take_ref) { struct sk_msg *msg = alloc_sk_msg(GFP_ATOMIC); struct sock *sk = psock->sk; @@ -609,7 +615,7 @@ static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb if (unlikely(!msg)) return -EAGAIN; skb_set_owner_r(skb, sk); - err = sk_psock_skb_ingress_enqueue(skb, off, len, psock, sk, msg); + err = sk_psock_skb_ingress_enqueue(skb, off, len, psock, sk, msg, take_ref); if (err < 0) kfree(msg); return err; @@ -618,18 +624,13 @@ static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb static int sk_psock_handle_skb(struct sk_psock *psock, struct sk_buff *skb, u32 off, u32 len, bool ingress) { - int err = 0; - if (!ingress) { if (!sock_writeable(psock->sk)) return -EAGAIN; return skb_send_sock(psock->sk, skb, off, len); } - skb_get(skb); - err = sk_psock_skb_ingress(psock, skb, off, len); - if (err < 0) - kfree_skb(skb); - return err; + + return sk_psock_skb_ingress(psock, skb, off, len); } static void sk_psock_skb_state(struct sk_psock *psock, @@ -1017,7 +1018,7 @@ static int sk_psock_verdict_apply(struct sk_psock *psock, struct sk_buff *skb, off = stm->offset; len = stm->full_len; } - err = sk_psock_skb_ingress_self(psock, skb, off, len); + err = sk_psock_skb_ingress_self(psock, skb, off, len, false); } if (err < 0) { spin_lock_bh(&psock->ingress_lock); From a93db61dfa92aab4a89a50bbfa637c5aaad5354b Mon Sep 17 00:00:00 2001 From: Ramya Gnanasekar Date: Wed, 9 Apr 2025 20:53:41 +0530 Subject: [PATCH 133/971] wifi: ath12k: Fix WMI tag for EHT rate in peer assoc [ Upstream commit 1a0e65750b55d2cf5de4a9bf7d6d55718784bdb7 ] Incorrect WMI tag is used for EHT rate update from host to firmware while encoding peer assoc WMI. Correct the WMI tag used for EHT rate update from WMI_TAG_HE_RATE_SET to the proper tag. This ensures firmware does not mistakenly update HE rate during parsing. Found during code review. Compile tested only. Fixes: 5b70ec6036c1 ("wifi: ath12k: add WMI support for EHT peer") Signed-off-by: Ramya Gnanasekar Link: https://patch.msgid.link/20250409152341.944628-1-ramya.gnanasekar@oss.qualcomm.com Signed-off-by: Jeff Johnson Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath12k/wmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index d87d5980325e..a96bf261a3f7 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -2066,7 +2066,7 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar, for (i = 0; i < arg->peer_eht_mcs_count; i++) { eht_mcs = ptr; - eht_mcs->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_HE_RATE_SET, + eht_mcs->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_EHT_RATE_SET, sizeof(*eht_mcs)); eht_mcs->rx_mcs_set = cpu_to_le32(arg->peer_eht_rx_mcs_set[i]); From a39cc43efc1bca74ed9d6cf9e60b995071f7d178 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 8 Apr 2025 20:22:08 +0800 Subject: [PATCH 134/971] f2fs: fix to do sanity check on sbi->total_valid_block_count [ Upstream commit 05872a167c2cab80ef186ef23cc34a6776a1a30c ] syzbot reported a f2fs bug as below: ------------[ cut here ]------------ kernel BUG at fs/f2fs/f2fs.h:2521! RIP: 0010:dec_valid_block_count+0x3b2/0x3c0 fs/f2fs/f2fs.h:2521 Call Trace: f2fs_truncate_data_blocks_range+0xc8c/0x11a0 fs/f2fs/file.c:695 truncate_dnode+0x417/0x740 fs/f2fs/node.c:973 truncate_nodes+0x3ec/0xf50 fs/f2fs/node.c:1014 f2fs_truncate_inode_blocks+0x8e3/0x1370 fs/f2fs/node.c:1197 f2fs_do_truncate_blocks+0x840/0x12b0 fs/f2fs/file.c:810 f2fs_truncate_blocks+0x10d/0x300 fs/f2fs/file.c:838 f2fs_truncate+0x417/0x720 fs/f2fs/file.c:888 f2fs_setattr+0xc4f/0x12f0 fs/f2fs/file.c:1112 notify_change+0xbca/0xe90 fs/attr.c:552 do_truncate+0x222/0x310 fs/open.c:65 handle_truncate fs/namei.c:3466 [inline] do_open fs/namei.c:3849 [inline] path_openat+0x2e4f/0x35d0 fs/namei.c:4004 do_filp_open+0x284/0x4e0 fs/namei.c:4031 do_sys_openat2+0x12b/0x1d0 fs/open.c:1429 do_sys_open fs/open.c:1444 [inline] __do_sys_creat fs/open.c:1522 [inline] __se_sys_creat fs/open.c:1516 [inline] __x64_sys_creat+0x124/0x170 fs/open.c:1516 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/syscall_64.c:94 The reason is: in fuzzed image, sbi->total_valid_block_count is inconsistent w/ mapped blocks indexed by inode, so, we should not trigger panic for such case, instead, let's print log and set fsck flag. Fixes: 39a53e0ce0df ("f2fs: add superblock and major in-memory structure") Reported-by: syzbot+8b376a77b2f364097fbe@syzkaller.appspotmail.com Closes: https://lore.kernel.org/linux-f2fs-devel/67f3c0b2.050a0220.396535.0547.GAE@google.com Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- fs/f2fs/f2fs.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 5f6f159be456..911c4c64d729 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -2474,8 +2474,14 @@ static inline void dec_valid_block_count(struct f2fs_sb_info *sbi, blkcnt_t sectors = count << F2FS_LOG_SECTORS_PER_BLOCK; spin_lock(&sbi->stat_lock); - f2fs_bug_on(sbi, sbi->total_valid_block_count < (block_t) count); - sbi->total_valid_block_count -= (block_t)count; + if (unlikely(sbi->total_valid_block_count < count)) { + f2fs_warn(sbi, "Inconsistent total_valid_block_count:%u, ino:%lu, count:%u", + sbi->total_valid_block_count, inode->i_ino, count); + sbi->total_valid_block_count = 0; + set_sbi_flag(sbi, SBI_NEED_FSCK); + } else { + sbi->total_valid_block_count -= count; + } if (sbi->reserved_blocks && sbi->current_reserved_blocks < sbi->reserved_blocks) sbi->current_reserved_blocks = min(sbi->reserved_blocks, From 0e9c13ed852edfb0969f20a752bf87c2ee42d27e Mon Sep 17 00:00:00 2001 From: Hari Kalavakunta Date: Wed, 9 Apr 2025 18:23:08 -0700 Subject: [PATCH 135/971] net: ncsi: Fix GCPS 64-bit member variables [ Upstream commit e8a1bd8344054ce27bebf59f48e3f6bc10bc419b ] Correct Get Controller Packet Statistics (GCPS) 64-bit wide member variables, as per DSP0222 v1.0.0 and forward specs. The Driver currently collects these stats, but they are yet to be exposed to the user. Therefore, no user impact. Statistics fixes: Total Bytes Received (byte range 28..35) Total Bytes Transmitted (byte range 36..43) Total Unicast Packets Received (byte range 44..51) Total Multicast Packets Received (byte range 52..59) Total Broadcast Packets Received (byte range 60..67) Total Unicast Packets Transmitted (byte range 68..75) Total Multicast Packets Transmitted (byte range 76..83) Total Broadcast Packets Transmitted (byte range 84..91) Valid Bytes Received (byte range 204..11) Signed-off-by: Hari Kalavakunta Reviewed-by: Paul Fertser Link: https://patch.msgid.link/20250410012309.1343-1-kalavakunta.hari.prasad@gmail.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- net/ncsi/internal.h | 21 ++++++++++----------- net/ncsi/ncsi-pkt.h | 23 +++++++++++------------ net/ncsi/ncsi-rsp.c | 21 ++++++++++----------- 3 files changed, 31 insertions(+), 34 deletions(-) diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h index 4e0842df5234..2c260f33b55c 100644 --- a/net/ncsi/internal.h +++ b/net/ncsi/internal.h @@ -143,16 +143,15 @@ struct ncsi_channel_vlan_filter { }; struct ncsi_channel_stats { - u32 hnc_cnt_hi; /* Counter cleared */ - u32 hnc_cnt_lo; /* Counter cleared */ - u32 hnc_rx_bytes; /* Rx bytes */ - u32 hnc_tx_bytes; /* Tx bytes */ - u32 hnc_rx_uc_pkts; /* Rx UC packets */ - u32 hnc_rx_mc_pkts; /* Rx MC packets */ - u32 hnc_rx_bc_pkts; /* Rx BC packets */ - u32 hnc_tx_uc_pkts; /* Tx UC packets */ - u32 hnc_tx_mc_pkts; /* Tx MC packets */ - u32 hnc_tx_bc_pkts; /* Tx BC packets */ + u64 hnc_cnt; /* Counter cleared */ + u64 hnc_rx_bytes; /* Rx bytes */ + u64 hnc_tx_bytes; /* Tx bytes */ + u64 hnc_rx_uc_pkts; /* Rx UC packets */ + u64 hnc_rx_mc_pkts; /* Rx MC packets */ + u64 hnc_rx_bc_pkts; /* Rx BC packets */ + u64 hnc_tx_uc_pkts; /* Tx UC packets */ + u64 hnc_tx_mc_pkts; /* Tx MC packets */ + u64 hnc_tx_bc_pkts; /* Tx BC packets */ u32 hnc_fcs_err; /* FCS errors */ u32 hnc_align_err; /* Alignment errors */ u32 hnc_false_carrier; /* False carrier detection */ @@ -181,7 +180,7 @@ struct ncsi_channel_stats { u32 hnc_tx_1023_frames; /* Tx 512-1023 bytes frames */ u32 hnc_tx_1522_frames; /* Tx 1024-1522 bytes frames */ u32 hnc_tx_9022_frames; /* Tx 1523-9022 bytes frames */ - u32 hnc_rx_valid_bytes; /* Rx valid bytes */ + u64 hnc_rx_valid_bytes; /* Rx valid bytes */ u32 hnc_rx_runt_pkts; /* Rx error runt packets */ u32 hnc_rx_jabber_pkts; /* Rx error jabber packets */ u32 ncsi_rx_cmds; /* Rx NCSI commands */ diff --git a/net/ncsi/ncsi-pkt.h b/net/ncsi/ncsi-pkt.h index f2f3b5c1b941..24edb2737972 100644 --- a/net/ncsi/ncsi-pkt.h +++ b/net/ncsi/ncsi-pkt.h @@ -252,16 +252,15 @@ struct ncsi_rsp_gp_pkt { /* Get Controller Packet Statistics */ struct ncsi_rsp_gcps_pkt { struct ncsi_rsp_pkt_hdr rsp; /* Response header */ - __be32 cnt_hi; /* Counter cleared */ - __be32 cnt_lo; /* Counter cleared */ - __be32 rx_bytes; /* Rx bytes */ - __be32 tx_bytes; /* Tx bytes */ - __be32 rx_uc_pkts; /* Rx UC packets */ - __be32 rx_mc_pkts; /* Rx MC packets */ - __be32 rx_bc_pkts; /* Rx BC packets */ - __be32 tx_uc_pkts; /* Tx UC packets */ - __be32 tx_mc_pkts; /* Tx MC packets */ - __be32 tx_bc_pkts; /* Tx BC packets */ + __be64 cnt; /* Counter cleared */ + __be64 rx_bytes; /* Rx bytes */ + __be64 tx_bytes; /* Tx bytes */ + __be64 rx_uc_pkts; /* Rx UC packets */ + __be64 rx_mc_pkts; /* Rx MC packets */ + __be64 rx_bc_pkts; /* Rx BC packets */ + __be64 tx_uc_pkts; /* Tx UC packets */ + __be64 tx_mc_pkts; /* Tx MC packets */ + __be64 tx_bc_pkts; /* Tx BC packets */ __be32 fcs_err; /* FCS errors */ __be32 align_err; /* Alignment errors */ __be32 false_carrier; /* False carrier detection */ @@ -290,11 +289,11 @@ struct ncsi_rsp_gcps_pkt { __be32 tx_1023_frames; /* Tx 512-1023 bytes frames */ __be32 tx_1522_frames; /* Tx 1024-1522 bytes frames */ __be32 tx_9022_frames; /* Tx 1523-9022 bytes frames */ - __be32 rx_valid_bytes; /* Rx valid bytes */ + __be64 rx_valid_bytes; /* Rx valid bytes */ __be32 rx_runt_pkts; /* Rx error runt packets */ __be32 rx_jabber_pkts; /* Rx error jabber packets */ __be32 checksum; /* Checksum */ -}; +} __packed __aligned(4); /* Get NCSI Statistics */ struct ncsi_rsp_gns_pkt { diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c index 4a8ce2949fae..8668888c5a2f 100644 --- a/net/ncsi/ncsi-rsp.c +++ b/net/ncsi/ncsi-rsp.c @@ -926,16 +926,15 @@ static int ncsi_rsp_handler_gcps(struct ncsi_request *nr) /* Update HNC's statistics */ ncs = &nc->stats; - ncs->hnc_cnt_hi = ntohl(rsp->cnt_hi); - ncs->hnc_cnt_lo = ntohl(rsp->cnt_lo); - ncs->hnc_rx_bytes = ntohl(rsp->rx_bytes); - ncs->hnc_tx_bytes = ntohl(rsp->tx_bytes); - ncs->hnc_rx_uc_pkts = ntohl(rsp->rx_uc_pkts); - ncs->hnc_rx_mc_pkts = ntohl(rsp->rx_mc_pkts); - ncs->hnc_rx_bc_pkts = ntohl(rsp->rx_bc_pkts); - ncs->hnc_tx_uc_pkts = ntohl(rsp->tx_uc_pkts); - ncs->hnc_tx_mc_pkts = ntohl(rsp->tx_mc_pkts); - ncs->hnc_tx_bc_pkts = ntohl(rsp->tx_bc_pkts); + ncs->hnc_cnt = be64_to_cpu(rsp->cnt); + ncs->hnc_rx_bytes = be64_to_cpu(rsp->rx_bytes); + ncs->hnc_tx_bytes = be64_to_cpu(rsp->tx_bytes); + ncs->hnc_rx_uc_pkts = be64_to_cpu(rsp->rx_uc_pkts); + ncs->hnc_rx_mc_pkts = be64_to_cpu(rsp->rx_mc_pkts); + ncs->hnc_rx_bc_pkts = be64_to_cpu(rsp->rx_bc_pkts); + ncs->hnc_tx_uc_pkts = be64_to_cpu(rsp->tx_uc_pkts); + ncs->hnc_tx_mc_pkts = be64_to_cpu(rsp->tx_mc_pkts); + ncs->hnc_tx_bc_pkts = be64_to_cpu(rsp->tx_bc_pkts); ncs->hnc_fcs_err = ntohl(rsp->fcs_err); ncs->hnc_align_err = ntohl(rsp->align_err); ncs->hnc_false_carrier = ntohl(rsp->false_carrier); @@ -964,7 +963,7 @@ static int ncsi_rsp_handler_gcps(struct ncsi_request *nr) ncs->hnc_tx_1023_frames = ntohl(rsp->tx_1023_frames); ncs->hnc_tx_1522_frames = ntohl(rsp->tx_1522_frames); ncs->hnc_tx_9022_frames = ntohl(rsp->tx_9022_frames); - ncs->hnc_rx_valid_bytes = ntohl(rsp->rx_valid_bytes); + ncs->hnc_rx_valid_bytes = be64_to_cpu(rsp->rx_valid_bytes); ncs->hnc_rx_runt_pkts = ntohl(rsp->rx_runt_pkts); ncs->hnc_rx_jabber_pkts = ntohl(rsp->rx_jabber_pkts); From 18eb7b5f1e51fd2e03d1866a78c209b585f40254 Mon Sep 17 00:00:00 2001 From: Viktor Malik Date: Tue, 15 Apr 2025 17:50:14 +0200 Subject: [PATCH 136/971] libbpf: Fix buffer overflow in bpf_object__init_prog [ Upstream commit ee684de5c1b0ac01821320826baec7da93f3615b ] As shown in [1], it is possible to corrupt a BPF ELF file such that arbitrary BPF instructions are loaded by libbpf. This can be done by setting a symbol (BPF program) section offset to a large (unsigned) number such that
overflows and points before the section data in the memory. Consider the situation below where: - prog_start = sec_start + symbol_offset <-- size_t overflow here - prog_end = prog_start + prog_size prog_start sec_start prog_end sec_end | | | | v v v v .....................|################################|............ The report in [1] also provides a corrupted BPF ELF which can be used as a reproducer: $ readelf -S crash Section Headers: [Nr] Name Type Address Offset Size EntSize Flags Link Info Align ... [ 2] uretprobe.mu[...] PROGBITS 0000000000000000 00000040 0000000000000068 0000000000000000 AX 0 0 8 $ readelf -s crash Symbol table '.symtab' contains 8 entries: Num: Value Size Type Bind Vis Ndx Name ... 6: ffffffffffffffb8 104 FUNC GLOBAL DEFAULT 2 handle_tp Here, the handle_tp prog has section offset ffffffffffffffb8, i.e. will point before the actual memory where section 2 is allocated. This is also reported by AddressSanitizer: ================================================================= ==1232==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7c7302fe0000 at pc 0x7fc3046e4b77 bp 0x7ffe64677cd0 sp 0x7ffe64677490 READ of size 104 at 0x7c7302fe0000 thread T0 #0 0x7fc3046e4b76 in memcpy (/lib64/libasan.so.8+0xe4b76) #1 0x00000040df3e in bpf_object__init_prog /src/libbpf/src/libbpf.c:856 #2 0x00000040df3e in bpf_object__add_programs /src/libbpf/src/libbpf.c:928 #3 0x00000040df3e in bpf_object__elf_collect /src/libbpf/src/libbpf.c:3930 #4 0x00000040df3e in bpf_object_open /src/libbpf/src/libbpf.c:8067 #5 0x00000040f176 in bpf_object__open_file /src/libbpf/src/libbpf.c:8090 #6 0x000000400c16 in main /poc/poc.c:8 #7 0x7fc3043d25b4 in __libc_start_call_main (/lib64/libc.so.6+0x35b4) #8 0x7fc3043d2667 in __libc_start_main@@GLIBC_2.34 (/lib64/libc.so.6+0x3667) #9 0x000000400b34 in _start (/poc/poc+0x400b34) 0x7c7302fe0000 is located 64 bytes before 104-byte region [0x7c7302fe0040,0x7c7302fe00a8) allocated by thread T0 here: #0 0x7fc3046e716b in malloc (/lib64/libasan.so.8+0xe716b) #1 0x7fc3045ee600 in __libelf_set_rawdata_wrlock (/lib64/libelf.so.1+0xb600) #2 0x7fc3045ef018 in __elf_getdata_rdlock (/lib64/libelf.so.1+0xc018) #3 0x00000040642f in elf_sec_data /src/libbpf/src/libbpf.c:3740 The problem here is that currently, libbpf only checks that the program end is within the section bounds. There used to be a check `while (sec_off < sec_sz)` in bpf_object__add_programs, however, it was removed by commit 6245947c1b3c ("libbpf: Allow gaps in BPF program sections to support overriden weak functions"). Add a check for detecting the overflow of `sec_off + prog_sz` to bpf_object__init_prog to fix this issue. [1] https://github.com/lmarch2/poc/blob/main/libbpf/libbpf.md Fixes: 6245947c1b3c ("libbpf: Allow gaps in BPF program sections to support overriden weak functions") Reported-by: lmarch2 <2524158037@qq.com> Signed-off-by: Viktor Malik Signed-off-by: Andrii Nakryiko Reviewed-by: Shung-Hsi Yu Link: https://github.com/lmarch2/poc/blob/main/libbpf/libbpf.md Link: https://lore.kernel.org/bpf/20250415155014.397603-1-vmalik@redhat.com Signed-off-by: Sasha Levin --- tools/lib/bpf/libbpf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index fa2abe56e845..ca764ed3aaa9 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -838,7 +838,7 @@ bpf_object__add_programs(struct bpf_object *obj, Elf_Data *sec_data, return -LIBBPF_ERRNO__FORMAT; } - if (sec_off + prog_sz > sec_sz) { + if (sec_off + prog_sz > sec_sz || sec_off + prog_sz < sec_off) { pr_warn("sec '%s': program at offset %zu crosses section boundary\n", sec_name, sec_off); return -LIBBPF_ERRNO__FORMAT; From 6aa81fc0d67ac4cc6d8baa2753aa90dfc4159a00 Mon Sep 17 00:00:00 2001 From: Cosmin Ratiu Date: Fri, 11 Apr 2025 10:49:54 +0300 Subject: [PATCH 137/971] xfrm: Use xdo.dev instead of xdo.real_dev [ Upstream commit 25ac138f58e7d5c8bffa31e8891418d2819180c4 ] The policy offload struct was reused from the state offload and real_dev was copied from dev, but it was never set to anything else. Simplify the code by always using xdo.dev for policies. Signed-off-by: Cosmin Ratiu Reviewed-by: Leon Romanovsky Reviewed-by: Nikolay Aleksandrov Signed-off-by: Steffen Klassert Signed-off-by: Sasha Levin --- drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c | 2 +- net/xfrm/xfrm_device.c | 2 -- net/xfrm/xfrm_state.c | 2 -- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c index 463c23ae0ad1..5161bf51fa11 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c @@ -1093,7 +1093,7 @@ mlx5e_ipsec_build_accel_pol_attrs(struct mlx5e_ipsec_pol_entry *pol_entry, static int mlx5e_xfrm_add_policy(struct xfrm_policy *x, struct netlink_ext_ack *extack) { - struct net_device *netdev = x->xdo.real_dev; + struct net_device *netdev = x->xdo.dev; struct mlx5e_ipsec_pol_entry *pol_entry; struct mlx5e_priv *priv; int err; diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c index 04dc0c8a8370..7188d3592dde 100644 --- a/net/xfrm/xfrm_device.c +++ b/net/xfrm/xfrm_device.c @@ -371,7 +371,6 @@ int xfrm_dev_policy_add(struct net *net, struct xfrm_policy *xp, xdo->dev = dev; netdev_tracker_alloc(dev, &xdo->dev_tracker, GFP_ATOMIC); - xdo->real_dev = dev; xdo->type = XFRM_DEV_OFFLOAD_PACKET; switch (dir) { case XFRM_POLICY_IN: @@ -393,7 +392,6 @@ int xfrm_dev_policy_add(struct net *net, struct xfrm_policy *xp, err = dev->xfrmdev_ops->xdo_dev_policy_add(xp, extack); if (err) { xdo->dev = NULL; - xdo->real_dev = NULL; xdo->type = XFRM_DEV_OFFLOAD_UNSPECIFIED; xdo->dir = 0; netdev_put(dev, &xdo->dev_tracker); diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 86029cf5358c..d2bd5bddfb05 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -1326,7 +1326,6 @@ found: xso->type = XFRM_DEV_OFFLOAD_PACKET; xso->dir = xdo->dir; xso->dev = xdo->dev; - xso->real_dev = xdo->real_dev; xso->flags = XFRM_DEV_OFFLOAD_FLAG_ACQ; netdev_hold(xso->dev, &xso->dev_tracker, GFP_ATOMIC); error = xso->dev->xfrmdev_ops->xdo_dev_state_add(x, NULL); @@ -1334,7 +1333,6 @@ found: xso->dir = 0; netdev_put(xso->dev, &xso->dev_tracker); xso->dev = NULL; - xso->real_dev = NULL; xso->type = XFRM_DEV_OFFLOAD_UNSPECIFIED; x->km.state = XFRM_STATE_DEAD; to_put = x; From 446fcc230d9fc9795b6e90b07db29fa697779b24 Mon Sep 17 00:00:00 2001 From: Zhen XIN Date: Thu, 10 Apr 2025 15:42:17 +0000 Subject: [PATCH 138/971] wifi: rtw88: sdio: map mgmt frames to queue TX_DESC_QSEL_MGMT [ Upstream commit b2effcdc237979dcc533d446a792fc54fd0e1213 ] The rtw88-sdio do not work in AP mode due to the lack of TX status report for management frames. Map the management frames to queue TX_DESC_QSEL_MGMT, which enables the chip to generate TX reports for these frames Tested-on: rtl8723ds Fixes: 65371a3f14e7 ("wifi: rtw88: sdio: Add HCI implementation for SDIO based chipsets") Signed-off-by: Zhen XIN Reviewed-by: Martin Blumenstingl Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250410154217.1849977-3-zhen.xin@nokia-sbell.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtw88/sdio.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c index 904356993579..4df04579e2e7 100644 --- a/drivers/net/wireless/realtek/rtw88/sdio.c +++ b/drivers/net/wireless/realtek/rtw88/sdio.c @@ -718,10 +718,7 @@ static u8 rtw_sdio_get_tx_qsel(struct rtw_dev *rtwdev, struct sk_buff *skb, case RTW_TX_QUEUE_H2C: return TX_DESC_QSEL_H2C; case RTW_TX_QUEUE_MGMT: - if (rtw_chip_wcpu_11n(rtwdev)) - return TX_DESC_QSEL_HIGH; - else - return TX_DESC_QSEL_MGMT; + return TX_DESC_QSEL_MGMT; case RTW_TX_QUEUE_HI0: return TX_DESC_QSEL_HIGH; default: From 7b63e52a8bab308e6fe64ff40cf8e444802241cc Mon Sep 17 00:00:00 2001 From: Zhen XIN Date: Thu, 10 Apr 2025 15:42:16 +0000 Subject: [PATCH 139/971] wifi: rtw88: sdio: call rtw_sdio_indicate_tx_status unconditionally [ Upstream commit fc5f5a0ec463ae6a07850428bd3082947e01d276 ] The rtw88-sdio do not work in AP mode due to the lack of TX status report for management frames. Make the invocation of rtw_sdio_indicate_tx_status unconditional and cover all packet queues Tested-on: rtl8723ds Fixes: 65371a3f14e7 ("wifi: rtw88: sdio: Add HCI implementation for SDIO based chipsets") Signed-off-by: Zhen XIN Reviewed-by: Martin Blumenstingl Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250410154217.1849977-2-zhen.xin@nokia-sbell.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtw88/sdio.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c index 4df04579e2e7..832a427279b4 100644 --- a/drivers/net/wireless/realtek/rtw88/sdio.c +++ b/drivers/net/wireless/realtek/rtw88/sdio.c @@ -1223,10 +1223,7 @@ static void rtw_sdio_process_tx_queue(struct rtw_dev *rtwdev, return; } - if (queue <= RTW_TX_QUEUE_VO) - rtw_sdio_indicate_tx_status(rtwdev, skb); - else - dev_kfree_skb_any(skb); + rtw_sdio_indicate_tx_status(rtwdev, skb); } static void rtw_sdio_tx_handler(struct work_struct *work) From f76f399004c6fefdbc44c8a05c8e1147989a27ce Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Tue, 15 Apr 2025 12:07:20 +0300 Subject: [PATCH 140/971] wifi: rtw88: do not ignore hardware read error during DPK [ Upstream commit 20d3c19bd8f9b498173c198eadf54580c8caa336 ] In 'rtw8822c_dpk_cal_coef1()', do not ignore error returned by 'check_hw_ready()' but issue a warning to denote possible DPK issue. Compile tested only. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 5227c2ee453d ("rtw88: 8822c: add SW DPK support") Suggested-by: Ping-Ke Shih Signed-off-by: Dmitry Antipov Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250415090720.194048-1-dmantipov@yandex.ru Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtw88/rtw8822c.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c index 3fe5c70ce731..f9b2527fbeee 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c @@ -3991,7 +3991,8 @@ static void rtw8822c_dpk_cal_coef1(struct rtw_dev *rtwdev) rtw_write32(rtwdev, REG_NCTL0, 0x00001148); rtw_write32(rtwdev, REG_NCTL0, 0x00001149); - check_hw_ready(rtwdev, 0x2d9c, MASKBYTE0, 0x55); + if (!check_hw_ready(rtwdev, 0x2d9c, MASKBYTE0, 0x55)) + rtw_warn(rtwdev, "DPK stuck, performance may be suboptimal"); rtw_write8(rtwdev, 0x1b10, 0x0); rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x0000000c); From c9c9107ffa0e0f36df9842212307e104d2af544f Mon Sep 17 00:00:00 2001 From: P Praneesh Date: Wed, 16 Apr 2025 07:49:03 +0530 Subject: [PATCH 141/971] wifi: ath12k: Add MSDU length validation for TKIP MIC error [ Upstream commit 763216fe6c5df95d122c71ef34c342427c987820 ] In the WBM error path, while processing TKIP MIC errors, MSDU length is fetched from the hal_rx_desc's msdu_end. This MSDU length is directly passed to skb_put() without validation. In stress test scenarios, the WBM error ring may receive invalid descriptors, which could lead to an invalid MSDU length. To fix this, add a check to drop the skb when the calculated MSDU length is greater than the skb size. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") Signed-off-by: P Praneesh Signed-off-by: Nithyanantham Paramasivam Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20250416021903.3178962-1-nithyanantham.paramasivam@oss.qualcomm.com Signed-off-by: Jeff Johnson Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath12k/dp_rx.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 8d9315038a75..56dda76d066c 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -3683,6 +3683,15 @@ static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, l3pad_bytes = ath12k_dp_rx_h_l3pad(ab, desc); msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc); + + if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) { + ath12k_dbg(ab, ATH12K_DBG_DATA, + "invalid msdu len in tkip mic err %u\n", msdu_len); + ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", desc, + sizeof(*desc)); + return true; + } + skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len); skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes); From be049199dec9189602bc06e2c70eda3aa0f2ea6e Mon Sep 17 00:00:00 2001 From: Maharaja Kennadyrajan Date: Wed, 16 Apr 2025 07:47:24 +0530 Subject: [PATCH 142/971] wifi: ath12k: fix node corruption in ar->arvifs list [ Upstream commit 823435bd23108d6f8be89ea2d025c0e2e3769c51 ] In current WLAN recovery code flow, ath12k_core_halt() only reinitializes the "arvifs" list head. This will cause the list node immediately following the list head to become an invalid list node. Because the prev of that node still points to the list head "arvifs", but the next of the list head "arvifs" no longer points to that list node. When a WLAN recovery occurs during the execution of a vif removal, and it happens before the spin_lock_bh(&ar->data_lock) in ath12k_mac_vdev_delete(), list_del() will detect the previously mentioned situation, thereby triggering a kernel panic. The fix is to remove and reinitialize all vif list nodes from the list head "arvifs" during WLAN halt. The reinitialization is to make the list nodes valid, ensuring that the list_del() in ath12k_mac_vdev_delete() can execute normally. Call trace: __list_del_entry_valid_or_report+0xd4/0x100 (P) ath12k_mac_remove_link_interface.isra.0+0xf8/0x2e4 [ath12k] ath12k_scan_vdev_clean_work+0x40/0x164 [ath12k] cfg80211_wiphy_work+0xfc/0x100 process_one_work+0x164/0x2d0 worker_thread+0x254/0x380 kthread+0xfc/0x100 ret_from_fork+0x10/0x20 The change is mostly copied from the ath11k patch: https://lore.kernel.org/all/20250320053145.3445187-1-quic_stonez@quicinc.com/ Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") Signed-off-by: Maharaja Kennadyrajan Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20250416021724.2162519-1-maharaja.kennadyrajan@oss.qualcomm.com Signed-off-by: Jeff Johnson Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath12k/core.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 3df8059d5512..1b07a183aaed 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -657,6 +657,7 @@ err_hal_srng_deinit: void ath12k_core_halt(struct ath12k *ar) { + struct list_head *pos, *n; struct ath12k_base *ab = ar->ab; lockdep_assert_held(&ar->conf_mutex); @@ -671,7 +672,12 @@ void ath12k_core_halt(struct ath12k *ar) rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL); synchronize_rcu(); - INIT_LIST_HEAD(&ar->arvifs); + + spin_lock_bh(&ar->data_lock); + list_for_each_safe(pos, n, &ar->arvifs) + list_del_init(pos); + spin_unlock_bh(&ar->data_lock); + idr_init(&ar->txmgmt_idr); } From 5edd80d4b9c821c8cefd24f676a705cf4ce47d0b Mon Sep 17 00:00:00 2001 From: Junxian Huang Date: Mon, 21 Apr 2025 21:27:49 +0800 Subject: [PATCH 143/971] RDMA/hns: Include hnae3.h in hns_roce_hw_v2.h [ Upstream commit 2b11d33de23262cb20d1dcb24b586dbb8f54d463 ] hns_roce_hw_v2.h has a direct dependency on hnae3.h due to the inline function hns_roce_write64(), but it doesn't include this header currently. This leads to that files including hns_roce_hw_v2.h must also include hnae3.h to avoid compilation errors, even if they themselves don't really rely on hnae3.h. This doesn't make sense, hns_roce_hw_v2.h should include hnae3.h directly. Fixes: d3743fa94ccd ("RDMA/hns: Fix the chip hanging caused by sending doorbell during reset") Signed-off-by: Junxian Huang Link: https://patch.msgid.link/20250421132750.1363348-6-huangjunxian6@hisilicon.com Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin --- drivers/infiniband/hw/hns/hns_roce_ah.c | 1 - drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 1 - drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 1 + drivers/infiniband/hw/hns/hns_roce_main.c | 1 - drivers/infiniband/hw/hns/hns_roce_restrack.c | 1 - 5 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_ah.c b/drivers/infiniband/hw/hns/hns_roce_ah.c index 3df032ddda18..e99890e0c8c3 100644 --- a/drivers/infiniband/hw/hns/hns_roce_ah.c +++ b/drivers/infiniband/hw/hns/hns_roce_ah.c @@ -33,7 +33,6 @@ #include #include #include -#include "hnae3.h" #include "hns_roce_device.h" #include "hns_roce_hw_v2.h" diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index aded0a7f4283..9d23d4b5c128 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -42,7 +42,6 @@ #include #include -#include "hnae3.h" #include "hns_roce_common.h" #include "hns_roce_device.h" #include "hns_roce_cmd.h" diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h index b8e17721f6fd..7875283eb9d6 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h @@ -34,6 +34,7 @@ #define _HNS_ROCE_HW_V2_H #include +#include "hnae3.h" #define HNS_ROCE_V2_MAX_RC_INL_INN_SZ 32 #define HNS_ROCE_V2_MTT_ENTRY_SZ 64 diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index a7e4c951f8fe..5f39a25064d1 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -37,7 +37,6 @@ #include #include #include -#include "hnae3.h" #include "hns_roce_common.h" #include "hns_roce_device.h" #include "hns_roce_hem.h" diff --git a/drivers/infiniband/hw/hns/hns_roce_restrack.c b/drivers/infiniband/hw/hns/hns_roce_restrack.c index 081a01de3055..1fb5e2468364 100644 --- a/drivers/infiniband/hw/hns/hns_roce_restrack.c +++ b/drivers/infiniband/hw/hns/hns_roce_restrack.c @@ -4,7 +4,6 @@ #include #include #include -#include "hnae3.h" #include "hns_roce_common.h" #include "hns_roce_device.h" #include "hns_roce_hw_v2.h" From 624b4cf6c49ceb4f813ff53b001623f05bce7804 Mon Sep 17 00:00:00 2001 From: Yihang Li Date: Mon, 14 Apr 2025 16:08:44 +0800 Subject: [PATCH 144/971] scsi: hisi_sas: Call I_T_nexus after soft reset for SATA disk [ Upstream commit e4d953ca557e02edd3aed7390043e1b8ad1c9723 ] In commit 21c7e972475e ("scsi: hisi_sas: Disable SATA disk phy for severe I_T nexus reset failure"), if the softreset fails upon certain conditions, the PHY connected to the disk is disabled directly. Manual recovery is required, which is inconvenient for users in actual use. In addition, SATA disks do not support simultaneous connection of multiple hosts. Therefore, when multiple controllers are connected to a SATA disk at the same time, the controller which is connected later failed to issue an ATA softreset to the SATA disk. As a result, the PHY associated with the disk is disabled and cannot be automatically recovered. Now that, we will not focus on the execution result of softreset. No matter whether the execution is successful or not, we will directly carry out I_T_nexus_reset. Fixes: 21c7e972475e ("scsi: hisi_sas: Disable SATA disk phy for severe I_T nexus reset failure") Signed-off-by: Yihang Li Link: https://lore.kernel.org/r/20250414080845.1220997-4-liyihang9@huawei.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/hisi_sas/hisi_sas_main.c | 29 +++++---------------------- 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 7e64661d215b..3ad58250bf6b 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -1844,33 +1844,14 @@ static int hisi_sas_I_T_nexus_reset(struct domain_device *device) } hisi_sas_dereg_device(hisi_hba, device); - rc = hisi_sas_debug_I_T_nexus_reset(device); - if (rc == TMF_RESP_FUNC_COMPLETE && dev_is_sata(device)) { - struct sas_phy *local_phy; - + if (dev_is_sata(device)) { rc = hisi_sas_softreset_ata_disk(device); - switch (rc) { - case -ECOMM: - rc = -ENODEV; - break; - case TMF_RESP_FUNC_FAILED: - case -EMSGSIZE: - case -EIO: - local_phy = sas_get_local_phy(device); - rc = sas_phy_enable(local_phy, 0); - if (!rc) { - local_phy->enabled = 0; - dev_err(dev, "Disabled local phy of ATA disk %016llx due to softreset fail (%d)\n", - SAS_ADDR(device->sas_addr), rc); - rc = -ENODEV; - } - sas_put_local_phy(local_phy); - break; - default: - break; - } + if (rc == TMF_RESP_FUNC_FAILED) + dev_err(dev, "ata disk %016llx reset (%d)\n", + SAS_ADDR(device->sas_addr), rc); } + rc = hisi_sas_debug_I_T_nexus_reset(device); if ((rc == TMF_RESP_FUNC_COMPLETE) || (rc == -ENODEV)) hisi_sas_release_task(hisi_hba, device); From 79669facfe9255e6a12b62effd1ea29b7d48b5f0 Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Thu, 24 Apr 2025 00:39:01 +0800 Subject: [PATCH 145/971] libbpf: Remove sample_period init in perf_buffer [ Upstream commit 64821d25f05ac468d435e61669ae745ce5a633ea ] It seems that sample_period is not used in perf buffer. Actually, only wakeup_events are meaningful to enable events aggregation for wakeup notification. Remove sample_period setting code to avoid confusion. Fixes: fb84b8224655 ("libbpf: add perf buffer API") Signed-off-by: Tao Chen Signed-off-by: Andrii Nakryiko Acked-by: Jiri Olsa Acked-by: Namhyung Kim Link: https://lore.kernel.org/bpf/20250423163901.2983689-1-chen.dylane@linux.dev Signed-off-by: Sasha Levin --- tools/lib/bpf/libbpf.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index ca764ed3aaa9..18e96375dc31 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -12453,7 +12453,6 @@ struct perf_buffer *perf_buffer__new(int map_fd, size_t page_cnt, attr.config = PERF_COUNT_SW_BPF_OUTPUT; attr.type = PERF_TYPE_SOFTWARE; attr.sample_type = PERF_SAMPLE_RAW; - attr.sample_period = sample_period; attr.wakeup_events = sample_period; p.attr = &attr; From cb4b9369463eb6f6d0f4bdeaf35d183a935c2573 Mon Sep 17 00:00:00 2001 From: Jonathan Wiepert Date: Thu, 24 Apr 2025 18:14:57 -0400 Subject: [PATCH 146/971] Use thread-safe function pointer in libbpf_print [ Upstream commit 91dbac4076537b464639953c055c460d2bdfc7ea ] This patch fixes a thread safety bug where libbpf_print uses the global variable storing the print function pointer rather than the local variable that had the print function set via __atomic_load_n. Fixes: f1cb927cdb62 ("libbpf: Ensure print callback usage is thread-safe") Signed-off-by: Jonathan Wiepert Signed-off-by: Andrii Nakryiko Acked-by: Mykyta Yatsenko Link: https://lore.kernel.org/bpf/20250424221457.793068-1-jonathan.wiepert@gmail.com Signed-off-by: Sasha Levin --- tools/lib/bpf/libbpf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 18e96375dc31..5dc2e5555335 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -246,7 +246,7 @@ void libbpf_print(enum libbpf_print_level level, const char *format, ...) old_errno = errno; va_start(args, format); - __libbpf_pr(level, format, args); + print_fn(level, format, args); va_end(args); errno = old_errno; From 8fa998b842f291618bb4ccc822af72f6879d3ad6 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Fri, 25 Apr 2025 10:08:37 -0300 Subject: [PATCH 147/971] iommu: Protect against overflow in iommu_pgsize() [ Upstream commit e586e22974d2b7acbef3c6c3e01b2d5ce69efe33 ] On a 32 bit system calling: iommu_map(0, 0x40000000) When using the AMD V1 page table type with a domain->pgsize of 0xfffff000 causes iommu_pgsize() to miscalculate a result of: size=0x40000000 count=2 count should be 1. This completely corrupts the mapping process. This is because the final test to adjust the pagesize malfunctions when the addition overflows. Use check_add_overflow() to prevent this. Fixes: b1d99dc5f983 ("iommu: Hook up '->unmap_pages' driver callback") Signed-off-by: Jason Gunthorpe Reviewed-by: Lu Baolu Link: https://lore.kernel.org/r/0-v1-3ad28fc2e3a3+163327-iommu_overflow_pgsize_jgg@nvidia.com Signed-off-by: Joerg Roedel Signed-off-by: Sasha Levin --- drivers/iommu/iommu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index f2b3a4e2e54f..3fa5699b9ff1 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2382,6 +2382,7 @@ static size_t iommu_pgsize(struct iommu_domain *domain, unsigned long iova, unsigned int pgsize_idx, pgsize_idx_next; unsigned long pgsizes; size_t offset, pgsize, pgsize_next; + size_t offset_end; unsigned long addr_merge = paddr | iova; /* Page sizes supported by the hardware and small enough for @size */ @@ -2422,7 +2423,8 @@ static size_t iommu_pgsize(struct iommu_domain *domain, unsigned long iova, * If size is big enough to accommodate the larger page, reduce * the number of smaller pages. */ - if (offset + pgsize_next <= size) + if (!check_add_overflow(offset, pgsize_next, &offset_end) && + offset_end <= size) size = offset; out_set_count: From 4b88a4dfbea0ef1553b75d6e0b3f1b1e2831476a Mon Sep 17 00:00:00 2001 From: Hangbin Liu Date: Thu, 24 Apr 2025 04:22:38 +0000 Subject: [PATCH 148/971] bonding: assign random address if device address is same as bond [ Upstream commit 5c3bf6cba7911f470afd748606be5c03a9512fcc ] This change addresses a MAC address conflict issue in failover scenarios, similar to the problem described in commit a951bc1e6ba5 ("bonding: correct the MAC address for 'follow' fail_over_mac policy"). In fail_over_mac=follow mode, the bonding driver expects the formerly active slave to swap MAC addresses with the newly active slave during failover. However, under certain conditions, two slaves may end up with the same MAC address, which breaks this policy: 1) ip link set eth0 master bond0 -> bond0 adopts eth0's MAC address (MAC0). 2) ip link set eth1 master bond0 -> eth1 is added as a backup with its own MAC (MAC1). 3) ip link set eth0 nomaster -> eth0 is released and restores its MAC (MAC0). -> eth1 becomes the active slave, and bond0 assigns MAC0 to eth1. 4) ip link set eth0 master bond0 -> eth0 is re-added to bond0, now both eth0 and eth1 have MAC0. This results in a MAC address conflict and violates the expected behavior of the failover policy. To fix this, we assign a random MAC address to any newly added slave if its current MAC address matches that of the bond. The original (permanent) MAC address is saved and will be restored when the device is released from the bond. This ensures that each slave has a unique MAC address during failover transitions, preserving the integrity of the fail_over_mac=follow policy. Fixes: 3915c1e8634a ("bonding: Add "follow" option to fail_over_mac") Signed-off-by: Hangbin Liu Acked-by: Jay Vosburgh Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/bonding/bond_main.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 56c241246d1a..85ab69257162 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2040,15 +2040,26 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev, * set the master's mac address to that of the first slave */ memcpy(ss.__data, bond_dev->dev_addr, bond_dev->addr_len); - ss.ss_family = slave_dev->type; - res = dev_set_mac_address(slave_dev, (struct sockaddr *)&ss, - extack); - if (res) { - slave_err(bond_dev, slave_dev, "Error %d calling set_mac_address\n", res); - goto err_restore_mtu; - } + } else if (bond->params.fail_over_mac == BOND_FOM_FOLLOW && + BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP && + memcmp(slave_dev->dev_addr, bond_dev->dev_addr, bond_dev->addr_len) == 0) { + /* Set slave to random address to avoid duplicate mac + * address in later fail over. + */ + eth_random_addr(ss.__data); + } else { + goto skip_mac_set; } + ss.ss_family = slave_dev->type; + res = dev_set_mac_address(slave_dev, (struct sockaddr *)&ss, extack); + if (res) { + slave_err(bond_dev, slave_dev, "Error %d calling set_mac_address\n", res); + goto err_restore_mtu; + } + +skip_mac_set: + /* set no_addrconf flag before open to prevent IPv6 addrconf */ slave_dev->priv_flags |= IFF_NO_ADDRCONF; From 43cec280496a75d1c9303a6bfc3fd922db4592ff Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Mon, 14 Apr 2025 18:52:36 +0800 Subject: [PATCH 149/971] f2fs: clean up w/ fscrypt_is_bounce_page() [ Upstream commit 0c708e35cf26449ca317fcbfc274704660b6d269 ] Just cleanup, no logic changes. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- fs/f2fs/data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index acd0764b0286..5a3fa2f887a7 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -54,7 +54,7 @@ bool f2fs_is_cp_guaranteed(struct page *page) struct inode *inode; struct f2fs_sb_info *sbi; - if (!mapping) + if (fscrypt_is_bounce_page(page)) return false; inode = mapping->host; From 1c005c53cf8ecebca5b2e0177726aed378a54d92 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Mon, 14 Apr 2025 18:52:37 +0800 Subject: [PATCH 150/971] f2fs: fix to detect gcing page in f2fs_is_cp_guaranteed() [ Upstream commit aa1be8dd64163eca4dde7fd2557eb19927a06a47 ] Jan Prusakowski reported a f2fs bug as below: f2fs/007 will hang kernel during testing w/ below configs: kernel 6.12.18 (from pixel-kernel/android16-6.12) export MKFS_OPTIONS="-O encrypt -O extra_attr -O project_quota -O quota" export F2FS_MOUNT_OPTIONS="test_dummy_encryption,discard,fsync_mode=nobarrier,reserve_root=32768,checkpoint_merge,atgc" cat /proc//stack f2fs_wait_on_all_pages+0xa3/0x130 do_checkpoint+0x40c/0x5d0 f2fs_write_checkpoint+0x258/0x550 kill_f2fs_super+0x14f/0x190 deactivate_locked_super+0x30/0xb0 cleanup_mnt+0xba/0x150 task_work_run+0x59/0xa0 syscall_exit_to_user_mode+0x12d/0x130 do_syscall_64+0x57/0x110 entry_SYSCALL_64_after_hwframe+0x76/0x7e cat /sys/kernel/debug/f2fs/status - IO_W (CP: -256, Data: 256, Flush: ( 0 0 1), Discard: ( 0 0)) cmd: 0 undiscard: 0 CP IOs reference count becomes negative. The root cause is: After 4961acdd65c9 ("f2fs: fix to tag gcing flag on page during block migration"), we will tag page w/ gcing flag for raw page of cluster during its migration. However, if the inode is both encrypted and compressed, during ioc_decompress(), it will tag page w/ gcing flag, and it increase F2FS_WB_DATA reference count: - f2fs_write_multi_page - f2fs_write_raw_page - f2fs_write_single_page - do_write_page - f2fs_submit_page_write - WB_DATA_TYPE(bio_page, fio->compressed_page) : bio_page is encrypted, so mapping is NULL, and fio->compressed_page is NULL, it returns F2FS_WB_DATA - inc_page_count(.., F2FS_WB_DATA) Then, during end_io(), it decrease F2FS_WB_CP_DATA reference count: - f2fs_write_end_io - f2fs_compress_write_end_io - fscrypt_pagecache_folio : get raw page from encrypted page - WB_DATA_TYPE(&folio->page, false) : raw page has gcing flag, it returns F2FS_WB_CP_DATA - dec_page_count(.., F2FS_WB_CP_DATA) In order to fix this issue, we need to detect gcing flag in raw page in f2fs_is_cp_guaranteed(). Fixes: 4961acdd65c9 ("f2fs: fix to tag gcing flag on page during block migration") Reported-by: Jan Prusakowski Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- fs/f2fs/data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 5a3fa2f887a7..a123bb26acd8 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -55,7 +55,7 @@ bool f2fs_is_cp_guaranteed(struct page *page) struct f2fs_sb_info *sbi; if (fscrypt_is_bounce_page(page)) - return false; + return page_private_gcing(fscrypt_pagecache_page(page)); inode = mapping->host; sbi = F2FS_I_SB(inode); From 1066c5a7d0832be91d2dc1bcee115b1866596017 Mon Sep 17 00:00:00 2001 From: Anton Protopopov Date: Wed, 30 Apr 2025 12:08:20 +0000 Subject: [PATCH 151/971] libbpf: Use proper errno value in linker [ Upstream commit 358b1c0f56ebb6996fcec7dcdcf6bae5dcbc8b6c ] Return values of the linker_append_sec_data() and the linker_append_elf_relos() functions are propagated all the way up to users of libbpf API. In some error cases these functions return -1 which will be seen as -EPERM from user's point of view. Instead, return a more reasonable -EINVAL. Fixes: faf6ed321cf6 ("libbpf: Add BPF static linker APIs") Signed-off-by: Anton Protopopov Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20250430120820.2262053-1-a.s.protopopov@gmail.com Signed-off-by: Sasha Levin --- tools/lib/bpf/linker.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c index a3a190d13db8..e1b3136643aa 100644 --- a/tools/lib/bpf/linker.c +++ b/tools/lib/bpf/linker.c @@ -1187,7 +1187,7 @@ static int linker_append_sec_data(struct bpf_linker *linker, struct src_obj *obj } else { if (!secs_match(dst_sec, src_sec)) { pr_warn("ELF sections %s are incompatible\n", src_sec->sec_name); - return -1; + return -EINVAL; } /* "license" and "version" sections are deduped */ @@ -2034,7 +2034,7 @@ static int linker_append_elf_relos(struct bpf_linker *linker, struct src_obj *ob } } else if (!secs_match(dst_sec, src_sec)) { pr_warn("sections %s are not compatible\n", src_sec->sec_name); - return -1; + return -EINVAL; } /* shdr->sh_link points to SYMTAB */ From 50bbbd25597d34f6096a40a5981518fa115ab2ab Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Mon, 28 Apr 2025 17:44:02 +0200 Subject: [PATCH 152/971] bpf: Allow XDP dev-bound programs to perform XDP_REDIRECT into maps [ Upstream commit 714070c4cb7a10ff57450a618a936775f3036245 ] In the current implementation if the program is dev-bound to a specific device, it will not be possible to perform XDP_REDIRECT into a DEVMAP or CPUMAP even if the program is running in the driver NAPI context and it is not attached to any map entry. This seems in contrast with the explanation available in bpf_prog_map_compatible routine. Fix the issue introducing __bpf_prog_map_compatible utility routine in order to avoid bpf_prog_is_dev_bound() check running bpf_check_tail_call() at program load time (bpf_prog_select_runtime()). Continue forbidding to attach a dev-bound program to XDP maps (BPF_MAP_TYPE_PROG_ARRAY, BPF_MAP_TYPE_DEVMAP and BPF_MAP_TYPE_CPUMAP). Fixes: 3d76a4d3d4e59 ("bpf: XDP metadata RX kfuncs") Signed-off-by: Lorenzo Bianconi Signed-off-by: Martin KaFai Lau Acked-by: Stanislav Fomichev Signed-off-by: Sasha Levin --- kernel/bpf/core.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 81fd1bb99416..3f140b7527cf 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -2258,8 +2258,8 @@ static unsigned int __bpf_prog_ret0_warn(const void *ctx, } #endif -bool bpf_prog_map_compatible(struct bpf_map *map, - const struct bpf_prog *fp) +static bool __bpf_prog_map_compatible(struct bpf_map *map, + const struct bpf_prog *fp) { enum bpf_prog_type prog_type = resolve_prog_type(fp); bool ret; @@ -2268,14 +2268,6 @@ bool bpf_prog_map_compatible(struct bpf_map *map, if (fp->kprobe_override) return false; - /* XDP programs inserted into maps are not guaranteed to run on - * a particular netdev (and can run outside driver context entirely - * in the case of devmap and cpumap). Until device checks - * are implemented, prohibit adding dev-bound programs to program maps. - */ - if (bpf_prog_is_dev_bound(aux)) - return false; - spin_lock(&map->owner.lock); if (!map->owner.type) { /* There's no owner yet where we could check for @@ -2309,6 +2301,19 @@ bool bpf_prog_map_compatible(struct bpf_map *map, return ret; } +bool bpf_prog_map_compatible(struct bpf_map *map, const struct bpf_prog *fp) +{ + /* XDP programs inserted into maps are not guaranteed to run on + * a particular netdev (and can run outside driver context entirely + * in the case of devmap and cpumap). Until device checks + * are implemented, prohibit adding dev-bound programs to program maps. + */ + if (bpf_prog_is_dev_bound(fp->aux)) + return false; + + return __bpf_prog_map_compatible(map, fp); +} + static int bpf_check_tail_call(const struct bpf_prog *fp) { struct bpf_prog_aux *aux = fp->aux; @@ -2321,7 +2326,7 @@ static int bpf_check_tail_call(const struct bpf_prog *fp) if (!map_type_contains_progs(map)) continue; - if (!bpf_prog_map_compatible(map, fp)) { + if (!__bpf_prog_map_compatible(map, fp)) { ret = -EINVAL; goto out; } From 585c9ed565c57aaafded664282e4f70ff60d8c35 Mon Sep 17 00:00:00 2001 From: Huajian Yang Date: Thu, 17 Apr 2025 17:29:53 +0800 Subject: [PATCH 153/971] netfilter: bridge: Move specific fragmented packet to slow_path instead of dropping it [ Upstream commit aa04c6f45b9224b949aa35d4fa5f8d0ba07b23d4 ] The config NF_CONNTRACK_BRIDGE will change the bridge forwarding for fragmented packets. The original bridge does not know that it is a fragmented packet and forwards it directly, after NF_CONNTRACK_BRIDGE is enabled, function nf_br_ip_fragment and br_ip6_fragment will check the headroom. In original br_forward, insufficient headroom of skb may indeed exist, but there's still a way to save the skb in the device driver after dev_queue_xmit.So droping the skb will change the original bridge forwarding in some cases. Fixes: 3c171f496ef5 ("netfilter: bridge: add connection tracking system") Signed-off-by: Huajian Yang Reviewed-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- net/bridge/netfilter/nf_conntrack_bridge.c | 12 ++++++------ net/ipv6/netfilter.c | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/net/bridge/netfilter/nf_conntrack_bridge.c b/net/bridge/netfilter/nf_conntrack_bridge.c index 4fbfbafdfa02..4b4a396d9722 100644 --- a/net/bridge/netfilter/nf_conntrack_bridge.c +++ b/net/bridge/netfilter/nf_conntrack_bridge.c @@ -60,19 +60,19 @@ static int nf_br_ip_fragment(struct net *net, struct sock *sk, struct ip_fraglist_iter iter; struct sk_buff *frag; - if (first_len - hlen > mtu || - skb_headroom(skb) < ll_rs) + if (first_len - hlen > mtu) goto blackhole; - if (skb_cloned(skb)) + if (skb_cloned(skb) || + skb_headroom(skb) < ll_rs) goto slow_path; skb_walk_frags(skb, frag) { - if (frag->len > mtu || - skb_headroom(frag) < hlen + ll_rs) + if (frag->len > mtu) goto blackhole; - if (skb_shared(frag)) + if (skb_shared(frag) || + skb_headroom(frag) < hlen + ll_rs) goto slow_path; } diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index 7c4af48d529e..606aae4e78a9 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c @@ -163,20 +163,20 @@ int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, struct ip6_fraglist_iter iter; struct sk_buff *frag2; - if (first_len - hlen > mtu || - skb_headroom(skb) < (hroom + sizeof(struct frag_hdr))) + if (first_len - hlen > mtu) goto blackhole; - if (skb_cloned(skb)) + if (skb_cloned(skb) || + skb_headroom(skb) < (hroom + sizeof(struct frag_hdr))) goto slow_path; skb_walk_frags(skb, frag2) { - if (frag2->len > mtu || - skb_headroom(frag2) < (hlen + hroom + sizeof(struct frag_hdr))) + if (frag2->len > mtu) goto blackhole; /* Partially cloned skb? */ - if (skb_shared(frag2)) + if (skb_shared(frag2) || + skb_headroom(frag2) < (hlen + hroom + sizeof(struct frag_hdr))) goto slow_path; } From 5e4519d8cdd892e569892df32be361314321cfb4 Mon Sep 17 00:00:00 2001 From: Zhongqiu Duan Date: Thu, 17 Apr 2025 15:49:30 +0000 Subject: [PATCH 154/971] netfilter: nft_quota: match correctly when the quota just depleted [ Upstream commit bfe7cfb65c753952735c3eed703eba9a8b96a18d ] The xt_quota compares skb length with remaining quota, but the nft_quota compares it with consumed bytes. The xt_quota can match consumed bytes up to quota at maximum. But the nft_quota break match when consumed bytes equal to quota. i.e., nft_quota match consumed bytes in [0, quota - 1], not [0, quota]. Fixes: 795595f68d6c ("netfilter: nft_quota: dump consumed quota") Signed-off-by: Zhongqiu Duan Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- net/netfilter/nft_quota.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/net/netfilter/nft_quota.c b/net/netfilter/nft_quota.c index 9b2d7463d3d3..df0798da2329 100644 --- a/net/netfilter/nft_quota.c +++ b/net/netfilter/nft_quota.c @@ -19,10 +19,16 @@ struct nft_quota { }; static inline bool nft_overquota(struct nft_quota *priv, - const struct sk_buff *skb) + const struct sk_buff *skb, + bool *report) { - return atomic64_add_return(skb->len, priv->consumed) >= - atomic64_read(&priv->quota); + u64 consumed = atomic64_add_return(skb->len, priv->consumed); + u64 quota = atomic64_read(&priv->quota); + + if (report) + *report = consumed >= quota; + + return consumed > quota; } static inline bool nft_quota_invert(struct nft_quota *priv) @@ -34,7 +40,7 @@ static inline void nft_quota_do_eval(struct nft_quota *priv, struct nft_regs *regs, const struct nft_pktinfo *pkt) { - if (nft_overquota(priv, pkt->skb) ^ nft_quota_invert(priv)) + if (nft_overquota(priv, pkt->skb, NULL) ^ nft_quota_invert(priv)) regs->verdict.code = NFT_BREAK; } @@ -51,13 +57,13 @@ static void nft_quota_obj_eval(struct nft_object *obj, const struct nft_pktinfo *pkt) { struct nft_quota *priv = nft_obj_data(obj); - bool overquota; + bool overquota, report; - overquota = nft_overquota(priv, pkt->skb); + overquota = nft_overquota(priv, pkt->skb, &report); if (overquota ^ nft_quota_invert(priv)) regs->verdict.code = NFT_BREAK; - if (overquota && + if (report && !test_and_set_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags)) nft_obj_notify(nft_net(pkt), obj->key.table, obj, 0, 0, NFT_MSG_NEWOBJ, 0, nft_pf(pkt), 0, GFP_ATOMIC); From 7c4c84cdcc19e89d42f6bf117238e5471173423e Mon Sep 17 00:00:00 2001 From: Patrisious Haddad Date: Mon, 28 Apr 2025 14:34:07 +0300 Subject: [PATCH 155/971] RDMA/mlx5: Fix error flow upon firmware failure for RQ destruction [ Upstream commit 5d2ea5aebbb2f3ebde4403f9c55b2b057e5dd2d6 ] Upon RQ destruction if the firmware command fails which is the last resource to be destroyed some SW resources were already cleaned regardless of the failure. Now properly rollback the object to its original state upon such failure. In order to avoid a use-after free in case someone tries to destroy the object again, which results in the following kernel trace: refcount_t: underflow; use-after-free. WARNING: CPU: 0 PID: 37589 at lib/refcount.c:28 refcount_warn_saturate+0xf4/0x148 Modules linked in: rdma_ucm(OE) rdma_cm(OE) iw_cm(OE) ib_ipoib(OE) ib_cm(OE) ib_umad(OE) mlx5_ib(OE) rfkill mlx5_core(OE) mlxdevm(OE) ib_uverbs(OE) ib_core(OE) psample mlxfw(OE) mlx_compat(OE) macsec tls pci_hyperv_intf sunrpc vfat fat virtio_net net_failover failover fuse loop nfnetlink vsock_loopback vmw_vsock_virtio_transport_common vmw_vsock_vmci_transport vmw_vmci vsock xfs crct10dif_ce ghash_ce sha2_ce sha256_arm64 sha1_ce virtio_console virtio_gpu virtio_blk virtio_dma_buf virtio_mmio dm_mirror dm_region_hash dm_log dm_mod xpmem(OE) CPU: 0 UID: 0 PID: 37589 Comm: python3 Kdump: loaded Tainted: G OE ------- --- 6.12.0-54.el10.aarch64 #1 Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015 pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : refcount_warn_saturate+0xf4/0x148 lr : refcount_warn_saturate+0xf4/0x148 sp : ffff80008b81b7e0 x29: ffff80008b81b7e0 x28: ffff000133d51600 x27: 0000000000000001 x26: 0000000000000000 x25: 00000000ffffffea x24: ffff00010ae80f00 x23: ffff00010ae80f80 x22: ffff0000c66e5d08 x21: 0000000000000000 x20: ffff0000c66e0000 x19: ffff00010ae80340 x18: 0000000000000006 x17: 0000000000000000 x16: 0000000000000020 x15: ffff80008b81b37f x14: 0000000000000000 x13: 2e656572662d7265 x12: ffff80008283ef78 x11: ffff80008257efd0 x10: ffff80008283efd0 x9 : ffff80008021ed90 x8 : 0000000000000001 x7 : 00000000000bffe8 x6 : c0000000ffff7fff x5 : ffff0001fb8e3408 x4 : 0000000000000000 x3 : ffff800179993000 x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff000133d51600 Call trace: refcount_warn_saturate+0xf4/0x148 mlx5_core_put_rsc+0x88/0xa0 [mlx5_ib] mlx5_core_destroy_rq_tracked+0x64/0x98 [mlx5_ib] mlx5_ib_destroy_wq+0x34/0x80 [mlx5_ib] ib_destroy_wq_user+0x30/0xc0 [ib_core] uverbs_free_wq+0x28/0x58 [ib_uverbs] destroy_hw_idr_uobject+0x34/0x78 [ib_uverbs] uverbs_destroy_uobject+0x48/0x240 [ib_uverbs] __uverbs_cleanup_ufile+0xd4/0x1a8 [ib_uverbs] uverbs_destroy_ufile_hw+0x48/0x120 [ib_uverbs] ib_uverbs_close+0x2c/0x100 [ib_uverbs] __fput+0xd8/0x2f0 __fput_sync+0x50/0x70 __arm64_sys_close+0x40/0x90 invoke_syscall.constprop.0+0x74/0xd0 do_el0_svc+0x48/0xe8 el0_svc+0x44/0x1d0 el0t_64_sync_handler+0x120/0x130 el0t_64_sync+0x1a4/0x1a8 Fixes: e2013b212f9f ("net/mlx5_core: Add RQ and SQ event handling") Signed-off-by: Patrisious Haddad Link: https://patch.msgid.link/3181433ccdd695c63560eeeb3f0c990961732101.1745839855.git.leon@kernel.org Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin --- drivers/infiniband/hw/mlx5/qpc.c | 30 ++++++++++++++++++++++++++++-- include/linux/mlx5/driver.h | 1 + 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/mlx5/qpc.c b/drivers/infiniband/hw/mlx5/qpc.c index d9cf6982d645..9de9bea1025e 100644 --- a/drivers/infiniband/hw/mlx5/qpc.c +++ b/drivers/infiniband/hw/mlx5/qpc.c @@ -21,8 +21,10 @@ mlx5_get_rsc(struct mlx5_qp_table *table, u32 rsn) spin_lock_irqsave(&table->lock, flags); common = radix_tree_lookup(&table->tree, rsn); - if (common) + if (common && !common->invalid) refcount_inc(&common->refcount); + else + common = NULL; spin_unlock_irqrestore(&table->lock, flags); @@ -178,6 +180,18 @@ static int create_resource_common(struct mlx5_ib_dev *dev, return 0; } +static void modify_resource_common_state(struct mlx5_ib_dev *dev, + struct mlx5_core_qp *qp, + bool invalid) +{ + struct mlx5_qp_table *table = &dev->qp_table; + unsigned long flags; + + spin_lock_irqsave(&table->lock, flags); + qp->common.invalid = invalid; + spin_unlock_irqrestore(&table->lock, flags); +} + static void destroy_resource_common(struct mlx5_ib_dev *dev, struct mlx5_core_qp *qp) { @@ -604,8 +618,20 @@ err_destroy_rq: int mlx5_core_destroy_rq_tracked(struct mlx5_ib_dev *dev, struct mlx5_core_qp *rq) { + int ret; + + /* The rq destruction can be called again in case it fails, hence we + * mark the common resource as invalid and only once FW destruction + * is completed successfully we actually destroy the resources. + */ + modify_resource_common_state(dev, rq, true); + ret = destroy_rq_tracked(dev, rq->qpn, rq->uid); + if (ret) { + modify_resource_common_state(dev, rq, false); + return ret; + } destroy_resource_common(dev, rq); - return destroy_rq_tracked(dev, rq->qpn, rq->uid); + return 0; } static void destroy_sq_tracked(struct mlx5_ib_dev *dev, u32 sqn, u16 uid) diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index 69d844b34da0..696a2227869f 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -390,6 +390,7 @@ struct mlx5_core_rsc_common { enum mlx5_res_type res; refcount_t refcount; struct completion free; + bool invalid; }; struct mlx5_uars_page { From c60f57a4961915a19637997de6a8000677bea34a Mon Sep 17 00:00:00 2001 From: Anton Protopopov Date: Fri, 2 May 2025 19:30:31 +0000 Subject: [PATCH 156/971] bpf: Fix uninitialized values in BPF_{CORE,PROBE}_READ [ Upstream commit 41d4ce6df3f4945341ec509a840cc002a413b6cc ] With the latest LLVM bpf selftests build will fail with the following error message: progs/profiler.inc.h:710:31: error: default initialization of an object of type 'typeof ((parent_task)->real_cred->uid.val)' (aka 'const unsigned int') leaves the object uninitialized and is incompatible with C++ [-Werror,-Wdefault-const-init-unsafe] 710 | proc_exec_data->parent_uid = BPF_CORE_READ(parent_task, real_cred, uid.val); | ^ tools/testing/selftests/bpf/tools/include/bpf/bpf_core_read.h:520:35: note: expanded from macro 'BPF_CORE_READ' 520 | ___type((src), a, ##__VA_ARGS__) __r; \ | ^ This happens because BPF_CORE_READ (and other macro) declare the variable __r using the ___type macro which can inherit const modifier from intermediate types. Fix this by using __typeof_unqual__, when supported. (And when it is not supported, the problem shouldn't appear, as older compilers haven't complained.) Fixes: 792001f4f7aa ("libbpf: Add user-space variants of BPF_CORE_READ() family of macros") Fixes: a4b09a9ef945 ("libbpf: Add non-CO-RE variants of BPF_CORE_READ() macro family") Signed-off-by: Anton Protopopov Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20250502193031.3522715-1-a.s.protopopov@gmail.com Signed-off-by: Sasha Levin --- tools/lib/bpf/bpf_core_read.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/lib/bpf/bpf_core_read.h b/tools/lib/bpf/bpf_core_read.h index e2b9e8415c04..b3fc384595a9 100644 --- a/tools/lib/bpf/bpf_core_read.h +++ b/tools/lib/bpf/bpf_core_read.h @@ -312,7 +312,13 @@ enum bpf_enum_value_kind { #define ___arrow10(a, b, c, d, e, f, g, h, i, j) a->b->c->d->e->f->g->h->i->j #define ___arrow(...) ___apply(___arrow, ___narg(__VA_ARGS__))(__VA_ARGS__) +#if defined(__clang__) && (__clang_major__ >= 19) +#define ___type(...) __typeof_unqual__(___arrow(__VA_ARGS__)) +#elif defined(__GNUC__) && (__GNUC__ >= 14) +#define ___type(...) __typeof_unqual__(___arrow(__VA_ARGS__)) +#else #define ___type(...) typeof(___arrow(__VA_ARGS__)) +#endif #define ___read(read_fn, dst, src_type, src, accessor) \ read_fn((void *)(dst), sizeof(*(dst)), &((src_type)(src))->accessor) From ac7ab38c271ba2edaeb0dc35b200ec13339776ae Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 7 Apr 2025 12:38:51 -0400 Subject: [PATCH 157/971] tracing: Move histogram trigger variables from stack to per CPU structure [ Upstream commit 7ab0fc61ce73040f89b12d76a8279995ec283541 ] The histogram trigger has three somewhat large arrays on the kernel stack: unsigned long entries[HIST_STACKTRACE_DEPTH]; u64 var_ref_vals[TRACING_MAP_VARS_MAX]; char compound_key[HIST_KEY_SIZE_MAX]; Checking the function event_hist_trigger() stack frame size, it currently uses 816 bytes for its stack frame due to these variables! Instead, allocate a per CPU structure that holds these arrays for each context level (normal, softirq, irq and NMI). That is, each CPU will have 4 of these structures. This will be allocated when the first histogram trigger is enabled and freed when the last is disabled. When the histogram callback triggers, it will request this structure. The request will disable preemption, get the per CPU structure at the index of the per CPU variable, and increment that variable. The callback will use the arrays in this structure to perform its work and then release the structure. That in turn will simply decrement the per CPU index and enable preemption. Moving the variables from the kernel stack to the per CPU structure brings the stack frame of event_hist_trigger() down to just 112 bytes. Cc: Mathieu Desnoyers Cc: Tom Zanussi Link: https://lore.kernel.org/20250407123851.74ea8d58@gandalf.local.home Fixes: 067fe038e70f6 ("tracing: Add variable reference handling to hist triggers") Reviewed-by: Masami Hiramatsu (Google) Signed-off-by: Steven Rostedt (Google) Signed-off-by: Sasha Levin --- kernel/trace/trace_events_hist.c | 120 +++++++++++++++++++++++++++---- 1 file changed, 105 insertions(+), 15 deletions(-) diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index e6f9cbc622c7..29fcd8787344 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -5257,17 +5257,94 @@ hist_trigger_actions(struct hist_trigger_data *hist_data, } } +/* + * The hist_pad structure is used to save information to create + * a histogram from the histogram trigger. It's too big to store + * on the stack, so when the histogram trigger is initialized + * a percpu array of 4 hist_pad structures is allocated. + * This will cover every context from normal, softirq, irq and NMI + * in the very unlikely event that a tigger happens at each of + * these contexts and interrupts a currently active trigger. + */ +struct hist_pad { + unsigned long entries[HIST_STACKTRACE_DEPTH]; + u64 var_ref_vals[TRACING_MAP_VARS_MAX]; + char compound_key[HIST_KEY_SIZE_MAX]; +}; + +static struct hist_pad __percpu *hist_pads; +static DEFINE_PER_CPU(int, hist_pad_cnt); +static refcount_t hist_pad_ref; + +/* One hist_pad for every context (normal, softirq, irq, NMI) */ +#define MAX_HIST_CNT 4 + +static int alloc_hist_pad(void) +{ + lockdep_assert_held(&event_mutex); + + if (refcount_read(&hist_pad_ref)) { + refcount_inc(&hist_pad_ref); + return 0; + } + + hist_pads = __alloc_percpu(sizeof(struct hist_pad) * MAX_HIST_CNT, + __alignof__(struct hist_pad)); + if (!hist_pads) + return -ENOMEM; + + refcount_set(&hist_pad_ref, 1); + return 0; +} + +static void free_hist_pad(void) +{ + lockdep_assert_held(&event_mutex); + + if (!refcount_dec_and_test(&hist_pad_ref)) + return; + + free_percpu(hist_pads); + hist_pads = NULL; +} + +static struct hist_pad *get_hist_pad(void) +{ + struct hist_pad *hist_pad; + int cnt; + + if (WARN_ON_ONCE(!hist_pads)) + return NULL; + + preempt_disable(); + + hist_pad = per_cpu_ptr(hist_pads, smp_processor_id()); + + if (this_cpu_read(hist_pad_cnt) == MAX_HIST_CNT) { + preempt_enable(); + return NULL; + } + + cnt = this_cpu_inc_return(hist_pad_cnt) - 1; + + return &hist_pad[cnt]; +} + +static void put_hist_pad(void) +{ + this_cpu_dec(hist_pad_cnt); + preempt_enable(); +} + static void event_hist_trigger(struct event_trigger_data *data, struct trace_buffer *buffer, void *rec, struct ring_buffer_event *rbe) { struct hist_trigger_data *hist_data = data->private_data; bool use_compound_key = (hist_data->n_keys > 1); - unsigned long entries[HIST_STACKTRACE_DEPTH]; - u64 var_ref_vals[TRACING_MAP_VARS_MAX]; - char compound_key[HIST_KEY_SIZE_MAX]; struct tracing_map_elt *elt = NULL; struct hist_field *key_field; + struct hist_pad *hist_pad; u64 field_contents; void *key = NULL; unsigned int i; @@ -5275,12 +5352,18 @@ static void event_hist_trigger(struct event_trigger_data *data, if (unlikely(!rbe)) return; - memset(compound_key, 0, hist_data->key_size); + hist_pad = get_hist_pad(); + if (!hist_pad) + return; + + memset(hist_pad->compound_key, 0, hist_data->key_size); for_each_hist_key_field(i, hist_data) { key_field = hist_data->fields[i]; if (key_field->flags & HIST_FIELD_FL_STACKTRACE) { + unsigned long *entries = hist_pad->entries; + memset(entries, 0, HIST_STACKTRACE_SIZE); if (key_field->field) { unsigned long *stack, n_entries; @@ -5304,26 +5387,31 @@ static void event_hist_trigger(struct event_trigger_data *data, } if (use_compound_key) - add_to_key(compound_key, key, key_field, rec); + add_to_key(hist_pad->compound_key, key, key_field, rec); } if (use_compound_key) - key = compound_key; + key = hist_pad->compound_key; if (hist_data->n_var_refs && - !resolve_var_refs(hist_data, key, var_ref_vals, false)) - return; + !resolve_var_refs(hist_data, key, hist_pad->var_ref_vals, false)) + goto out; elt = tracing_map_insert(hist_data->map, key); if (!elt) - return; + goto out; - hist_trigger_elt_update(hist_data, elt, buffer, rec, rbe, var_ref_vals); + hist_trigger_elt_update(hist_data, elt, buffer, rec, rbe, hist_pad->var_ref_vals); - if (resolve_var_refs(hist_data, key, var_ref_vals, true)) - hist_trigger_actions(hist_data, elt, buffer, rec, rbe, key, var_ref_vals); + if (resolve_var_refs(hist_data, key, hist_pad->var_ref_vals, true)) { + hist_trigger_actions(hist_data, elt, buffer, rec, rbe, + key, hist_pad->var_ref_vals); + } hist_poll_wakeup(); + + out: + put_hist_pad(); } static void hist_trigger_stacktrace_print(struct seq_file *m, @@ -6168,6 +6256,9 @@ static int event_hist_trigger_init(struct event_trigger_data *data) { struct hist_trigger_data *hist_data = data->private_data; + if (alloc_hist_pad() < 0) + return -ENOMEM; + if (!data->ref && hist_data->attrs->name) save_named_trigger(hist_data->attrs->name, data); @@ -6212,6 +6303,7 @@ static void event_hist_trigger_free(struct event_trigger_data *data) destroy_hist_data(hist_data); } + free_hist_pad(); } static struct event_trigger_ops event_hist_trigger_ops = { @@ -6227,9 +6319,7 @@ static int event_hist_trigger_named_init(struct event_trigger_data *data) save_named_trigger(data->named_data->name, data); - event_hist_trigger_init(data->named_data); - - return 0; + return event_hist_trigger_init(data->named_data); } static void event_hist_trigger_named_free(struct event_trigger_data *data) From a1383eb9d6c45d3208ee5fdb9682435cfc9c0f90 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Fri, 25 Apr 2025 14:12:55 +0200 Subject: [PATCH 158/971] clk: qcom: camcc-sm6350: Add *_wait_val values for GDSCs [ Upstream commit e7b1c13280ad866f3b935f6c658713c41db61635 ] Compared to the msm-4.19 driver the mainline GDSC driver always sets the bits for en_rest, en_few & clk_dis, and if those values are not set per-GDSC in the respective driver then the default value from the GDSC driver is used. The downstream driver only conditionally sets clk_dis_wait_val if qcom,clk-dis-wait-val is given in devicetree. Correct this situation by explicitly setting those values. For all GDSCs the reset value of those bits are used. Fixes: 80f5451d9a7c ("clk: qcom: Add camera clock controller driver for SM6350") Signed-off-by: Luca Weiss Reviewed-by: Taniya Das Link: https://lore.kernel.org/r/20250425-sm6350-gdsc-val-v1-1-1f252d9c5e4e@fairphone.com Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- drivers/clk/qcom/camcc-sm6350.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/clk/qcom/camcc-sm6350.c b/drivers/clk/qcom/camcc-sm6350.c index acba9f99d960..eca36bd3ba5c 100644 --- a/drivers/clk/qcom/camcc-sm6350.c +++ b/drivers/clk/qcom/camcc-sm6350.c @@ -1694,6 +1694,9 @@ static struct clk_branch camcc_sys_tmr_clk = { static struct gdsc bps_gdsc = { .gdscr = 0x6004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "bps_gdsc", }, @@ -1703,6 +1706,9 @@ static struct gdsc bps_gdsc = { static struct gdsc ipe_0_gdsc = { .gdscr = 0x7004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "ipe_0_gdsc", }, @@ -1712,6 +1718,9 @@ static struct gdsc ipe_0_gdsc = { static struct gdsc ife_0_gdsc = { .gdscr = 0x9004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "ife_0_gdsc", }, @@ -1720,6 +1729,9 @@ static struct gdsc ife_0_gdsc = { static struct gdsc ife_1_gdsc = { .gdscr = 0xa004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "ife_1_gdsc", }, @@ -1728,6 +1740,9 @@ static struct gdsc ife_1_gdsc = { static struct gdsc ife_2_gdsc = { .gdscr = 0xb004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "ife_2_gdsc", }, @@ -1736,6 +1751,9 @@ static struct gdsc ife_2_gdsc = { static struct gdsc titan_top_gdsc = { .gdscr = 0x14004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "titan_top_gdsc", }, From f2692b21774d2b60efc53b3c25e48a439e6ddb85 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Fri, 25 Apr 2025 14:12:56 +0200 Subject: [PATCH 159/971] clk: qcom: dispcc-sm6350: Add *_wait_val values for GDSCs [ Upstream commit 673989d27123618afab56df1143a75454178b4ae ] Compared to the msm-4.19 driver the mainline GDSC driver always sets the bits for en_rest, en_few & clk_dis, and if those values are not set per-GDSC in the respective driver then the default value from the GDSC driver is used. The downstream driver only conditionally sets clk_dis_wait_val if qcom,clk-dis-wait-val is given in devicetree. Correct this situation by explicitly setting those values. For all GDSCs the reset value of those bits are used. Fixes: 837519775f1d ("clk: qcom: Add display clock controller driver for SM6350") Signed-off-by: Luca Weiss Reviewed-by: Taniya Das Link: https://lore.kernel.org/r/20250425-sm6350-gdsc-val-v1-2-1f252d9c5e4e@fairphone.com Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- drivers/clk/qcom/dispcc-sm6350.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/clk/qcom/dispcc-sm6350.c b/drivers/clk/qcom/dispcc-sm6350.c index ddacb4f76eca..ea98a63746f0 100644 --- a/drivers/clk/qcom/dispcc-sm6350.c +++ b/drivers/clk/qcom/dispcc-sm6350.c @@ -680,6 +680,9 @@ static struct clk_branch disp_cc_xo_clk = { static struct gdsc mdss_gdsc = { .gdscr = 0x1004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "mdss_gdsc", }, From 7c95e4a31fc45052af31676aac959e2413f5c625 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Fri, 25 Apr 2025 14:12:57 +0200 Subject: [PATCH 160/971] clk: qcom: gcc-sm6350: Add *_wait_val values for GDSCs [ Upstream commit afdfd829a99e467869e3ca1955fb6c6e337c340a ] Compared to the msm-4.19 driver the mainline GDSC driver always sets the bits for en_rest, en_few & clk_dis, and if those values are not set per-GDSC in the respective driver then the default value from the GDSC driver is used. The downstream driver only conditionally sets clk_dis_wait_val if qcom,clk-dis-wait-val is given in devicetree. Correct this situation by explicitly setting those values. For all GDSCs the reset value of those bits are used. Fixes: 131abae905df ("clk: qcom: Add SM6350 GCC driver") Signed-off-by: Luca Weiss Reviewed-by: Taniya Das Link: https://lore.kernel.org/r/20250425-sm6350-gdsc-val-v1-3-1f252d9c5e4e@fairphone.com Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- drivers/clk/qcom/gcc-sm6350.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/clk/qcom/gcc-sm6350.c b/drivers/clk/qcom/gcc-sm6350.c index 428cd99dcdcb..4031613c6236 100644 --- a/drivers/clk/qcom/gcc-sm6350.c +++ b/drivers/clk/qcom/gcc-sm6350.c @@ -2320,6 +2320,9 @@ static struct clk_branch gcc_video_xo_clk = { static struct gdsc usb30_prim_gdsc = { .gdscr = 0x1a004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "usb30_prim_gdsc", }, @@ -2328,6 +2331,9 @@ static struct gdsc usb30_prim_gdsc = { static struct gdsc ufs_phy_gdsc = { .gdscr = 0x3a004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "ufs_phy_gdsc", }, From 012fd59873092a37d78b72a3648eeb717adafece Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Fri, 25 Apr 2025 14:12:58 +0200 Subject: [PATCH 161/971] clk: qcom: gpucc-sm6350: Add *_wait_val values for GDSCs [ Upstream commit d988b0b866c2aeb23aa74022b5bbd463165a7a33 ] Compared to the msm-4.19 driver the mainline GDSC driver always sets the bits for en_rest, en_few & clk_dis, and if those values are not set per-GDSC in the respective driver then the default value from the GDSC driver is used. The downstream driver only conditionally sets clk_dis_wait_val if qcom,clk-dis-wait-val is given in devicetree. Correct this situation by explicitly setting those values. For all GDSCs the reset value of those bits are used, with the exception of gpu_cx_gdsc which has an explicit value (qcom,clk-dis-wait-val = <8>). Fixes: 013804a727a0 ("clk: qcom: Add GPU clock controller driver for SM6350") Signed-off-by: Luca Weiss Reviewed-by: Taniya Das Link: https://lore.kernel.org/r/20250425-sm6350-gdsc-val-v1-4-1f252d9c5e4e@fairphone.com Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- drivers/clk/qcom/gpucc-sm6350.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/clk/qcom/gpucc-sm6350.c b/drivers/clk/qcom/gpucc-sm6350.c index 0bcbba2a2943..86c8ad5b55ba 100644 --- a/drivers/clk/qcom/gpucc-sm6350.c +++ b/drivers/clk/qcom/gpucc-sm6350.c @@ -412,6 +412,9 @@ static struct clk_branch gpu_cc_gx_vsense_clk = { static struct gdsc gpu_cx_gdsc = { .gdscr = 0x106c, .gds_hw_ctrl = 0x1540, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x8, .pd = { .name = "gpu_cx_gdsc", }, @@ -422,6 +425,9 @@ static struct gdsc gpu_cx_gdsc = { static struct gdsc gpu_gx_gdsc = { .gdscr = 0x100c, .clamp_io_ctrl = 0x1508, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, .pd = { .name = "gpu_gx_gdsc", .power_on = gdsc_gx_do_nothing_enable, From 3c1adc2f8c732ea09e8c4bce5941fec019c6205d Mon Sep 17 00:00:00 2001 From: Henry Martin Date: Wed, 2 Apr 2025 10:05:13 +0800 Subject: [PATCH 162/971] clk: bcm: rpi: Add NULL check in raspberrypi_clk_register() [ Upstream commit 73c46d9a93d071ca69858dea3f569111b03e549e ] devm_kasprintf() returns NULL when memory allocation fails. Currently, raspberrypi_clk_register() does not check for this case, which results in a NULL pointer dereference. Add NULL check after devm_kasprintf() to prevent this issue. Fixes: 93d2725affd6 ("clk: bcm: rpi: Discover the firmware clocks") Signed-off-by: Henry Martin Reviewed-by: Dave Stevenson Link: https://lore.kernel.org/r/20250402020513.42628-1-bsdhenrymartin@gmail.com Reviewed-by: Stefan Wahren Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/bcm/clk-raspberrypi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c index 4d411408e4af..cc4ca336ac13 100644 --- a/drivers/clk/bcm/clk-raspberrypi.c +++ b/drivers/clk/bcm/clk-raspberrypi.c @@ -271,6 +271,8 @@ static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi, init.name = devm_kasprintf(rpi->dev, GFP_KERNEL, "fw-clk-%s", rpi_firmware_clk_names[id]); + if (!init.name) + return ERR_PTR(-ENOMEM); init.ops = &raspberrypi_firmware_clk_ops; init.flags = CLK_GET_RATE_NOCACHE; From 3f7724fcc1935d2815d2e401f24b154674701b98 Mon Sep 17 00:00:00 2001 From: Hans Zhang <18255117159@163.com> Date: Wed, 7 May 2025 00:31:11 +0800 Subject: [PATCH 163/971] efi/libstub: Describe missing 'out' parameter in efi_load_initrd [ Upstream commit c8e1927e7f7d63721e32ec41d27ccb0eb1a1b0fc ] The function efi_load_initrd() had a documentation warning due to the missing description for the 'out' parameter. Add the parameter description to the kernel-doc comment to resolve the warning and improve API documentation. Fixes the following compiler warning: drivers/firmware/efi/libstub/efi-stub-helper.c:611: warning: Function parameter or struct member 'out' not described in 'efi_load_initrd' Fixes: f4dc7fffa987 ("efi: libstub: unify initrd loading between architectures") Signed-off-by: Hans Zhang <18255117159@163.com> Signed-off-by: Ard Biesheuvel Signed-off-by: Sasha Levin --- drivers/firmware/efi/libstub/efi-stub-helper.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index 3dc2f9aaf08d..492d09b6048b 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -561,6 +561,7 @@ efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image, * @image: EFI loaded image protocol * @soft_limit: preferred address for loading the initrd * @hard_limit: upper limit address for loading the initrd + * @out: pointer to store the address of the initrd table * * Return: status code */ From ae015964d7ffc9bae5b28cabedc0389fe8a4905e Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 7 May 2025 10:53:06 -0400 Subject: [PATCH 164/971] tracing: Rename event_trigger_alloc() to trigger_data_alloc() [ Upstream commit f2947c4b7d0f235621c5daf78aecfbd6e22c05e5 ] The function event_trigger_alloc() creates an event_trigger_data descriptor and states that it needs to be freed via event_trigger_free(). This is incorrect, it needs to be freed by trigger_data_free() as event_trigger_free() adds ref counting. Rename event_trigger_alloc() to trigger_data_alloc() and state that it needs to be freed via trigger_data_free(). This naming convention was introducing bugs. Cc: Masami Hiramatsu Cc: Mark Rutland Cc: Mathieu Desnoyers Cc: Andrew Morton Cc: Tom Zanussi Link: https://lore.kernel.org/20250507145455.776436410@goodmis.org Fixes: 86599dbe2c527 ("tracing: Add helper functions to simplify event_command.parse() callback handling") Signed-off-by: Steven Rostedt (Google) Signed-off-by: Sasha Levin --- kernel/trace/trace.h | 8 +++----- kernel/trace/trace_events_hist.c | 2 +- kernel/trace/trace_events_trigger.c | 16 ++++++++-------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index faf892aecdf4..e3afb830fbcc 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -1643,6 +1643,9 @@ extern int event_enable_register_trigger(char *glob, extern void event_enable_unregister_trigger(char *glob, struct event_trigger_data *test, struct trace_event_file *file); +extern struct event_trigger_data * +trigger_data_alloc(struct event_command *cmd_ops, char *cmd, char *param, + void *private_data); extern void trigger_data_free(struct event_trigger_data *data); extern int event_trigger_init(struct event_trigger_data *data); extern int trace_event_trigger_enable_disable(struct trace_event_file *file, @@ -1669,11 +1672,6 @@ extern bool event_trigger_check_remove(const char *glob); extern bool event_trigger_empty_param(const char *param); extern int event_trigger_separate_filter(char *param_and_filter, char **param, char **filter, bool param_required); -extern struct event_trigger_data * -event_trigger_alloc(struct event_command *cmd_ops, - char *cmd, - char *param, - void *private_data); extern int event_trigger_parse_num(char *trigger, struct event_trigger_data *trigger_data); extern int event_trigger_set_filter(struct event_command *cmd_ops, diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index 29fcd8787344..88985aefb71f 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -6806,7 +6806,7 @@ static int event_hist_trigger_parse(struct event_command *cmd_ops, return PTR_ERR(hist_data); } - trigger_data = event_trigger_alloc(cmd_ops, cmd, param, hist_data); + trigger_data = trigger_data_alloc(cmd_ops, cmd, param, hist_data); if (!trigger_data) { ret = -ENOMEM; goto out_free; diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c index 2c233c0d38fa..4c92def8b114 100644 --- a/kernel/trace/trace_events_trigger.c +++ b/kernel/trace/trace_events_trigger.c @@ -809,7 +809,7 @@ out: } /** - * event_trigger_alloc - allocate and init event_trigger_data for a trigger + * trigger_data_alloc - allocate and init event_trigger_data for a trigger * @cmd_ops: The event_command operations for the trigger * @cmd: The cmd string * @param: The param string @@ -820,14 +820,14 @@ out: * trigger_ops to assign to the event_trigger_data. @private_data can * also be passed in and associated with the event_trigger_data. * - * Use event_trigger_free() to free an event_trigger_data object. + * Use trigger_data_free() to free an event_trigger_data object. * * Return: The trigger_data object success, NULL otherwise */ -struct event_trigger_data *event_trigger_alloc(struct event_command *cmd_ops, - char *cmd, - char *param, - void *private_data) +struct event_trigger_data *trigger_data_alloc(struct event_command *cmd_ops, + char *cmd, + char *param, + void *private_data) { struct event_trigger_data *trigger_data; struct event_trigger_ops *trigger_ops; @@ -994,7 +994,7 @@ event_trigger_parse(struct event_command *cmd_ops, return ret; ret = -ENOMEM; - trigger_data = event_trigger_alloc(cmd_ops, cmd, param, file); + trigger_data = trigger_data_alloc(cmd_ops, cmd, param, file); if (!trigger_data) goto out; @@ -1787,7 +1787,7 @@ int event_enable_trigger_parse(struct event_command *cmd_ops, enable_data->enable = enable; enable_data->file = event_enable_file; - trigger_data = event_trigger_alloc(cmd_ops, cmd, param, enable_data); + trigger_data = trigger_data_alloc(cmd_ops, cmd, param, enable_data); if (!trigger_data) { kfree(enable_data); goto out; From 94ade4147a094cc407827539ee75873957efd290 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Wed, 7 May 2025 10:53:07 -0400 Subject: [PATCH 165/971] tracing: Fix error handling in event_trigger_parse() [ Upstream commit c5dd28e7fb4f63475b50df4f58311df92939d011 ] According to trigger_data_alloc() doc, trigger_data_free() should be used to free an event_trigger_data object. This fixes a mismatch introduced when kzalloc was replaced with trigger_data_alloc without updating the corresponding deallocation calls. Cc: Masami Hiramatsu Cc: Mark Rutland Cc: Andrew Morton Cc: Mathieu Desnoyers Cc: Tom Zanussi Link: https://lore.kernel.org/20250507145455.944453325@goodmis.org Link: https://lore.kernel.org/20250318112737.4174-1-linmq006@gmail.com Fixes: e1f187d09e11 ("tracing: Have existing event_command.parse() implementations use helpers") Signed-off-by: Miaoqian Lin [ SDR: Changed event_trigger_alloc/free() to trigger_data_alloc/free() ] Signed-off-by: Steven Rostedt (Google) Signed-off-by: Sasha Levin --- kernel/trace/trace_events_trigger.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c index 4c92def8b114..fe079ff82ef1 100644 --- a/kernel/trace/trace_events_trigger.c +++ b/kernel/trace/trace_events_trigger.c @@ -1000,7 +1000,7 @@ event_trigger_parse(struct event_command *cmd_ops, if (remove) { event_trigger_unregister(cmd_ops, file, glob+1, trigger_data); - kfree(trigger_data); + trigger_data_free(trigger_data); ret = 0; goto out; } @@ -1027,7 +1027,7 @@ event_trigger_parse(struct event_command *cmd_ops, out_free: event_trigger_reset_filter(cmd_ops, trigger_data); - kfree(trigger_data); + trigger_data_free(trigger_data); goto out; } From 07680e38b78d69c294ebc60f5c3a335fb7d793fc Mon Sep 17 00:00:00 2001 From: Jiayuan Chen Date: Fri, 25 Apr 2025 13:59:57 +0800 Subject: [PATCH 166/971] ktls, sockmap: Fix missing uncharge operation [ Upstream commit 79f0c39ae7d3dc628c01b02f23ca5d01f9875040 ] When we specify apply_bytes, we divide the msg into multiple segments, each with a length of 'send', and every time we send this part of the data using tcp_bpf_sendmsg_redir(), we use sk_msg_return_zero() to uncharge the memory of the specified 'send' size. However, if the first segment of data fails to send, for example, the peer's buffer is full, we need to release all of the msg. When releasing the msg, we haven't uncharged the memory of the subsequent segments. This modification does not make significant logical changes, but only fills in the missing uncharge places. This issue has existed all along, until it was exposed after we added the apply test in test_sockmap: commit 3448ad23b34e ("selftests/bpf: Add apply_bytes test to test_txmsg_redir_wait_sndmem in test_sockmap") Fixes: d3b18ad31f93 ("tls: add bpf support to sk_msg handling") Reported-by: Cong Wang Closes: https://lore.kernel.org/bpf/aAmIi0vlycHtbXeb@pop-os.localdomain/T/#t Signed-off-by: Jiayuan Chen Signed-off-by: Martin KaFai Lau Acked-by: John Fastabend Reviewed-by: Cong Wang Link: https://lore.kernel.org/r/20250425060015.6968-2-jiayuan.chen@linux.dev Signed-off-by: Sasha Levin --- net/tls/tls_sw.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index bf445a518883..4a9a3aed5d6d 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -908,6 +908,13 @@ more_data: &msg_redir, send, flags); lock_sock(sk); if (err < 0) { + /* Regardless of whether the data represented by + * msg_redir is sent successfully, we have already + * uncharged it via sk_msg_return_zero(). The + * msg->sg.size represents the remaining unprocessed + * data, which needs to be uncharged here. + */ + sk_mem_uncharge(sk, msg->sg.size); *copied -= sk_msg_free_nocharge(sk, &msg_redir); msg->sg.size = 0; } From b44672c17ca02838a0a26739390e9550c8c1f054 Mon Sep 17 00:00:00 2001 From: Anton Protopopov Date: Sat, 10 May 2025 18:20:11 +0000 Subject: [PATCH 167/971] libbpf: Use proper errno value in nlattr [ Upstream commit fd5fd538a1f4b34cee6823ba0ddda2f7a55aca96 ] Return value of the validate_nla() function can be propagated all the way up to users of libbpf API. In case of error this libbpf version of validate_nla returns -1 which will be seen as -EPERM from user's point of view. Instead, return a more reasonable -EINVAL. Fixes: bbf48c18ee0c ("libbpf: add error reporting in XDP") Suggested-by: Andrii Nakryiko Signed-off-by: Anton Protopopov Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20250510182011.2246631-1-a.s.protopopov@gmail.com Signed-off-by: Sasha Levin --- tools/lib/bpf/nlattr.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/tools/lib/bpf/nlattr.c b/tools/lib/bpf/nlattr.c index 975e265eab3b..06663f9ea581 100644 --- a/tools/lib/bpf/nlattr.c +++ b/tools/lib/bpf/nlattr.c @@ -63,16 +63,16 @@ static int validate_nla(struct nlattr *nla, int maxtype, minlen = nla_attr_minlen[pt->type]; if (libbpf_nla_len(nla) < minlen) - return -1; + return -EINVAL; if (pt->maxlen && libbpf_nla_len(nla) > pt->maxlen) - return -1; + return -EINVAL; if (pt->type == LIBBPF_NLA_STRING) { char *data = libbpf_nla_data(nla); if (data[libbpf_nla_len(nla) - 1] != '\0') - return -1; + return -EINVAL; } return 0; @@ -118,19 +118,18 @@ int libbpf_nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, if (policy) { err = validate_nla(nla, maxtype, policy); if (err < 0) - goto errout; + return err; } - if (tb[type]) + if (tb[type]) { pr_warn("Attribute of type %#x found multiple times in message, " "previous attribute is being ignored.\n", type); + } tb[type] = nla; } - err = 0; -errout: - return err; + return 0; } /** From eb435bc4c74acbb286cec773deac13d117d3ef39 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 8 May 2025 23:08:07 +0300 Subject: [PATCH 168/971] pinctrl: at91: Fix possible out-of-boundary access [ Upstream commit 762ef7d1e6eefad9896560bfcb9bcf7f1b6df9c1 ] at91_gpio_probe() doesn't check that given OF alias is not available or something went wrong when trying to get it. This might have consequences when accessing gpio_chips array with that value as an index. Note, that BUG() can be compiled out and hence won't actually perform the required checks. Fixes: 6732ae5cb47c ("ARM: at91: add pinctrl support") Signed-off-by: Andy Shevchenko Closes: https://lore.kernel.org/r/202505052343.UHF1Zo93-lkp@intel.com/ Link: https://lore.kernel.org/20250508200807.1384558-1-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin --- drivers/pinctrl/pinctrl-at91.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index d7b66928a4e5..3c09f743b68c 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -1825,12 +1825,16 @@ static int at91_gpio_probe(struct platform_device *pdev) struct at91_gpio_chip *at91_chip = NULL; struct gpio_chip *chip; struct pinctrl_gpio_range *range; + int alias_idx; int ret = 0; int irq, i; - int alias_idx = of_alias_get_id(np, "gpio"); uint32_t ngpio; char **names; + alias_idx = of_alias_get_id(np, "gpio"); + if (alias_idx < 0) + return alias_idx; + BUG_ON(alias_idx >= ARRAY_SIZE(gpio_chips)); if (gpio_chips[alias_idx]) return dev_err_probe(dev, -EBUSY, "%d slot is occupied.\n", alias_idx); From 6d8f39875a10a194051c3eaefebc7ac06a34aaf3 Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Tue, 13 May 2025 12:27:47 +0800 Subject: [PATCH 169/971] bpf: Fix WARN() in get_bpf_raw_tp_regs [ Upstream commit 3880cdbed1c4607e378f58fa924c5d6df900d1d3 ] syzkaller reported an issue: WARNING: CPU: 3 PID: 5971 at kernel/trace/bpf_trace.c:1861 get_bpf_raw_tp_regs+0xa4/0x100 kernel/trace/bpf_trace.c:1861 Modules linked in: CPU: 3 UID: 0 PID: 5971 Comm: syz-executor205 Not tainted 6.15.0-rc5-syzkaller-00038-g707df3375124 #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 RIP: 0010:get_bpf_raw_tp_regs+0xa4/0x100 kernel/trace/bpf_trace.c:1861 RSP: 0018:ffffc90003636fa8 EFLAGS: 00010293 RAX: 0000000000000000 RBX: 0000000000000003 RCX: ffffffff81c6bc4c RDX: ffff888032efc880 RSI: ffffffff81c6bc83 RDI: 0000000000000005 RBP: ffff88806a730860 R08: 0000000000000005 R09: 0000000000000003 R10: 0000000000000004 R11: 0000000000000000 R12: 0000000000000004 R13: 0000000000000001 R14: ffffc90003637008 R15: 0000000000000900 FS: 0000000000000000(0000) GS:ffff8880d6cdf000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f7baee09130 CR3: 0000000029f5a000 CR4: 0000000000352ef0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: ____bpf_get_stack_raw_tp kernel/trace/bpf_trace.c:1934 [inline] bpf_get_stack_raw_tp+0x24/0x160 kernel/trace/bpf_trace.c:1931 bpf_prog_ec3b2eefa702d8d3+0x43/0x47 bpf_dispatcher_nop_func include/linux/bpf.h:1316 [inline] __bpf_prog_run include/linux/filter.h:718 [inline] bpf_prog_run include/linux/filter.h:725 [inline] __bpf_trace_run kernel/trace/bpf_trace.c:2363 [inline] bpf_trace_run3+0x23f/0x5a0 kernel/trace/bpf_trace.c:2405 __bpf_trace_mmap_lock_acquire_returned+0xfc/0x140 include/trace/events/mmap_lock.h:47 __traceiter_mmap_lock_acquire_returned+0x79/0xc0 include/trace/events/mmap_lock.h:47 __do_trace_mmap_lock_acquire_returned include/trace/events/mmap_lock.h:47 [inline] trace_mmap_lock_acquire_returned include/trace/events/mmap_lock.h:47 [inline] __mmap_lock_do_trace_acquire_returned+0x138/0x1f0 mm/mmap_lock.c:35 __mmap_lock_trace_acquire_returned include/linux/mmap_lock.h:36 [inline] mmap_read_trylock include/linux/mmap_lock.h:204 [inline] stack_map_get_build_id_offset+0x535/0x6f0 kernel/bpf/stackmap.c:157 __bpf_get_stack+0x307/0xa10 kernel/bpf/stackmap.c:483 ____bpf_get_stack kernel/bpf/stackmap.c:499 [inline] bpf_get_stack+0x32/0x40 kernel/bpf/stackmap.c:496 ____bpf_get_stack_raw_tp kernel/trace/bpf_trace.c:1941 [inline] bpf_get_stack_raw_tp+0x124/0x160 kernel/trace/bpf_trace.c:1931 bpf_prog_ec3b2eefa702d8d3+0x43/0x47 Tracepoint like trace_mmap_lock_acquire_returned may cause nested call as the corner case show above, which will be resolved with more general method in the future. As a result, WARN_ON_ONCE will be triggered. As Alexei suggested, remove the WARN_ON_ONCE first. Fixes: 9594dc3c7e71 ("bpf: fix nested bpf tracepoints with per-cpu data") Reported-by: syzbot+45b0c89a0fc7ae8dbadc@syzkaller.appspotmail.com Suggested-by: Alexei Starovoitov Signed-off-by: Tao Chen Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20250513042747.757042-1-chen.dylane@linux.dev Closes: https://lore.kernel.org/bpf/8bc2554d-1052-4922-8832-e0078a033e1d@gmail.com Signed-off-by: Sasha Levin --- kernel/trace/bpf_trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 97f660a8ddc7..8903db0b5960 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -1834,7 +1834,7 @@ static struct pt_regs *get_bpf_raw_tp_regs(void) struct bpf_raw_tp_regs *tp_regs = this_cpu_ptr(&bpf_raw_tp_regs); int nest_level = this_cpu_inc_return(bpf_raw_tp_nest_level); - if (WARN_ON_ONCE(nest_level > ARRAY_SIZE(tp_regs->regs))) { + if (nest_level > ARRAY_SIZE(tp_regs->regs)) { this_cpu_dec(bpf_raw_tp_nest_level); return ERR_PTR(-EBUSY); } From fbd4d6293b539a217db22f444683419cccea6cca Mon Sep 17 00:00:00 2001 From: Vincent Knecht Date: Mon, 14 Apr 2025 18:45:12 +0200 Subject: [PATCH 170/971] clk: qcom: gcc-msm8939: Fix mclk0 & mclk1 for 24 MHz [ Upstream commit 9e7acf70cf6aa7b22f67d911f50a8cd510e8fb00 ] Fix mclk0 & mclk1 parent map to use correct GPLL6 configuration and freq_tbl to use GPLL6 instead of GPLL0 so that they tick at 24 MHz. Fixes: 1664014e4679 ("clk: qcom: gcc-msm8939: Add MSM8939 Generic Clock Controller") Suggested-by: Stephan Gerhold Reviewed-by: Konrad Dybcio Reviewed-by: Bryan O'Donoghue Signed-off-by: Vincent Knecht Link: https://lore.kernel.org/r/20250414-gcc-msm8939-fixes-mclk-v2-resend2-v2-1-5ddcf572a6de@mailoo.org Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- drivers/clk/qcom/gcc-msm8939.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/gcc-msm8939.c b/drivers/clk/qcom/gcc-msm8939.c index b45f97c07eeb..e4a44377b75f 100644 --- a/drivers/clk/qcom/gcc-msm8939.c +++ b/drivers/clk/qcom/gcc-msm8939.c @@ -432,7 +432,7 @@ static const struct parent_map gcc_xo_gpll0_gpll1a_gpll6_sleep_map[] = { { P_XO, 0 }, { P_GPLL0, 1 }, { P_GPLL1_AUX, 2 }, - { P_GPLL6, 2 }, + { P_GPLL6, 3 }, { P_SLEEP_CLK, 6 }, }; @@ -1100,7 +1100,7 @@ static struct clk_rcg2 jpeg0_clk_src = { }; static const struct freq_tbl ftbl_gcc_camss_mclk0_1_clk[] = { - F(24000000, P_GPLL0, 1, 1, 45), + F(24000000, P_GPLL6, 1, 1, 45), F(66670000, P_GPLL0, 12, 0, 0), { } }; From f61b8fecec96ea9d4c931ea2abf9b7a3a66cba78 Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Mon, 12 May 2025 14:26:15 +0200 Subject: [PATCH 171/971] s390/bpf: Store backchain even for leaf progs [ Upstream commit 5f55f2168432298f5a55294831ab6a76a10cb3c3 ] Currently a crash in a leaf prog (caused by a bug) produces the following call trace: [<000003ff600ebf00>] bpf_prog_6df0139e1fbf2789_fentry+0x20/0x78 [<0000000000000000>] 0x0 This is because leaf progs do not store backchain. Fix by making all progs do it. This is what GCC and Clang-generated code does as well. Now the call trace looks like this: [<000003ff600eb0f2>] bpf_prog_6df0139e1fbf2789_fentry+0x2a/0x80 [<000003ff600ed096>] bpf_trampoline_201863462940+0x96/0xf4 [<000003ff600e3a40>] bpf_prog_05f379658fdd72f2_classifier_0+0x58/0xc0 [<000003ffe0aef070>] bpf_test_run+0x210/0x390 [<000003ffe0af0dc2>] bpf_prog_test_run_skb+0x25a/0x668 [<000003ffe038a90e>] __sys_bpf+0xa46/0xdb0 [<000003ffe038ad0c>] __s390x_sys_bpf+0x44/0x50 [<000003ffe0defea8>] __do_syscall+0x150/0x280 [<000003ffe0e01d5c>] system_call+0x74/0x98 Fixes: 054623105728 ("s390/bpf: Add s390x eBPF JIT compiler backend") Signed-off-by: Ilya Leoshkevich Link: https://lore.kernel.org/r/20250512122717.54878-1-iii@linux.ibm.com Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin --- arch/s390/net/bpf_jit_comp.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 62ee557d4b49..a40c7ff91caf 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -587,17 +587,15 @@ static void bpf_jit_prologue(struct bpf_jit *jit, struct bpf_prog *fp, } /* Setup stack and backchain */ if (is_first_pass(jit) || (jit->seen & SEEN_STACK)) { - if (is_first_pass(jit) || (jit->seen & SEEN_FUNC)) - /* lgr %w1,%r15 (backchain) */ - EMIT4(0xb9040000, REG_W1, REG_15); + /* lgr %w1,%r15 (backchain) */ + EMIT4(0xb9040000, REG_W1, REG_15); /* la %bfp,STK_160_UNUSED(%r15) (BPF frame pointer) */ EMIT4_DISP(0x41000000, BPF_REG_FP, REG_15, STK_160_UNUSED); /* aghi %r15,-STK_OFF */ EMIT4_IMM(0xa70b0000, REG_15, -(STK_OFF + stack_depth)); - if (is_first_pass(jit) || (jit->seen & SEEN_FUNC)) - /* stg %w1,152(%r15) (backchain) */ - EMIT6_DISP_LH(0xe3000000, 0x0024, REG_W1, REG_0, - REG_15, 152); + /* stg %w1,152(%r15) (backchain) */ + EMIT6_DISP_LH(0xe3000000, 0x0024, REG_W1, REG_0, + REG_15, 152); } } From 74e18211c2c89ab66c9546baa7408288db61aa0d Mon Sep 17 00:00:00 2001 From: Alexey Kodanev Date: Tue, 13 May 2025 12:13:04 +0000 Subject: [PATCH 172/971] wifi: rtw88: fix the 'para' buffer size to avoid reading out of bounds [ Upstream commit 4c2c372de2e108319236203cce6de44d70ae15cd ] Set the size to 6 instead of 2, since 'para' array is passed to 'rtw_fw_bt_wifi_control(rtwdev, para[0], ¶[1])', which reads 5 bytes: void rtw_fw_bt_wifi_control(struct rtw_dev *rtwdev, u8 op_code, u8 *data) { ... SET_BT_WIFI_CONTROL_DATA1(h2c_pkt, *data); SET_BT_WIFI_CONTROL_DATA2(h2c_pkt, *(data + 1)); ... SET_BT_WIFI_CONTROL_DATA5(h2c_pkt, *(data + 4)); Detected using the static analysis tool - Svace. Fixes: 4136214f7c46 ("rtw88: add BT co-existence support") Signed-off-by: Alexey Kodanev Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250513121304.124141-1-aleksei.kodanev@bell-sw.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtw88/coex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c index d35f26919806..c45c7b596ffe 100644 --- a/drivers/net/wireless/realtek/rtw88/coex.c +++ b/drivers/net/wireless/realtek/rtw88/coex.c @@ -309,7 +309,7 @@ static void rtw_coex_tdma_timer_base(struct rtw_dev *rtwdev, u8 type) { struct rtw_coex *coex = &rtwdev->coex; struct rtw_coex_stat *coex_stat = &coex->stat; - u8 para[2] = {0}; + u8 para[6] = {}; u8 times; u16 tbtt_interval = coex_stat->wl_beacon_interval; From 4b1cf1f040a0a931cd7287ca3015d3b5e9322ae2 Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Mon, 12 May 2025 15:10:44 +0200 Subject: [PATCH 173/971] iommu: remove duplicate selection of DMAR_TABLE [ Upstream commit 9548feff840a05d61783e6316d08ed37e115f3b1 ] This is already done in intel/Kconfig. Fixes: 70bad345e622 ("iommu: Fix compilation without CONFIG_IOMMU_INTEL") Signed-off-by: Rolf Eike Beer Reviewed-by: Lu Baolu Link: https://lore.kernel.org/r/2232605.Mh6RI2rZIc@devpool92.emlix.com Signed-off-by: Joerg Roedel Signed-off-by: Sasha Levin --- drivers/iommu/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index d57c5adf932e..20aa5ed80aa3 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -191,7 +191,6 @@ source "drivers/iommu/iommufd/Kconfig" config IRQ_REMAP bool "Support for Interrupt Remapping" depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI - select DMAR_TABLE if INTEL_IOMMU help Supports Interrupt remapping for IO-APIC and MSI devices. To use x2apic mode in the CPU's which support x2APIC enhancements or From 99dbad1b01d3b2f361a9db55c1af1212be497a3d Mon Sep 17 00:00:00 2001 From: Rajat Soni Date: Wed, 30 Apr 2025 10:25:38 +0530 Subject: [PATCH 174/971] wifi: ath12k: fix memory leak in ath12k_service_ready_ext_event [ Upstream commit 89142d34d5602c7447827beb181fa06eb08b9d5c ] Currently, in ath12k_service_ready_ext_event(), svc_rdy_ext.mac_phy_caps is not freed in the failure case, causing a memory leak. The following trace is observed in kmemleak: unreferenced object 0xffff8b3eb5789c00 (size 1024): comm "softirq", pid 0, jiffies 4294942577 hex dump (first 32 bytes): 00 00 00 00 01 00 00 00 00 00 00 00 7b 00 00 10 ............{... 01 00 00 00 00 00 00 00 01 00 00 00 1f 38 00 00 .............8.. backtrace (crc 44e1c357): __kmalloc_noprof+0x30b/0x410 ath12k_wmi_mac_phy_caps_parse+0x84/0x100 [ath12k] ath12k_wmi_tlv_iter+0x5e/0x140 [ath12k] ath12k_wmi_svc_rdy_ext_parse+0x308/0x4c0 [ath12k] ath12k_wmi_tlv_iter+0x5e/0x140 [ath12k] ath12k_service_ready_ext_event.isra.0+0x44/0xd0 [ath12k] ath12k_wmi_op_rx+0x2eb/0xd70 [ath12k] ath12k_htc_rx_completion_handler+0x1f4/0x330 [ath12k] ath12k_ce_recv_process_cb+0x218/0x300 [ath12k] ath12k_pci_ce_workqueue+0x1b/0x30 [ath12k] process_one_work+0x219/0x680 bh_worker+0x198/0x1f0 tasklet_action+0x13/0x30 handle_softirqs+0xca/0x460 __irq_exit_rcu+0xbe/0x110 irq_exit_rcu+0x9/0x30 Free svc_rdy_ext.mac_phy_caps in the error case to fix this memory leak. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") Signed-off-by: Rajat Soni Signed-off-by: Raj Kumar Bhagat Link: https://patch.msgid.link/20250430-wmi-mem-leak-v1-1-fcc9b49c2ddc@quicinc.com Signed-off-by: Jeff Johnson Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath12k/wmi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index a96bf261a3f7..a0ac2f350934 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -4128,6 +4128,7 @@ static int ath12k_service_ready_ext_event(struct ath12k_base *ab, return 0; err: + kfree(svc_rdy_ext.mac_phy_caps); ath12k_wmi_free_dbring_caps(ab); return ret; } From f0423873e7aeb69cb68f4e8fa3827832e7b037ba Mon Sep 17 00:00:00 2001 From: Longfang Liu Date: Sat, 10 May 2025 16:11:50 +0800 Subject: [PATCH 175/971] hisi_acc_vfio_pci: fix XQE dma address error [ Upstream commit 8bb7170c5a055ea17c6857c256ee73c10ff872eb ] The dma addresses of EQE and AEQE are wrong after migration and results in guest kernel-mode encryption services failure. Comparing the definition of hardware registers, we found that there was an error when the data read from the register was combined into an address. Therefore, the address combination sequence needs to be corrected. Even after fixing the above problem, we still have an issue where the Guest from an old kernel can get migrated to new kernel and may result in wrong data. In order to ensure that the address is correct after migration, if an old magic number is detected, the dma address needs to be updated. Fixes: b0eed085903e ("hisi_acc_vfio_pci: Add support for VFIO live migration") Signed-off-by: Longfang Liu Reviewed-by: Shameer Kolothum Link: https://lore.kernel.org/r/20250510081155.55840-2-liulongfang@huawei.com Signed-off-by: Alex Williamson Signed-off-by: Sasha Levin --- .../vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 41 ++++++++++++++++--- .../vfio/pci/hisilicon/hisi_acc_vfio_pci.h | 14 ++++++- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c index 4d27465c8f1a..d09e7d295625 100644 --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c @@ -350,6 +350,32 @@ static int vf_qm_func_stop(struct hisi_qm *qm) return hisi_qm_mb(qm, QM_MB_CMD_PAUSE_QM, 0, 0, 0); } +static int vf_qm_version_check(struct acc_vf_data *vf_data, struct device *dev) +{ + switch (vf_data->acc_magic) { + case ACC_DEV_MAGIC_V2: + if (vf_data->major_ver != ACC_DRV_MAJOR_VER) { + dev_info(dev, "migration driver version<%u.%u> not match!\n", + vf_data->major_ver, vf_data->minor_ver); + return -EINVAL; + } + break; + case ACC_DEV_MAGIC_V1: + /* Correct dma address */ + vf_data->eqe_dma = vf_data->qm_eqc_dw[QM_XQC_ADDR_HIGH]; + vf_data->eqe_dma <<= QM_XQC_ADDR_OFFSET; + vf_data->eqe_dma |= vf_data->qm_eqc_dw[QM_XQC_ADDR_LOW]; + vf_data->aeqe_dma = vf_data->qm_aeqc_dw[QM_XQC_ADDR_HIGH]; + vf_data->aeqe_dma <<= QM_XQC_ADDR_OFFSET; + vf_data->aeqe_dma |= vf_data->qm_aeqc_dw[QM_XQC_ADDR_LOW]; + break; + default: + return -EINVAL; + } + + return 0; +} + static int vf_qm_check_match(struct hisi_acc_vf_core_device *hisi_acc_vdev, struct hisi_acc_vf_migration_file *migf) { @@ -363,7 +389,8 @@ static int vf_qm_check_match(struct hisi_acc_vf_core_device *hisi_acc_vdev, if (migf->total_length < QM_MATCH_SIZE || hisi_acc_vdev->match_done) return 0; - if (vf_data->acc_magic != ACC_DEV_MAGIC) { + ret = vf_qm_version_check(vf_data, dev); + if (ret) { dev_err(dev, "failed to match ACC_DEV_MAGIC\n"); return -EINVAL; } @@ -418,7 +445,9 @@ static int vf_qm_get_match_data(struct hisi_acc_vf_core_device *hisi_acc_vdev, int vf_id = hisi_acc_vdev->vf_id; int ret; - vf_data->acc_magic = ACC_DEV_MAGIC; + vf_data->acc_magic = ACC_DEV_MAGIC_V2; + vf_data->major_ver = ACC_DRV_MAJOR_VER; + vf_data->minor_ver = ACC_DRV_MINOR_VER; /* Save device id */ vf_data->dev_id = hisi_acc_vdev->vf_dev->device; @@ -516,12 +545,12 @@ static int vf_qm_state_save(struct hisi_acc_vf_core_device *hisi_acc_vdev, return -EINVAL; /* Every reg is 32 bit, the dma address is 64 bit. */ - vf_data->eqe_dma = vf_data->qm_eqc_dw[1]; + vf_data->eqe_dma = vf_data->qm_eqc_dw[QM_XQC_ADDR_HIGH]; vf_data->eqe_dma <<= QM_XQC_ADDR_OFFSET; - vf_data->eqe_dma |= vf_data->qm_eqc_dw[0]; - vf_data->aeqe_dma = vf_data->qm_aeqc_dw[1]; + vf_data->eqe_dma |= vf_data->qm_eqc_dw[QM_XQC_ADDR_LOW]; + vf_data->aeqe_dma = vf_data->qm_aeqc_dw[QM_XQC_ADDR_HIGH]; vf_data->aeqe_dma <<= QM_XQC_ADDR_OFFSET; - vf_data->aeqe_dma |= vf_data->qm_aeqc_dw[0]; + vf_data->aeqe_dma |= vf_data->qm_aeqc_dw[QM_XQC_ADDR_LOW]; /* Through SQC_BT/CQC_BT to get sqc and cqc address */ ret = qm_get_sqc(vf_qm, &vf_data->sqc_dma); diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h index dcabfeec6ca1..f1d8fe86b6eb 100644 --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h @@ -38,6 +38,9 @@ #define QM_REG_ADDR_OFFSET 0x0004 #define QM_XQC_ADDR_OFFSET 32U +#define QM_XQC_ADDR_LOW 0x1 +#define QM_XQC_ADDR_HIGH 0x2 + #define QM_VF_AEQ_INT_MASK 0x0004 #define QM_VF_EQ_INT_MASK 0x000c #define QM_IFC_INT_SOURCE_V 0x0020 @@ -49,10 +52,15 @@ #define QM_EQC_DW0 0X8000 #define QM_AEQC_DW0 0X8020 +#define ACC_DRV_MAJOR_VER 1 +#define ACC_DRV_MINOR_VER 0 + +#define ACC_DEV_MAGIC_V1 0XCDCDCDCDFEEDAACC +#define ACC_DEV_MAGIC_V2 0xAACCFEEDDECADEDE + struct acc_vf_data { #define QM_MATCH_SIZE offsetofend(struct acc_vf_data, qm_rsv_state) /* QM match information */ -#define ACC_DEV_MAGIC 0XCDCDCDCDFEEDAACC u64 acc_magic; u32 qp_num; u32 dev_id; @@ -60,7 +68,9 @@ struct acc_vf_data { u32 qp_base; u32 vf_qm_state; /* QM reserved match information */ - u32 qm_rsv_state[3]; + u16 major_ver; + u16 minor_ver; + u32 qm_rsv_state[2]; /* QM RW regs */ u32 aeq_int_mask; From 5be5cd86d1e9646858b3e6457ceac32e686b700d Mon Sep 17 00:00:00 2001 From: Longfang Liu Date: Sat, 10 May 2025 16:11:51 +0800 Subject: [PATCH 176/971] hisi_acc_vfio_pci: add eq and aeq interruption restore [ Upstream commit 3495cec0787721ba7a9d5c19d0bbb66d182de584 ] In order to ensure that the task packets of the accelerator device are not lost during the migration process, it is necessary to send an EQ and AEQ command to the device after the live migration is completed and to update the completion position of the task queue. Let the device recheck the completed tasks data and if there are uncollected packets, device resend a task completion interrupt to the software. Fixes: b0eed085903e ("hisi_acc_vfio_pci: Add support for VFIO live migration") Signed-off-by: Longfang Liu Reviewed-by: Shameer Kolothum Link: https://lore.kernel.org/r/20250510081155.55840-3-liulongfang@huawei.com Signed-off-by: Alex Williamson Signed-off-by: Sasha Levin --- drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c index d09e7d295625..521f969e1c60 100644 --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c @@ -470,6 +470,19 @@ static int vf_qm_get_match_data(struct hisi_acc_vf_core_device *hisi_acc_vdev, return 0; } +static void vf_qm_xeqc_save(struct hisi_qm *qm, + struct hisi_acc_vf_migration_file *migf) +{ + struct acc_vf_data *vf_data = &migf->vf_data; + u16 eq_head, aeq_head; + + eq_head = vf_data->qm_eqc_dw[0] & 0xFFFF; + qm_db(qm, 0, QM_DOORBELL_CMD_EQ, eq_head, 0); + + aeq_head = vf_data->qm_aeqc_dw[0] & 0xFFFF; + qm_db(qm, 0, QM_DOORBELL_CMD_AEQ, aeq_head, 0); +} + static int vf_qm_load_data(struct hisi_acc_vf_core_device *hisi_acc_vdev, struct hisi_acc_vf_migration_file *migf) { @@ -566,6 +579,9 @@ static int vf_qm_state_save(struct hisi_acc_vf_core_device *hisi_acc_vdev, } migf->total_length = sizeof(struct acc_vf_data); + /* Save eqc and aeqc interrupt information */ + vf_qm_xeqc_save(vf_qm, migf); + return 0; } From b5ef128926cd34dffa2a66607b9c82b902581ef8 Mon Sep 17 00:00:00 2001 From: Longfang Liu Date: Sat, 10 May 2025 16:11:54 +0800 Subject: [PATCH 177/971] hisi_acc_vfio_pci: bugfix live migration function without VF device driver [ Upstream commit 2777a40998deb36f96b6afc48bd397cf58a4edf0 ] If the VF device driver is not loaded in the Guest OS and we attempt to perform device data migration, the address of the migrated data will be NULL. The live migration recovery operation on the destination side will access a null address value, which will cause access errors. Therefore, live migration of VMs without added VF device drivers does not require device data migration. In addition, when the queue address data obtained by the destination is empty, device queue recovery processing will not be performed. Fixes: b0eed085903e ("hisi_acc_vfio_pci: Add support for VFIO live migration") Signed-off-by: Longfang Liu Reviewed-by: Shameer Kolothum Link: https://lore.kernel.org/r/20250510081155.55840-6-liulongfang@huawei.com Signed-off-by: Alex Williamson Signed-off-by: Sasha Levin --- .../vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c index 521f969e1c60..712b178c42aa 100644 --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c @@ -426,13 +426,6 @@ static int vf_qm_check_match(struct hisi_acc_vf_core_device *hisi_acc_vdev, return -EINVAL; } - ret = qm_write_regs(vf_qm, QM_VF_STATE, &vf_data->vf_qm_state, 1); - if (ret) { - dev_err(dev, "failed to write QM_VF_STATE\n"); - return ret; - } - - hisi_acc_vdev->vf_qm_state = vf_data->vf_qm_state; hisi_acc_vdev->match_done = true; return 0; } @@ -498,6 +491,20 @@ static int vf_qm_load_data(struct hisi_acc_vf_core_device *hisi_acc_vdev, if (migf->total_length < sizeof(struct acc_vf_data)) return -EINVAL; + if (!vf_data->eqe_dma || !vf_data->aeqe_dma || + !vf_data->sqc_dma || !vf_data->cqc_dma) { + dev_info(dev, "resume dma addr is NULL!\n"); + hisi_acc_vdev->vf_qm_state = QM_NOT_READY; + return 0; + } + + ret = qm_write_regs(qm, QM_VF_STATE, &vf_data->vf_qm_state, 1); + if (ret) { + dev_err(dev, "failed to write QM_VF_STATE\n"); + return -EINVAL; + } + hisi_acc_vdev->vf_qm_state = vf_data->vf_qm_state; + qm->eqe_dma = vf_data->eqe_dma; qm->aeqe_dma = vf_data->aeqe_dma; qm->sqc_dma = vf_data->sqc_dma; @@ -1397,6 +1404,7 @@ static int hisi_acc_vfio_pci_migrn_init_dev(struct vfio_device *core_vdev) hisi_acc_vdev->vf_id = pci_iov_vf_id(pdev) + 1; hisi_acc_vdev->pf_qm = pf_qm; hisi_acc_vdev->vf_dev = pdev; + hisi_acc_vdev->vf_qm_state = QM_NOT_READY; mutex_init(&hisi_acc_vdev->state_mutex); core_vdev->migration_flags = VFIO_MIGRATION_STOP_COPY | VFIO_MIGRATION_PRE_COPY; From 5482ef9875eaa43f0435e14570e1193823de857e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= Date: Wed, 2 Apr 2025 13:22:16 +0200 Subject: [PATCH 178/971] wifi: ath9k_htc: Abort software beacon handling if disabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit ac4e317a95a1092b5da5b9918b7118759342641c ] A malicious USB device can send a WMI_SWBA_EVENTID event from an ath9k_htc-managed device before beaconing has been enabled. This causes a device-by-zero error in the driver, leading to either a crash or an out of bounds read. Prevent this by aborting the handling in ath9k_htc_swba() if beacons are not enabled. Reported-by: Robert Morris Closes: https://lore.kernel.org/r/88967.1743099372@localhost Fixes: 832f6a18fc2a ("ath9k_htc: Add beacon slots") Signed-off-by: Toke Høiland-Jørgensen Link: https://patch.msgid.link/20250402112217.58533-1-toke@toke.dk Signed-off-by: Jeff Johnson Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 533471e69400..18c7654bc539 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -290,6 +290,9 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, struct ath_common *common = ath9k_hw_common(priv->ah); int slot; + if (!priv->cur_beacon_conf.enable_beacon) + return; + if (swba->beacon_pending != 0) { priv->beacon.bmisscnt++; if (priv->beacon.bmisscnt > BSTUCK_THRESHOLD) { From 713b9bfa939d48ae9589138b03bb2c3fafcadadf Mon Sep 17 00:00:00 2001 From: "ping.gao" Date: Fri, 16 May 2025 16:38:12 +0800 Subject: [PATCH 179/971] scsi: ufs: mcq: Delete ufshcd_release_scsi_cmd() in ufshcd_mcq_abort() [ Upstream commit 53755903b9357e69b2dd6a02fafbb1e30c741895 ] After UFS_ABORT_TASK has been processed successfully, the host will generate MCQ IRQ for ABORT TAG with response OCS_ABORTED. This results in ufshcd_compl_one_cqe() calling ufshcd_release_scsi_cmd(). But ufshcd_mcq_abort() already calls ufshcd_release_scsi_cmd(), resulting in __ufshcd_release() being called twice. This means hba->clk_gating.active_reqs will be decreased twice, making it go negative. Delete ufshcd_release_scsi_cmd() in ufshcd_mcq_abort(). Fixes: f1304d442077 ("scsi: ufs: mcq: Added ufshcd_mcq_abort()") Signed-off-by: ping.gao Link: https://lore.kernel.org/r/20250516083812.3894396-1-ping.gao@samsung.com Reviewed-by: Peter Wang Reviewed-by: Bart Van Assche Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/ufs/core/ufs-mcq.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/ufs/core/ufs-mcq.c b/drivers/ufs/core/ufs-mcq.c index 411109a5ebbf..14864cfc2422 100644 --- a/drivers/ufs/core/ufs-mcq.c +++ b/drivers/ufs/core/ufs-mcq.c @@ -629,7 +629,6 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd) int tag = scsi_cmd_to_rq(cmd)->tag; struct ufshcd_lrb *lrbp = &hba->lrb[tag]; struct ufs_hw_queue *hwq; - unsigned long flags; int err; /* Skip task abort in case previous aborts failed and report failure */ @@ -668,10 +667,5 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd) return FAILED; } - spin_lock_irqsave(&hwq->cq_lock, flags); - if (ufshcd_cmd_inflight(lrbp->cmd)) - ufshcd_release_scsi_cmd(hba, lrbp); - spin_unlock_irqrestore(&hwq->cq_lock, flags); - return SUCCESS; } From 6c81f1c7812c61f187bed1b938f1d2e391d503ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Koutn=C3=BD?= Date: Mon, 5 May 2025 14:12:00 +0200 Subject: [PATCH 180/971] kernfs: Relax constraint in draining guard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 071d8e4c2a3b0999a9b822e2eb8854784a350f8a ] The active reference lifecycle provides the break/unbreak mechanism but the active reference is not truly active after unbreak -- callers don't use it afterwards but it's important for proper pairing of kn->active counting. Assuming this mechanism is in place, the WARN check in kernfs_should_drain_open_files() is too sensitive -- it may transiently catch those (rightful) callers between kernfs_unbreak_active_protection() and kernfs_put_active() as found out by Chen Ridong: kernfs_remove_by_name_ns kernfs_get_active // active=1 __kernfs_remove // active=0x80000002 kernfs_drain ... wait_event //waiting (active == 0x80000001) kernfs_break_active_protection // active = 0x80000001 // continue kernfs_unbreak_active_protection // active = 0x80000002 ... kernfs_should_drain_open_files // warning occurs kernfs_put_active To avoid the false positives (mind panic_on_warn) remove the check altogether. (This is meant as quick fix, I think active reference break/unbreak may be simplified with larger rework.) Fixes: bdb2fd7fc56e1 ("kernfs: Skip kernfs_drain_open_files() more aggressively") Link: https://lore.kernel.org/r/kmmrseckjctb4gxcx2rdminrjnq2b4ipf7562nvfd432ld5v5m@2byj5eedkb2o/ Cc: Chen Ridong Signed-off-by: Michal Koutný Acked-by: Tejun Heo Link: https://lore.kernel.org/r/20250505121201.879823-1-mkoutny@suse.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- fs/kernfs/dir.c | 5 +++-- fs/kernfs/file.c | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index b068ed32d7b3..f6e2a4523f7e 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -1560,8 +1560,9 @@ void kernfs_break_active_protection(struct kernfs_node *kn) * invoked before finishing the kernfs operation. Note that while this * function restores the active reference, it doesn't and can't actually * restore the active protection - @kn may already or be in the process of - * being removed. Once kernfs_break_active_protection() is invoked, that - * protection is irreversibly gone for the kernfs operation instance. + * being drained and removed. Once kernfs_break_active_protection() is + * invoked, that protection is irreversibly gone for the kernfs operation + * instance. * * While this function may be called at any point after * kernfs_break_active_protection() is invoked, its most useful location diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 332d08d2fe0d..6b90fea6cca2 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -820,8 +820,9 @@ bool kernfs_should_drain_open_files(struct kernfs_node *kn) /* * @kn being deactivated guarantees that @kn->attr.open can't change * beneath us making the lockless test below safe. + * Callers post kernfs_unbreak_active_protection may be counted in + * kn->active by now, do not WARN_ON because of them. */ - WARN_ON_ONCE(atomic_read(&kn->active) != KN_DEACTIVATED_BIAS); rcu_read_lock(); on = rcu_dereference(kn->attr.open); From e9f9cef1877ac32285dbc1f31b86c8955b712fc2 Mon Sep 17 00:00:00 2001 From: Henry Martin Date: Mon, 7 Apr 2025 14:19:00 +0800 Subject: [PATCH 181/971] wifi: mt76: mt7915: Fix null-ptr-deref in mt7915_mmio_wed_init() [ Upstream commit efb95439c1477bbc955cacd0179c35e7861b437c ] devm_ioremap() returns NULL on error. Currently, mt7915_mmio_wed_init() does not check for this case, which results in a NULL pointer dereference. Prevent null pointer dereference in mt7915_mmio_wed_init(). Fixes: 4f831d18d12d ("wifi: mt76: mt7915: enable WED RX support") Signed-off-by: Henry Martin Link: https://patch.msgid.link/20250407061900.85317-1-bsdhenrymartin@gmail.com Signed-off-by: Felix Fietkau Signed-off-by: Sasha Levin --- drivers/net/wireless/mediatek/mt76/mt7915/mmio.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c index 7db436d908a3..f4850c6daeb7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c @@ -755,6 +755,9 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr, wed->wlan.base = devm_ioremap(dev->mt76.dev, pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); + if (!wed->wlan.base) + return -ENOMEM; + wed->wlan.phy_base = pci_resource_start(pci_dev, 0); wed->wlan.wpdma_int = pci_resource_start(pci_dev, 0) + MT_INT_WED_SOURCE_CSR; @@ -782,6 +785,9 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr, wed->wlan.bus_type = MTK_WED_BUS_AXI; wed->wlan.base = devm_ioremap(dev->mt76.dev, res->start, resource_size(res)); + if (!wed->wlan.base) + return -ENOMEM; + wed->wlan.phy_base = res->start; wed->wlan.wpdma_int = res->start + MT_INT_SOURCE_CSR; wed->wlan.wpdma_mask = res->start + MT_INT_MASK_CSR; From 800f7e73a679f7658e8580540ef97b449e68f47e Mon Sep 17 00:00:00 2001 From: Peter Chiu Date: Thu, 15 May 2025 11:29:46 +0800 Subject: [PATCH 182/971] wifi: mt76: mt7996: set EHT max ampdu length capability [ Upstream commit 8b2f574845e33d02e7fbad2d3192a8b717567afa ] Set the max AMPDU length in the EHT MAC CAP. Without this patch, the peer station cannot obtain the correct capability, which prevents achieving peak throughput on the 2 GHz band. Fixes: 1816ad9381e0 ("wifi: mt76: mt7996: add max mpdu len capability") Signed-off-by: Peter Chiu Signed-off-by: Shayne Chen Link: https://patch.msgid.link/20250515032952.1653494-3-shayne.chen@mediatek.com Signed-off-by: Felix Fietkau Signed-off-by: Sasha Levin --- drivers/net/wireless/mediatek/mt76/mt7996/init.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c index 0a701dcb8a92..375a3d6f4b38 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c @@ -735,6 +735,9 @@ mt7996_init_eht_caps(struct mt7996_phy *phy, enum nl80211_band band, u8_encode_bits(IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_11454, IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_MASK); + eht_cap_elem->mac_cap_info[1] |= + IEEE80211_EHT_MAC_CAP1_MAX_AMPDU_LEN_MASK; + eht_cap_elem->phy_cap_info[0] = IEEE80211_EHT_PHY_CAP0_NDP_4_EHT_LFT_32_GI | IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER | From 1e8b2048f9e9a4743735963aee72ea8671687150 Mon Sep 17 00:00:00 2001 From: Shayne Chen Date: Thu, 15 May 2025 11:29:50 +0800 Subject: [PATCH 183/971] wifi: mt76: mt7996: fix RX buffer size of MCU event [ Upstream commit 42cb27af34de4acf680606fad2c1f2932110591f ] Some management frames are first processed by the firmware and then passed to the driver through the MCU event rings. In CONNAC3, event rings do not support scatter-gather and have a size limitation of 2048 bytes. If a packet sized between 1728 and 2048 bytes arrives from an event ring, the ring will hang because the driver attempts to use scatter-gather to process it. To fix this, include the size of struct skb_shared_info in the MCU RX buffer size to prevent scatter-gather from being used for event skb in mt76_dma_rx_fill_buf(). Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices") Co-developed-by: Peter Chiu Signed-off-by: Peter Chiu Signed-off-by: Shayne Chen Link: https://patch.msgid.link/20250515032952.1653494-7-shayne.chen@mediatek.com Signed-off-by: Felix Fietkau Signed-off-by: Sasha Levin --- drivers/net/wireless/mediatek/mt76/mt7996/dma.c | 4 ++-- drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/dma.c b/drivers/net/wireless/mediatek/mt76/mt7996/dma.c index 586e247a1e06..04c9fd0e6b00 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/dma.c @@ -300,7 +300,7 @@ int mt7996_dma_init(struct mt7996_dev *dev) ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU], MT_RXQ_ID(MT_RXQ_MCU), MT7996_RX_MCU_RING_SIZE, - MT_RX_BUF_SIZE, + MT7996_RX_MCU_BUF_SIZE, MT_RXQ_RING_BASE(MT_RXQ_MCU)); if (ret) return ret; @@ -309,7 +309,7 @@ int mt7996_dma_init(struct mt7996_dev *dev) ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA], MT_RXQ_ID(MT_RXQ_MCU_WA), MT7996_RX_MCU_RING_SIZE_WA, - MT_RX_BUF_SIZE, + MT7996_RX_MCU_BUF_SIZE, MT_RXQ_RING_BASE(MT_RXQ_MCU_WA)); if (ret) return ret; diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h index 25bb36561231..7d2074e2b635 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h @@ -27,6 +27,9 @@ #define MT7996_RX_RING_SIZE 1536 #define MT7996_RX_MCU_RING_SIZE 512 #define MT7996_RX_MCU_RING_SIZE_WA 1024 +/* scatter-gather of mcu event is not supported in connac3 */ +#define MT7996_RX_MCU_BUF_SIZE (2048 + \ + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) #define MT7996_FIRMWARE_WA "mediatek/mt7996/mt7996_wa.bin" #define MT7996_FIRMWARE_WM "mediatek/mt7996/mt7996_wm.bin" From cf008d9a08a7ae12d7cedc42ec02a36002ac79c0 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Wed, 21 May 2025 11:38:47 +0200 Subject: [PATCH 184/971] netfilter: nf_tables: nft_fib_ipv6: fix VRF ipv4/ipv6 result discrepancy [ Upstream commit 8b53f46eb430fe5b42d485873b85331d2de2c469 ] With a VRF, ipv4 and ipv6 FIB expression behave differently. fib daddr . iif oif Will return the input interface name for ipv4, but the real device for ipv6. Example: If VRF device name is tvrf and real (incoming) device is veth0. First round is ok, both ipv4 and ipv6 will yield 'veth0'. But in the second round (incoming device will be set to "tvrf"), ipv4 will yield "tvrf" whereas ipv6 returns "veth0" for the second round too. This makes ipv6 behave like ipv4. A followup patch will add a test case for this, without this change it will fail with: get element inet t fibif6iif { tvrf . dead:1::99 . tvrf } ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FAIL: did not find tvrf . dead:1::99 . tvrf in fibif6iif Alternatively we could either not do anything at all or change ipv4 to also return the lower/real device, however, nft (userspace) doc says "iif: if fib lookup provides a route then check its output interface is identical to the packets input interface." which is what the nft fib ipv4 behaviour is. Fixes: f6d0cbcf09c5 ("netfilter: nf_tables: add fib expression") Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- net/ipv6/netfilter/nft_fib_ipv6.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/net/ipv6/netfilter/nft_fib_ipv6.c b/net/ipv6/netfilter/nft_fib_ipv6.c index c9f1634b3838..a89ce0fbfe4b 100644 --- a/net/ipv6/netfilter/nft_fib_ipv6.c +++ b/net/ipv6/netfilter/nft_fib_ipv6.c @@ -158,6 +158,7 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs, { const struct nft_fib *priv = nft_expr_priv(expr); int noff = skb_network_offset(pkt->skb); + const struct net_device *found = NULL; const struct net_device *oif = NULL; u32 *dest = ®s->data[priv->dreg]; struct ipv6hdr *iph, _iph; @@ -202,11 +203,15 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs, if (rt->rt6i_flags & (RTF_REJECT | RTF_ANYCAST | RTF_LOCAL)) goto put_rt_err; - if (oif && oif != rt->rt6i_idev->dev && - l3mdev_master_ifindex_rcu(rt->rt6i_idev->dev) != oif->ifindex) - goto put_rt_err; + if (!oif) { + found = rt->rt6i_idev->dev; + } else { + if (oif == rt->rt6i_idev->dev || + l3mdev_master_ifindex_rcu(rt->rt6i_idev->dev) == oif->ifindex) + found = oif; + } - nft_fib_store_result(dest, priv, rt->rt6i_idev->dev); + nft_fib_store_result(dest, priv, found); put_rt_err: ip6_rt_put(rt); } From 801677040bb284bf0c61e049aed06de843687c59 Mon Sep 17 00:00:00 2001 From: Li RongQing Date: Wed, 21 May 2025 11:46:47 +0800 Subject: [PATCH 185/971] vfio/type1: Fix error unwind in migration dirty bitmap allocation [ Upstream commit 4518e5a60c7fbf0cdff393c2681db39d77b4f87e ] When setting up dirty page tracking at the vfio IOMMU backend for device migration, if an error is encountered allocating a tracking bitmap, the unwind loop fails to free previously allocated tracking bitmaps. This occurs because the wrong loop index is used to generate the tracking object. This results in unintended memory usage for the life of the current DMA mappings where bitmaps were successfully allocated. Use the correct loop index to derive the tracking object for freeing during unwind. Fixes: d6a4c185660c ("vfio iommu: Implementation of ioctl for dirty pages tracking") Signed-off-by: Li RongQing Link: https://lore.kernel.org/r/20250521034647.2877-1-lirongqing@baidu.com Signed-off-by: Alex Williamson Signed-off-by: Sasha Levin --- drivers/vfio/vfio_iommu_type1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index eacd6ec04de5..5fe7aed3672e 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -294,7 +294,7 @@ static int vfio_dma_bitmap_alloc_all(struct vfio_iommu *iommu, size_t pgsize) struct rb_node *p; for (p = rb_prev(n); p; p = rb_prev(p)) { - struct vfio_dma *dma = rb_entry(n, + struct vfio_dma *dma = rb_entry(p, struct vfio_dma, node); vfio_dma_bitmap_free(dma); From 9c73afd7f1c95e133f9fa4fd0cbc1c76ac694c51 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Tue, 20 May 2025 11:42:30 +0300 Subject: [PATCH 186/971] Bluetooth: MGMT: iterate over mesh commands in mgmt_mesh_foreach() [ Upstream commit 3bb88524b7d030160bb3c9b35f928b2778092111 ] In 'mgmt_mesh_foreach()', iterate over mesh commands rather than generic mgmt ones. Compile tested only. Fixes: b338d91703fa ("Bluetooth: Implement support for Mesh") Signed-off-by: Dmitry Antipov Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- net/bluetooth/mgmt_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/mgmt_util.c b/net/bluetooth/mgmt_util.c index 0115f783bde8..17e32605d9b0 100644 --- a/net/bluetooth/mgmt_util.c +++ b/net/bluetooth/mgmt_util.c @@ -321,7 +321,7 @@ void mgmt_mesh_foreach(struct hci_dev *hdev, { struct mgmt_mesh_tx *mesh_tx, *tmp; - list_for_each_entry_safe(mesh_tx, tmp, &hdev->mgmt_pending, list) { + list_for_each_entry_safe(mesh_tx, tmp, &hdev->mesh_pending, list) { if (!sk || mesh_tx->sk == sk) cb(mesh_tx, data); } From 4c6fa65ab2aec7df94809478c8d28ef38676a1b7 Mon Sep 17 00:00:00 2001 From: Jiayuan Chen Date: Fri, 16 May 2025 22:17:12 +0800 Subject: [PATCH 187/971] bpf, sockmap: Avoid using sk_socket after free when sending [ Upstream commit 8259eb0e06d8f64c700f5fbdb28a5c18e10de291 ] The sk->sk_socket is not locked or referenced in backlog thread, and during the call to skb_send_sock(), there is a race condition with the release of sk_socket. All types of sockets(tcp/udp/unix/vsock) will be affected. Race conditions: ''' CPU0 CPU1 backlog::skb_send_sock sendmsg_unlocked sock_sendmsg sock_sendmsg_nosec close(fd): ... ops->release() -> sock_map_close() sk_socket->ops = NULL free(socket) sock->ops->sendmsg ^ panic here ''' The ref of psock become 0 after sock_map_close() executed. ''' void sock_map_close() { ... if (likely(psock)) { ... // !! here we remove psock and the ref of psock become 0 sock_map_remove_links(sk, psock) psock = sk_psock_get(sk); if (unlikely(!psock)) goto no_psock; <=== Control jumps here via goto ... cancel_delayed_work_sync(&psock->work); <=== not executed sk_psock_put(sk, psock); ... } ''' Based on the fact that we already wait for the workqueue to finish in sock_map_close() if psock is held, we simply increase the psock reference count to avoid race conditions. With this patch, if the backlog thread is running, sock_map_close() will wait for the backlog thread to complete and cancel all pending work. If no backlog running, any pending work that hasn't started by then will fail when invoked by sk_psock_get(), as the psock reference count have been zeroed, and sk_psock_drop() will cancel all jobs via cancel_delayed_work_sync(). In summary, we require synchronization to coordinate the backlog thread and close() thread. The panic I catched: ''' Workqueue: events sk_psock_backlog RIP: 0010:sock_sendmsg+0x21d/0x440 RAX: 0000000000000000 RBX: ffffc9000521fad8 RCX: 0000000000000001 ... Call Trace: ? die_addr+0x40/0xa0 ? exc_general_protection+0x14c/0x230 ? asm_exc_general_protection+0x26/0x30 ? sock_sendmsg+0x21d/0x440 ? sock_sendmsg+0x3e0/0x440 ? __pfx_sock_sendmsg+0x10/0x10 __skb_send_sock+0x543/0xb70 sk_psock_backlog+0x247/0xb80 ... ''' Fixes: 4b4647add7d3 ("sock_map: avoid race between sock_map_close and sk_psock_put") Reported-by: Michal Luczaj Signed-off-by: Jiayuan Chen Signed-off-by: Martin KaFai Lau Reviewed-by: John Fastabend Link: https://lore.kernel.org/r/20250516141713.291150-1-jiayuan.chen@linux.dev Signed-off-by: Sasha Levin --- net/core/skmsg.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/core/skmsg.c b/net/core/skmsg.c index c7edf77fd6fd..2076db464e93 100644 --- a/net/core/skmsg.c +++ b/net/core/skmsg.c @@ -655,6 +655,13 @@ static void sk_psock_backlog(struct work_struct *work) bool ingress; int ret; + /* Increment the psock refcnt to synchronize with close(fd) path in + * sock_map_close(), ensuring we wait for backlog thread completion + * before sk_socket freed. If refcnt increment fails, it indicates + * sock_map_close() completed with sk_socket potentially already freed. + */ + if (!sk_psock_get(psock->sk)) + return; mutex_lock(&psock->work_mutex); while ((skb = skb_peek(&psock->ingress_skb))) { len = skb->len; @@ -706,6 +713,7 @@ static void sk_psock_backlog(struct work_struct *work) } end: mutex_unlock(&psock->work_mutex); + sk_psock_put(psock->sk, psock); } struct sk_psock *sk_psock_init(struct sock *sk, int node) From 68b69b50dfba54c5a30d32e18903742628911ed4 Mon Sep 17 00:00:00 2001 From: Fernando Fernandez Mancera Date: Wed, 21 May 2025 11:41:08 +0200 Subject: [PATCH 188/971] netfilter: nft_tunnel: fix geneve_opt dump [ Upstream commit 22a9613de4c29d7d0770bfb8a5a9d73eb8df7dad ] When dumping a nft_tunnel with more than one geneve_opt configured the netlink attribute hierarchy should be as follow: NFTA_TUNNEL_KEY_OPTS | |--NFTA_TUNNEL_KEY_OPTS_GENEVE | | | |--NFTA_TUNNEL_KEY_GENEVE_CLASS | |--NFTA_TUNNEL_KEY_GENEVE_TYPE | |--NFTA_TUNNEL_KEY_GENEVE_DATA | |--NFTA_TUNNEL_KEY_OPTS_GENEVE | | | |--NFTA_TUNNEL_KEY_GENEVE_CLASS | |--NFTA_TUNNEL_KEY_GENEVE_TYPE | |--NFTA_TUNNEL_KEY_GENEVE_DATA | |--NFTA_TUNNEL_KEY_OPTS_GENEVE ... Otherwise, userspace tools won't be able to fetch the geneve options configured correctly. Fixes: 925d844696d9 ("netfilter: nft_tunnel: add support for geneve opts") Signed-off-by: Fernando Fernandez Mancera Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- net/netfilter/nft_tunnel.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/netfilter/nft_tunnel.c b/net/netfilter/nft_tunnel.c index d499eb3f4f29..3e3ae29dde33 100644 --- a/net/netfilter/nft_tunnel.c +++ b/net/netfilter/nft_tunnel.c @@ -617,10 +617,10 @@ static int nft_tunnel_opts_dump(struct sk_buff *skb, struct geneve_opt *opt; int offset = 0; - inner = nla_nest_start_noflag(skb, NFTA_TUNNEL_KEY_OPTS_GENEVE); - if (!inner) - goto failure; while (opts->len > offset) { + inner = nla_nest_start_noflag(skb, NFTA_TUNNEL_KEY_OPTS_GENEVE); + if (!inner) + goto failure; opt = (struct geneve_opt *)(opts->u.data + offset); if (nla_put_be16(skb, NFTA_TUNNEL_KEY_GENEVE_CLASS, opt->opt_class) || @@ -630,8 +630,8 @@ static int nft_tunnel_opts_dump(struct sk_buff *skb, opt->length * 4, opt->opt_data)) goto inner_failure; offset += sizeof(*opt) + opt->length * 4; + nla_nest_end(skb, inner); } - nla_nest_end(skb, inner); } nla_nest_end(skb, nest); return 0; From 333262e5dd8c2eff32c4bcc57c8ccd895a893a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Date: Fri, 23 May 2025 12:47:28 +0200 Subject: [PATCH 189/971] RISC-V: KVM: lock the correct mp_state during reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 7917be170928189fefad490d1a1237fdfa6b856f ] Currently, the kvm_riscv_vcpu_sbi_system_reset() function locks vcpu->arch.mp_state_lock when updating tmp->arch.mp_state.mp_state which is incorrect hence fix it. Fixes: 2121cadec45a ("RISCV: KVM: Introduce mp_state_lock to avoid lock inversion") Signed-off-by: Radim Krčmář Reviewed-by: Anup Patel Link: https://lore.kernel.org/r/20250523104725.2894546-4-rkrcmar@ventanamicro.com Signed-off-by: Anup Patel Signed-off-by: Sasha Levin --- arch/riscv/kvm/vcpu_sbi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index be43278109f4..a71d33cd81d3 100644 --- a/arch/riscv/kvm/vcpu_sbi.c +++ b/arch/riscv/kvm/vcpu_sbi.c @@ -103,9 +103,9 @@ void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu, struct kvm_vcpu *tmp; kvm_for_each_vcpu(i, tmp, vcpu->kvm) { - spin_lock(&vcpu->arch.mp_state_lock); + spin_lock(&tmp->arch.mp_state_lock); WRITE_ONCE(tmp->arch.mp_state.mp_state, KVM_MP_STATE_STOPPED); - spin_unlock(&vcpu->arch.mp_state_lock); + spin_unlock(&tmp->arch.mp_state_lock); } kvm_make_all_cpus_request(vcpu->kvm, KVM_REQ_SLEEP); From 60790d287c1a1ced3554d4a87c2f27bf299a932a Mon Sep 17 00:00:00 2001 From: Nikita Zhandarovich Date: Tue, 20 May 2025 14:32:39 +0300 Subject: [PATCH 190/971] net: usb: aqc111: fix error handling of usbnet read calls [ Upstream commit 405b0d610745fb5e84fc2961d9b960abb9f3d107 ] Syzkaller, courtesy of syzbot, identified an error (see report [1]) in aqc111 driver, caused by incomplete sanitation of usb read calls' results. This problem is quite similar to the one fixed in commit 920a9fa27e78 ("net: asix: add proper error handling of usb read errors"). For instance, usbnet_read_cmd() may read fewer than 'size' bytes, even if the caller expected the full amount, and aqc111_read_cmd() will not check its result properly. As [1] shows, this may lead to MAC address in aqc111_bind() being only partly initialized, triggering KMSAN warnings. Fix the issue by verifying that the number of bytes read is as expected and not less. [1] Partial syzbot report: BUG: KMSAN: uninit-value in is_valid_ether_addr include/linux/etherdevice.h:208 [inline] BUG: KMSAN: uninit-value in usbnet_probe+0x2e57/0x4390 drivers/net/usb/usbnet.c:1830 is_valid_ether_addr include/linux/etherdevice.h:208 [inline] usbnet_probe+0x2e57/0x4390 drivers/net/usb/usbnet.c:1830 usb_probe_interface+0xd01/0x1310 drivers/usb/core/driver.c:396 call_driver_probe drivers/base/dd.c:-1 [inline] really_probe+0x4d1/0xd90 drivers/base/dd.c:658 __driver_probe_device+0x268/0x380 drivers/base/dd.c:800 ... Uninit was stored to memory at: dev_addr_mod+0xb0/0x550 net/core/dev_addr_lists.c:582 __dev_addr_set include/linux/netdevice.h:4874 [inline] eth_hw_addr_set include/linux/etherdevice.h:325 [inline] aqc111_bind+0x35f/0x1150 drivers/net/usb/aqc111.c:717 usbnet_probe+0xbe6/0x4390 drivers/net/usb/usbnet.c:1772 usb_probe_interface+0xd01/0x1310 drivers/usb/core/driver.c:396 ... Uninit was stored to memory at: ether_addr_copy include/linux/etherdevice.h:305 [inline] aqc111_read_perm_mac drivers/net/usb/aqc111.c:663 [inline] aqc111_bind+0x794/0x1150 drivers/net/usb/aqc111.c:713 usbnet_probe+0xbe6/0x4390 drivers/net/usb/usbnet.c:1772 usb_probe_interface+0xd01/0x1310 drivers/usb/core/driver.c:396 call_driver_probe drivers/base/dd.c:-1 [inline] ... Local variable buf.i created at: aqc111_read_perm_mac drivers/net/usb/aqc111.c:656 [inline] aqc111_bind+0x221/0x1150 drivers/net/usb/aqc111.c:713 usbnet_probe+0xbe6/0x4390 drivers/net/usb/usbnet.c:1772 Reported-by: syzbot+3b6b9ff7b80430020c7b@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=3b6b9ff7b80430020c7b Tested-by: syzbot+3b6b9ff7b80430020c7b@syzkaller.appspotmail.com Fixes: df2d59a2ab6c ("net: usb: aqc111: Add support for getting and setting of MAC address") Signed-off-by: Nikita Zhandarovich Link: https://patch.msgid.link/20250520113240.2369438-1-n.zhandarovich@fintech.ru Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- drivers/net/usb/aqc111.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c index 284375f662f1..04d5573123be 100644 --- a/drivers/net/usb/aqc111.c +++ b/drivers/net/usb/aqc111.c @@ -30,10 +30,13 @@ static int aqc111_read_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value, ret = usbnet_read_cmd_nopm(dev, cmd, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, data, size); - if (unlikely(ret < 0)) + if (unlikely(ret < size)) { + ret = ret < 0 ? ret : -ENODATA; + netdev_warn(dev->net, "Failed to read(0x%x) reg index 0x%04x: %d\n", cmd, index, ret); + } return ret; } @@ -46,10 +49,13 @@ static int aqc111_read_cmd(struct usbnet *dev, u8 cmd, u16 value, ret = usbnet_read_cmd(dev, cmd, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, data, size); - if (unlikely(ret < 0)) + if (unlikely(ret < size)) { + ret = ret < 0 ? ret : -ENODATA; + netdev_warn(dev->net, "Failed to read(0x%x) reg index 0x%04x: %d\n", cmd, index, ret); + } return ret; } From ac7897c0124066b9705ffca252a3662d54fc0c9b Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Wed, 21 May 2025 14:36:02 +0300 Subject: [PATCH 191/971] RDMA/cma: Fix hang when cma_netevent_callback fails to queue_work [ Upstream commit 92a251c3df8ea1991cd9fe00f1ab0cfce18d7711 ] The cited commit fixed a crash when cma_netevent_callback was called for a cma_id while work on that id from a previous call had not yet started. The work item was re-initialized in the second call, which corrupted the work item currently in the work queue. However, it left a problem when queue_work fails (because the item is still pending in the work queue from a previous call). In this case, cma_id_put (which is called in the work handler) is therefore not called. This results in a userspace process hang (zombie process). Fix this by calling cma_id_put() if queue_work fails. Fixes: 45f5dcdd0497 ("RDMA/cma: Fix workqueue crash in cma_netevent_work_handler") Link: https://patch.msgid.link/r/4f3640b501e48d0166f312a64fdadf72b059bd04.1747827103.git.leon@kernel.org Signed-off-by: Jack Morgenstein Signed-off-by: Feng Liu Reviewed-by: Vlad Dumitrescu Signed-off-by: Leon Romanovsky Reviewed-by: Sharath Srinivasan Reviewed-by: Kalesh AP Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin --- drivers/infiniband/core/cma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 348527cf1e7b..a5ceae2e075a 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -5215,7 +5215,8 @@ static int cma_netevent_callback(struct notifier_block *self, neigh->ha, ETH_ALEN)) continue; cma_id_get(current_id); - queue_work(cma_wq, ¤t_id->id.net_work); + if (!queue_work(cma_wq, ¤t_id->id.net_work)) + cma_id_put(current_id); } out: spin_unlock_irqrestore(&id_table_lock, flags); From 8d5bc5ec6c9446155adfab14b9e70e2309a8d087 Mon Sep 17 00:00:00 2001 From: Horatiu Vultur Date: Wed, 21 May 2025 14:41:59 +0200 Subject: [PATCH 192/971] net: lan966x: Fix 1-step timestamping over ipv4 or ipv6 [ Upstream commit 57ee9584fd8606deef66d7b65fa4dcf94f6843aa ] When enabling 1-step timestamping for ptp frames that are over udpv4 or udpv6 then the inserted timestamp is added at the wrong offset in the frame, meaning that will modify the frame at the wrong place, so the frame will be malformed. To fix this, the HW needs to know which kind of frame it is to know where to insert the timestamp. For that there is a field in the IFH that says the PDU_TYPE, which can be NONE which is the default value, IPV4 or IPV6. Therefore make sure to set the PDU_TYPE so the HW knows where to insert the timestamp. Like I mention before the issue is not seen with L2 frames because by default the PDU_TYPE has a value of 0, which represents the L2 frames. Fixes: 77eecf25bd9d2f ("net: lan966x: Update extraction/injection for timestamping") Signed-off-by: Horatiu Vultur Link: https://patch.msgid.link/20250521124159.2713525-1-horatiu.vultur@microchip.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- .../ethernet/microchip/lan966x/lan966x_main.c | 6 +++ .../ethernet/microchip/lan966x/lan966x_main.h | 5 ++ .../ethernet/microchip/lan966x/lan966x_ptp.c | 49 ++++++++++++++----- 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c index c3f6c10bc239..05f6c9227583 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c @@ -353,6 +353,11 @@ static void lan966x_ifh_set_rew_op(void *ifh, u64 rew_op) lan966x_ifh_set(ifh, rew_op, IFH_POS_REW_CMD, IFH_WID_REW_CMD); } +static void lan966x_ifh_set_oam_type(void *ifh, u64 oam_type) +{ + lan966x_ifh_set(ifh, oam_type, IFH_POS_PDU_TYPE, IFH_WID_PDU_TYPE); +} + static void lan966x_ifh_set_timestamp(void *ifh, u64 timestamp) { lan966x_ifh_set(ifh, timestamp, IFH_POS_TIMESTAMP, IFH_WID_TIMESTAMP); @@ -380,6 +385,7 @@ static netdev_tx_t lan966x_port_xmit(struct sk_buff *skb, return err; lan966x_ifh_set_rew_op(ifh, LAN966X_SKB_CB(skb)->rew_op); + lan966x_ifh_set_oam_type(ifh, LAN966X_SKB_CB(skb)->pdu_type); lan966x_ifh_set_timestamp(ifh, LAN966X_SKB_CB(skb)->ts_id); } diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h index caa9e0533c96..b65d58a1552b 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h @@ -74,6 +74,10 @@ #define IFH_REW_OP_ONE_STEP_PTP 0x3 #define IFH_REW_OP_TWO_STEP_PTP 0x4 +#define IFH_PDU_TYPE_NONE 0 +#define IFH_PDU_TYPE_IPV4 7 +#define IFH_PDU_TYPE_IPV6 8 + #define FDMA_RX_DCB_MAX_DBS 1 #define FDMA_TX_DCB_MAX_DBS 1 #define FDMA_DCB_INFO_DATAL(x) ((x) & GENMASK(15, 0)) @@ -306,6 +310,7 @@ struct lan966x_phc { struct lan966x_skb_cb { u8 rew_op; + u8 pdu_type; u16 ts_id; unsigned long jiffies; }; diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c index 63905bb5a63a..87e5e81d40dc 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c @@ -322,34 +322,55 @@ void lan966x_ptp_hwtstamp_get(struct lan966x_port *port, *cfg = phc->hwtstamp_config; } -static int lan966x_ptp_classify(struct lan966x_port *port, struct sk_buff *skb) +static void lan966x_ptp_classify(struct lan966x_port *port, struct sk_buff *skb, + u8 *rew_op, u8 *pdu_type) { struct ptp_header *header; u8 msgtype; int type; - if (port->ptp_tx_cmd == IFH_REW_OP_NOOP) - return IFH_REW_OP_NOOP; + if (port->ptp_tx_cmd == IFH_REW_OP_NOOP) { + *rew_op = IFH_REW_OP_NOOP; + *pdu_type = IFH_PDU_TYPE_NONE; + return; + } type = ptp_classify_raw(skb); - if (type == PTP_CLASS_NONE) - return IFH_REW_OP_NOOP; + if (type == PTP_CLASS_NONE) { + *rew_op = IFH_REW_OP_NOOP; + *pdu_type = IFH_PDU_TYPE_NONE; + return; + } header = ptp_parse_header(skb, type); - if (!header) - return IFH_REW_OP_NOOP; + if (!header) { + *rew_op = IFH_REW_OP_NOOP; + *pdu_type = IFH_PDU_TYPE_NONE; + return; + } - if (port->ptp_tx_cmd == IFH_REW_OP_TWO_STEP_PTP) - return IFH_REW_OP_TWO_STEP_PTP; + if (type & PTP_CLASS_L2) + *pdu_type = IFH_PDU_TYPE_NONE; + if (type & PTP_CLASS_IPV4) + *pdu_type = IFH_PDU_TYPE_IPV4; + if (type & PTP_CLASS_IPV6) + *pdu_type = IFH_PDU_TYPE_IPV6; + + if (port->ptp_tx_cmd == IFH_REW_OP_TWO_STEP_PTP) { + *rew_op = IFH_REW_OP_TWO_STEP_PTP; + return; + } /* If it is sync and run 1 step then set the correct operation, * otherwise run as 2 step */ msgtype = ptp_get_msgtype(header, type); - if ((msgtype & 0xf) == 0) - return IFH_REW_OP_ONE_STEP_PTP; + if ((msgtype & 0xf) == 0) { + *rew_op = IFH_REW_OP_ONE_STEP_PTP; + return; + } - return IFH_REW_OP_TWO_STEP_PTP; + *rew_op = IFH_REW_OP_TWO_STEP_PTP; } static void lan966x_ptp_txtstamp_old_release(struct lan966x_port *port) @@ -374,10 +395,12 @@ int lan966x_ptp_txtstamp_request(struct lan966x_port *port, { struct lan966x *lan966x = port->lan966x; unsigned long flags; + u8 pdu_type; u8 rew_op; - rew_op = lan966x_ptp_classify(port, skb); + lan966x_ptp_classify(port, skb, &rew_op, &pdu_type); LAN966X_SKB_CB(skb)->rew_op = rew_op; + LAN966X_SKB_CB(skb)->pdu_type = pdu_type; if (rew_op != IFH_REW_OP_TWO_STEP_PTP) return 0; From 6f639c25bfad17d9fd7379ab91ff9678ea9aac85 Mon Sep 17 00:00:00 2001 From: KaFai Wan Date: Mon, 26 May 2025 21:33:58 +0800 Subject: [PATCH 193/971] bpf: Avoid __bpf_prog_ret0_warn when jit fails [ Upstream commit 86bc9c742426a16b52a10ef61f5b721aecca2344 ] syzkaller reported an issue: WARNING: CPU: 3 PID: 217 at kernel/bpf/core.c:2357 __bpf_prog_ret0_warn+0xa/0x20 kernel/bpf/core.c:2357 Modules linked in: CPU: 3 UID: 0 PID: 217 Comm: kworker/u32:6 Not tainted 6.15.0-rc4-syzkaller-00040-g8bac8898fe39 RIP: 0010:__bpf_prog_ret0_warn+0xa/0x20 kernel/bpf/core.c:2357 Call Trace: bpf_dispatcher_nop_func include/linux/bpf.h:1316 [inline] __bpf_prog_run include/linux/filter.h:718 [inline] bpf_prog_run include/linux/filter.h:725 [inline] cls_bpf_classify+0x74a/0x1110 net/sched/cls_bpf.c:105 ... When creating bpf program, 'fp->jit_requested' depends on bpf_jit_enable. This issue is triggered because of CONFIG_BPF_JIT_ALWAYS_ON is not set and bpf_jit_enable is set to 1, causing the arch to attempt JIT the prog, but jit failed due to FAULT_INJECTION. As a result, incorrectly treats the program as valid, when the program runs it calls `__bpf_prog_ret0_warn` and triggers the WARN_ON_ONCE(1). Reported-by: syzbot+0903f6d7f285e41cdf10@syzkaller.appspotmail.com Closes: https://lore.kernel.org/bpf/6816e34e.a70a0220.254cdc.002c.GAE@google.com Fixes: fa9dd599b4da ("bpf: get rid of pure_initcall dependency to enable jits") Signed-off-by: KaFai Wan Link: https://lore.kernel.org/r/20250526133358.2594176-1-mannkafai@gmail.com Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin --- kernel/bpf/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 3f140b7527cf..5eaaf95048ab 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -2364,7 +2364,7 @@ struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err) /* In case of BPF to BPF calls, verifier did all the prep * work with regards to JITing, etc. */ - bool jit_needed = false; + bool jit_needed = fp->jit_requested; if (fp->bpf_func) goto finalize; From 363fdf2777423ad346d781f09548cca14877f729 Mon Sep 17 00:00:00 2001 From: Wei Fang Date: Fri, 23 May 2025 16:37:59 +0800 Subject: [PATCH 194/971] net: phy: clear phydev->devlink when the link is deleted [ Upstream commit 0795b05a59b1371b18ffbf09d385296b12e9f5d5 ] There is a potential crash issue when disabling and re-enabling the network port. When disabling the network port, phy_detach() calls device_link_del() to remove the device link, but it does not clear phydev->devlink, so phydev->devlink is not a NULL pointer. Then the network port is re-enabled, but if phy_attach_direct() fails before calling device_link_add(), the code jumps to the "error" label and calls phy_detach(). Since phydev->devlink retains the old value from the previous attach/detach cycle, device_link_del() uses the old value, which accesses a NULL pointer and causes a crash. The simplified crash log is as follows. [ 24.702421] Call trace: [ 24.704856] device_link_put_kref+0x20/0x120 [ 24.709124] device_link_del+0x30/0x48 [ 24.712864] phy_detach+0x24/0x168 [ 24.716261] phy_attach_direct+0x168/0x3a4 [ 24.720352] phylink_fwnode_phy_connect+0xc8/0x14c [ 24.725140] phylink_of_phy_connect+0x1c/0x34 Therefore, phydev->devlink needs to be cleared when the device link is deleted. Fixes: bc66fa87d4fd ("net: phy: Add link between phy dev and mac dev") Signed-off-by: Wei Fang Reviewed-by: Andrew Lunn Reviewed-by: Florian Fainelli Link: https://patch.msgid.link/20250523083759.3741168-1-wei.fang@nxp.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/phy/phy_device.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index ec2a3d16b1a2..cde0e80474a1 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -1806,8 +1806,10 @@ void phy_detach(struct phy_device *phydev) struct module *ndev_owner = NULL; struct mii_bus *bus; - if (phydev->devlink) + if (phydev->devlink) { device_link_del(phydev->devlink); + phydev->devlink = NULL; + } if (phydev->sysfs_links) { if (dev) From 4744a5d71d2abfcbfc0dfacbd2e7eef03d9db01c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 22 May 2025 13:21:47 +0200 Subject: [PATCH 195/971] net: phy: fix up const issues in to_mdio_device() and to_phy_device() [ Upstream commit e9cb929670a1e98b592b30f03f06e9e20110f318 ] Both to_mdio_device() and to_phy_device() "throw away" the const pointer attribute passed to them and return a non-const pointer, which generally is not a good thing overall. Fix this up by using container_of_const() which was designed for this very problem. Cc: Alexander Lobakin Cc: Andrew Lunn Cc: Heiner Kallweit Cc: Russell King Fixes: 7eab14de73a8 ("mdio, phy: fix -Wshadow warnings triggered by nested container_of()") Signed-off-by: Greg Kroah-Hartman Link: https://patch.msgid.link/2025052246-conduit-glory-8fc9@gregkh Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- include/linux/mdio.h | 5 +---- include/linux/phy.h | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/include/linux/mdio.h b/include/linux/mdio.h index 8fa23bdcedbf..0bca1a960853 100644 --- a/include/linux/mdio.h +++ b/include/linux/mdio.h @@ -44,10 +44,7 @@ struct mdio_device { unsigned int reset_deassert_delay; }; -static inline struct mdio_device *to_mdio_device(const struct device *dev) -{ - return container_of(dev, struct mdio_device, dev); -} +#define to_mdio_device(__dev) container_of_const(__dev, struct mdio_device, dev) /* struct mdio_driver_common: Common to all MDIO drivers */ struct mdio_driver_common { diff --git a/include/linux/phy.h b/include/linux/phy.h index 5aa30ee99810..a57e799b1de1 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -766,10 +766,7 @@ struct phy_device { /* Generic phy_device::dev_flags */ #define PHY_F_NO_IRQ 0x80000000 -static inline struct phy_device *to_phy_device(const struct device *dev) -{ - return container_of(to_mdio_device(dev), struct phy_device, mdio); -} +#define to_phy_device(__dev) container_of_const(to_mdio_device(__dev), struct phy_device, mdio) /** * struct phy_tdr_config - Configuration of a TDR raw test From 6486f11ccef4a1a6b0a6a0af7a936e4e417fc099 Mon Sep 17 00:00:00 2001 From: Thangaraj Samynathan Date: Mon, 26 May 2025 11:00:47 +0530 Subject: [PATCH 196/971] net: lan743x: rename lan743x_reset_phy to lan743x_hw_reset_phy [ Upstream commit 68927eb52d0af04863584930db06075d2610e194 ] rename the function to lan743x_hw_reset_phy to better describe it operation. Fixes: 23f0703c125be ("lan743x: Add main source files for new lan743x driver") Signed-off-by: Thangaraj Samynathan Reviewed-by: Andrew Lunn Link: https://patch.msgid.link/20250526053048.287095-2-thangaraj.s@microchip.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/microchip/lan743x_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c index f971d60484f0..781440d5756f 100644 --- a/drivers/net/ethernet/microchip/lan743x_main.c +++ b/drivers/net/ethernet/microchip/lan743x_main.c @@ -1373,7 +1373,7 @@ static int lan743x_mac_set_mtu(struct lan743x_adapter *adapter, int new_mtu) } /* PHY */ -static int lan743x_phy_reset(struct lan743x_adapter *adapter) +static int lan743x_hw_reset_phy(struct lan743x_adapter *adapter) { u32 data; @@ -1407,7 +1407,7 @@ static void lan743x_phy_update_flowcontrol(struct lan743x_adapter *adapter, static int lan743x_phy_init(struct lan743x_adapter *adapter) { - return lan743x_phy_reset(adapter); + return lan743x_hw_reset_phy(adapter); } static void lan743x_phy_link_status_change(struct net_device *netdev) From 0b40aeaf83ca04d4c9801e235b7533400c8b5f17 Mon Sep 17 00:00:00 2001 From: Horatiu Vultur Date: Thu, 22 May 2025 13:57:22 +0200 Subject: [PATCH 197/971] net: phy: mscc: Fix memory leak when using one step timestamping [ Upstream commit 846992645b25ec4253167e3f931e4597eb84af56 ] Fix memory leak when running one-step timestamping. When running one-step sync timestamping, the HW is configured to insert the TX time into the frame, so there is no reason to keep the skb anymore. As in this case the HW will never generate an interrupt to say that the frame was timestamped, then the frame will never released. Fix this by freeing the frame in case of one-step timestamping. Fixes: 7d272e63e0979d ("net: phy: mscc: timestamping and PHC support") Signed-off-by: Horatiu Vultur Link: https://patch.msgid.link/20250522115722.2827199-1-horatiu.vultur@microchip.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/phy/mscc/mscc_ptp.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c index cf728bfd83e2..af44b01f3d38 100644 --- a/drivers/net/phy/mscc/mscc_ptp.c +++ b/drivers/net/phy/mscc/mscc_ptp.c @@ -1165,18 +1165,24 @@ static void vsc85xx_txtstamp(struct mii_timestamper *mii_ts, container_of(mii_ts, struct vsc8531_private, mii_ts); if (!vsc8531->ptp->configured) - return; + goto out; - if (vsc8531->ptp->tx_type == HWTSTAMP_TX_OFF) { - kfree_skb(skb); - return; - } + if (vsc8531->ptp->tx_type == HWTSTAMP_TX_OFF) + goto out; + + if (vsc8531->ptp->tx_type == HWTSTAMP_TX_ONESTEP_SYNC) + if (ptp_msg_is_sync(skb, type)) + goto out; skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; mutex_lock(&vsc8531->ts_lock); __skb_queue_tail(&vsc8531->ptp->tx_queue, skb); mutex_unlock(&vsc8531->ts_lock); + return; + +out: + kfree_skb(skb); } static bool vsc85xx_rxtstamp(struct mii_timestamper *mii_ts, From 5df8db01d6a4e9c35a5ba5d7e130d5cecd3ffcb4 Mon Sep 17 00:00:00 2001 From: Hariprasad Kelam Date: Thu, 22 May 2025 17:28:42 +0530 Subject: [PATCH 198/971] octeontx2-pf: QOS: Refactor TC_HTB_LEAF_DEL_LAST callback [ Upstream commit 67af4ec948e8ce3ea53a9cf614d01fddf172e56d ] This patch addresses below issues, 1. Active traffic on the leaf node must be stopped before its send queue is reassigned to the parent. This patch resolves the issue by marking the node as 'Inner'. 2. During a system reboot, the interface receives TC_HTB_LEAF_DEL and TC_HTB_LEAF_DEL_LAST callbacks to delete its HTB queues. In the case of TC_HTB_LEAF_DEL_LAST, although the same send queue is reassigned to the parent, the current logic still attempts to update the real number of queues, leadning to below warnings New queues can't be registered after device unregistration. WARNING: CPU: 0 PID: 6475 at net/core/net-sysfs.c:1714 netdev_queue_update_kobjects+0x1e4/0x200 Fixes: 5e6808b4c68d ("octeontx2-pf: Add support for HTB offload") Signed-off-by: Hariprasad Kelam Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250522115842.1499666-1-hkelam@marvell.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- drivers/net/ethernet/marvell/octeontx2/nic/qos.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/qos.c b/drivers/net/ethernet/marvell/octeontx2/nic/qos.c index 37db19584c14..92861f102590 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/qos.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/qos.c @@ -1560,6 +1560,7 @@ static int otx2_qos_leaf_del_last(struct otx2_nic *pfvf, u16 classid, bool force if (!node->is_static) dwrr_del_node = true; + WRITE_ONCE(node->qid, OTX2_QOS_QID_INNER); /* destroy the leaf node */ otx2_qos_disable_sq(pfvf, qid); otx2_qos_destroy_node(pfvf, node); @@ -1604,9 +1605,6 @@ static int otx2_qos_leaf_del_last(struct otx2_nic *pfvf, u16 classid, bool force } kfree(new_cfg); - /* update tx_real_queues */ - otx2_qos_update_tx_netdev_queues(pfvf); - return 0; } From 946bfdfcb76ac2bac5b8526447035885ff41c598 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Thu, 22 May 2025 15:18:56 -0700 Subject: [PATCH 199/971] calipso: Don't call calipso functions for AF_INET sk. [ Upstream commit 6e9f2df1c550ead7cecb3e450af1105735020c92 ] syzkaller reported a null-ptr-deref in txopt_get(). [0] The offset 0x70 was of struct ipv6_txoptions in struct ipv6_pinfo, so struct ipv6_pinfo was NULL there. However, this never happens for IPv6 sockets as inet_sk(sk)->pinet6 is always set in inet6_create(), meaning the socket was not IPv6 one. The root cause is missing validation in netlbl_conn_setattr(). netlbl_conn_setattr() switches branches based on struct sockaddr.sa_family, which is passed from userspace. However, netlbl_conn_setattr() does not check if the address family matches the socket. The syzkaller must have called connect() for an IPv6 address on an IPv4 socket. We have a proper validation in tcp_v[46]_connect(), but security_socket_connect() is called in the earlier stage. Let's copy the validation to netlbl_conn_setattr(). [0]: Oops: general protection fault, probably for non-canonical address 0xdffffc000000000e: 0000 [#1] PREEMPT SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000070-0x0000000000000077] CPU: 2 UID: 0 PID: 12928 Comm: syz.9.1677 Not tainted 6.12.0 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 RIP: 0010:txopt_get include/net/ipv6.h:390 [inline] RIP: 0010: Code: 02 00 00 49 8b ac 24 f8 02 00 00 e8 84 69 2a fd e8 ff 00 16 fd 48 8d 7d 70 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 53 02 00 00 48 8b 6d 70 48 85 ed 0f 84 ab 01 00 RSP: 0018:ffff88811b8afc48 EFLAGS: 00010212 RAX: dffffc0000000000 RBX: 1ffff11023715f8a RCX: ffffffff841ab00c RDX: 000000000000000e RSI: ffffc90007d9e000 RDI: 0000000000000070 RBP: 0000000000000000 R08: ffffed1023715f9d R09: ffffed1023715f9e R10: ffffed1023715f9d R11: 0000000000000003 R12: ffff888123075f00 R13: ffff88810245bd80 R14: ffff888113646780 R15: ffff888100578a80 FS: 00007f9019bd7640(0000) GS:ffff8882d2d00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f901b927bac CR3: 0000000104788003 CR4: 0000000000770ef0 PKRU: 80000000 Call Trace: calipso_sock_setattr+0x56/0x80 net/netlabel/netlabel_calipso.c:557 netlbl_conn_setattr+0x10c/0x280 net/netlabel/netlabel_kapi.c:1177 selinux_netlbl_socket_connect_helper+0xd3/0x1b0 security/selinux/netlabel.c:569 selinux_netlbl_socket_connect_locked security/selinux/netlabel.c:597 [inline] selinux_netlbl_socket_connect+0xb6/0x100 security/selinux/netlabel.c:615 selinux_socket_connect+0x5f/0x80 security/selinux/hooks.c:4931 security_socket_connect+0x50/0xa0 security/security.c:4598 __sys_connect_file+0xa4/0x190 net/socket.c:2067 __sys_connect+0x12c/0x170 net/socket.c:2088 __do_sys_connect net/socket.c:2098 [inline] __se_sys_connect net/socket.c:2095 [inline] __x64_sys_connect+0x73/0xb0 net/socket.c:2095 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xaa/0x1b0 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f901b61a12d Code: 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f9019bd6fa8 EFLAGS: 00000246 ORIG_RAX: 000000000000002a RAX: ffffffffffffffda RBX: 00007f901b925fa0 RCX: 00007f901b61a12d RDX: 000000000000001c RSI: 0000200000000140 RDI: 0000000000000003 RBP: 00007f901b701505 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000000000 R14: 00007f901b5b62a0 R15: 00007f9019bb7000 Modules linked in: Fixes: ceba1832b1b2 ("calipso: Set the calipso socket label to match the secattr.") Reported-by: syzkaller Reported-by: John Cheung Closes: https://lore.kernel.org/netdev/CAP=Rh=M1LzunrcQB1fSGauMrJrhL6GGps5cPAKzHJXj6GQV+-g@mail.gmail.com/ Signed-off-by: Kuniyuki Iwashima Acked-by: Paul Moore Link: https://patch.msgid.link/20250522221858.91240-1-kuniyu@amazon.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- net/netlabel/netlabel_kapi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index 27511c90a26f..75b645c1928d 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c @@ -1140,6 +1140,9 @@ int netlbl_conn_setattr(struct sock *sk, break; #if IS_ENABLED(CONFIG_IPV6) case AF_INET6: + if (sk->sk_family != AF_INET6) + return -EAFNOSUPPORT; + addr6 = (struct sockaddr_in6 *)addr; entry = netlbl_domhsh_getentry_af6(secattr->domain, &addr6->sin6_addr); From 8ebcd311b4866ab911d1445ead08690e67f0c488 Mon Sep 17 00:00:00 2001 From: Faicker Mo Date: Fri, 23 May 2025 03:41:43 +0000 Subject: [PATCH 200/971] net: openvswitch: Fix the dead loop of MPLS parse [ Upstream commit 0bdc924bfb319fb10d1113cbf091fc26fb7b1f99 ] The unexpected MPLS packet may not end with the bottom label stack. When there are many stacks, The label count value has wrapped around. A dead loop occurs, soft lockup/CPU stuck finally. stack backtrace: UBSAN: array-index-out-of-bounds in /build/linux-0Pa0xK/linux-5.15.0/net/openvswitch/flow.c:662:26 index -1 is out of range for type '__be32 [3]' CPU: 34 PID: 0 Comm: swapper/34 Kdump: loaded Tainted: G OE 5.15.0-121-generic #131-Ubuntu Hardware name: Dell Inc. PowerEdge C6420/0JP9TF, BIOS 2.12.2 07/14/2021 Call Trace: show_stack+0x52/0x5c dump_stack_lvl+0x4a/0x63 dump_stack+0x10/0x16 ubsan_epilogue+0x9/0x36 __ubsan_handle_out_of_bounds.cold+0x44/0x49 key_extract_l3l4+0x82a/0x840 [openvswitch] ? kfree_skbmem+0x52/0xa0 key_extract+0x9c/0x2b0 [openvswitch] ovs_flow_key_extract+0x124/0x350 [openvswitch] ovs_vport_receive+0x61/0xd0 [openvswitch] ? kernel_init_free_pages.part.0+0x4a/0x70 ? get_page_from_freelist+0x353/0x540 netdev_port_receive+0xc4/0x180 [openvswitch] ? netdev_port_receive+0x180/0x180 [openvswitch] netdev_frame_hook+0x1f/0x40 [openvswitch] __netif_receive_skb_core.constprop.0+0x23a/0xf00 __netif_receive_skb_list_core+0xfa/0x240 netif_receive_skb_list_internal+0x18e/0x2a0 napi_complete_done+0x7a/0x1c0 bnxt_poll+0x155/0x1c0 [bnxt_en] __napi_poll+0x30/0x180 net_rx_action+0x126/0x280 ? bnxt_msix+0x67/0x80 [bnxt_en] handle_softirqs+0xda/0x2d0 irq_exit_rcu+0x96/0xc0 common_interrupt+0x8e/0xa0 Fixes: fbdcdd78da7c ("Change in Openvswitch to support MPLS label depth of 3 in ingress direction") Signed-off-by: Faicker Mo Acked-by: Ilya Maximets Reviewed-by: Aaron Conole Link: https://patch.msgid.link/259D3404-575D-4A6D-B263-1DF59A67CF89@zenlayer.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- net/openvswitch/flow.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 8a848ce72e29..b80bd3a90773 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c @@ -788,7 +788,7 @@ static int key_extract_l3l4(struct sk_buff *skb, struct sw_flow_key *key) memset(&key->ipv4, 0, sizeof(key->ipv4)); } } else if (eth_p_mpls(key->eth.type)) { - u8 label_count = 1; + size_t label_count = 1; memset(&key->mpls, 0, sizeof(key->mpls)); skb_set_inner_network_header(skb, skb->mac_len); From 857b4d2bbeb4e36bde4cf9eb362e1ce947c658ab Mon Sep 17 00:00:00 2001 From: Horatiu Vultur Date: Fri, 23 May 2025 10:27:16 +0200 Subject: [PATCH 201/971] net: phy: mscc: Stop clearing the the UDPv4 checksum for L2 frames [ Upstream commit 57a92d14659df3e7e7e0052358c8cc68bbbc3b5e ] We have noticed that when PHY timestamping is enabled, L2 frames seems to be modified by changing two 2 bytes with a value of 0. The place were these 2 bytes seems to be random(or I couldn't find a pattern). In most of the cases the userspace can ignore these frames but if for example those 2 bytes are in the correction field there is nothing to do. This seems to happen when configuring the HW for IPv4 even that the flow is not enabled. These 2 bytes correspond to the UDPv4 checksum and once we don't enable clearing the checksum when using L2 frames then the frame doesn't seem to be changed anymore. Fixes: 7d272e63e0979d ("net: phy: mscc: timestamping and PHC support") Signed-off-by: Horatiu Vultur Link: https://patch.msgid.link/20250523082716.2935895-1-horatiu.vultur@microchip.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- drivers/net/phy/mscc/mscc_ptp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c index af44b01f3d38..7e7ce79eadff 100644 --- a/drivers/net/phy/mscc/mscc_ptp.c +++ b/drivers/net/phy/mscc/mscc_ptp.c @@ -943,7 +943,9 @@ static int vsc85xx_ip1_conf(struct phy_device *phydev, enum ts_blk blk, /* UDP checksum offset in IPv4 packet * according to: https://tools.ietf.org/html/rfc768 */ - val |= IP1_NXT_PROT_UDP_CHKSUM_OFF(26) | IP1_NXT_PROT_UDP_CHKSUM_CLEAR; + val |= IP1_NXT_PROT_UDP_CHKSUM_OFF(26); + if (enable) + val |= IP1_NXT_PROT_UDP_CHKSUM_CLEAR; vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_NXT_PROT_UDP_CHKSUM, val); From 67b800b6d772e84a4591c1c2b8f627511e6a8d80 Mon Sep 17 00:00:00 2001 From: Zhiguo Niu Date: Wed, 14 May 2025 16:45:48 +0800 Subject: [PATCH 202/971] f2fs: use d_inode(dentry) cleanup dentry->d_inode [ Upstream commit a6c397a31f58a1d577c2c8d04b624e9baa31951c ] no logic changes. Signed-off-by: Zhiguo Niu Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- fs/f2fs/namei.c | 8 ++++---- fs/f2fs/super.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 2e08e1fdf485..58ab04aff6bf 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -411,7 +411,7 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir, if (is_inode_flag_set(dir, FI_PROJ_INHERIT) && (!projid_eq(F2FS_I(dir)->i_projid, - F2FS_I(old_dentry->d_inode)->i_projid))) + F2FS_I(inode)->i_projid))) return -EXDEV; err = f2fs_dquot_initialize(dir); @@ -905,7 +905,7 @@ static int f2fs_rename(struct mnt_idmap *idmap, struct inode *old_dir, if (is_inode_flag_set(new_dir, FI_PROJ_INHERIT) && (!projid_eq(F2FS_I(new_dir)->i_projid, - F2FS_I(old_dentry->d_inode)->i_projid))) + F2FS_I(old_inode)->i_projid))) return -EXDEV; /* @@ -1101,10 +1101,10 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry, if ((is_inode_flag_set(new_dir, FI_PROJ_INHERIT) && !projid_eq(F2FS_I(new_dir)->i_projid, - F2FS_I(old_dentry->d_inode)->i_projid)) || + F2FS_I(old_inode)->i_projid)) || (is_inode_flag_set(new_dir, FI_PROJ_INHERIT) && !projid_eq(F2FS_I(old_dir)->i_projid, - F2FS_I(new_dentry->d_inode)->i_projid))) + F2FS_I(new_inode)->i_projid))) return -EXDEV; err = f2fs_dquot_initialize(old_dir); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 4cc87921aac3..6b3cafbe9867 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1849,9 +1849,9 @@ static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf) buf->f_fsid = u64_to_fsid(id); #ifdef CONFIG_QUOTA - if (is_inode_flag_set(dentry->d_inode, FI_PROJ_INHERIT) && + if (is_inode_flag_set(d_inode(dentry), FI_PROJ_INHERIT) && sb_has_quota_limits_enabled(sb, PRJQUOTA)) { - f2fs_statfs_project(sb, F2FS_I(dentry->d_inode)->i_projid, buf); + f2fs_statfs_project(sb, F2FS_I(d_inode(dentry))->i_projid, buf); } #endif return 0; From c4f2f90ebbad9dff761517941ed93590622c1427 Mon Sep 17 00:00:00 2001 From: Zhiguo Niu Date: Wed, 14 May 2025 16:45:49 +0800 Subject: [PATCH 203/971] f2fs: fix to correct check conditions in f2fs_cross_rename [ Upstream commit 9883494c45a13dc88d27dde4f988c04823b42a2f ] Should be "old_dir" here. Fixes: 5c57132eaf52 ("f2fs: support project quota") Signed-off-by: Zhiguo Niu Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- fs/f2fs/namei.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 58ab04aff6bf..4d6f0a6365fe 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -1102,7 +1102,7 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry, if ((is_inode_flag_set(new_dir, FI_PROJ_INHERIT) && !projid_eq(F2FS_I(new_dir)->i_projid, F2FS_I(old_inode)->i_projid)) || - (is_inode_flag_set(new_dir, FI_PROJ_INHERIT) && + (is_inode_flag_set(old_dir, FI_PROJ_INHERIT) && !projid_eq(F2FS_I(old_dir)->i_projid, F2FS_I(new_inode)->i_projid))) return -EXDEV; From 8218e21030bdda1c171b87a201fb4fea3ddee705 Mon Sep 17 00:00:00 2001 From: Dzmitry Sankouski Date: Tue, 25 Feb 2025 19:38:53 +0300 Subject: [PATCH 204/971] arm64: dts: qcom: sdm845-starqltechn: remove wifi [ Upstream commit 2d3dd4b237638853b8a99353401ab8d88a6afb6c ] Starqltechn has broadcom chip for wifi, so sdm845 wifi part can be disabled. Fixes: d711b22eee55 ("arm64: dts: qcom: starqltechn: add initial device tree for starqltechn") Reviewed-by: Konrad Dybcio Signed-off-by: Dzmitry Sankouski Fixes: d711b22eee55 ("arm64: dts: qcom: starqltechn: add initial device tree for starqltechn") Reviewed-by: Bryan O'Donoghue Link: https://lore.kernel.org/r/20250225-starqltechn_integration_upstream-v9-2-a5d80375cb66@gmail.com Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts index d37a433130b9..6fc30fd1262b 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts @@ -418,14 +418,6 @@ status = "okay"; }; -&wifi { - vdd-0.8-cx-mx-supply = <&vreg_l5a_0p8>; - vdd-1.8-xo-supply = <&vreg_l7a_1p8>; - vdd-1.3-rfa-supply = <&vreg_l17a_1p3>; - vdd-3.3-ch0-supply = <&vreg_l25a_3p3>; - status = "okay"; -}; - &tlmm { gpio-reserved-ranges = <0 4>, <27 4>, <81 4>, <85 4>; From 2bf235c5dddf3636de83d373380efa05dd6bd428 Mon Sep 17 00:00:00 2001 From: Dzmitry Sankouski Date: Tue, 25 Feb 2025 19:38:54 +0300 Subject: [PATCH 205/971] arm64: dts: qcom: sdm845-starqltechn: fix usb regulator mistake [ Upstream commit 242e4126ee007b95765c21a9d74651fdcf221f2b ] Usb regulator was wrongly pointed to vreg_l1a_0p875. However, on starqltechn it's powered from vreg_l5a_0p8. Fixes: d711b22eee55 ("arm64: dts: qcom: starqltechn: add initial device tree for starqltechn") Reviewed-by: Konrad Dybcio Signed-off-by: Dzmitry Sankouski Link: https://lore.kernel.org/r/20250225-starqltechn_integration_upstream-v9-3-a5d80375cb66@gmail.com Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts index 6fc30fd1262b..f3f2b25883d8 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts @@ -135,8 +135,6 @@ vdda_sp_sensor: vdda_ufs1_core: vdda_ufs2_core: - vdda_usb1_ss_core: - vdda_usb2_ss_core: vreg_l1a_0p875: ldo1 { regulator-min-microvolt = <880000>; regulator-max-microvolt = <880000>; @@ -157,6 +155,7 @@ regulator-initial-mode = ; }; + vdda_usb1_ss_core: vdd_wcss_cx: vdd_wcss_mx: vdda_wcss_pll: From 618060fc563bbe9332f5e9c95668fa2980158b81 Mon Sep 17 00:00:00 2001 From: Dzmitry Sankouski Date: Tue, 25 Feb 2025 19:38:55 +0300 Subject: [PATCH 206/971] arm64: dts: qcom: sdm845-starqltechn: refactor node order [ Upstream commit cba1dd3d851ebc1b6c5ae4000208a9753320694b ] Fixes: d711b22eee55 ("arm64: dts: qcom: starqltechn: add initial device tree for starqltechn") Signed-off-by: Dzmitry Sankouski Link: https://lore.kernel.org/r/20250225-starqltechn_integration_upstream-v9-4-a5d80375cb66@gmail.com Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts index f3f2b25883d8..8a0d63bd594b 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts @@ -382,8 +382,8 @@ }; &sdhc_2 { - pinctrl-names = "default"; pinctrl-0 = <&sdc2_clk_state &sdc2_cmd_state &sdc2_data_state &sd_card_det_n_state>; + pinctrl-names = "default"; cd-gpios = <&tlmm 126 GPIO_ACTIVE_LOW>; vmmc-supply = <&vreg_l21a_2p95>; vqmmc-supply = <&vddpx_2>; From 072b6f8e39ce90810797ce9c812471ce21ca3134 Mon Sep 17 00:00:00 2001 From: Dzmitry Sankouski Date: Tue, 25 Feb 2025 19:38:56 +0300 Subject: [PATCH 207/971] arm64: dts: qcom: sdm845-starqltechn: remove excess reserved gpios [ Upstream commit fb5fce873b952f8b1c5f7edcabcc8611ef45ea7a ] Starqltechn has 2 reserved gpio ranges <27 4>, <85 4>. <27 4> is spi for eSE(embedded Secure Element). <85 4> is spi for fingerprint. Remove excess reserved gpio regions. Fixes: d711b22eee55 ("arm64: dts: qcom: starqltechn: add initial device tree for starqltechn") Reviewed-by: Konrad Dybcio Signed-off-by: Dzmitry Sankouski Link: https://lore.kernel.org/r/20250225-starqltechn_integration_upstream-v9-5-a5d80375cb66@gmail.com Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts index 8a0d63bd594b..5948b401165c 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts @@ -418,7 +418,8 @@ }; &tlmm { - gpio-reserved-ranges = <0 4>, <27 4>, <81 4>, <85 4>; + gpio-reserved-ranges = <27 4>, /* SPI (eSE - embedded Secure Element) */ + <85 4>; /* SPI (fingerprint reader) */ sdc2_clk_state: sdc2-clk-state { pins = "sdc2_clk"; From ac0df85cc591a754121a34f87c2971b5955e378c Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Wed, 12 Feb 2025 18:03:47 +0100 Subject: [PATCH 208/971] arm64: dts: qcom: sm8350: Reenable crypto & cryptobam [ Upstream commit 75eefd474469abf95aa9ef6da8161d69f86b98b4 ] When num-channels and qcom,num-ees is not provided in devicetree, the driver will try to read these values from the registers during probe but this fails if the interconnect is not on and then crashes the system. So we can provide these properties in devicetree (queried after patching BAM driver to enable the necessary interconnect) so we can probe cryptobam without reading registers and then also use the QCE as expected. Fixes: 4d29db204361 ("arm64: dts: qcom: sm8350: fix BAM DMA crash and reboot") Fixes: f1040a7fe8f0 ("arm64: dts: qcom: sm8350: Add Crypto Engine support") Signed-off-by: Luca Weiss Signed-off-by: Stephan Gerhold Link: https://lore.kernel.org/r/20250212-bam-dma-fixes-v1-1-f560889e65d8@linaro.org Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/qcom/sm8350.dtsi | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi index 5376c0a00fab..215782b1970d 100644 --- a/arch/arm64/boot/dts/qcom/sm8350.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi @@ -1754,11 +1754,11 @@ interrupts = ; #dma-cells = <1>; qcom,ee = <0>; + qcom,num-ees = <4>; + num-channels = <16>; qcom,controlled-remotely; iommus = <&apps_smmu 0x594 0x0011>, <&apps_smmu 0x596 0x0011>; - /* FIXME: Probing BAM DMA causes some abort and system hang */ - status = "fail"; }; crypto: crypto@1dfa000 { @@ -1770,8 +1770,6 @@ <&apps_smmu 0x596 0x0011>; interconnects = <&aggre2_noc MASTER_CRYPTO 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "memory"; - /* FIXME: dependency BAM DMA is disabled */ - status = "disabled"; }; ipa: ipa@1e40000 { From b1253f7c65d12fcd1de8625840df61f5be6b31d0 Mon Sep 17 00:00:00 2001 From: Xilin Wu Date: Sat, 8 Mar 2025 18:27:51 +0800 Subject: [PATCH 209/971] arm64: dts: qcom: sm8250: Fix CPU7 opp table [ Upstream commit 28f997b89967afdc0855d8aa7538b251fb44f654 ] There is a typo in cpu7_opp9. Fix it to get rid of the following errors. [ 0.198043] cpu cpu7: Voltage update failed freq=1747200 [ 0.198052] cpu cpu7: failed to update OPP for freq=1747200 Fixes: 8e0e8016cb79 ("arm64: dts: qcom: sm8250: Add CPU opp tables") Signed-off-by: Xilin Wu Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20250308-fix-sm8250-cpufreq-v1-1-8a0226721399@gmail.com Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/qcom/sm8250.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi index 21bbffc4e5a2..c9a7d1b75c65 100644 --- a/arch/arm64/boot/dts/qcom/sm8250.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi @@ -601,7 +601,7 @@ }; cpu7_opp9: opp-1747200000 { - opp-hz = /bits/ 64 <1708800000>; + opp-hz = /bits/ 64 <1747200000>; opp-peak-kBps = <5412000 42393600>; }; From 3c947298903116e445a952624c7c98bc26e8a404 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Tue, 3 Dec 2024 18:44:02 +0100 Subject: [PATCH 210/971] arm64: dts: qcom: sc8280xp-x13s: Drop duplicate DMIC supplies [ Upstream commit a2e617f4e6981aa514a569e927f90b0d39bb31b2 ] The WCD938x codec provides two controls for each of the MIC_BIASn outputs: - "MIC BIASn" enables an internal regulator to generate the output with a configurable voltage (qcom,micbiasN-microvolt). - "VA MIC BIASn" enables "pull-up mode" that bypasses the internal regulator and directly outputs fixed 1.8V from the VDD_PX pin. This is intended for low-power VA (voice activation) use cases. The audio-routing setup for the ThinkPad X13s currently specifies both as power supplies for the DMICs, but only one of them can be active at the same time. In practice, only the internal regulator is used with the current setup because the driver prefers it over pull-up mode. Make this more clear by dropping the redundant routes to the pull-up "VA MIC BIASn" supply. There is no functional difference except that we skip briefly switching to pull-up mode when shutting down the microphone. Fixes: 2e498f35c385 ("arm64: dts: qcom: sc8280xp-x13s: fix va dmic dai links and routing") Signed-off-by: Stephan Gerhold Link: https://lore.kernel.org/r/20241203-x1e80100-va-mic-bias-v1-1-0dfd4d9b492c@linaro.org Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts index 5c2894fcfa4a..5498e84bfead 100644 --- a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts +++ b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts @@ -985,9 +985,6 @@ "VA DMIC0", "MIC BIAS1", "VA DMIC1", "MIC BIAS1", "VA DMIC2", "MIC BIAS3", - "VA DMIC0", "VA MIC BIAS1", - "VA DMIC1", "VA MIC BIAS1", - "VA DMIC2", "VA MIC BIAS3", "TX SWR_ADC1", "ADC2_OUTPUT"; wcd-playback-dai-link { From e6ef5b282e334eaa6831e90d468a21f4997a16c8 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 4 Apr 2025 13:27:43 +0200 Subject: [PATCH 211/971] ARM: dts: at91: usb_a9263: fix GPIO for Dataflash chip select [ Upstream commit 67ba341e57ab158423818ed33bfa1c40eb0e5e7e ] Dataflash did not work on my board. After checking schematics and using the proper GPIO, it works now. Also, make it active low to avoid: flash@0 enforce active low on GPIO handle Fixes: 2432d201468d ("ARM: at91: dt: usb-a9263: add dataflash support") Signed-off-by: Wolfram Sang Link: https://lore.kernel.org/r/20250404112742.67416-2-wsa+renesas@sang-engineering.com Signed-off-by: Claudiu Beznea Signed-off-by: Sasha Levin --- arch/arm/boot/dts/microchip/usb_a9263.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/microchip/usb_a9263.dts b/arch/arm/boot/dts/microchip/usb_a9263.dts index 45745915b2e1..25c643067b2e 100644 --- a/arch/arm/boot/dts/microchip/usb_a9263.dts +++ b/arch/arm/boot/dts/microchip/usb_a9263.dts @@ -58,7 +58,7 @@ }; spi0: spi@fffa4000 { - cs-gpios = <&pioB 15 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioA 5 GPIO_ACTIVE_LOW>; status = "okay"; flash@0 { compatible = "atmel,at45", "atmel,dataflash"; From 8af84ebd27fcbee761ee9ba5bcbc5bc6ccfab445 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 2 Apr 2025 23:04:46 +0200 Subject: [PATCH 212/971] ARM: dts: at91: at91sam9263: fix NAND chip selects [ Upstream commit c72ede1c24be689733bcd2233a3a56f2478429c8 ] NAND did not work on my USB-A9263. I discovered that the offending commit converted the PIO bank for chip selects wrongly, so all A9263 boards need to be fixed. Fixes: 1004a2977bdc ("ARM: dts: at91: Switch to the new NAND bindings") Signed-off-by: Wolfram Sang Reviewed-by: Alexandre Belloni Link: https://lore.kernel.org/r/20250402210446.5972-2-wsa+renesas@sang-engineering.com Signed-off-by: Claudiu Beznea Signed-off-by: Sasha Levin --- arch/arm/boot/dts/microchip/at91sam9263ek.dts | 2 +- arch/arm/boot/dts/microchip/tny_a9263.dts | 2 +- arch/arm/boot/dts/microchip/usb_a9263.dts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/microchip/at91sam9263ek.dts b/arch/arm/boot/dts/microchip/at91sam9263ek.dts index ce8baff6a9f4..e42e1a75a715 100644 --- a/arch/arm/boot/dts/microchip/at91sam9263ek.dts +++ b/arch/arm/boot/dts/microchip/at91sam9263ek.dts @@ -152,7 +152,7 @@ nand@3 { reg = <0x3 0x0 0x800000>; rb-gpios = <&pioA 22 GPIO_ACTIVE_HIGH>; - cs-gpios = <&pioA 15 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioD 15 GPIO_ACTIVE_HIGH>; nand-bus-width = <8>; nand-ecc-mode = "soft"; nand-on-flash-bbt; diff --git a/arch/arm/boot/dts/microchip/tny_a9263.dts b/arch/arm/boot/dts/microchip/tny_a9263.dts index 62b7d9f9a926..c8b6318aaa83 100644 --- a/arch/arm/boot/dts/microchip/tny_a9263.dts +++ b/arch/arm/boot/dts/microchip/tny_a9263.dts @@ -64,7 +64,7 @@ nand@3 { reg = <0x3 0x0 0x800000>; rb-gpios = <&pioA 22 GPIO_ACTIVE_HIGH>; - cs-gpios = <&pioA 15 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioD 15 GPIO_ACTIVE_HIGH>; nand-bus-width = <8>; nand-ecc-mode = "soft"; nand-on-flash-bbt; diff --git a/arch/arm/boot/dts/microchip/usb_a9263.dts b/arch/arm/boot/dts/microchip/usb_a9263.dts index 25c643067b2e..454176ce6d3f 100644 --- a/arch/arm/boot/dts/microchip/usb_a9263.dts +++ b/arch/arm/boot/dts/microchip/usb_a9263.dts @@ -84,7 +84,7 @@ nand@3 { reg = <0x3 0x0 0x800000>; rb-gpios = <&pioA 22 GPIO_ACTIVE_HIGH>; - cs-gpios = <&pioA 15 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioD 15 GPIO_ACTIVE_HIGH>; nand-bus-width = <8>; nand-ecc-mode = "soft"; nand-on-flash-bbt; From 62f142f9b8638d14e763332a7a1a773acc6433a7 Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Wed, 2 Apr 2025 11:06:15 +0200 Subject: [PATCH 213/971] arm64: dts: mediatek: mt8195: Reparent vdec1/2 and venc1 power domains [ Upstream commit 394f29033324e2317bfd6a7ed99b9a60832b36a2 ] By hardware, the first and second core of the video decoder IP need the VDEC_SOC to be powered up in order to be able to be accessed (both internally, by firmware, and externally, by the kernel). Similarly, for the video encoder IP, the second core needs the first core to be powered up in order to be accessible. Fix that by reparenting the VDEC1/2 power domains to be children of VDEC0 (VDEC_SOC), and the VENC1 to be a child of VENC0. Fixes: 2b515194bf0c ("arm64: dts: mt8195: Add power domains controller") Reviewed-by: Chen-Yu Tsai Link: https://lore.kernel.org/r/20250402090615.25871-3-angelogioacchino.delregno@collabora.com Signed-off-by: AngeloGioacchino Del Regno Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/mediatek/mt8195.dtsi | 50 +++++++++++++----------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi index 7ba30209ba9a..22604d3abde3 100644 --- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi @@ -617,22 +617,6 @@ #size-cells = <0>; #power-domain-cells = <1>; - power-domain@MT8195_POWER_DOMAIN_VDEC1 { - reg = ; - clocks = <&vdecsys CLK_VDEC_LARB1>; - clock-names = "vdec1-0"; - mediatek,infracfg = <&infracfg_ao>; - #power-domain-cells = <0>; - }; - - power-domain@MT8195_POWER_DOMAIN_VENC_CORE1 { - reg = ; - clocks = <&vencsys_core1 CLK_VENC_CORE1_LARB>; - clock-names = "venc1-larb"; - mediatek,infracfg = <&infracfg_ao>; - #power-domain-cells = <0>; - }; - power-domain@MT8195_POWER_DOMAIN_VDOSYS0 { reg = ; clocks = <&topckgen CLK_TOP_CFG_VDO0>, @@ -678,15 +662,25 @@ clocks = <&vdecsys_soc CLK_VDEC_SOC_LARB1>; clock-names = "vdec0-0"; mediatek,infracfg = <&infracfg_ao>; + #address-cells = <1>; + #size-cells = <0>; #power-domain-cells = <0>; - }; - power-domain@MT8195_POWER_DOMAIN_VDEC2 { - reg = ; - clocks = <&vdecsys_core1 CLK_VDEC_CORE1_LARB1>; - clock-names = "vdec2-0"; - mediatek,infracfg = <&infracfg_ao>; - #power-domain-cells = <0>; + power-domain@MT8195_POWER_DOMAIN_VDEC1 { + reg = ; + clocks = <&vdecsys CLK_VDEC_LARB1>; + clock-names = "vdec1-0"; + mediatek,infracfg = <&infracfg_ao>; + #power-domain-cells = <0>; + }; + + power-domain@MT8195_POWER_DOMAIN_VDEC2 { + reg = ; + clocks = <&vdecsys_core1 CLK_VDEC_CORE1_LARB1>; + clock-names = "vdec2-0"; + mediatek,infracfg = <&infracfg_ao>; + #power-domain-cells = <0>; + }; }; power-domain@MT8195_POWER_DOMAIN_VENC { @@ -694,7 +688,17 @@ clocks = <&vencsys CLK_VENC_LARB>; clock-names = "venc0-larb"; mediatek,infracfg = <&infracfg_ao>; + #address-cells = <1>; + #size-cells = <0>; #power-domain-cells = <0>; + + power-domain@MT8195_POWER_DOMAIN_VENC_CORE1 { + reg = ; + clocks = <&vencsys_core1 CLK_VENC_CORE1_LARB>; + clock-names = "venc1-larb"; + mediatek,infracfg = <&infracfg_ao>; + #power-domain-cells = <0>; + }; }; power-domain@MT8195_POWER_DOMAIN_VDOSYS1 { From c8658f43df4f8d36b5827db89cf00a3bd752775e Mon Sep 17 00:00:00 2001 From: Alexey Minnekhanov Date: Tue, 15 Apr 2025 16:01:01 +0300 Subject: [PATCH 214/971] arm64: dts: qcom: sdm660-xiaomi-lavender: Add missing SD card detect GPIO [ Upstream commit 2eca6af66709de0d1ba14cdf8b6d200a1337a3a2 ] During initial porting these cd-gpios were missed. Having card detect is beneficial because driver does not need to do polling every second and it can just use IRQ. SD card detection in U-Boot is also fixed by this. Fixes: cf85e9aee210 ("arm64: dts: qcom: sdm660-xiaomi-lavender: Add eMMC and SD") Signed-off-by: Alexey Minnekhanov Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250415130101.1429281-1-alexeymin@postmarketos.org Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts b/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts index 3c47410ba94c..ec4245bbfffa 100644 --- a/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts +++ b/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts @@ -404,6 +404,8 @@ &sdhc_2 { status = "okay"; + cd-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>; + vmmc-supply = <&vreg_l5b_2p95>; vqmmc-supply = <&vreg_l2b_2p95>; }; From 986c6c52d4aafa429f329b840e70c378b59f32e3 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Tue, 15 Apr 2025 20:01:27 -0500 Subject: [PATCH 215/971] arm64: dts: imx8mm-beacon: Fix RTC capacitive load [ Upstream commit 2e98d456666d63f897ba153210bcef9d78ba0f3a ] Although not noticeable when used every day, the RTC appears to drift when left to sit over time. This is due to the capacitive load not being properly set. Fix RTC drift by correcting the capacitive load setting from 7000 to 12500, which matches the actual hardware configuration. Fixes: 593816fa2f35 ("arm64: dts: imx: Add Beacon i.MX8m-Mini development kit") Signed-off-by: Adam Ford Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi index f264102bdb27..8ab0e45f2ad3 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi @@ -231,6 +231,7 @@ rtc: rtc@51 { compatible = "nxp,pcf85263"; reg = <0x51>; + quartz-load-femtofarads = <12500>; }; }; From 75b985ef1e641dd990bc312e3bca7f4bae164723 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Tue, 15 Apr 2025 20:01:28 -0500 Subject: [PATCH 216/971] arm64: dts: imx8mn-beacon: Fix RTC capacitive load [ Upstream commit c3f03bec30efd5082b55876846d57b5d17dae7b9 ] Although not noticeable when used every day, the RTC appears to drift when left to sit over time. This is due to the capacitive load not being properly set. Fix RTC drift by correcting the capacitive load setting from 7000 to 12500, which matches the actual hardware configuration. Fixes: 36ca3c8ccb53 ("arm64: dts: imx: Add Beacon i.MX8M Nano development kit") Signed-off-by: Adam Ford Reviewed-by: Frank Li Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi index 90073b16536f..1760062e6ffc 100644 --- a/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi @@ -240,6 +240,7 @@ rtc: rtc@51 { compatible = "nxp,pcf85263"; reg = <0x51>; + quartz-load-femtofarads = <12500>; }; }; From 7a276effd5061d2dbec34d7b17e09c9529234631 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Tue, 15 Apr 2025 20:01:29 -0500 Subject: [PATCH 217/971] arm64: dts: imx8mp-beacon: Fix RTC capacitive load [ Upstream commit 6821ee17537938e919e8b86a541aae451f73165b ] Although not noticeable when used every day, the RTC appears to drift when left to sit over time. This is due to the capacitive load not being properly set. Fix RTC drift by correcting the capacitive load setting from 7000 to 12500, which matches the actual hardware configuration. Fixes: 25a5ccdce767 ("arm64: dts: freescale: Introduce imx8mp-beacon-kit") Signed-off-by: Adam Ford Reviewed-by: Frank Li Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi index e5da90804780..24380f8a0085 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi @@ -192,6 +192,7 @@ rtc: rtc@51 { compatible = "nxp,pcf85263"; reg = <0x51>; + quartz-load-femtofarads = <12500>; }; }; From 2eb09d84a00abe10567ff93f2b0e4a397af76b24 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Tue, 15 Apr 2025 20:01:30 -0500 Subject: [PATCH 218/971] arm64: dts: imx8mm-beacon: Set SAI5 MCLK direction to output for HDMI audio [ Upstream commit 8c716f80dfe8cd6ed9a2696847cea1affeeff6ff ] The HDMI bridge chip fails to generate an audio source due to the SAI5 master clock (MCLK) direction not being set to output. This prevents proper clocking of the HDMI audio interface. Add the `fsl,sai-mclk-direction-output` property to the SAI5 node to ensure the MCLK is driven by the SoC, resolving the HDMI sound issue. Fixes: 8ad7d14d99f3 ("arm64: dts: imx8mm-beacon: Add HDMI video with sound") Signed-off-by: Adam Ford Reviewed-by: Frank Li Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dts b/arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dts index 905c98cb080d..a6e6860bf018 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dts +++ b/arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dts @@ -124,6 +124,7 @@ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>; assigned-clock-rates = <24576000>; #sound-dai-cells = <0>; + fsl,sai-mclk-direction-output; status = "okay"; }; From d6d756d3ea21a5f50df13503fe38f5655e97ac7f Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Tue, 15 Apr 2025 20:01:31 -0500 Subject: [PATCH 219/971] arm64: dts: imx8mn-beacon: Set SAI5 MCLK direction to output for HDMI audio [ Upstream commit a747c4dd2a60c4d0179b372032a4b98548135096 ] The HDMI bridge chip fails to generate an audio source due to the SAI5 master clock (MCLK) direction not being set to output. This prevents proper clocking of the HDMI audio interface. Add the `fsl,sai-mclk-direction-output` property to the SAI5 node to ensure the MCLK is driven by the SoC, resolving the HDMI sound issue. Fixes: 1d6880ceef43 ("arm64: dts: imx8mn-beacon: Add HDMI video with sound") Signed-off-by: Adam Ford Reviewed-by: Frank Li Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts b/arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts index 35b8d2060cd9..dfa08be33a4f 100644 --- a/arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts +++ b/arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts @@ -126,6 +126,7 @@ assigned-clock-parents = <&clk IMX8MN_AUDIO_PLL1_OUT>; assigned-clock-rates = <24576000>; #sound-dai-cells = <0>; + fsl,sai-mclk-direction-output; status = "okay"; }; From 018324818ad51a0504e5076fa318cc67268d5620 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?= Date: Fri, 2 May 2025 11:32:10 -0400 Subject: [PATCH 220/971] arm64: dts: mediatek: mt6357: Drop regulator-fixed compatibles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit d77e89b7b03fb945b4353f2dcc4a70b34baa7bcb ] Some of the regulators in the MT6357 PMIC dtsi have compatible set to regulator-fixed, even though they don't serve any purpose: all those regulators are handled as a whole by the mt6357-regulator driver. In fact this is the only dtsi in this family of chips where this is the case: mt6359 and mt6358 don't have any such compatibles. A side-effect caused by this is that the DT kselftest, which is supposed to identify nodes with compatibles that can be probed, but haven't, shows these nodes as failures. Remove the useless compatibles to move the dtsi in line with the others in its family and fix the DT kselftest failures. Fixes: 55749bb478f8 ("arm64: dts: mediatek: add mt6357 device-tree") Signed-off-by: Nícolas F. R. A. Prado Link: https://lore.kernel.org/r/20250502-mt6357-regulator-fixed-compatibles-removal-v1-1-a582c16743fe@collabora.com Signed-off-by: AngeloGioacchino Del Regno Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/mediatek/mt6357.dtsi | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt6357.dtsi b/arch/arm64/boot/dts/mediatek/mt6357.dtsi index 5fafa842d312..dca4e5c3d8e2 100644 --- a/arch/arm64/boot/dts/mediatek/mt6357.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt6357.dtsi @@ -60,7 +60,6 @@ }; mt6357_vfe28_reg: ldo-vfe28 { - compatible = "regulator-fixed"; regulator-name = "vfe28"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; @@ -75,7 +74,6 @@ }; mt6357_vrf18_reg: ldo-vrf18 { - compatible = "regulator-fixed"; regulator-name = "vrf18"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; @@ -83,7 +81,6 @@ }; mt6357_vrf12_reg: ldo-vrf12 { - compatible = "regulator-fixed"; regulator-name = "vrf12"; regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; @@ -112,7 +109,6 @@ }; mt6357_vcn28_reg: ldo-vcn28 { - compatible = "regulator-fixed"; regulator-name = "vcn28"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; @@ -120,7 +116,6 @@ }; mt6357_vcn18_reg: ldo-vcn18 { - compatible = "regulator-fixed"; regulator-name = "vcn18"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; @@ -142,7 +137,6 @@ }; mt6357_vcamio_reg: ldo-vcamio18 { - compatible = "regulator-fixed"; regulator-name = "vcamio"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; @@ -175,7 +169,6 @@ }; mt6357_vaux18_reg: ldo-vaux18 { - compatible = "regulator-fixed"; regulator-name = "vaux18"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; @@ -183,7 +176,6 @@ }; mt6357_vaud28_reg: ldo-vaud28 { - compatible = "regulator-fixed"; regulator-name = "vaud28"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; @@ -191,7 +183,6 @@ }; mt6357_vio28_reg: ldo-vio28 { - compatible = "regulator-fixed"; regulator-name = "vio28"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; @@ -199,7 +190,6 @@ }; mt6357_vio18_reg: ldo-vio18 { - compatible = "regulator-fixed"; regulator-name = "vio18"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; From 6145c491d649f93d7f01996c57ad56b10492e0ca Mon Sep 17 00:00:00 2001 From: Julien Massot Date: Mon, 5 May 2025 15:23:39 +0200 Subject: [PATCH 221/971] arm64: dts: mt6359: Add missing 'compatible' property to regulators node [ Upstream commit 1fe38d2a19950fa6dbc384ee8967c057aef9faf4 ] The 'compatible' property is required by the 'mfd/mediatek,mt6397.yaml' binding. Add it to fix the following dtb-check error: mediatek/mt8395-radxa-nio-12l.dtb: pmic: regulators: 'compatible' is a required property Fixes: 3b7d143be4b7 ("arm64: dts: mt6359: add PMIC MT6359 related nodes") Signed-off-by: Julien Massot Link: https://lore.kernel.org/r/20250505-mt8395-dtb-errors-v1-3-9c4714dcdcdb@collabora.com Signed-off-by: AngeloGioacchino Del Regno Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/mediatek/mt6359.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt6359.dtsi b/arch/arm64/boot/dts/mediatek/mt6359.dtsi index 8e1b8c85c6ed..57af3e789984 100644 --- a/arch/arm64/boot/dts/mediatek/mt6359.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt6359.dtsi @@ -18,6 +18,8 @@ }; regulators { + compatible = "mediatek,mt6359-regulator"; + mt6359_vs1_buck_reg: buck_vs1 { regulator-name = "vs1"; regulator-min-microvolt = <800000>; From ac25c30462a52616567667fd6349b53042d86e0e Mon Sep 17 00:00:00 2001 From: Alexey Minnekhanov Date: Sun, 4 May 2025 14:51:19 +0300 Subject: [PATCH 222/971] arm64: dts: qcom: sdm660-lavender: Add missing USB phy supply [ Upstream commit dbf62a117a1b7f605a98dd1fd1fd6c85ec324ea0 ] Fixes the following dtbs check error: phy@c012000: 'vdda-pll-supply' is a required property Fixes: e5d3e752b050e ("arm64: dts: qcom: sdm660-xiaomi-lavender: Add USB") Signed-off-by: Alexey Minnekhanov Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250504115120.1432282-3-alexeymin@postmarketos.org Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts b/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts index ec4245bbfffa..8221da390e1a 100644 --- a/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts +++ b/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts @@ -107,6 +107,7 @@ status = "okay"; vdd-supply = <&vreg_l1b_0p925>; + vdda-pll-supply = <&vreg_l10a_1p8>; vdda-phy-dpdm-supply = <&vreg_l7b_3p125>; }; From 850fd99f22fc676e3752628358a23eef604ad47f Mon Sep 17 00:00:00 2001 From: Alexey Minnekhanov Date: Sun, 4 May 2025 14:51:20 +0300 Subject: [PATCH 223/971] arm64: dts: qcom: sda660-ifc6560: Fix dt-validate warning [ Upstream commit f5110806b41eaa0eb0ab1bf2787876a580c6246c ] If you remove clocks property, you should remove clock-names, too. Fixes warning with dtbs check: 'clocks' is a dependency of 'clock-names' Fixes: 34279d6e3f32c ("arm64: dts: qcom: sdm660: Add initial Inforce IFC6560 board support") Signed-off-by: Alexey Minnekhanov Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250504115120.1432282-4-alexeymin@postmarketos.org Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts b/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts index 2ed39d402d3f..d687cfadee6a 100644 --- a/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts +++ b/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts @@ -155,6 +155,7 @@ * BAM DMA interconnects support is in place. */ /delete-property/ clocks; + /delete-property/ clock-names; }; &blsp1_uart2 { @@ -167,6 +168,7 @@ * BAM DMA interconnects support is in place. */ /delete-property/ clocks; + /delete-property/ clock-names; }; &blsp2_uart1 { From 1aaffafdd44b78c429e219018a875b25e7e6fcdf Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Tue, 6 May 2025 23:25:28 +0100 Subject: [PATCH 224/971] arm64: dts: rockchip: Update eMMC for NanoPi R5 series [ Upstream commit 8eca9e979a1efbcc3d090f6eb3f4da621e7c87e0 ] Add the 3.3v and 1.8v regulators that are connected to the eMMC on the R5 series devices, as well as adding the eMMC data strobe, and enable eMMC HS200 mode as the Foresee FEMDNN0xxG-A3A55 modules support it. Fixes: c8ec73b05a95d ("arm64: dts: rockchip: create common dtsi for NanoPi R5 series") Signed-off-by: Peter Robinson Reviewed-by: Diederik de Haas Link: https://lore.kernel.org/r/20250506222531.625157-1-pbrobinson@gmail.com Signed-off-by: Heiko Stuebner Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi index 93189f830640..c30354268c8f 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi @@ -486,9 +486,12 @@ &sdhci { bus-width = <8>; max-frequency = <200000000>; + mmc-hs200-1_8v; non-removable; pinctrl-names = "default"; - pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd>; + pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&vcc_1v8>; status = "okay"; }; From 38caeda97b5de683d701a15bb4cd7b0cc235b4c7 Mon Sep 17 00:00:00 2001 From: Aaron Kling Date: Mon, 28 Apr 2025 20:51:47 -0500 Subject: [PATCH 225/971] arm64: tegra: Drop remaining serial clock-names and reset-names [ Upstream commit 4cd763297c2203c6ba587d7d4a9105f96597b998 ] The referenced commit only removed some of the names, missing all that weren't in use at the time. The commit removes the rest. Fixes: 71de0a054d0e ("arm64: tegra: Drop serial clock-names and reset-names") Signed-off-by: Aaron Kling Link: https://lore.kernel.org/r/20250428-tegra-serial-fixes-v1-1-4f47c5d85bf6@gmail.com Signed-off-by: Thierry Reding Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/nvidia/tegra186.dtsi | 12 ------------ arch/arm64/boot/dts/nvidia/tegra194.dtsi | 12 ------------ 2 files changed, 24 deletions(-) diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi index 2b3bb5d0af17..f0b7949df92c 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi @@ -621,9 +621,7 @@ reg-shift = <2>; interrupts = ; clocks = <&bpmp TEGRA186_CLK_UARTB>; - clock-names = "serial"; resets = <&bpmp TEGRA186_RESET_UARTB>; - reset-names = "serial"; status = "disabled"; }; @@ -633,9 +631,7 @@ reg-shift = <2>; interrupts = ; clocks = <&bpmp TEGRA186_CLK_UARTD>; - clock-names = "serial"; resets = <&bpmp TEGRA186_RESET_UARTD>; - reset-names = "serial"; status = "disabled"; }; @@ -645,9 +641,7 @@ reg-shift = <2>; interrupts = ; clocks = <&bpmp TEGRA186_CLK_UARTE>; - clock-names = "serial"; resets = <&bpmp TEGRA186_RESET_UARTE>; - reset-names = "serial"; status = "disabled"; }; @@ -657,9 +651,7 @@ reg-shift = <2>; interrupts = ; clocks = <&bpmp TEGRA186_CLK_UARTF>; - clock-names = "serial"; resets = <&bpmp TEGRA186_RESET_UARTF>; - reset-names = "serial"; status = "disabled"; }; @@ -1236,9 +1228,7 @@ reg-shift = <2>; interrupts = ; clocks = <&bpmp TEGRA186_CLK_UARTC>; - clock-names = "serial"; resets = <&bpmp TEGRA186_RESET_UARTC>; - reset-names = "serial"; status = "disabled"; }; @@ -1248,9 +1238,7 @@ reg-shift = <2>; interrupts = ; clocks = <&bpmp TEGRA186_CLK_UARTG>; - clock-names = "serial"; resets = <&bpmp TEGRA186_RESET_UARTG>; - reset-names = "serial"; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi index 33f92b77cd9d..c36950774785 100644 --- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi @@ -766,9 +766,7 @@ reg-shift = <2>; interrupts = ; clocks = <&bpmp TEGRA194_CLK_UARTD>; - clock-names = "serial"; resets = <&bpmp TEGRA194_RESET_UARTD>; - reset-names = "serial"; status = "disabled"; }; @@ -778,9 +776,7 @@ reg-shift = <2>; interrupts = ; clocks = <&bpmp TEGRA194_CLK_UARTE>; - clock-names = "serial"; resets = <&bpmp TEGRA194_RESET_UARTE>; - reset-names = "serial"; status = "disabled"; }; @@ -790,9 +786,7 @@ reg-shift = <2>; interrupts = ; clocks = <&bpmp TEGRA194_CLK_UARTF>; - clock-names = "serial"; resets = <&bpmp TEGRA194_RESET_UARTF>; - reset-names = "serial"; status = "disabled"; }; @@ -817,9 +811,7 @@ reg-shift = <2>; interrupts = ; clocks = <&bpmp TEGRA194_CLK_UARTH>; - clock-names = "serial"; resets = <&bpmp TEGRA194_RESET_UARTH>; - reset-names = "serial"; status = "disabled"; }; @@ -1616,9 +1608,7 @@ reg-shift = <2>; interrupts = ; clocks = <&bpmp TEGRA194_CLK_UARTC>; - clock-names = "serial"; resets = <&bpmp TEGRA194_RESET_UARTC>; - reset-names = "serial"; status = "disabled"; }; @@ -1628,9 +1618,7 @@ reg-shift = <2>; interrupts = ; clocks = <&bpmp TEGRA194_CLK_UARTG>; - clock-names = "serial"; resets = <&bpmp TEGRA194_RESET_UARTG>; - reset-names = "serial"; status = "disabled"; }; From 2d4ad56428eda50dc87c326bfb3196f231ae7247 Mon Sep 17 00:00:00 2001 From: Prasanth Babu Mantena Date: Wed, 7 May 2025 10:37:01 +0530 Subject: [PATCH 226/971] arm64: dts: ti: k3-j721e-common-proc-board: Enable OSPI1 on J721E [ Upstream commit 6b8deb2ff0d31848c43a73f6044e69ba9276b3ec ] J721E SoM has MT25QU512AB Serial NOR flash connected to OSPI1 controller. Enable ospi1 node in device tree. Fixes: 73676c480b72 ("arm64: dts: ti: k3-j721e: Enable OSPI nodes at the board level") Signed-off-by: Prasanth Babu Mantena Link: https://lore.kernel.org/r/20250507050701.3007209-1-p-mantena@ti.com Signed-off-by: Nishanth Menon Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts index fe5207ac7d85..90ae8e948671 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts +++ b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts @@ -557,6 +557,7 @@ &ospi1 { pinctrl-names = "default"; pinctrl-0 = <&mcu_fss0_ospi1_pins_default>; + status = "okay"; flash@0 { compatible = "jedec,spi-nor"; From 4f99357dadbf9c979ad737156ad4c37fadf7c56b Mon Sep 17 00:00:00 2001 From: Phillip Lougher Date: Wed, 9 Apr 2025 03:47:47 +0100 Subject: [PATCH 227/971] Squashfs: check return result of sb_min_blocksize [ Upstream commit 734aa85390ea693bb7eaf2240623d41b03705c84 ] Syzkaller reports an "UBSAN: shift-out-of-bounds in squashfs_bio_read" bug. Syzkaller forks multiple processes which after mounting the Squashfs filesystem, issues an ioctl("/dev/loop0", LOOP_SET_BLOCK_SIZE, 0x8000). Now if this ioctl occurs at the same time another process is in the process of mounting a Squashfs filesystem on /dev/loop0, the failure occurs. When this happens the following code in squashfs_fill_super() fails. ---- msblk->devblksize = sb_min_blocksize(sb, SQUASHFS_DEVBLK_SIZE); msblk->devblksize_log2 = ffz(~msblk->devblksize); ---- sb_min_blocksize() returns 0, which means msblk->devblksize is set to 0. As a result, ffz(~msblk->devblksize) returns 64, and msblk->devblksize_log2 is set to 64. This subsequently causes the UBSAN: shift-out-of-bounds in fs/squashfs/block.c:195:36 shift exponent 64 is too large for 64-bit type 'u64' (aka 'unsigned long long') This commit adds a check for a 0 return by sb_min_blocksize(). Link: https://lkml.kernel.org/r/20250409024747.876480-1-phillip@squashfs.org.uk Fixes: 0aa666190509 ("Squashfs: super block operations") Reported-by: syzbot+65761fc25a137b9c8c6e@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/67f0dd7a.050a0220.0a13.0230.GAE@google.com/ Signed-off-by: Phillip Lougher Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin --- fs/squashfs/super.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c index 22e812808e5c..3a27d4268b3c 100644 --- a/fs/squashfs/super.c +++ b/fs/squashfs/super.c @@ -202,6 +202,11 @@ static int squashfs_fill_super(struct super_block *sb, struct fs_context *fc) msblk->panic_on_errors = (opts->errors == Opt_errors_panic); msblk->devblksize = sb_min_blocksize(sb, SQUASHFS_DEVBLK_SIZE); + if (!msblk->devblksize) { + errorf(fc, "squashfs: unable to set blocksize\n"); + return -EINVAL; + } + msblk->devblksize_log2 = ffz(~msblk->devblksize); mutex_init(&msblk->meta_index_mutex); From 681a35b1dcf19222f36b53f1ad7e7ce5e5ed0a52 Mon Sep 17 00:00:00 2001 From: Murad Masimov Date: Wed, 2 Apr 2025 09:56:27 +0300 Subject: [PATCH 228/971] ocfs2: fix possible memory leak in ocfs2_finish_quota_recovery [ Upstream commit cdc3ed3035d0fe934aa1d9b78ce256752fd3bb7d ] If ocfs2_finish_quota_recovery() exits due to an error before passing all rc_list elements to ocfs2_recover_local_quota_file() then it can lead to a memory leak as rc_list may still contain elements that have to be freed. Release all memory allocated by ocfs2_add_recovery_chunk() using ocfs2_free_quota_recovery() instead of kfree(). Found by Linux Verification Center (linuxtesting.org) with Syzkaller. Link: https://lkml.kernel.org/r/20250402065628.706359-2-m.masimov@mt-integration.ru Fixes: 2205363dce74 ("ocfs2: Implement quota recovery") Signed-off-by: Murad Masimov Reviewed-by: Jan Kara Reviewed-by: Joseph Qi Cc: Mark Fasheh Cc: Joel Becker Cc: Junxiao Bi Cc: Changwei Ge Cc: Jun Piao Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin --- fs/ocfs2/quota_local.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c index 0ca8975a1df4..c7bda48b5fb2 100644 --- a/fs/ocfs2/quota_local.c +++ b/fs/ocfs2/quota_local.c @@ -671,7 +671,7 @@ out_put: break; } out: - kfree(rec); + ocfs2_free_quota_recovery(rec); return status; } From 9ab3008bf984716076bf77d228cff45a8ed26248 Mon Sep 17 00:00:00 2001 From: Wentao Liang Date: Tue, 29 Apr 2025 02:37:07 +0900 Subject: [PATCH 229/971] nilfs2: add pointer check for nilfs_direct_propagate() [ Upstream commit f43f02429295486059605997bc43803527d69791 ] Patch series "nilfs2: improve sanity checks in dirty state propagation". This fixes one missed check for block mapping anomalies and one improper return of an error code during a preparation step for log writing, thereby improving checking for filesystem corruption on writeback. This patch (of 2): In nilfs_direct_propagate(), the printer get from nilfs_direct_get_ptr() need to be checked to ensure it is not an invalid pointer. If the pointer value obtained by nilfs_direct_get_ptr() is NILFS_BMAP_INVALID_PTR, means that the metadata (in this case, i_bmap in the nilfs_inode_info struct) that should point to the data block at the buffer head of the argument is corrupted and the data block is orphaned, meaning that the file system has lost consistency. Add a value check and return -EINVAL when it is an invalid pointer. Link: https://lkml.kernel.org/r/20250428173808.6452-1-konishi.ryusuke@gmail.com Link: https://lkml.kernel.org/r/20250428173808.6452-2-konishi.ryusuke@gmail.com Fixes: 36a580eb489f ("nilfs2: direct block mapping") Signed-off-by: Wentao Liang Signed-off-by: Ryusuke Konishi Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin --- fs/nilfs2/direct.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/nilfs2/direct.c b/fs/nilfs2/direct.c index 893ab36824cc..2d8dc6b35b54 100644 --- a/fs/nilfs2/direct.c +++ b/fs/nilfs2/direct.c @@ -273,6 +273,9 @@ static int nilfs_direct_propagate(struct nilfs_bmap *bmap, dat = nilfs_bmap_get_dat(bmap); key = nilfs_bmap_data_get_key(bmap, bh); ptr = nilfs_direct_get_ptr(bmap, key); + if (ptr == NILFS_BMAP_INVALID_PTR) + return -EINVAL; + if (!buffer_nilfs_volatile(bh)) { oldreq.pr_entry_nr = ptr; newreq.pr_entry_nr = ptr; From 8b8e2966477eafeec5028aa3d6e7698c578fb63c Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Tue, 29 Apr 2025 02:37:08 +0900 Subject: [PATCH 230/971] nilfs2: do not propagate ENOENT error from nilfs_btree_propagate() [ Upstream commit 8e39fbb1edbb4ec9d7c1124f403877fc167fcecd ] In preparation for writing logs, in nilfs_btree_propagate(), which makes parent and ancestor node blocks dirty starting from a modified data block or b-tree node block, if the starting block does not belong to the b-tree, i.e. is isolated, nilfs_btree_do_lookup() called within the function fails with -ENOENT. In this case, even though -ENOENT is an internal code, it is propagated to the log writer via nilfs_bmap_propagate() and may be erroneously returned to system calls such as fsync(). Fix this issue by changing the error code to -EINVAL in this case, and having the bmap layer detect metadata corruption and convert the error code appropriately. Link: https://lkml.kernel.org/r/20250428173808.6452-3-konishi.ryusuke@gmail.com Fixes: 1f5abe7e7dbc ("nilfs2: replace BUG_ON and BUG calls triggerable from ioctl") Signed-off-by: Ryusuke Konishi Cc: Wentao Liang Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin --- fs/nilfs2/btree.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c index dbd27a44632f..5e70a3478afe 100644 --- a/fs/nilfs2/btree.c +++ b/fs/nilfs2/btree.c @@ -2094,11 +2094,13 @@ static int nilfs_btree_propagate(struct nilfs_bmap *btree, ret = nilfs_btree_do_lookup(btree, path, key, NULL, level + 1, 0); if (ret < 0) { - if (unlikely(ret == -ENOENT)) + if (unlikely(ret == -ENOENT)) { nilfs_crit(btree->b_inode->i_sb, "writing node/leaf block does not appear in b-tree (ino=%lu) at key=%llu, level=%d", btree->b_inode->i_ino, (unsigned long long)key, level); + ret = -EINVAL; + } goto out; } From 4b23c46eb2d88924b93aca647bde9a4b9cf62cf9 Mon Sep 17 00:00:00 2001 From: Ioana Ciornei Date: Tue, 8 Apr 2025 13:58:09 +0300 Subject: [PATCH 231/971] bus: fsl-mc: fix double-free on mc_dev [ Upstream commit d694bf8a9acdbd061596f3e7549bc8cb70750a60 ] The blamed commit tried to simplify how the deallocations are done but, in the process, introduced a double-free on the mc_dev variable. In case the MC device is a DPRC, a new mc_bus is allocated and the mc_dev variable is just a reference to one of its fields. In this circumstance, on the error path only the mc_bus should be freed. This commit introduces back the following checkpatch warning which is a false-positive. WARNING: kfree(NULL) is safe and this check is probably not required + if (mc_bus) + kfree(mc_bus); Fixes: a042fbed0290 ("staging: fsl-mc: simplify couple of deallocations") Signed-off-by: Ioana Ciornei Link: https://lore.kernel.org/r/20250408105814.2837951-2-ioana.ciornei@nxp.com Signed-off-by: Christophe Leroy Signed-off-by: Sasha Levin --- drivers/bus/fsl-mc/fsl-mc-bus.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index 2f6d5002e43d..b405ee330af1 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -905,8 +905,10 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, error_cleanup_dev: kfree(mc_dev->regions); - kfree(mc_bus); - kfree(mc_dev); + if (mc_bus) + kfree(mc_bus); + else + kfree(mc_dev); return error; } From 4ca90f54bc656d9973f030e197d5b06c0034913d Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 5 May 2025 17:47:27 +0100 Subject: [PATCH 232/971] dt-bindings: vendor-prefixes: Add Liontron name [ Upstream commit 9baa27a2e9fc746143ab686b6dbe2d515284a4c5 ] Liontron is a company based in Shenzen, China, making industrial development boards and embedded computers, mostly using Rockchip and Allwinner SoCs. Add their name to the list of vendors. Signed-off-by: Andre Przywara Acked-by: Rob Herring (Arm) Link: https://patch.msgid.link/20250505164729.18175-2-andre.przywara@arm.com Signed-off-by: Chen-Yu Tsai Signed-off-by: Sasha Levin --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index dc275ab60e53..7376a924e9ac 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -773,6 +773,8 @@ patternProperties: description: Linux-specific binding "^linx,.*": description: Linx Technologies + "^liontron,.*": + description: Shenzhen Liontron Technology Co., Ltd "^liteon,.*": description: LITE-ON Technology Corp. "^litex,.*": From 9337a54bc620fbedbbcf3ef6177c80e55e259f39 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 18 Mar 2025 15:21:59 +0200 Subject: [PATCH 233/971] ARM: dts: qcom: apq8064: add missing clocks to the timer node [ Upstream commit 4b0eb149df58b6750cd8113e5ee5b3ac7cc51743 ] In order to fix DT schema warning and describe hardware properly, add missing sleep clock to the timer node. Fixes: f335b8af4fd5 ("ARM: dts: qcom: Add initial APQ8064 SoC and IFC6410 board device trees") Signed-off-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20250318-fix-nexus-4-v2-6-bcedd1406790@oss.qualcomm.com Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- arch/arm/boot/dts/qcom/qcom-apq8064.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi index 950adb63af70..06251aba80d8 100644 --- a/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi +++ b/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi @@ -343,6 +343,8 @@ <1 3 0x301>; reg = <0x0200a000 0x100>; clock-frequency = <27000000>; + clocks = <&sleep_clk>; + clock-names = "sleep"; cpu-offset = <0x80000>; }; From 978991404adc665ef4aeb27426b74da153353855 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 18 Mar 2025 15:22:00 +0200 Subject: [PATCH 234/971] ARM: dts: qcom: apq8064 merge hw splinlock into corresponding syscon device [ Upstream commit 325c6a441ae1f8fcb1db9bb945b8bdbd3142141e ] Follow up the expected way of describing the SFPB hwspinlock and merge hwspinlock node into corresponding syscon node, fixing several dt-schema warnings. Fixes: 24a9baf933dc ("ARM: dts: qcom: apq8064: Add hwmutex and SMEM nodes") Signed-off-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20250318-fix-nexus-4-v2-7-bcedd1406790@oss.qualcomm.com Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- arch/arm/boot/dts/qcom/qcom-apq8064.dtsi | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi index 06251aba80d8..b8f160cfe8e1 100644 --- a/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi +++ b/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi @@ -213,12 +213,6 @@ }; }; - sfpb_mutex: hwmutex { - compatible = "qcom,sfpb-mutex"; - syscon = <&sfpb_wrapper_mutex 0x604 0x4>; - #hwlock-cells = <1>; - }; - smem { compatible = "qcom,smem"; memory-region = <&smem_region>; @@ -322,9 +316,10 @@ pinctrl-0 = <&ps_hold>; }; - sfpb_wrapper_mutex: syscon@1200000 { - compatible = "syscon"; - reg = <0x01200000 0x8000>; + sfpb_mutex: hwmutex@1200600 { + compatible = "qcom,sfpb-mutex"; + reg = <0x01200600 0x100>; + #hwlock-cells = <1>; }; intc: interrupt-controller@2000000 { From 867dd8a356a1a8b0f834662f68fe6efc9168caaf Mon Sep 17 00:00:00 2001 From: Vignesh Raman Date: Mon, 12 May 2025 18:49:24 +0530 Subject: [PATCH 235/971] arm64: defconfig: mediatek: enable PHY drivers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit f52cd248d844f9451858992f924988ac413fdc7e ] The mediatek display driver fails to probe on mt8173-elm-hana and mt8183-kukui-jacuzzi-juniper-sku16 in v6.14-rc4 due to missing PHY configurations. Commit 924d66011f24 ("drm/mediatek: stop selecting foreign drivers") stopped selecting the MediaTek PHY drivers, requiring them to be explicitly enabled in defconfig. Enable the following PHY drivers for MediaTek platforms: CONFIG_PHY_MTK_HDMI=m for HDMI display CONFIG_PHY_MTK_MIPI_DSI=m for DSI display CONFIG_PHY_MTK_DP=m for DP display Fixes: 924d66011f24 ("drm/mediatek: stop selecting foreign drivers") Reviewed-by: Nícolas F. R. A. Prado Signed-off-by: Vignesh Raman Link: https://lore.kernel.org/r/20250512131933.1247830-1-vignesh.raman@collabora.com Signed-off-by: AngeloGioacchino Del Regno Signed-off-by: Sasha Levin --- arch/arm64/configs/defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 60af93c04b45..a4fc913d1e49 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1412,6 +1412,9 @@ CONFIG_PHY_HISTB_COMBPHY=y CONFIG_PHY_HISI_INNO_USB2=y CONFIG_PHY_MVEBU_CP110_COMPHY=y CONFIG_PHY_MTK_TPHY=y +CONFIG_PHY_MTK_HDMI=m +CONFIG_PHY_MTK_MIPI_DSI=m +CONFIG_PHY_MTK_DP=m CONFIG_PHY_QCOM_EDP=m CONFIG_PHY_QCOM_EUSB2_REPEATER=m CONFIG_PHY_QCOM_PCIE2=m From 0d5dd35f7a732a3088aa504f59bf511c55f7f1ac Mon Sep 17 00:00:00 2001 From: Quentin Schulz Date: Fri, 25 Apr 2025 17:18:10 +0200 Subject: [PATCH 236/971] arm64: dts: rockchip: disable unrouted USB controllers and PHY on RK3399 Puma with Haikou [ Upstream commit febd8c6ab52c683b447fe22fc740918c86feae43 ] The u2phy0_host port is the part of the USB PHY0 (namely the HOST0_DP/DM lanes) which routes directly to the USB2.0 HOST controller[1]. The other lanes of the PHY are routed to the USB3.0 OTG controller (dwc3), which we do use. The HOST0_DP/DM lanes aren't routed on RK3399 Puma so let's simply disable the USB2.0 controllers. USB3 OTG has been known to be unstable on RK3399 Puma Haikou for a while, one of the recurring issues being that only USB2 is detected and not USB3 in host mode. Reading the justification above and seeing that we are keeping u2phy0_host in the Haikou carrierboard DTS probably may have bothered you since it should be changed to u2phy0_otg. The issue is that if it's switched to that, USB OTG on Haikou is entirely broken. I have checked the routing in the Gerber file, the lanes are going to the expected ball pins (that is, NOT HOST0_DP/DM). u2phy0_host is for sure the wrong part of the PHY to use, but it's the only one that works at the moment for that board so keep it until we figure out what exactly is broken. No intended functional change. [1] https://rockchip.fr/Rockchip%20RK3399%20TRM%20V1.3%20Part2.pdf Chapter 2 USB2.0 PHY Fixes: 2c66fc34e945 ("arm64: dts: rockchip: add RK3399-Q7 (Puma) SoM") Signed-off-by: Quentin Schulz Signed-off-by: Lukasz Czechowski Link: https://lore.kernel.org/r/20250425-onboard_usb_dev-v2-5-4a76a474a010@thaumatec.com Signed-off-by: Heiko Stuebner Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts index 115c14c0a3c6..396a6636073b 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts @@ -251,14 +251,6 @@ status = "okay"; }; -&usb_host0_ehci { - status = "okay"; -}; - -&usb_host0_ohci { - status = "okay"; -}; - &vopb { status = "okay"; }; From 5b91fc48dcbb9af6cfdc0b1acf4342e85d52da3f Mon Sep 17 00:00:00 2001 From: Thuan Nguyen Date: Mon, 19 May 2025 06:43:24 +0000 Subject: [PATCH 237/971] arm64: dts: renesas: white-hawk-ard-audio: Fix TPU0 groups [ Upstream commit 652eea251dd852f02cef6223f367220acb3d1867 ] White Hawk ARD audio uses a clock generated by the TPU, but commit 3d144ef10a44 ("pinctrl: renesas: r8a779g0: Fix TPU suffixes") renamed pin group "tpu_to0_a" to "tpu_to0_b". Update DTS accordingly otherwise the sound driver does not receive a clock signal. Fixes: 3d144ef10a448f89 ("pinctrl: renesas: r8a779g0: Fix TPU suffixes") Signed-off-by: Thuan Nguyen Signed-off-by: Duy Nguyen Reviewed-by: Geert Uytterhoeven Acked-by: Kuninori Morimoto Link: https://lore.kernel.org/TYCPR01MB8740608B675365215ADB0374B49CA@TYCPR01MB8740.jpnprd01.prod.outlook.com Signed-off-by: Geert Uytterhoeven Signed-off-by: Sasha Levin --- .../boot/dts/renesas/r8a779g0-white-hawk-ard-audio-da7212.dtso | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-ard-audio-da7212.dtso b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-ard-audio-da7212.dtso index e6f53377ecd9..99f62574bc3c 100644 --- a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-ard-audio-da7212.dtso +++ b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-ard-audio-da7212.dtso @@ -108,7 +108,7 @@ }; tpu0_pins: tpu0 { - groups = "tpu_to0_a"; + groups = "tpu_to0_b"; function = "tpu"; }; }; From e774ce479f62c9a615e542fa8aecbcc0829612b6 Mon Sep 17 00:00:00 2001 From: Julien Massot Date: Wed, 14 May 2025 10:19:58 +0200 Subject: [PATCH 238/971] arm64: dts: mt6359: Rename RTC node to match binding expectations [ Upstream commit cfe035d8662cfbd6edff9bd89c4b516bbb34c350 ] Rename the node 'mt6359rtc' to 'rtc', as required by the binding. Fix the following dtb-check error: mediatek/mt8395-radxa-nio-12l.dtb: pmic: 'mt6359rtc' do not match any of the regexes: 'pinctrl-[0-9]+' Fixes: 3b7d143be4b7 ("arm64: dts: mt6359: add PMIC MT6359 related nodes") Signed-off-by: Julien Massot Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20250514-mt8395-dtb-errors-v2-3-d67b9077c59a@collabora.com Signed-off-by: AngeloGioacchino Del Regno Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/mediatek/mt6359.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/mediatek/mt6359.dtsi b/arch/arm64/boot/dts/mediatek/mt6359.dtsi index 57af3e789984..779d6dfb55c0 100644 --- a/arch/arm64/boot/dts/mediatek/mt6359.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt6359.dtsi @@ -298,7 +298,7 @@ }; }; - mt6359rtc: mt6359rtc { + mt6359rtc: rtc { compatible = "mediatek,mt6358-rtc"; }; }; From fc5a7a966466b1c289be7db867b95fb57ee7d912 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 15 May 2025 16:00:42 +0930 Subject: [PATCH 239/971] ARM: aspeed: Don't select SRAM [ Upstream commit e4f59f873c3ffe2a0150e11115a83e2dfb671dbf ] The ASPEED devices have SRAM, but don't require it for basic function (or any function; there's no known users of the driver). Fixes: 8c2ed9bcfbeb ("arm: Add Aspeed machine") Signed-off-by: Joel Stanley Link: https://patch.msgid.link/20250115103942.421429-1-joel@jms.id.au Signed-off-by: Andrew Jeffery Signed-off-by: Arnd Bergmann Signed-off-by: Sasha Levin --- arch/arm/mach-aspeed/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig index 080019aa6fcd..fcf287edd0e5 100644 --- a/arch/arm/mach-aspeed/Kconfig +++ b/arch/arm/mach-aspeed/Kconfig @@ -2,7 +2,6 @@ menuconfig ARCH_ASPEED bool "Aspeed BMC architectures" depends on (CPU_LITTLE_ENDIAN && ARCH_MULTI_V5) || ARCH_MULTI_V6 || ARCH_MULTI_V7 - select SRAM select WATCHDOG select ASPEED_WATCHDOG select MFD_SYSCON From b828083b3d7da486dc95b4b3a9c7b27c55d9204a Mon Sep 17 00:00:00 2001 From: Su Hui Date: Thu, 15 May 2025 16:00:43 +0930 Subject: [PATCH 240/971] soc: aspeed: lpc: Fix impossible judgment condition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit d9f0a97e859bdcef51f9c187b1eb712eb13fd3ff ] smatch error: drivers/soc/aspeed/aspeed-lpc-snoop.c:169 aspeed_lpc_snoop_config_irq() warn: platform_get_irq() does not return zero platform_get_irq() return non-zero IRQ number or negative error code, change '!lpc_snoop->irq' to 'lpc_snoop->irq < 0' to fix this. Fixes: 9f4f9ae81d0a ("drivers/misc: add Aspeed LPC snoop driver") Signed-off-by: Su Hui Reviewed-by: Dan Carpenter Link: https://lore.kernel.org/r/20231027020703.1231875-1-suhui@nfschina.com Signed-off-by: Andrew Jeffery Signed-off-by: Arnd Bergmann Signed-off-by: Sasha Levin --- drivers/soc/aspeed/aspeed-lpc-snoop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/aspeed/aspeed-lpc-snoop.c b/drivers/soc/aspeed/aspeed-lpc-snoop.c index 773dbcbc03a6..8cb3a0b4692c 100644 --- a/drivers/soc/aspeed/aspeed-lpc-snoop.c +++ b/drivers/soc/aspeed/aspeed-lpc-snoop.c @@ -166,7 +166,7 @@ static int aspeed_lpc_snoop_config_irq(struct aspeed_lpc_snoop *lpc_snoop, int rc; lpc_snoop->irq = platform_get_irq(pdev, 0); - if (!lpc_snoop->irq) + if (lpc_snoop->irq < 0) return -ENODEV; rc = devm_request_irq(dev, lpc_snoop->irq, From 8312b1f776f71979bf33bda7acc05b348e8792c7 Mon Sep 17 00:00:00 2001 From: Henry Martin Date: Thu, 15 May 2025 16:00:44 +0930 Subject: [PATCH 241/971] soc: aspeed: Add NULL check in aspeed_lpc_enable_snoop() [ Upstream commit f1706e0e1a74b095cbc60375b9b1e6205f5f4c98 ] devm_kasprintf() returns NULL when memory allocation fails. Currently, aspeed_lpc_enable_snoop() does not check for this case, which results in a NULL pointer dereference. Add NULL check after devm_kasprintf() to prevent this issue. Fixes: 3772e5da4454 ("drivers/misc: Aspeed LPC snoop output using misc chardev") Signed-off-by: Henry Martin Link: https://patch.msgid.link/20250401074647.21300-1-bsdhenrymartin@gmail.com [arj: Fix Fixes: tag to use subject from 3772e5da4454] Signed-off-by: Andrew Jeffery Signed-off-by: Arnd Bergmann Signed-off-by: Sasha Levin --- drivers/soc/aspeed/aspeed-lpc-snoop.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/soc/aspeed/aspeed-lpc-snoop.c b/drivers/soc/aspeed/aspeed-lpc-snoop.c index 8cb3a0b4692c..0f2ffee321dd 100644 --- a/drivers/soc/aspeed/aspeed-lpc-snoop.c +++ b/drivers/soc/aspeed/aspeed-lpc-snoop.c @@ -200,11 +200,15 @@ static int aspeed_lpc_enable_snoop(struct aspeed_lpc_snoop *lpc_snoop, lpc_snoop->chan[channel].miscdev.minor = MISC_DYNAMIC_MINOR; lpc_snoop->chan[channel].miscdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s%d", DEVICE_NAME, channel); + if (!lpc_snoop->chan[channel].miscdev.name) { + rc = -ENOMEM; + goto err_free_fifo; + } lpc_snoop->chan[channel].miscdev.fops = &snoop_fops; lpc_snoop->chan[channel].miscdev.parent = dev; rc = misc_register(&lpc_snoop->chan[channel].miscdev); if (rc) - return rc; + goto err_free_fifo; /* Enable LPC snoop channel at requested port */ switch (channel) { @@ -221,7 +225,8 @@ static int aspeed_lpc_enable_snoop(struct aspeed_lpc_snoop *lpc_snoop, hicrb_en = HICRB_ENSNP1D; break; default: - return -EINVAL; + rc = -EINVAL; + goto err_misc_deregister; } regmap_update_bits(lpc_snoop->regmap, HICR5, hicr5_en, hicr5_en); @@ -231,6 +236,12 @@ static int aspeed_lpc_enable_snoop(struct aspeed_lpc_snoop *lpc_snoop, regmap_update_bits(lpc_snoop->regmap, HICRB, hicrb_en, hicrb_en); + return 0; + +err_misc_deregister: + misc_deregister(&lpc_snoop->chan[channel].miscdev); +err_free_fifo: + kfifo_free(&lpc_snoop->chan[channel].fifo); return rc; } From ab91647acdf43b984824776559a452212eaeb21a Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Wed, 14 May 2025 23:35:58 +0300 Subject: [PATCH 242/971] fbdev: core: fbcvt: avoid division by 0 in fb_cvt_hperiod() [ Upstream commit 3f6dae09fc8c306eb70fdfef70726e1f154e173a ] In fb_find_mode_cvt(), iff mode->refresh somehow happens to be 0x80000000, cvt.f_refresh will become 0 when multiplying it by 2 due to overflow. It's then passed to fb_cvt_hperiod(), where it's used as a divider -- division by 0 will result in kernel oops. Add a sanity check for cvt.f_refresh to avoid such overflow... Found by Linux Verification Center (linuxtesting.org) with the Svace static analysis tool. Fixes: 96fe6a2109db ("[PATCH] fbdev: Add VESA Coordinated Video Timings (CVT) support") Signed-off-by: Sergey Shtylyov Signed-off-by: Helge Deller Signed-off-by: Sasha Levin --- drivers/video/fbdev/core/fbcvt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/core/fbcvt.c b/drivers/video/fbdev/core/fbcvt.c index 64843464c661..cd3821bd82e5 100644 --- a/drivers/video/fbdev/core/fbcvt.c +++ b/drivers/video/fbdev/core/fbcvt.c @@ -312,7 +312,7 @@ int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb) cvt.f_refresh = cvt.refresh; cvt.interlace = 1; - if (!cvt.xres || !cvt.yres || !cvt.refresh) { + if (!cvt.xres || !cvt.yres || !cvt.refresh || cvt.f_refresh > INT_MAX) { printk(KERN_INFO "fbcvt: Invalid input parameters\n"); return 1; } From c64a16344c5258dcaaa6caf2bbe2298e6e3e469c Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sat, 26 Apr 2025 00:37:52 -0700 Subject: [PATCH 243/971] randstruct: gcc-plugin: Remove bogus void member MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit e136a4062174a9a8d1c1447ca040ea81accfa6a8 ] When building the randomized replacement tree of struct members, the randstruct GCC plugin would insert, as the first member, a 0-sized void member. This appears as though it was done to catch non-designated ("unnamed") static initializers, which wouldn't be stable since they depend on the original struct layout order. This was accomplished by having the side-effect of the "void member" tripping an assert in GCC internals (count_type_elements) if the member list ever needed to be counted (e.g. for figuring out the order of members during a non-designated initialization), which would catch impossible type (void) in the struct: security/landlock/fs.c: In function ‘hook_file_ioctl_common’: security/landlock/fs.c:1745:61: internal compiler error: in count_type_elements, at expr.cc:7075 1745 | .u.op = &(struct lsm_ioctlop_audit) { | ^ static HOST_WIDE_INT count_type_elements (const_tree type, bool for_ctor_p) { switch (TREE_CODE (type)) ... case VOID_TYPE: default: gcc_unreachable (); } } However this is a redundant safety measure since randstruct uses the __designated_initializer attribute both internally and within the __randomized_layout attribute macro so that this would be enforced by the compiler directly even when randstruct was not enabled (via -Wdesignated-init). A recent change in Landlock ended up tripping the same member counting routine when using a full-struct copy initializer as part of an anonymous initializer. This, however, is a false positive as the initializer is copying between identical structs (and hence identical layouts). The "path" member is "struct path", a randomized struct, and is being copied to from another "struct path", the "f_path" member: landlock_log_denial(landlock_cred(file->f_cred), &(struct landlock_request) { .type = LANDLOCK_REQUEST_FS_ACCESS, .audit = { .type = LSM_AUDIT_DATA_IOCTL_OP, .u.op = &(struct lsm_ioctlop_audit) { .path = file->f_path, .cmd = cmd, }, }, ... As can be seen with the coming randstruct KUnit test, there appears to be no behavioral problems with this kind of initialization when the void member is removed from the randstruct GCC plugin, so remove it. Reported-by: "Dr. David Alan Gilbert" Closes: https://lore.kernel.org/lkml/Z_PRaKx7q70MKgCA@gallifrey/ Reported-by: Mark Brown Closes: https://lore.kernel.org/lkml/20250407-kbuild-disable-gcc-plugins-v1-1-5d46ae583f5e@kernel.org/ Reported-by: WangYuli Closes: https://lore.kernel.org/lkml/337D5D4887277B27+3c677db3-a8b9-47f0-93a4-7809355f1381@uniontech.com/ Fixes: 313dd1b62921 ("gcc-plugins: Add the randstruct plugin") Signed-off-by: Kees Cook Signed-off-by: Sasha Levin --- scripts/gcc-plugins/randomize_layout_plugin.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c index 746ff2d272f2..bb8c6631971d 100644 --- a/scripts/gcc-plugins/randomize_layout_plugin.c +++ b/scripts/gcc-plugins/randomize_layout_plugin.c @@ -348,29 +348,13 @@ static int relayout_struct(tree type) shuffle(type, (tree *)newtree, shuffle_length); - /* - * set up a bogus anonymous struct field designed to error out on unnamed struct initializers - * as gcc provides no other way to detect such code - */ - list = make_node(FIELD_DECL); - TREE_CHAIN(list) = newtree[0]; - TREE_TYPE(list) = void_type_node; - DECL_SIZE(list) = bitsize_zero_node; - DECL_NONADDRESSABLE_P(list) = 1; - DECL_FIELD_BIT_OFFSET(list) = bitsize_zero_node; - DECL_SIZE_UNIT(list) = size_zero_node; - DECL_FIELD_OFFSET(list) = size_zero_node; - DECL_CONTEXT(list) = type; - // to satisfy the constify plugin - TREE_READONLY(list) = 1; - for (i = 0; i < num_fields - 1; i++) TREE_CHAIN(newtree[i]) = newtree[i+1]; TREE_CHAIN(newtree[num_fields - 1]) = NULL_TREE; main_variant = TYPE_MAIN_VARIANT(type); for (variant = main_variant; variant; variant = TYPE_NEXT_VARIANT(variant)) { - TYPE_FIELDS(variant) = list; + TYPE_FIELDS(variant) = newtree[0]; TYPE_ATTRIBUTES(variant) = copy_list(TYPE_ATTRIBUTES(variant)); TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("randomize_performed"), NULL_TREE, TYPE_ATTRIBUTES(variant)); TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("designated_init"), NULL_TREE, TYPE_ATTRIBUTES(variant)); From 655d3c6f8ce711439305c7832c7330a977af8cf1 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 30 May 2025 15:18:28 -0700 Subject: [PATCH 244/971] randstruct: gcc-plugin: Fix attribute addition [ Upstream commit f39f18f3c3531aa802b58a20d39d96e82eb96c14 ] Based on changes in the 2021 public version of the randstruct out-of-tree GCC plugin[1], more carefully update the attributes on resulting decls, to avoid tripping checks in GCC 15's comptypes_check_enum_int() when it has been configured with "--enable-checking=misc": arch/arm64/kernel/kexec_image.c:132:14: internal compiler error: in comptypes_check_enum_int, at c/c-typeck.cc:1519 132 | const struct kexec_file_ops kexec_image_ops = { | ^~~~~~~~~~~~~~ internal_error(char const*, ...), at gcc/gcc/diagnostic-global-context.cc:517 fancy_abort(char const*, int, char const*), at gcc/gcc/diagnostic.cc:1803 comptypes_check_enum_int(tree_node*, tree_node*, bool*), at gcc/gcc/c/c-typeck.cc:1519 ... Link: https://archive.org/download/grsecurity/grsecurity-3.1-5.10.41-202105280954.patch.gz [1] Reported-by: Thiago Jung Bauermann Closes: https://github.com/KSPP/linux/issues/367 Closes: https://lore.kernel.org/lkml/20250530000646.104457-1-thiago.bauermann@linaro.org/ Reported-by: Ingo Saitz Closes: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1104745 Fixes: 313dd1b62921 ("gcc-plugins: Add the randstruct plugin") Tested-by: Thiago Jung Bauermann Link: https://lore.kernel.org/r/20250530221824.work.623-kees@kernel.org Signed-off-by: Kees Cook Signed-off-by: Sasha Levin --- scripts/gcc-plugins/gcc-common.h | 32 +++++++++++++++++++ scripts/gcc-plugins/randomize_layout_plugin.c | 22 ++++++------- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h index 1ae39b9f4a95..90e83d62adb5 100644 --- a/scripts/gcc-plugins/gcc-common.h +++ b/scripts/gcc-plugins/gcc-common.h @@ -128,6 +128,38 @@ static inline tree build_const_char_string(int len, const char *str) return cstr; } +static inline void __add_type_attr(tree type, const char *attr, tree args) +{ + tree oldattr; + + if (type == NULL_TREE) + return; + oldattr = lookup_attribute(attr, TYPE_ATTRIBUTES(type)); + if (oldattr != NULL_TREE) { + gcc_assert(TREE_VALUE(oldattr) == args || TREE_VALUE(TREE_VALUE(oldattr)) == TREE_VALUE(args)); + return; + } + + TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type)); + TYPE_ATTRIBUTES(type) = tree_cons(get_identifier(attr), args, TYPE_ATTRIBUTES(type)); +} + +static inline void add_type_attr(tree type, const char *attr, tree args) +{ + tree main_variant = TYPE_MAIN_VARIANT(type); + + __add_type_attr(TYPE_CANONICAL(type), attr, args); + __add_type_attr(TYPE_CANONICAL(main_variant), attr, args); + __add_type_attr(main_variant, attr, args); + + for (type = TYPE_NEXT_VARIANT(main_variant); type; type = TYPE_NEXT_VARIANT(type)) { + if (!lookup_attribute(attr, TYPE_ATTRIBUTES(type))) + TYPE_ATTRIBUTES(type) = TYPE_ATTRIBUTES(main_variant); + + __add_type_attr(TYPE_CANONICAL(type), attr, args); + } +} + #define PASS_INFO(NAME, REF, ID, POS) \ struct register_pass_info NAME##_pass_info = { \ .pass = make_##NAME##_pass(), \ diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c index bb8c6631971d..e70eef049ada 100644 --- a/scripts/gcc-plugins/randomize_layout_plugin.c +++ b/scripts/gcc-plugins/randomize_layout_plugin.c @@ -77,6 +77,9 @@ static tree handle_randomize_layout_attr(tree *node, tree name, tree args, int f if (TYPE_P(*node)) { type = *node; + } else if (TREE_CODE(*node) == FIELD_DECL) { + *no_add_attrs = false; + return NULL_TREE; } else { gcc_assert(TREE_CODE(*node) == TYPE_DECL); type = TREE_TYPE(*node); @@ -352,15 +355,14 @@ static int relayout_struct(tree type) TREE_CHAIN(newtree[i]) = newtree[i+1]; TREE_CHAIN(newtree[num_fields - 1]) = NULL_TREE; + add_type_attr(type, "randomize_performed", NULL_TREE); + add_type_attr(type, "designated_init", NULL_TREE); + if (has_flexarray) + add_type_attr(type, "has_flexarray", NULL_TREE); + main_variant = TYPE_MAIN_VARIANT(type); - for (variant = main_variant; variant; variant = TYPE_NEXT_VARIANT(variant)) { + for (variant = main_variant; variant; variant = TYPE_NEXT_VARIANT(variant)) TYPE_FIELDS(variant) = newtree[0]; - TYPE_ATTRIBUTES(variant) = copy_list(TYPE_ATTRIBUTES(variant)); - TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("randomize_performed"), NULL_TREE, TYPE_ATTRIBUTES(variant)); - TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("designated_init"), NULL_TREE, TYPE_ATTRIBUTES(variant)); - if (has_flexarray) - TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("has_flexarray"), NULL_TREE, TYPE_ATTRIBUTES(type)); - } /* * force a re-layout of the main variant @@ -428,10 +430,8 @@ static void randomize_type(tree type) if (lookup_attribute("randomize_layout", TYPE_ATTRIBUTES(TYPE_MAIN_VARIANT(type))) || is_pure_ops_struct(type)) relayout_struct(type); - for (variant = TYPE_MAIN_VARIANT(type); variant; variant = TYPE_NEXT_VARIANT(variant)) { - TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type)); - TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("randomize_considered"), NULL_TREE, TYPE_ATTRIBUTES(type)); - } + add_type_attr(type, "randomize_considered", NULL_TREE); + #ifdef __DEBUG_PLUGIN fprintf(stderr, "Marking randomize_considered on struct %s\n", ORIG_TYPE_NAME(type)); #ifdef __DEBUG_VERBOSE From 34e124dc2189d82e2793bbc1bc9a200944243c70 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 8 Apr 2025 11:37:20 -0300 Subject: [PATCH 245/971] perf build: Warn when libdebuginfod devel files are not available [ Upstream commit 4fce4b91fd1aabb326c46e237eb4b19ab72598f8 ] While working on 'perf version --build-options' I noticed that: $ perf version --build-options perf version 6.15.rc1.g312a07a00d31 aio: [ on ] # HAVE_AIO_SUPPORT bpf: [ on ] # HAVE_LIBBPF_SUPPORT bpf_skeletons: [ on ] # HAVE_BPF_SKEL debuginfod: [ OFF ] # HAVE_DEBUGINFOD_SUPPORT And looking at tools/perf/Makefile.config I also noticed that it is not opt-in, meaning we will attempt to build with it in all normal cases. So add the usual warning at build time to let the user know that something recommended is missing, now we see: Makefile.config:563: No elfutils/debuginfod.h found, no debuginfo server support, please install elfutils-debuginfod-client-devel or equivalent And after following the recommendation: $ perf check feature debuginfod debuginfod: [ on ] # HAVE_DEBUGINFOD_SUPPORT $ ldd ~/bin/perf | grep debuginfo libdebuginfod.so.1 => /lib64/libdebuginfod.so.1 (0x00007fee5cf5f000) $ With this feature on several perf tools will fetch what is needed and not require all the contents of the debuginfo packages, for instance: # rpm -qa | grep kernel-debuginfo # pahole --running_kernel_vmlinux pahole: couldn't find a vmlinux that matches the running kernel HINT: Maybe you're inside a container or missing a debuginfo package? # # perf trace -e open* perf probe --vars icmp_rcv 0.000 ( 0.005 ms): perf/97391 openat(dfd: CWD, filename: "/etc/ld.so.cache", flags: RDONLY|CLOEXEC) = 3 0.014 ( 0.004 ms): perf/97391 openat(dfd: CWD, filename: "/lib64/libm.so.6", flags: RDONLY|CLOEXEC) = 3 32130.100 ( 0.008 ms): perf/97391 openat(dfd: CWD, filename: "/root/.cache/debuginfod_client/aa3c82b4a13f9c0e0301bebb20fe958c4db6f362/debuginfo") = 3 Available variables at icmp_rcv @ struct sk_buff* skb # # pahole --running_kernel_vmlinux /root/.cache/debuginfod_client/aa3c82b4a13f9c0e0301bebb20fe958c4db6f362/debuginfo # file /root/.cache/debuginfod_client/aa3c82b4a13f9c0e0301bebb20fe958c4db6f362/debuginfo /root/.cache/debuginfod_client/aa3c82b4a13f9c0e0301bebb20fe958c4db6f362/debuginfo: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=aa3c82b4a13f9c0e0301bebb20fe958c4db6f362, with debug_info, not stripped # ls -la /root/.cache/debuginfod_client/aa3c82b4a13f9c0e0301bebb20fe958c4db6f362/debuginfo -r--------. 1 root root 475401512 Mar 27 21:00 /root/.cache/debuginfod_client/aa3c82b4a13f9c0e0301bebb20fe958c4db6f362/debuginfo # Then, cached: # perf stat --null perf probe --vars icmp_rcv Available variables at icmp_rcv @ struct sk_buff* skb Performance counter stats for 'perf probe --vars icmp_rcv': 0.671389041 seconds time elapsed 0.519176000 seconds user 0.150860000 seconds sys Fixes: c7a14fdcb3fa7736 ("perf build-ids: Fall back to debuginfod query if debuginfo not found") Tested-by: Ingo Molnar Cc: Adrian Hunter Cc: Dmitriy Vyukov Cc: Howard Chu Cc: Ian Rogers Cc: Jiri Olsa Cc: Kan Liang Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Frank Ch. Eigler Link: https://lore.kernel.org/r/Z_dkNDj9EPFwPqq1@gmail.com [ Folded patch from Ingo to have the debian/ubuntu devel package added build warning message ] Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/Makefile.config | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index d66b52407e19..9da9f878f50f 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -554,6 +554,8 @@ ifndef NO_LIBELF ifeq ($(feature-libdebuginfod), 1) CFLAGS += -DHAVE_DEBUGINFOD_SUPPORT EXTLIBS += -ldebuginfod + else + $(warning No elfutils/debuginfod.h found, no debuginfo server support, please install libdebuginfod-dev/elfutils-debuginfod-client-devel or equivalent) endif endif From e431cc956d6760e438e05091cd26b86f34d9ac9c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 9 Apr 2025 21:58:19 -0300 Subject: [PATCH 246/971] perf ui browser hists: Set actions->thread before calling do_zoom_thread() [ Upstream commit 1741189d843a1d5ef38538bc52a3760e2e46cb2e ] In 7cecb7fe8388d5c3 ("perf hists: Move sort__has_comm into struct perf_hpp_list") it assumes that act->thread is set prior to calling do_zoom_thread(). This doesn't happen when we use ESC or the Left arrow key to Zoom out of a specific thread, making this operation not to work and we get stuck into the thread zoom. In 6422184b087ff435 ("perf hists browser: Simplify zooming code using pstack_peek()") it says no need to set actions->thread, and at that point that was true, but in 7cecb7fe8388d5c3 a actions->thread == NULL check was added before the zoom out of thread could kick in. We can zoom out using the alternative 't' thread zoom toggle hotkey to finally set actions->thread before calling do_zoom_thread() and zoom out, but lets also fix the ESC/Zoom out of thread case. Fixes: 7cecb7fe8388d5c3 ("perf hists: Move sort__has_comm into struct perf_hpp_list") Reported-by: Ingo Molnar Tested-by: Ingo Molnar Cc: Adrian Hunter Cc: Ian Rogers Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Namhyung Kim Link: https://lore.kernel.org/r/Z_TYux5fUg2pW-pF@gmail.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/ui/browsers/hists.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index bb59d27642cc..a53a0257a4bc 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -3239,10 +3239,10 @@ do_hotkey: // key came straight from options ui__popup_menu() /* * No need to set actions->dso here since * it's just to remove the current filter. - * Ditto for thread below. */ do_zoom_dso(browser, actions); } else if (top == &browser->hists->thread_filter) { + actions->thread = thread; do_zoom_thread(browser, actions); } else if (top == &browser->hists->socket_filter) { do_zoom_socket(browser, actions); From 679d40ca030ad35778c0eb1473f090ed4bd25afd Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 10 Apr 2025 15:49:38 -0400 Subject: [PATCH 247/971] dm: don't change md if dm_table_set_restrictions() fails [ Upstream commit 9eb7109a5bfc5b8226e9517e9f3cc6d414391884 ] __bind was changing the disk capacity, geometry and mempools of the mapped device before calling dm_table_set_restrictions() which could fail, forcing dm to drop the new table. Failing here would leave the device using the old table but with the wrong capacity and mempools. Move dm_table_set_restrictions() earlier in __bind(). Since it needs the capacity to be set, save the old version and restore it on failure. Fixes: bb37d77239af2 ("dm: introduce zone append emulation") Reviewed-by: Damien Le Moal Tested-by: Damien Le Moal Signed-off-by: Benjamin Marzinski Signed-off-by: Mikulas Patocka Signed-off-by: Sasha Levin --- drivers/md/dm.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 9ea868bd0d12..d154c89305fb 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -2195,21 +2195,29 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t, struct queue_limits *limits) { struct dm_table *old_map; - sector_t size; + sector_t size, old_size; int ret; lockdep_assert_held(&md->suspend_lock); size = dm_table_get_size(t); + old_size = dm_get_size(md); + set_capacity(md->disk, size); + + ret = dm_table_set_restrictions(t, md->queue, limits); + if (ret) { + set_capacity(md->disk, old_size); + old_map = ERR_PTR(ret); + goto out; + } + /* * Wipe any geometry if the size of the table changed. */ - if (size != dm_get_size(md)) + if (size != old_size) memset(&md->geometry, 0, sizeof(md->geometry)); - set_capacity(md->disk, size); - dm_table_event_callback(t, event_callback, md); if (dm_table_request_based(t)) { @@ -2242,12 +2250,6 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t, t->mempools = NULL; } - ret = dm_table_set_restrictions(t, md->queue, limits); - if (ret) { - old_map = ERR_PTR(ret); - goto out; - } - old_map = rcu_dereference_protected(md->map, lockdep_is_held(&md->suspend_lock)); rcu_assign_pointer(md->map, (void *)t); md->immutable_target_type = dm_table_get_immutable_target_type(t); From 06f41679d35eeebb4cba33a2f5a58db48b0a7297 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 10 Apr 2025 15:49:39 -0400 Subject: [PATCH 248/971] dm: free table mempools if not used in __bind [ Upstream commit e8819e7f03470c5b468720630d9e4e1d5b99159e ] With request-based dm, the mempools don't need reloading when switching tables, but the unused table mempools are not freed until the active table is finally freed. Free them immediately if they are not needed. Fixes: 29dec90a0f1d9 ("dm: fix bio_set allocation") Reviewed-by: Damien Le Moal Tested-by: Damien Le Moal Signed-off-by: Benjamin Marzinski Signed-off-by: Mikulas Patocka Signed-off-by: Sasha Levin --- drivers/md/dm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index d154c89305fb..44424554e6b5 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -2235,10 +2235,10 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t, * requests in the queue may refer to bio from the old bioset, * so you must walk through the queue to unprep. */ - if (!md->mempools) { + if (!md->mempools) md->mempools = t->mempools; - t->mempools = NULL; - } + else + dm_free_md_mempools(t->mempools); } else { /* * The md may already have mempools that need changing. @@ -2247,8 +2247,8 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t, */ dm_free_md_mempools(md->mempools); md->mempools = t->mempools; - t->mempools = NULL; } + t->mempools = NULL; old_map = rcu_dereference_protected(md->map, lockdep_is_held(&md->suspend_lock)); rcu_assign_pointer(md->map, (void *)t); From fde314445332015273c8f51d2659885c606fe135 Mon Sep 17 00:00:00 2001 From: Henry Martin Date: Tue, 1 Apr 2025 17:16:47 +0800 Subject: [PATCH 249/971] backlight: pm8941: Add NULL check in wled_configure() [ Upstream commit e12d3e1624a02706cdd3628bbf5668827214fa33 ] devm_kasprintf() returns NULL when memory allocation fails. Currently, wled_configure() does not check for this case, which results in a NULL pointer dereference. Add NULL check after devm_kasprintf() to prevent this issue. Fixes: f86b77583d88 ("backlight: pm8941: Convert to using %pOFn instead of device_node.name") Signed-off-by: Henry Martin Reviewed-by: Dmitry Baryshkov Reviewed-by: "Daniel Thompson (RISCstar)" Link: https://lore.kernel.org/r/20250401091647.22784-1-bsdhenrymartin@gmail.com Signed-off-by: Lee Jones Signed-off-by: Sasha Levin --- drivers/video/backlight/qcom-wled.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/video/backlight/qcom-wled.c b/drivers/video/backlight/qcom-wled.c index 10129095a4c1..b19e5f73de8b 100644 --- a/drivers/video/backlight/qcom-wled.c +++ b/drivers/video/backlight/qcom-wled.c @@ -1406,9 +1406,11 @@ static int wled_configure(struct wled *wled) wled->ctrl_addr = be32_to_cpu(*prop_addr); rc = of_property_read_string(dev->of_node, "label", &wled->name); - if (rc) + if (rc) { wled->name = devm_kasprintf(dev, GFP_KERNEL, "%pOFn", dev->of_node); - + if (!wled->name) + return -ENOMEM; + } switch (wled->version) { case 3: u32_opts = wled3_opts; From a0d9d9b5a4634e146ae41cb25667322e5c7d74d2 Mon Sep 17 00:00:00 2001 From: Mikhail Arkhipov Date: Wed, 9 Apr 2025 00:39:06 +0300 Subject: [PATCH 250/971] mtd: nand: ecc-mxic: Fix use of uninitialized variable ret [ Upstream commit d95846350aac72303036a70c4cdc69ae314aa26d ] If ctx->steps is zero, the loop processing ECC steps is skipped, and the variable ret remains uninitialized. It is later checked and returned, which leads to undefined behavior and may cause unpredictable results in user space or kernel crashes. This scenario can be triggered in edge cases such as misconfigured geometry, ECC engine misuse, or if ctx->steps is not validated after initialization. Initialize ret to zero before the loop to ensure correct and safe behavior regardless of the ctx->steps value. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 48e6633a9fa2 ("mtd: nand: mxic-ecc: Add Macronix external ECC engine support") Signed-off-by: Mikhail Arkhipov Signed-off-by: Miquel Raynal Signed-off-by: Sasha Levin --- drivers/mtd/nand/ecc-mxic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/ecc-mxic.c b/drivers/mtd/nand/ecc-mxic.c index 47e10945b8d2..63cb206269dd 100644 --- a/drivers/mtd/nand/ecc-mxic.c +++ b/drivers/mtd/nand/ecc-mxic.c @@ -614,7 +614,7 @@ static int mxic_ecc_finish_io_req_external(struct nand_device *nand, { struct mxic_ecc_engine *mxic = nand_to_mxic(nand); struct mxic_ecc_ctx *ctx = nand_to_ecc_ctx(nand); - int nents, step, ret; + int nents, step, ret = 0; if (req->mode == MTD_OPS_RAW) return 0; From 4e9e45746b861ebd54c03ef301da2cb8fc990536 Mon Sep 17 00:00:00 2001 From: Alexei Safin Date: Thu, 24 Apr 2025 23:26:54 +0300 Subject: [PATCH 251/971] hwmon: (asus-ec-sensors) check sensor index in read_string() [ Upstream commit 25be318324563c63cbd9cb53186203a08d2f83a1 ] Prevent a potential invalid memory access when the requested sensor is not found. find_ec_sensor_index() may return a negative value (e.g. -ENOENT), but its result was used without checking, which could lead to undefined behavior when passed to get_sensor_info(). Add a proper check to return -EINVAL if sensor_index is negative. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: d0ddfd241e57 ("hwmon: (asus-ec-sensors) add driver for ASUS EC") Signed-off-by: Alexei Safin Link: https://lore.kernel.org/r/20250424202654.5902-1-a.safin@rosa.ru [groeck: Return error code returned from find_ec_sensor_index] Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin --- drivers/hwmon/asus-ec-sensors.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/hwmon/asus-ec-sensors.c b/drivers/hwmon/asus-ec-sensors.c index f20b864c1bb2..ce2f14a62754 100644 --- a/drivers/hwmon/asus-ec-sensors.c +++ b/drivers/hwmon/asus-ec-sensors.c @@ -888,6 +888,10 @@ static int asus_ec_hwmon_read_string(struct device *dev, { struct ec_sensors_data *state = dev_get_drvdata(dev); int sensor_index = find_ec_sensor_index(state, type, channel); + + if (sensor_index < 0) + return sensor_index; + *str = get_sensor_info(state, sensor_index)->label; return 0; From 1aef0e1083bbe060c9b17dae54783940600fe093 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 22 Apr 2025 19:47:36 -0400 Subject: [PATCH 252/971] dm-flakey: error all IOs when num_features is absent [ Upstream commit 40ed054f39bc99eac09871c33198e501f4acdf24 ] dm-flakey would error all IOs if num_features was 0, but if it was absent, dm-flakey would never error any IO. Fix this so that no num_features works the same as num_features set to 0. Fixes: aa7d7bc99fed7 ("dm flakey: add an "error_reads" option") Reported-by: Kent Overstreet Signed-off-by: Benjamin Marzinski Signed-off-by: Mikulas Patocka Signed-off-by: Sasha Levin --- drivers/md/dm-flakey.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c index dc491dc771d7..aeb9ecaf9a20 100644 --- a/drivers/md/dm-flakey.c +++ b/drivers/md/dm-flakey.c @@ -53,8 +53,8 @@ struct per_bio_data { static int parse_features(struct dm_arg_set *as, struct flakey_c *fc, struct dm_target *ti) { - int r; - unsigned int argc; + int r = 0; + unsigned int argc = 0; const char *arg_name; static const struct dm_arg _args[] = { @@ -65,14 +65,13 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc, {0, PROBABILITY_BASE, "Invalid random corrupt argument"}, }; - /* No feature arguments supplied. */ - if (!as->argc) - return 0; - - r = dm_read_arg_group(_args, as, &argc, &ti->error); - if (r) + if (as->argc && (r = dm_read_arg_group(_args, as, &argc, &ti->error))) return r; + /* No feature arguments supplied. */ + if (!argc) + goto error_all_io; + while (argc) { arg_name = dm_shift_arg(as); argc--; @@ -217,6 +216,7 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc, if (!fc->corrupt_bio_byte && !test_bit(ERROR_READS, &fc->flags) && !test_bit(DROP_WRITES, &fc->flags) && !test_bit(ERROR_WRITES, &fc->flags) && !fc->random_read_corrupt && !fc->random_write_corrupt) { +error_all_io: set_bit(ERROR_WRITES, &fc->flags); set_bit(ERROR_READS, &fc->flags); } From 84126960357de9a7a88a562af8cf3cc6fbfe0389 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 22 Apr 2025 19:47:38 -0400 Subject: [PATCH 253/971] dm-flakey: make corrupting read bios work [ Upstream commit 13e79076c89f6e96a6cca8f6df38b40d025907b4 ] dm-flakey corrupts the read bios in the endio function. However, the corrupt_bio_* functions checked bio_has_data() to see if there was data to corrupt. Since this was the endio function, there was no data left to complete, so bio_has_data() was always false. Fix this by saving a copy of the bio's bi_iter in flakey_map(), and using this to initialize the iter for corrupting the read bios. This patch also skips cloning the bio for write bios with no data. Reported-by: Kent Overstreet Fixes: a3998799fb4df ("dm flakey: add corrupt_bio_byte feature") Signed-off-by: Benjamin Marzinski Signed-off-by: Mikulas Patocka Signed-off-by: Sasha Levin --- drivers/md/dm-flakey.c | 54 ++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c index aeb9ecaf9a20..ada679f4fca6 100644 --- a/drivers/md/dm-flakey.c +++ b/drivers/md/dm-flakey.c @@ -47,7 +47,8 @@ enum feature_flag_bits { }; struct per_bio_data { - bool bio_submitted; + bool bio_can_corrupt; + struct bvec_iter saved_iter; }; static int parse_features(struct dm_arg_set *as, struct flakey_c *fc, @@ -339,7 +340,8 @@ static void flakey_map_bio(struct dm_target *ti, struct bio *bio) } static void corrupt_bio_common(struct bio *bio, unsigned int corrupt_bio_byte, - unsigned char corrupt_bio_value) + unsigned char corrupt_bio_value, + struct bvec_iter start) { struct bvec_iter iter; struct bio_vec bvec; @@ -348,7 +350,7 @@ static void corrupt_bio_common(struct bio *bio, unsigned int corrupt_bio_byte, * Overwrite the Nth byte of the bio's data, on whichever page * it falls. */ - bio_for_each_segment(bvec, bio, iter) { + __bio_for_each_segment(bvec, bio, iter, start) { if (bio_iter_len(bio, iter) > corrupt_bio_byte) { unsigned char *segment = bvec_kmap_local(&bvec); segment[corrupt_bio_byte] = corrupt_bio_value; @@ -357,36 +359,31 @@ static void corrupt_bio_common(struct bio *bio, unsigned int corrupt_bio_byte, "(rw=%c bi_opf=%u bi_sector=%llu size=%u)\n", bio, corrupt_bio_value, corrupt_bio_byte, (bio_data_dir(bio) == WRITE) ? 'w' : 'r', bio->bi_opf, - (unsigned long long)bio->bi_iter.bi_sector, - bio->bi_iter.bi_size); + (unsigned long long)start.bi_sector, + start.bi_size); break; } corrupt_bio_byte -= bio_iter_len(bio, iter); } } -static void corrupt_bio_data(struct bio *bio, struct flakey_c *fc) +static void corrupt_bio_data(struct bio *bio, struct flakey_c *fc, + struct bvec_iter start) { unsigned int corrupt_bio_byte = fc->corrupt_bio_byte - 1; - if (!bio_has_data(bio)) - return; - - corrupt_bio_common(bio, corrupt_bio_byte, fc->corrupt_bio_value); + corrupt_bio_common(bio, corrupt_bio_byte, fc->corrupt_bio_value, start); } -static void corrupt_bio_random(struct bio *bio) +static void corrupt_bio_random(struct bio *bio, struct bvec_iter start) { unsigned int corrupt_byte; unsigned char corrupt_value; - if (!bio_has_data(bio)) - return; - - corrupt_byte = get_random_u32() % bio->bi_iter.bi_size; + corrupt_byte = get_random_u32() % start.bi_size; corrupt_value = get_random_u8(); - corrupt_bio_common(bio, corrupt_byte, corrupt_value); + corrupt_bio_common(bio, corrupt_byte, corrupt_value, start); } static void clone_free(struct bio *clone) @@ -481,7 +478,7 @@ static int flakey_map(struct dm_target *ti, struct bio *bio) unsigned int elapsed; struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data)); - pb->bio_submitted = false; + pb->bio_can_corrupt = false; if (op_is_zone_mgmt(bio_op(bio))) goto map_bio; @@ -490,10 +487,11 @@ static int flakey_map(struct dm_target *ti, struct bio *bio) elapsed = (jiffies - fc->start_time) / HZ; if (elapsed % (fc->up_interval + fc->down_interval) >= fc->up_interval) { bool corrupt_fixed, corrupt_random; - /* - * Flag this bio as submitted while down. - */ - pb->bio_submitted = true; + + if (bio_has_data(bio)) { + pb->bio_can_corrupt = true; + pb->saved_iter = bio->bi_iter; + } /* * Error reads if neither corrupt_bio_byte or drop_writes or error_writes are set. @@ -516,6 +514,8 @@ static int flakey_map(struct dm_target *ti, struct bio *bio) return DM_MAPIO_SUBMITTED; } + if (!pb->bio_can_corrupt) + goto map_bio; /* * Corrupt matching writes. */ @@ -535,9 +535,11 @@ static int flakey_map(struct dm_target *ti, struct bio *bio) struct bio *clone = clone_bio(ti, fc, bio); if (clone) { if (corrupt_fixed) - corrupt_bio_data(clone, fc); + corrupt_bio_data(clone, fc, + clone->bi_iter); if (corrupt_random) - corrupt_bio_random(clone); + corrupt_bio_random(clone, + clone->bi_iter); submit_bio(clone); return DM_MAPIO_SUBMITTED; } @@ -559,21 +561,21 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio, if (op_is_zone_mgmt(bio_op(bio))) return DM_ENDIO_DONE; - if (!*error && pb->bio_submitted && (bio_data_dir(bio) == READ)) { + if (!*error && pb->bio_can_corrupt && (bio_data_dir(bio) == READ)) { if (fc->corrupt_bio_byte) { if ((fc->corrupt_bio_rw == READ) && all_corrupt_bio_flags_match(bio, fc)) { /* * Corrupt successful matching READs while in down state. */ - corrupt_bio_data(bio, fc); + corrupt_bio_data(bio, fc, pb->saved_iter); } } if (fc->random_read_corrupt) { u64 rnd = get_random_u64(); u32 rem = do_div(rnd, PROBABILITY_BASE); if (rem < fc->random_read_corrupt) - corrupt_bio_random(bio); + corrupt_bio_random(bio, pb->saved_iter); } if (test_bit(ERROR_READS, &fc->flags)) { /* From 1737865a12f8532492c7cf3f8012be6a6b7e2fce Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 2 Apr 2025 22:42:13 -0700 Subject: [PATCH 254/971] perf trace: Fix leaks of 'struct thread' in set_filter_loop_pids() [ Upstream commit 30d20fb1f84ad5c92706fe2c6cbb2d4cc293e671 ] I've found some leaks from 'perf trace -a'. It seems there are more leaks but this is what I can find for now. Fixes: 082ab9a18e532864 ("perf trace: Filter out 'sshd' in the tracer ancestry in syswide tracing") Reviewed-by: Howard Chu Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20250403054213.7021-1-namhyung@kernel.org [ split from a larget patch ] Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/builtin-trace.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 12bdbf3ecc6a..908509df007b 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -3589,10 +3589,13 @@ static int trace__set_filter_loop_pids(struct trace *trace) if (!strcmp(thread__comm_str(parent), "sshd") || strstarts(thread__comm_str(parent), "gnome-terminal")) { pids[nr++] = thread__tid(parent); + thread__put(parent); break; } + thread__put(thread); thread = parent; } + thread__put(thread); err = evlist__append_tp_filter_pids(trace->evlist, nr, pids); if (!err && trace->filter_pids.map) From 53385a400af6aae7e58eca6c8d2e9adcc9c26fe4 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 12 May 2025 12:39:30 +0300 Subject: [PATCH 255/971] perf intel-pt: Fix PEBS-via-PT data_src [ Upstream commit e00eac6b5b6d956f38d8880c44bf7fd9954063c3 ] The Fixes commit did not add support for decoding PEBS-via-PT data_src. Fix by adding support. PEBS-via-PT is a feature of some E-core processors, starting with processors based on Tremont microarchitecture. Because the kernel only supports Intel PT features that are on all processors, there is no support for PEBS-via-PT on hybrids. Currently that leaves processors based on Tremont, Gracemont and Crestmont, however there are no events on Tremont that produce data_src information, and for Gracemont and Crestmont there are only: mem-loads event=0xd0,umask=0x5,ldlat=3 mem-stores event=0xd0,umask=0x6 Affected processors include Alder Lake N (Gracemont), Sierra Forest (Crestmont) and Grand Ridge (Crestmont). Example: # perf record -d -e intel_pt/branch=0/ -e mem-loads/aux-output/pp uname Before: # perf.before script --itrace=o -Fdata_src 0 |OP No|LVL N/A|SNP N/A|TLB N/A|LCK No|BLK N/A 0 |OP No|LVL N/A|SNP N/A|TLB N/A|LCK No|BLK N/A After: # perf script --itrace=o -Fdata_src 10268100142 |OP LOAD|LVL L1 hit|SNP None|TLB L1 or L2 hit|LCK No|BLK N/A 10450100442 |OP LOAD|LVL L2 hit|SNP None|TLB L2 miss|LCK No|BLK N/A Fixes: 975846eddf907297 ("perf intel-pt: Add memory information to synthesized PEBS sample") Reviewed-by: Kan Liang Signed-off-by: Adrian Hunter Cc: Alexander Shishkin Cc: Ian Rogers Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lore.kernel.org/r/20250512093932.79854-2-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/util/intel-pt.c | 205 ++++++++++++++++++++++++++++++++++++- 1 file changed, 202 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index 4db9a098f592..e9f97c0c3358 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -127,6 +127,7 @@ struct intel_pt { bool single_pebs; bool sample_pebs; + int pebs_data_src_fmt; struct evsel *pebs_evsel; u64 evt_sample_type; @@ -175,6 +176,7 @@ enum switch_state { struct intel_pt_pebs_event { struct evsel *evsel; u64 id; + int data_src_fmt; }; struct intel_pt_queue { @@ -2232,7 +2234,146 @@ static void intel_pt_add_lbrs(struct branch_stack *br_stack, } } -static int intel_pt_do_synth_pebs_sample(struct intel_pt_queue *ptq, struct evsel *evsel, u64 id) +#define P(a, b) PERF_MEM_S(a, b) +#define OP_LH (P(OP, LOAD) | P(LVL, HIT)) +#define LEVEL(x) P(LVLNUM, x) +#define REM P(REMOTE, REMOTE) +#define SNOOP_NONE_MISS (P(SNOOP, NONE) | P(SNOOP, MISS)) + +#define PERF_PEBS_DATA_SOURCE_GRT_MAX 0x10 +#define PERF_PEBS_DATA_SOURCE_GRT_MASK (PERF_PEBS_DATA_SOURCE_GRT_MAX - 1) + +/* Based on kernel __intel_pmu_pebs_data_source_grt() and pebs_data_source */ +static const u64 pebs_data_source_grt[PERF_PEBS_DATA_SOURCE_GRT_MAX] = { + P(OP, LOAD) | P(LVL, MISS) | LEVEL(L3) | P(SNOOP, NA), /* L3 miss|SNP N/A */ + OP_LH | P(LVL, L1) | LEVEL(L1) | P(SNOOP, NONE), /* L1 hit|SNP None */ + OP_LH | P(LVL, LFB) | LEVEL(LFB) | P(SNOOP, NONE), /* LFB/MAB hit|SNP None */ + OP_LH | P(LVL, L2) | LEVEL(L2) | P(SNOOP, NONE), /* L2 hit|SNP None */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, NONE), /* L3 hit|SNP None */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HIT), /* L3 hit|SNP Hit */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM), /* L3 hit|SNP HitM */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM), /* L3 hit|SNP HitM */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOPX, FWD), /* L3 hit|SNP Fwd */ + OP_LH | P(LVL, REM_CCE1) | REM | LEVEL(L3) | P(SNOOP, HITM), /* Remote L3 hit|SNP HitM */ + OP_LH | P(LVL, LOC_RAM) | LEVEL(RAM) | P(SNOOP, HIT), /* RAM hit|SNP Hit */ + OP_LH | P(LVL, REM_RAM1) | REM | LEVEL(L3) | P(SNOOP, HIT), /* Remote L3 hit|SNP Hit */ + OP_LH | P(LVL, LOC_RAM) | LEVEL(RAM) | SNOOP_NONE_MISS, /* RAM hit|SNP None or Miss */ + OP_LH | P(LVL, REM_RAM1) | LEVEL(RAM) | REM | SNOOP_NONE_MISS, /* Remote RAM hit|SNP None or Miss */ + OP_LH | P(LVL, IO) | LEVEL(NA) | P(SNOOP, NONE), /* I/O hit|SNP None */ + OP_LH | P(LVL, UNC) | LEVEL(NA) | P(SNOOP, NONE), /* Uncached hit|SNP None */ +}; + +/* Based on kernel __intel_pmu_pebs_data_source_cmt() and pebs_data_source */ +static const u64 pebs_data_source_cmt[PERF_PEBS_DATA_SOURCE_GRT_MAX] = { + P(OP, LOAD) | P(LVL, MISS) | LEVEL(L3) | P(SNOOP, NA), /* L3 miss|SNP N/A */ + OP_LH | P(LVL, L1) | LEVEL(L1) | P(SNOOP, NONE), /* L1 hit|SNP None */ + OP_LH | P(LVL, LFB) | LEVEL(LFB) | P(SNOOP, NONE), /* LFB/MAB hit|SNP None */ + OP_LH | P(LVL, L2) | LEVEL(L2) | P(SNOOP, NONE), /* L2 hit|SNP None */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, NONE), /* L3 hit|SNP None */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, MISS), /* L3 hit|SNP Hit */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HIT), /* L3 hit|SNP HitM */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOPX, FWD), /* L3 hit|SNP HitM */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM), /* L3 hit|SNP Fwd */ + OP_LH | P(LVL, REM_CCE1) | REM | LEVEL(L3) | P(SNOOP, HITM), /* Remote L3 hit|SNP HitM */ + OP_LH | P(LVL, LOC_RAM) | LEVEL(RAM) | P(SNOOP, NONE), /* RAM hit|SNP Hit */ + OP_LH | LEVEL(RAM) | REM | P(SNOOP, NONE), /* Remote L3 hit|SNP Hit */ + OP_LH | LEVEL(RAM) | REM | P(SNOOPX, FWD), /* RAM hit|SNP None or Miss */ + OP_LH | LEVEL(RAM) | REM | P(SNOOP, HITM), /* Remote RAM hit|SNP None or Miss */ + OP_LH | P(LVL, IO) | LEVEL(NA) | P(SNOOP, NONE), /* I/O hit|SNP None */ + OP_LH | P(LVL, UNC) | LEVEL(NA) | P(SNOOP, NONE), /* Uncached hit|SNP None */ +}; + +/* Based on kernel pebs_set_tlb_lock() */ +static inline void pebs_set_tlb_lock(u64 *val, bool tlb, bool lock) +{ + /* + * TLB access + * 0 = did not miss 2nd level TLB + * 1 = missed 2nd level TLB + */ + if (tlb) + *val |= P(TLB, MISS) | P(TLB, L2); + else + *val |= P(TLB, HIT) | P(TLB, L1) | P(TLB, L2); + + /* locked prefix */ + if (lock) + *val |= P(LOCK, LOCKED); +} + +/* Based on kernel __grt_latency_data() */ +static u64 intel_pt_grt_latency_data(u8 dse, bool tlb, bool lock, bool blk, + const u64 *pebs_data_source) +{ + u64 val; + + dse &= PERF_PEBS_DATA_SOURCE_GRT_MASK; + val = pebs_data_source[dse]; + + pebs_set_tlb_lock(&val, tlb, lock); + + if (blk) + val |= P(BLK, DATA); + else + val |= P(BLK, NA); + + return val; +} + +/* Default value for data source */ +#define PERF_MEM_NA (PERF_MEM_S(OP, NA) |\ + PERF_MEM_S(LVL, NA) |\ + PERF_MEM_S(SNOOP, NA) |\ + PERF_MEM_S(LOCK, NA) |\ + PERF_MEM_S(TLB, NA) |\ + PERF_MEM_S(LVLNUM, NA)) + +enum DATA_SRC_FORMAT { + DATA_SRC_FORMAT_ERR = -1, + DATA_SRC_FORMAT_NA = 0, + DATA_SRC_FORMAT_GRT = 1, + DATA_SRC_FORMAT_CMT = 2, +}; + +/* Based on kernel grt_latency_data() and cmt_latency_data */ +static u64 intel_pt_get_data_src(u64 mem_aux_info, int data_src_fmt) +{ + switch (data_src_fmt) { + case DATA_SRC_FORMAT_GRT: { + union { + u64 val; + struct { + unsigned int dse:4; + unsigned int locked:1; + unsigned int stlb_miss:1; + unsigned int fwd_blk:1; + unsigned int reserved:25; + }; + } x = {.val = mem_aux_info}; + return intel_pt_grt_latency_data(x.dse, x.stlb_miss, x.locked, x.fwd_blk, + pebs_data_source_grt); + } + case DATA_SRC_FORMAT_CMT: { + union { + u64 val; + struct { + unsigned int dse:5; + unsigned int locked:1; + unsigned int stlb_miss:1; + unsigned int fwd_blk:1; + unsigned int reserved:24; + }; + } x = {.val = mem_aux_info}; + return intel_pt_grt_latency_data(x.dse, x.stlb_miss, x.locked, x.fwd_blk, + pebs_data_source_cmt); + } + default: + return PERF_MEM_NA; + } +} + +static int intel_pt_do_synth_pebs_sample(struct intel_pt_queue *ptq, struct evsel *evsel, + u64 id, int data_src_fmt) { const struct intel_pt_blk_items *items = &ptq->state->items; struct perf_sample sample = { .ip = 0, }; @@ -2350,6 +2491,18 @@ static int intel_pt_do_synth_pebs_sample(struct intel_pt_queue *ptq, struct evse } } + if (sample_type & PERF_SAMPLE_DATA_SRC) { + if (items->has_mem_aux_info && data_src_fmt) { + if (data_src_fmt < 0) { + pr_err("Intel PT missing data_src info\n"); + return -1; + } + sample.data_src = intel_pt_get_data_src(items->mem_aux_info, data_src_fmt); + } else { + sample.data_src = PERF_MEM_NA; + } + } + if (sample_type & PERF_SAMPLE_TRANSACTION && items->has_tsx_aux_info) { u64 ax = items->has_rax ? items->rax : 0; /* Refer kernel's intel_hsw_transaction() */ @@ -2368,9 +2521,10 @@ static int intel_pt_synth_single_pebs_sample(struct intel_pt_queue *ptq) { struct intel_pt *pt = ptq->pt; struct evsel *evsel = pt->pebs_evsel; + int data_src_fmt = pt->pebs_data_src_fmt; u64 id = evsel->core.id[0]; - return intel_pt_do_synth_pebs_sample(ptq, evsel, id); + return intel_pt_do_synth_pebs_sample(ptq, evsel, id, data_src_fmt); } static int intel_pt_synth_pebs_sample(struct intel_pt_queue *ptq) @@ -2395,7 +2549,7 @@ static int intel_pt_synth_pebs_sample(struct intel_pt_queue *ptq) hw_id); return intel_pt_synth_single_pebs_sample(ptq); } - err = intel_pt_do_synth_pebs_sample(ptq, pe->evsel, pe->id); + err = intel_pt_do_synth_pebs_sample(ptq, pe->evsel, pe->id, pe->data_src_fmt); if (err) return err; } @@ -3355,6 +3509,49 @@ static int intel_pt_process_itrace_start(struct intel_pt *pt, event->itrace_start.tid); } +/* + * Events with data_src are identified by L1_Hit_Indication + * refer https://github.com/intel/perfmon + */ +static int intel_pt_data_src_fmt(struct intel_pt *pt, struct evsel *evsel) +{ + struct perf_env *env = pt->machine->env; + int fmt = DATA_SRC_FORMAT_NA; + + if (!env->cpuid) + return DATA_SRC_FORMAT_ERR; + + /* + * PEBS-via-PT is only supported on E-core non-hybrid. Of those only + * Gracemont and Crestmont have data_src. Check for: + * Alderlake N (Gracemont) + * Sierra Forest (Crestmont) + * Grand Ridge (Crestmont) + */ + + if (!strncmp(env->cpuid, "GenuineIntel,6,190,", 19)) + fmt = DATA_SRC_FORMAT_GRT; + + if (!strncmp(env->cpuid, "GenuineIntel,6,175,", 19) || + !strncmp(env->cpuid, "GenuineIntel,6,182,", 19)) + fmt = DATA_SRC_FORMAT_CMT; + + if (fmt == DATA_SRC_FORMAT_NA) + return fmt; + + /* + * Only data_src events are: + * mem-loads event=0xd0,umask=0x5 + * mem-stores event=0xd0,umask=0x6 + */ + if (evsel->core.attr.type == PERF_TYPE_RAW && + ((evsel->core.attr.config & 0xffff) == 0x5d0 || + (evsel->core.attr.config & 0xffff) == 0x6d0)) + return fmt; + + return DATA_SRC_FORMAT_NA; +} + static int intel_pt_process_aux_output_hw_id(struct intel_pt *pt, union perf_event *event, struct perf_sample *sample) @@ -3375,6 +3572,7 @@ static int intel_pt_process_aux_output_hw_id(struct intel_pt *pt, ptq->pebs[hw_id].evsel = evsel; ptq->pebs[hw_id].id = sample->id; + ptq->pebs[hw_id].data_src_fmt = intel_pt_data_src_fmt(pt, evsel); return 0; } @@ -3946,6 +4144,7 @@ static void intel_pt_setup_pebs_events(struct intel_pt *pt) } pt->single_pebs = true; pt->sample_pebs = true; + pt->pebs_data_src_fmt = intel_pt_data_src_fmt(pt, evsel); pt->pebs_evsel = evsel; } } From 41581d392c810e9faadaa247ea0efabf80c5fb33 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 12 May 2025 12:39:32 +0300 Subject: [PATCH 256/971] perf scripts python: exported-sql-viewer.py: Fix pattern matching with Python 3 [ Upstream commit 17e548405a81665fd14cee960db7d093d1396400 ] The script allows the user to enter patterns to find symbols. The pattern matching characters are converted for use in SQL. For PostgreSQL the conversion involves using the Python maketrans() method which is slightly different in Python 3 compared with Python 2. Fix to work in Python 3. Fixes: beda0e725e5f06ac ("perf script python: Add Python3 support to exported-sql-viewer.py") Signed-off-by: Adrian Hunter Cc: Alexander Shishkin Cc: Ian Rogers Cc: Jiri Olsa Cc: Kan Liang Cc: Namhyung Kim Cc: Tony Jones Link: https://lore.kernel.org/r/20250512093932.79854-4-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/scripts/python/exported-sql-viewer.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py index 13f2d8a81610..99742013676b 100755 --- a/tools/perf/scripts/python/exported-sql-viewer.py +++ b/tools/perf/scripts/python/exported-sql-viewer.py @@ -680,7 +680,10 @@ class CallGraphModelBase(TreeModel): s = value.replace("%", "\%") s = s.replace("_", "\_") # Translate * and ? into SQL LIKE pattern characters % and _ - trans = string.maketrans("*?", "%_") + if sys.version_info[0] == 3: + trans = str.maketrans("*?", "%_") + else: + trans = string.maketrans("*?", "%_") match = " LIKE '" + str(s).translate(trans) + "'" else: match = " GLOB '" + str(value) + "'" From f1a3c8ceb21d53ec6ff449faf3d266bdb594ceb7 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 2 Apr 2025 13:59:51 +0300 Subject: [PATCH 257/971] remoteproc: qcom_wcnss_iris: Add missing put_device() on error in probe [ Upstream commit 0cb4b1b97041d8a1f773425208ded253c1cb5869 ] The device_del() call matches with the device_add() but we also need to call put_device() to trigger the qcom_iris_release(). Fixes: 1fcef985c8bd ("remoteproc: qcom: wcnss: Fix race with iris probe") Signed-off-by: Dan Carpenter Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/4604f7e0-3217-4095-b28a-3ff8b5afad3a@stanley.mountain Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- drivers/remoteproc/qcom_wcnss_iris.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/remoteproc/qcom_wcnss_iris.c b/drivers/remoteproc/qcom_wcnss_iris.c index dd36fd077911..1e197f773474 100644 --- a/drivers/remoteproc/qcom_wcnss_iris.c +++ b/drivers/remoteproc/qcom_wcnss_iris.c @@ -197,6 +197,7 @@ struct qcom_iris *qcom_iris_probe(struct device *parent, bool *use_48mhz_xo) err_device_del: device_del(&iris->dev); + put_device(&iris->dev); return ERR_PTR(ret); } @@ -204,4 +205,5 @@ err_device_del: void qcom_iris_remove(struct qcom_iris *iris) { device_del(&iris->dev); + put_device(&iris->dev); } From 3b726bc12624721d1abef06d44dc55251ead39a8 Mon Sep 17 00:00:00 2001 From: Siddharth Vadapalli Date: Tue, 13 May 2025 11:14:35 +0530 Subject: [PATCH 258/971] remoteproc: k3-r5: Drop check performed in k3_r5_rproc_{mbox_callback/kick} [ Upstream commit 9995dbfc2235efabdb3759606d522e1a7ec3bdcb ] Commit f3f11cfe8907 ("remoteproc: k3-r5: Acquire mailbox handle during probe routine") introduced a check in the "k3_r5_rproc_mbox_callback()" and "k3_r5_rproc_kick()" callbacks, causing them to exit if the remote core's state is "RPROC_DETACHED". However, the "__rproc_attach()" function that is responsible for attaching to a remote core, updates the state of the remote core to "RPROC_ATTACHED" only after invoking "rproc_start_subdevices()". The "rproc_start_subdevices()" function triggers the probe of the Virtio RPMsg devices associated with the remote core, which require that the "k3_r5_rproc_kick()" and "k3_r5_rproc_mbox_callback()" callbacks are functional. Hence, drop the check in the callbacks. Fixes: f3f11cfe8907 ("remoteproc: k3-r5: Acquire mailbox handle during probe routine") Signed-off-by: Siddharth Vadapalli Signed-off-by: Beleswar Padhi Tested-by: Judith Mendez Reviewed-by: Andrew Davis Link: https://lore.kernel.org/r/20250513054510.3439842-2-b-padhi@ti.com Signed-off-by: Mathieu Poirier Signed-off-by: Sasha Levin --- drivers/remoteproc/ti_k3_r5_remoteproc.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c b/drivers/remoteproc/ti_k3_r5_remoteproc.c index 5491b1b17ca3..37005640c784 100644 --- a/drivers/remoteproc/ti_k3_r5_remoteproc.c +++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c @@ -194,10 +194,6 @@ static void k3_r5_rproc_mbox_callback(struct mbox_client *client, void *data) const char *name = kproc->rproc->name; u32 msg = omap_mbox_message(data); - /* Do not forward message from a detached core */ - if (kproc->rproc->state == RPROC_DETACHED) - return; - dev_dbg(dev, "mbox msg: 0x%x\n", msg); switch (msg) { @@ -233,10 +229,6 @@ static void k3_r5_rproc_kick(struct rproc *rproc, int vqid) mbox_msg_t msg = (mbox_msg_t)vqid; int ret; - /* Do not forward message to a detached core */ - if (kproc->rproc->state == RPROC_DETACHED) - return; - /* send the index of the triggered virtqueue in the mailbox payload */ ret = mbox_send_message(kproc->mbox, (void *)msg); if (ret < 0) From 85322ddd449a8d2bd02dd3dc388932a62fd75b35 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 23 Apr 2025 20:22:05 +0300 Subject: [PATCH 259/971] rpmsg: qcom_smd: Fix uninitialized return variable in __qcom_smd_send() [ Upstream commit 5de775df3362090a6e90046d1f2d83fe62489aa0 ] The "ret" variable isn't initialized if we don't enter the loop. For example, if "channel->state" is not SMD_CHANNEL_OPENED. Fixes: 33e3820dda88 ("rpmsg: smd: Use spinlock in tx path") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/aAkhvV0nSbrsef1P@stanley.mountain Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- drivers/rpmsg/qcom_smd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c index 43f601c84b4f..79d35ab43729 100644 --- a/drivers/rpmsg/qcom_smd.c +++ b/drivers/rpmsg/qcom_smd.c @@ -746,7 +746,7 @@ static int __qcom_smd_send(struct qcom_smd_channel *channel, const void *data, __le32 hdr[5] = { cpu_to_le32(len), }; int tlen = sizeof(hdr) + len; unsigned long flags; - int ret; + int ret = 0; /* Word aligned channels only accept word size aligned data */ if (channel->info_word && len % 4) From 611efa317b70a5569c9daad58cbfd5f02ba72675 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Mon, 21 Apr 2025 17:00:34 +0200 Subject: [PATCH 260/971] mfd: exynos-lpass: Avoid calling exynos_lpass_disable() twice in exynos_lpass_remove() [ Upstream commit b70b84556eeca5262d290e8619fe0af5b7664a52 ] exynos_lpass_disable() is called twice in the remove function. Remove one of these calls. Fixes: 90f447170c6f ("mfd: exynos-lpass: Add runtime PM support") Signed-off-by: Christophe JAILLET Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/74d69e8de10308c9855db6d54155a3de4b11abfd.1745247209.git.christophe.jaillet@wanadoo.fr Signed-off-by: Lee Jones Signed-off-by: Sasha Levin --- drivers/mfd/exynos-lpass.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c index 1506d8d352b1..5e39d91b728f 100644 --- a/drivers/mfd/exynos-lpass.c +++ b/drivers/mfd/exynos-lpass.c @@ -141,7 +141,6 @@ static int exynos_lpass_remove(struct platform_device *pdev) { struct exynos_lpass *lpass = platform_get_drvdata(pdev); - exynos_lpass_disable(lpass); pm_runtime_disable(&pdev->dev); if (!pm_runtime_status_suspended(&pdev->dev)) exynos_lpass_disable(lpass); From a20bbd91622f56f9b883a89506515c7c8bc0d24f Mon Sep 17 00:00:00 2001 From: Alexey Gladkov Date: Sat, 26 Apr 2025 18:16:32 +0200 Subject: [PATCH 261/971] mfd: stmpe-spi: Correct the name used in MODULE_DEVICE_TABLE [ Upstream commit 59d60c16ed41475f3b5f7b605e75fbf8e3628720 ] The name used in the macro does not exist. drivers/mfd/stmpe-spi.c:132:26: error: use of undeclared identifier 'stmpe_id' 132 | MODULE_DEVICE_TABLE(spi, stmpe_id); Fixes: e789995d5c61 ("mfd: Add support for STMPE SPI interface") Signed-off-by: Alexey Gladkov Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/79d5a847303e45a46098f2d827d3d8a249a32be3.1745591072.git.legion@kernel.org Signed-off-by: Lee Jones Signed-off-by: Sasha Levin --- drivers/mfd/stmpe-spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/stmpe-spi.c b/drivers/mfd/stmpe-spi.c index 792236f56399..b9cc85ea2c40 100644 --- a/drivers/mfd/stmpe-spi.c +++ b/drivers/mfd/stmpe-spi.c @@ -129,7 +129,7 @@ static const struct spi_device_id stmpe_spi_id[] = { { "stmpe2403", STMPE2403 }, { } }; -MODULE_DEVICE_TABLE(spi, stmpe_id); +MODULE_DEVICE_TABLE(spi, stmpe_spi_id); static struct spi_driver stmpe_spi_driver = { .driver = { From 5ec729bc5b03a595b0fd280d8e6760edf15ca0cf Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Mon, 31 Mar 2025 18:27:59 +0100 Subject: [PATCH 262/971] perf tests switch-tracking: Fix timestamp comparison [ Upstream commit 628e124404b3db5e10e17228e680a2999018ab33 ] The test might fail on the Arm64 platform with the error: # perf test -vvv "Track with sched_switch" Missing sched_switch events # The issue is caused by incorrect handling of timestamp comparisons. The comparison result, a signed 64-bit value, was being directly cast to an int, leading to incorrect sorting for sched events. The case does not fail everytime, usually I can trigger the failure after run 20 ~ 30 times: # while true; do perf test "Track with sched_switch"; done 106: Track with sched_switch : Ok 106: Track with sched_switch : Ok 106: Track with sched_switch : Ok 106: Track with sched_switch : Ok 106: Track with sched_switch : Ok 106: Track with sched_switch : Ok 106: Track with sched_switch : Ok 106: Track with sched_switch : Ok 106: Track with sched_switch : Ok 106: Track with sched_switch : Ok 106: Track with sched_switch : Ok 106: Track with sched_switch : Ok 106: Track with sched_switch : Ok 106: Track with sched_switch : Ok 106: Track with sched_switch : FAILED! 106: Track with sched_switch : Ok 106: Track with sched_switch : Ok 106: Track with sched_switch : Ok 106: Track with sched_switch : Ok 106: Track with sched_switch : Ok 106: Track with sched_switch : Ok 106: Track with sched_switch : Ok 106: Track with sched_switch : Ok 106: Track with sched_switch : FAILED! 106: Track with sched_switch : Ok 106: Track with sched_switch : Ok I used cross compiler to build Perf tool on my host machine and tested on Debian / Juno board. Generally, I think this issue is not very specific to GCC versions. As both internal CI and my local env can reproduce the issue. My Host Build compiler: # aarch64-linux-gnu-gcc --version aarch64-linux-gnu-gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0 Juno Board: # lsb_release -a No LSB modules are available. Distributor ID: Debian Description: Debian GNU/Linux 12 (bookworm) Release: 12 Codename: bookworm Fix this by explicitly returning 0, 1, or -1 based on whether the result is zero, positive, or negative. Fixes: d44bc558297222d9 ("perf tests: Add a test for tracking with sched_switch") Reviewed-by: Ian Rogers Signed-off-by: Leo Yan Cc: Adrian Hunter Cc: James Clark Cc: Kan Liang Cc: Namhyung Kim Link: https://lore.kernel.org/r/20250331172759.115604-1-leo.yan@arm.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/tests/switch-tracking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index e52b031bedc5..2c7bdf4fd55e 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -258,7 +258,7 @@ static int compar(const void *a, const void *b) const struct event_node *nodeb = b; s64 cmp = nodea->event_time - nodeb->event_time; - return cmp; + return cmp < 0 ? -1 : (cmp > 0 ? 1 : 0); } static int process_events(struct evlist *evlist, From 494395071e854f49f3066e2abe17daa9427b6999 Mon Sep 17 00:00:00 2001 From: Dapeng Mi Date: Thu, 3 Apr 2025 06:08:10 +0000 Subject: [PATCH 263/971] perf record: Fix incorrect --user-regs comments [ Upstream commit a4a859eb6704a8aa46aa1cec5396c8d41383a26b ] The comment of "--user-regs" option is not correct, fix it. "on interrupt," -> "in user space," Fixes: 84c417422798c897 ("perf record: Support direct --user-regs arguments") Reviewed-by: Ian Rogers Signed-off-by: Dapeng Mi Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ingo Molnar Cc: Kan Liang Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20250403060810.196028-1-dapeng1.mi@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/builtin-record.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index b94ae33a343c..81f77c0505fd 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -3427,7 +3427,7 @@ static struct option __record_options[] = { "sample selected machine registers on interrupt," " use '-I?' to list register names", parse_intr_regs), OPT_CALLBACK_OPTARG(0, "user-regs", &record.opts.sample_user_regs, NULL, "any register", - "sample selected machine registers on interrupt," + "sample selected machine registers in user space," " use '--user-regs=?' to list register names", parse_user_regs), OPT_BOOLEAN(0, "running-time", &record.opts.running_time, "Record running/enabled time of read (:S) events"), From 7101de2396335ba44733e49a07df4dae51af140b Mon Sep 17 00:00:00 2001 From: Anubhav Shelat Date: Thu, 3 Apr 2025 12:04:12 -0400 Subject: [PATCH 264/971] perf trace: Always print return value for syscalls returning a pid [ Upstream commit c7a48ea9b919e2fa0e4a1d9938fdb03e9afe276c ] The syscalls that were consistently observed were set_robust_list and rseq. This is because perf cannot find their child process. This change ensures that the return value is always printed. Before: 0.256 ( 0.001 ms): set_robust_list(head: 0x7f09c77dba20, len: 24) = 0.259 ( 0.001 ms): rseq(rseq: 0x7f09c77dc0e0, rseq_len: 32, sig: 1392848979) = After: 0.270 ( 0.002 ms): set_robust_list(head: 0x7f0bb14a6a20, len: 24) = 0 0.273 ( 0.002 ms): rseq(rseq: 0x7f0bb14a70e0, rseq_len: 32, sig: 1392848979) = 0 Committer notes: As discussed in the thread in the Link: tag below, these two don't return a pid, but for syscalls returning one, we need to print the result and if we manage to find the children in 'perf trace' data structures, then print its name as well. Fixes: 11c8e39f5133aed9 ("perf trace: Infrastructure to show COMM strings for syscalls returning PIDs") Reviewed-by: Howard Chu Signed-off-by: Anubhav Shelat Acked-by: Namhyung Kim Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Dapeng Mi Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Mark Rutland Cc: Michael Petlan Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20250403160411.159238-2-ashelat@redhat.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/builtin-trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 908509df007b..7ee3285af10c 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2586,8 +2586,8 @@ errno_print: { else if (sc->fmt->errpid) { struct thread *child = machine__find_thread(trace->host, ret, ret); + fprintf(trace->output, "%ld", ret); if (child != NULL) { - fprintf(trace->output, "%ld", ret); if (thread__comm_set(child)) fprintf(trace->output, " (%s)", thread__comm_str(child)); thread__put(child); From c9d9a8995f69f9d05a90da6b5877aa87bd377fbe Mon Sep 17 00:00:00 2001 From: Li Lingfeng Date: Tue, 4 Mar 2025 21:05:32 +0800 Subject: [PATCH 265/971] nfs: clear SB_RDONLY before getting superblock [ Upstream commit 8cd9b785943c57a136536250da80ba1eb6f8eb18 ] As described in the link, commit 52cb7f8f1778 ("nfs: ignore SB_RDONLY when mounting nfs") removed the check for the ro flag when determining whether to share the superblock, which caused issues when mounting different subdirectories under the same export directory via NFSv3. However, this change did not affect NFSv4. For NFSv3: 1) A single superblock is created for the initial mount. 2) When mounted read-only, this superblock carries the SB_RDONLY flag. 3) Before commit 52cb7f8f1778 ("nfs: ignore SB_RDONLY when mounting nfs"): Subsequent rw mounts would not share the existing ro superblock due to flag mismatch, creating a new superblock without SB_RDONLY. After the commit: The SB_RDONLY flag is ignored during superblock comparison, and this leads to sharing the existing superblock even for rw mounts. Ultimately results in write operations being rejected at the VFS layer. For NFSv4: 1) Multiple superblocks are created and the last one will be kept. 2) The actually used superblock for ro mounts doesn't carry SB_RDONLY flag. Therefore, commit 52cb7f8f1778 doesn't affect NFSv4 mounts. Clear SB_RDONLY before getting superblock when NFS_MOUNT_UNSHARED is not set to fix it. Fixes: 52cb7f8f1778 ("nfs: ignore SB_RDONLY when mounting nfs") Closes: https://lore.kernel.org/all/12d7ea53-1202-4e21-a7ef-431c94758ce5@app.fastmail.com/T/ Signed-off-by: Li Lingfeng Signed-off-by: Anna Schumaker Signed-off-by: Sasha Levin --- fs/nfs/super.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index e1bcad5906ae..59bf4b2c0f86 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1277,8 +1277,17 @@ int nfs_get_tree_common(struct fs_context *fc) if (IS_ERR(server)) return PTR_ERR(server); + /* + * When NFS_MOUNT_UNSHARED is not set, NFS forces the sharing of a + * superblock among each filesystem that mounts sub-directories + * belonging to a single exported root path. + * To prevent interference between different filesystems, the + * SB_RDONLY flag should be removed from the superblock. + */ if (server->flags & NFS_MOUNT_UNSHARED) compare_super = NULL; + else + fc->sb_flags &= ~SB_RDONLY; /* -o noac implies -o sync */ if (server->flags & NFS_MOUNT_NOAC) From c050dc2669c2d2cb34c1441a81141ebf7214a682 Mon Sep 17 00:00:00 2001 From: Li Lingfeng Date: Tue, 4 Mar 2025 21:05:33 +0800 Subject: [PATCH 266/971] nfs: ignore SB_RDONLY when remounting nfs [ Upstream commit 80c4de6ab44c14e910117a02f2f8241ffc6ec54a ] In some scenarios, when mounting NFS, more than one superblock may be created. The final superblock used is the last one created, but only the first superblock carries the ro flag passed from user space. If a ro flag is added to the superblock via remount, it will trigger the issue described in Link[1]. Link[2] attempted to address this by marking the superblock as ro during the initial mount. However, this introduced a new problem in scenarios where multiple mount points share the same superblock: [root@a ~]# mount /dev/sdb /mnt/sdb [root@a ~]# echo "/mnt/sdb *(rw,no_root_squash)" > /etc/exports [root@a ~]# echo "/mnt/sdb/test_dir2 *(ro,no_root_squash)" >> /etc/exports [root@a ~]# systemctl restart nfs-server [root@a ~]# mount -t nfs -o rw 127.0.0.1:/mnt/sdb/test_dir1 /mnt/test_mp1 [root@a ~]# mount | grep nfs4 127.0.0.1:/mnt/sdb/test_dir1 on /mnt/test_mp1 type nfs4 (rw,relatime,... [root@a ~]# mount -t nfs -o ro 127.0.0.1:/mnt/sdb/test_dir2 /mnt/test_mp2 [root@a ~]# mount | grep nfs4 127.0.0.1:/mnt/sdb/test_dir1 on /mnt/test_mp1 type nfs4 (ro,relatime,... 127.0.0.1:/mnt/sdb/test_dir2 on /mnt/test_mp2 type nfs4 (ro,relatime,... [root@a ~]# When mounting the second NFS, the shared superblock is marked as ro, causing the previous NFS mount to become read-only. To resolve both issues, the ro flag is no longer applied to the superblock during remount. Instead, the ro flag on the mount is used to control whether the mount point is read-only. Fixes: 281cad46b34d ("NFS: Create a submount rpc_op") Link[1]: https://lore.kernel.org/all/20240604112636.236517-3-lilingfeng@huaweicloud.com/ Link[2]: https://lore.kernel.org/all/20241130035818.1459775-1-lilingfeng3@huawei.com/ Signed-off-by: Li Lingfeng Signed-off-by: Anna Schumaker Signed-off-by: Sasha Levin --- fs/nfs/super.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 59bf4b2c0f86..4e72ee57fc8f 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1020,6 +1020,16 @@ int nfs_reconfigure(struct fs_context *fc) sync_filesystem(sb); + /* + * The SB_RDONLY flag has been removed from the superblock during + * mounts to prevent interference between different filesystems. + * Similarly, it is also necessary to ignore the SB_RDONLY flag + * during reconfiguration; otherwise, it may also result in the + * creation of redundant superblocks when mounting a directory with + * different rw and ro flags multiple times. + */ + fc->sb_flags_mask &= ~SB_RDONLY; + /* * Userspace mount programs that send binary options generally send * them populated with default values. We have no way to know which From 848d78e3625f15de09d34a562dc49a98b78a62f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Thu, 26 Dec 2024 19:55:13 +0100 Subject: [PATCH 267/971] cifs: Fix validation of SMB1 query reparse point response MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 56e84c64fc257a95728ee73165456b025c48d408 ] Validate the SMB1 query reparse point response per [MS-CIFS] section 2.2.7.2 NT_TRANSACT_IOCTL. NT_TRANSACT_IOCTL response contains one word long setup data after which is ByteCount member. So check that SetupCount is 1 before trying to read and use ByteCount member. Output setup data contains ReturnedDataLen member which is the output length of executed IOCTL command by remote system. So check that output was not truncated before transferring over network. Change MaxSetupCount of NT_TRANSACT_IOCTL request from 4 to 1 as io_rsp structure already expects one word long output setup data. This should prevent server sending incompatible structure (in case it would be extended in future, which is unlikely). Change MaxParameterCount of NT_TRANSACT_IOCTL request from 2 to 0 as NT IOCTL does not have any documented output parameters and this function does not parse any output parameters at all. Fixes: ed3e0a149b58 ("smb: client: implement ->query_reparse_point() for SMB1") Signed-off-by: Pali Rohár Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/smb/client/cifssmb.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c index b91184ebce02..c36ab20050c1 100644 --- a/fs/smb/client/cifssmb.c +++ b/fs/smb/client/cifssmb.c @@ -2738,10 +2738,10 @@ int cifs_query_reparse_point(const unsigned int xid, io_req->TotalParameterCount = 0; io_req->TotalDataCount = 0; - io_req->MaxParameterCount = cpu_to_le32(2); + io_req->MaxParameterCount = cpu_to_le32(0); /* BB find exact data count max from sess structure BB */ io_req->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00); - io_req->MaxSetupCount = 4; + io_req->MaxSetupCount = 1; io_req->Reserved = 0; io_req->ParameterOffset = 0; io_req->DataCount = 0; @@ -2768,6 +2768,22 @@ int cifs_query_reparse_point(const unsigned int xid, goto error; } + /* SetupCount must be 1, otherwise offset to ByteCount is incorrect. */ + if (io_rsp->SetupCount != 1) { + rc = -EIO; + goto error; + } + + /* + * ReturnedDataLen is output length of executed IOCTL. + * DataCount is output length transferred over network. + * Check that we have full FSCTL_GET_REPARSE_POINT buffer. + */ + if (data_count != le16_to_cpu(io_rsp->ReturnedDataLen)) { + rc = -EIO; + goto error; + } + end = 2 + get_bcc(&io_rsp->hdr) + (__u8 *)&io_rsp->ByteCount; start = (__u8 *)&io_rsp->hdr.Protocol + data_offset; if (start >= end) { From 2e6d9128fe9b6296100d602acafb742d98dde2d6 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 27 Feb 2025 14:42:56 +0100 Subject: [PATCH 268/971] rtc: sh: assign correct interrupts with DT [ Upstream commit 8f2efdbc303fe7baa83843d3290dd6ea5ba3276c ] The DT bindings for this driver define the interrupts in the order as they are numbered in the interrupt controller. The old platform_data, however, listed them in a different order. So, for DT based platforms, they are mixed up. Assign them specifically for DT, so we can keep the bindings stable. After the fix, 'rtctest' passes again on the Renesas Genmai board (RZ-A1 / R7S72100). Fixes: dab5aec64bf5 ("rtc: sh: add support for rza series") Signed-off-by: Wolfram Sang Link: https://lore.kernel.org/r/20250227134256.9167-11-wsa+renesas@sang-engineering.com Signed-off-by: Alexandre Belloni Signed-off-by: Sasha Levin --- drivers/rtc/rtc-sh.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index cd146b574143..341b1b776e1a 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -485,9 +485,15 @@ static int __init sh_rtc_probe(struct platform_device *pdev) return -ENOENT; } - rtc->periodic_irq = ret; - rtc->carry_irq = platform_get_irq(pdev, 1); - rtc->alarm_irq = platform_get_irq(pdev, 2); + if (!pdev->dev.of_node) { + rtc->periodic_irq = ret; + rtc->carry_irq = platform_get_irq(pdev, 1); + rtc->alarm_irq = platform_get_irq(pdev, 2); + } else { + rtc->alarm_irq = ret; + rtc->periodic_irq = platform_get_irq(pdev, 1); + rtc->carry_irq = platform_get_irq(pdev, 2); + } res = platform_get_resource(pdev, IORESOURCE_IO, 0); if (!res) From 92d879eff459873cea4fb317c404f210906430dc Mon Sep 17 00:00:00 2001 From: Wilfred Mallawa Date: Mon, 14 Apr 2025 10:15:06 +1000 Subject: [PATCH 269/971] PCI: Print the actual delay time in pci_bridge_wait_for_secondary_bus() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit d24eba726aadf8778f2907dd42281c6380b0ccaa ] Print the delay amount that pcie_wait_for_link_delay() is invoked with instead of the hardcoded 1000ms value in the debug info print. Fixes: 7b3ba09febf4 ("PCI/PM: Shorten pci_bridge_wait_for_secondary_bus() wait time for slow links") Signed-off-by: Wilfred Mallawa Signed-off-by: Bjorn Helgaas Reviewed-by: Damien Le Moal Reviewed-by: Kuppuswamy Sathyanarayanan Reviewed-by: Mika Westerberg Reviewed-by: Ilpo Järvinen Link: https://patch.msgid.link/20250414001505.21243-2-wilfred.opensource@gmail.com Signed-off-by: Sasha Levin --- drivers/pci/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 095fa1910d36..503304aba9ea 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -5221,7 +5221,7 @@ int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type) delay); if (!pcie_wait_for_link_delay(dev, true, delay)) { /* Did not train, no need to wait any further */ - pci_info(dev, "Data Link Layer Link Active not set in 1000 msec\n"); + pci_info(dev, "Data Link Layer Link Active not set in %d msec\n", delay); return -ENOTTY; } From 004316d2de7e667f2391bf5145246a1ad2253bd3 Mon Sep 17 00:00:00 2001 From: Hans Zhang <18255117159@163.com> Date: Sat, 19 Apr 2025 21:30:58 +0800 Subject: [PATCH 270/971] PCI: cadence: Fix runtime atomic count underflow [ Upstream commit 8805f32a96d3b97cef07999fa6f52112678f7e65 ] If the call to pci_host_probe() in cdns_pcie_host_setup() fails, PM runtime count is decremented in the error path using pm_runtime_put_sync(). But the runtime count is not incremented by this driver, but only by the callers (cdns_plat_pcie_probe/j721e_pcie_probe). And the callers also decrement the runtime PM count in their error path. So this leads to the below warning from the PM core: "runtime PM usage count underflow!" So fix it by getting rid of pm_runtime_put_sync() in the error path and directly return the errno. Fixes: 49e427e6bdd1 ("Merge branch 'pci/host-probe-refactor'") Signed-off-by: Hans Zhang <18255117159@163.com> Signed-off-by: Manivannan Sadhasivam Link: https://patch.msgid.link/20250419133058.162048-1-18255117159@163.com Signed-off-by: Sasha Levin --- drivers/pci/controller/cadence/pcie-cadence-host.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c index 8af95e9da7ce..741e10a575ec 100644 --- a/drivers/pci/controller/cadence/pcie-cadence-host.c +++ b/drivers/pci/controller/cadence/pcie-cadence-host.c @@ -570,14 +570,5 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc) if (!bridge->ops) bridge->ops = &cdns_pcie_host_ops; - ret = pci_host_probe(bridge); - if (ret < 0) - goto err_init; - - return 0; - - err_init: - pm_runtime_put_sync(dev); - - return ret; + return pci_host_probe(bridge); } From 248f52ad6e82fef08e22fb56d45aaf3527fcaedc Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Tue, 1 Apr 2025 10:17:11 +0100 Subject: [PATCH 271/971] PCI: apple: Use gpiod_set_value_cansleep in probe flow [ Upstream commit 7334364f9de79a9a236dd0243ba574b8d2876e89 ] We're allowed to sleep here, so tell the GPIO core by using gpiod_set_value_cansleep instead of gpiod_set_value. Fixes: 1e33888fbe44 ("PCI: apple: Add initial hardware bring-up") Signed-off-by: Hector Martin Signed-off-by: Alyssa Rosenzweig Signed-off-by: Marc Zyngier Signed-off-by: Manivannan Sadhasivam Tested-by: Janne Grunau Reviewed-by: Rob Herring (Arm) Reviewed-by: Manivannan Sadhasivam Acked-by: Alyssa Rosenzweig Link: https://patch.msgid.link/20250401091713.2765724-12-maz@kernel.org Signed-off-by: Sasha Levin --- drivers/pci/controller/pcie-apple.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c index f7a248393a8f..7e6bd63a6425 100644 --- a/drivers/pci/controller/pcie-apple.c +++ b/drivers/pci/controller/pcie-apple.c @@ -541,7 +541,7 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie, rmw_set(PORT_APPCLK_EN, port->base + PORT_APPCLK); /* Assert PERST# before setting up the clock */ - gpiod_set_value(reset, 1); + gpiod_set_value_cansleep(reset, 1); ret = apple_pcie_setup_refclk(pcie, port); if (ret < 0) @@ -552,7 +552,7 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie, /* Deassert PERST# */ rmw_set(PORT_PERST_OFF, port->base + PORT_PERST); - gpiod_set_value(reset, 0); + gpiod_set_value_cansleep(reset, 0); /* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */ msleep(100); From 127dfb4f1c5a2b622039c5d203f321380ea36665 Mon Sep 17 00:00:00 2001 From: Chenyuan Yang Date: Mon, 14 Apr 2025 07:50:50 -0500 Subject: [PATCH 272/971] phy: qcom-qmp-usb: Fix an NULL vs IS_ERR() bug [ Upstream commit d14402a38c2d868cacb1facaf9be908ca6558e59 ] The qmp_usb_iomap() helper function currently returns the raw result of devm_ioremap() for non-exclusive mappings. Since devm_ioremap() may return a NULL pointer and the caller only checks error pointers with IS_ERR(), NULL could bypass the check and lead to an invalid dereference. Fix the issue by checking if devm_ioremap() returns NULL. When it does, qmp_usb_iomap() now returns an error pointer via IOMEM_ERR_PTR(-ENOMEM), ensuring safe and consistent error handling. Signed-off-by: Chenyuan Yang Fixes: a5d6b1ac56cb ("phy: qcom-qmp-usb: fix memleak on probe deferral") CC: Johan Hovold CC: Krzysztof Kozlowski Reviewed-by: Johan Hovold Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250414125050.2118619-1-chenyuan0y@gmail.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/phy/qualcomm/phy-qcom-qmp-usb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c index c697d01b2a2a..5072bca0af7c 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c @@ -2044,12 +2044,16 @@ static void __iomem *qmp_usb_iomap(struct device *dev, struct device_node *np, int index, bool exclusive) { struct resource res; + void __iomem *mem; if (!exclusive) { if (of_address_to_resource(np, index, &res)) return IOMEM_ERR_PTR(-EINVAL); - return devm_ioremap(dev, res.start, resource_size(&res)); + mem = devm_ioremap(dev, res.start, resource_size(&res)); + if (!mem) + return IOMEM_ERR_PTR(-ENOMEM); + return mem; } return devm_of_iomap(dev, np, index, NULL); From b79e10050d9d1e200541d25751dd5cb8ec58483c Mon Sep 17 00:00:00 2001 From: Henry Martin Date: Wed, 2 Apr 2025 10:39:00 +0800 Subject: [PATCH 273/971] dmaengine: ti: Add NULL check in udma_probe() [ Upstream commit fd447415e74bccd7362f760d4ea727f8e1ebfe91 ] devm_kasprintf() returns NULL when memory allocation fails. Currently, udma_probe() does not check for this case, which results in a NULL pointer dereference. Add NULL check after devm_kasprintf() to prevent this issue. Fixes: 25dcb5dd7b7c ("dmaengine: ti: New driver for K3 UDMA") Signed-off-by: Henry Martin Reviewed-by: Nathan Lynch Acked-by: Peter Ujfalusi Link: https://lore.kernel.org/r/20250402023900.43440-1-bsdhenrymartin@gmail.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/dma/ti/k3-udma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c index 418e1774af1e..d99cf81358c5 100644 --- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c @@ -5537,7 +5537,8 @@ static int udma_probe(struct platform_device *pdev) uc->config.dir = DMA_MEM_TO_MEM; uc->name = devm_kasprintf(dev, GFP_KERNEL, "%s chan%d", dev_name(dev), i); - + if (!uc->name) + return -ENOMEM; vchan_init(&uc->vc, &ud->ddev); /* Use custom vchan completion handling */ tasklet_setup(&uc->vc.task, udma_vchan_complete); From 56035627865e48d0ef0665eeb77b742e7faf4bbb Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 22 May 2025 18:21:07 -0500 Subject: [PATCH 274/971] PCI/DPC: Initialize aer_err_info before using it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit a424b598e6a6c1e69a2bb801d6fd16e805ab2c38 ] Previously the struct aer_err_info "info" was allocated on the stack without being initialized, so it contained junk except for the fields we explicitly set later. Initialize "info" at declaration so it starts as all zeros. Fixes: 8aefa9b0d910 ("PCI/DPC: Print AER status in DPC event handling") Signed-off-by: Bjorn Helgaas Tested-by: Krzysztof Wilczyński Reviewed-by: Kuppuswamy Sathyanarayanan Reviewed-by: Ilpo Järvinen Reviewed-by: Jonathan Cameron Link: https://patch.msgid.link/20250522232339.1525671-2-helgaas@kernel.org Signed-off-by: Sasha Levin --- drivers/pci/pcie/dpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c index a5cec2a4e057..3c3ecb9cf57a 100644 --- a/drivers/pci/pcie/dpc.c +++ b/drivers/pci/pcie/dpc.c @@ -263,7 +263,7 @@ static int dpc_get_aer_uncorrect_severity(struct pci_dev *dev, void dpc_process_error(struct pci_dev *pdev) { u16 cap = pdev->dpc_cap, status, source, reason, ext_reason; - struct aer_err_info info; + struct aer_err_info info = {}; pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, &status); pci_read_config_word(pdev, cap + PCI_EXP_DPC_SOURCE_ID, &source); From 63df0a22dabc04bdc193b31325874424760c03d1 Mon Sep 17 00:00:00 2001 From: Liu Dalin Date: Fri, 9 May 2025 16:44:16 +0800 Subject: [PATCH 275/971] rtc: loongson: Add missing alarm notifications for ACPI RTC events [ Upstream commit 5af9f1fa576874b24627d4c05e3a84672204c200 ] When an application sets and enables an alarm on Loongson RTC devices, the alarm notification fails to propagate to userspace because the ACPI event handler omits calling rtc_update_irq(). As a result, processes waiting via select() or poll() on RTC device files fail to receive alarm notifications. The ACPI interrupt is also triggered multiple times. In loongson_rtc_handler, we need to clear TOY_MATCH0_REG to resolve this issue. Fixes: 09471d8f5b39 ("rtc: loongson: clear TOY_MATCH0_REG in loongson_rtc_isr()") Fixes: 1b733a9ebc3d ("rtc: Add rtc driver for the Loongson family chips") Signed-off-by: Liu Dalin Reviewed-by: Binbin Zhou Link: https://lore.kernel.org/r/20250509084416.7979-1-liudalin@kylinsec.com.cn Signed-off-by: Alexandre Belloni Signed-off-by: Sasha Levin --- drivers/rtc/rtc-loongson.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/rtc/rtc-loongson.c b/drivers/rtc/rtc-loongson.c index 90e9d97a86b4..c9d5b91a6544 100644 --- a/drivers/rtc/rtc-loongson.c +++ b/drivers/rtc/rtc-loongson.c @@ -129,6 +129,14 @@ static u32 loongson_rtc_handler(void *id) { struct loongson_rtc_priv *priv = (struct loongson_rtc_priv *)id; + rtc_update_irq(priv->rtcdev, 1, RTC_AF | RTC_IRQF); + + /* + * The TOY_MATCH0_REG should be cleared 0 here, + * otherwise the interrupt cannot be cleared. + */ + regmap_write(priv->regmap, TOY_MATCH0_REG, 0); + spin_lock(&priv->lock); /* Disable RTC alarm wakeup and interrupt */ writel(readl(priv->pm_base + PM1_EN_REG) & ~RTC_EN, From db96a4fd8614d47c0def265e0e6c996b0ee52a38 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Mon, 7 Apr 2025 11:50:02 +0100 Subject: [PATCH 276/971] usb: renesas_usbhs: Reorder clock handling and power management in probe [ Upstream commit ffb34a60ce86656ba12d46e91f1ccc71dd221251 ] Reorder the initialization sequence in `usbhs_probe()` to enable runtime PM before accessing registers, preventing potential crashes due to uninitialized clocks. Currently, in the probe path, registers are accessed before enabling the clocks, leading to a synchronous external abort on the RZ/V2H SoC. The problematic call flow is as follows: usbhs_probe() usbhs_sys_clock_ctrl() usbhs_bset() usbhs_write() iowrite16() <-- Register access before enabling clocks Since `iowrite16()` is performed without ensuring the required clocks are enabled, this can lead to access errors. To fix this, enable PM runtime early in the probe function and ensure clocks are acquired before register access, preventing crashes like the following on RZ/V2H: [13.272640] Internal error: synchronous external abort: 0000000096000010 [#1] PREEMPT SMP [13.280814] Modules linked in: cec renesas_usbhs(+) drm_kms_helper fuse drm backlight ipv6 [13.289088] CPU: 1 UID: 0 PID: 195 Comm: (udev-worker) Not tainted 6.14.0-rc7+ #98 [13.296640] Hardware name: Renesas RZ/V2H EVK Board based on r9a09g057h44 (DT) [13.303834] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [13.310770] pc : usbhs_bset+0x14/0x4c [renesas_usbhs] [13.315831] lr : usbhs_probe+0x2e4/0x5ac [renesas_usbhs] [13.321138] sp : ffff8000827e3850 [13.324438] x29: ffff8000827e3860 x28: 0000000000000000 x27: ffff8000827e3ca0 [13.331554] x26: ffff8000827e3ba0 x25: ffff800081729668 x24: 0000000000000025 [13.338670] x23: ffff0000c0f08000 x22: 0000000000000000 x21: ffff0000c0f08010 [13.345783] x20: 0000000000000000 x19: ffff0000c3b52080 x18: 00000000ffffffff [13.352895] x17: 0000000000000000 x16: 0000000000000000 x15: ffff8000827e36ce [13.360009] x14: 00000000000003d7 x13: 00000000000003d7 x12: 0000000000000000 [13.367122] x11: 0000000000000000 x10: 0000000000000aa0 x9 : ffff8000827e3750 [13.374235] x8 : ffff0000c1850b00 x7 : 0000000003826060 x6 : 000000000000001c [13.381347] x5 : 000000030d5fcc00 x4 : ffff8000825c0000 x3 : 0000000000000000 [13.388459] x2 : 0000000000000400 x1 : 0000000000000000 x0 : ffff0000c3b52080 [13.395574] Call trace: [13.398013] usbhs_bset+0x14/0x4c [renesas_usbhs] (P) [13.403076] platform_probe+0x68/0xdc [13.406738] really_probe+0xbc/0x2c0 [13.410306] __driver_probe_device+0x78/0x120 [13.414653] driver_probe_device+0x3c/0x154 [13.418825] __driver_attach+0x90/0x1a0 [13.422647] bus_for_each_dev+0x7c/0xe0 [13.426470] driver_attach+0x24/0x30 [13.430032] bus_add_driver+0xe4/0x208 [13.433766] driver_register+0x68/0x130 [13.437587] __platform_driver_register+0x24/0x30 [13.442273] renesas_usbhs_driver_init+0x20/0x1000 [renesas_usbhs] [13.448450] do_one_initcall+0x60/0x1d4 [13.452276] do_init_module+0x54/0x1f8 [13.456014] load_module+0x1754/0x1c98 [13.459750] init_module_from_file+0x88/0xcc [13.464004] __arm64_sys_finit_module+0x1c4/0x328 [13.468689] invoke_syscall+0x48/0x104 [13.472426] el0_svc_common.constprop.0+0xc0/0xe0 [13.477113] do_el0_svc+0x1c/0x28 [13.480415] el0_svc+0x30/0xcc [13.483460] el0t_64_sync_handler+0x10c/0x138 [13.487800] el0t_64_sync+0x198/0x19c [13.491453] Code: 2a0103e1 12003c42 12003c63 8b010084 (79400084) [13.497522] ---[ end trace 0000000000000000 ]--- Fixes: f1407d5c66240 ("usb: renesas_usbhs: Add Renesas USBHS common code") Signed-off-by: Lad Prabhakar Reviewed-by: Yoshihiro Shimoda Tested-by: Yoshihiro Shimoda Link: https://lore.kernel.org/r/20250407105002.107181-4-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/renesas_usbhs/common.c | 50 +++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 205820544f6f..b720899725e5 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -674,10 +674,29 @@ static int usbhs_probe(struct platform_device *pdev) INIT_DELAYED_WORK(&priv->notify_hotplug_work, usbhsc_notify_hotplug); spin_lock_init(usbhs_priv_to_lock(priv)); + /* + * Acquire clocks and enable power management (PM) early in the + * probe process, as the driver accesses registers during + * initialization. Ensure the device is active before proceeding. + */ + pm_runtime_enable(dev); + + ret = usbhsc_clk_get(dev, priv); + if (ret) + goto probe_pm_disable; + + ret = pm_runtime_resume_and_get(dev); + if (ret) + goto probe_clk_put; + + ret = usbhsc_clk_prepare_enable(priv); + if (ret) + goto probe_pm_put; + /* call pipe and module init */ ret = usbhs_pipe_probe(priv); if (ret < 0) - return ret; + goto probe_clk_dis_unprepare; ret = usbhs_fifo_probe(priv); if (ret < 0) @@ -694,10 +713,6 @@ static int usbhs_probe(struct platform_device *pdev) if (ret) goto probe_fail_rst; - ret = usbhsc_clk_get(dev, priv); - if (ret) - goto probe_fail_clks; - /* * deviece reset here because * USB device might be used in boot loader. @@ -710,7 +725,7 @@ static int usbhs_probe(struct platform_device *pdev) if (ret) { dev_warn(dev, "USB function not selected (GPIO)\n"); ret = -ENOTSUPP; - goto probe_end_mod_exit; + goto probe_assert_rest; } } @@ -724,14 +739,19 @@ static int usbhs_probe(struct platform_device *pdev) ret = usbhs_platform_call(priv, hardware_init, pdev); if (ret < 0) { dev_err(dev, "platform init failed.\n"); - goto probe_end_mod_exit; + goto probe_assert_rest; } /* reset phy for connection */ usbhs_platform_call(priv, phy_reset, pdev); - /* power control */ - pm_runtime_enable(dev); + /* + * Disable the clocks that were enabled earlier in the probe path, + * and let the driver handle the clocks beyond this point. + */ + usbhsc_clk_disable_unprepare(priv); + pm_runtime_put(dev); + if (!usbhs_get_dparam(priv, runtime_pwctrl)) { usbhsc_power_ctrl(priv, 1); usbhs_mod_autonomy_mode(priv); @@ -748,9 +768,7 @@ static int usbhs_probe(struct platform_device *pdev) return ret; -probe_end_mod_exit: - usbhsc_clk_put(priv); -probe_fail_clks: +probe_assert_rest: reset_control_assert(priv->rsts); probe_fail_rst: usbhs_mod_remove(priv); @@ -758,6 +776,14 @@ probe_end_fifo_exit: usbhs_fifo_remove(priv); probe_end_pipe_exit: usbhs_pipe_remove(priv); +probe_clk_dis_unprepare: + usbhsc_clk_disable_unprepare(priv); +probe_pm_put: + pm_runtime_put(dev); +probe_clk_put: + usbhsc_clk_put(priv); +probe_pm_disable: + pm_runtime_disable(dev); dev_info(dev, "probe failed (%d)\n", ret); From a6c7c365734cd0fa1c5aa225a6294fdf80cad2ea Mon Sep 17 00:00:00 2001 From: Henry Martin Date: Thu, 3 Apr 2025 15:03:39 +0800 Subject: [PATCH 277/971] serial: Fix potential null-ptr-deref in mlb_usio_probe() [ Upstream commit 86bcae88c9209e334b2f8c252f4cc66beb261886 ] devm_ioremap() can return NULL on error. Currently, mlb_usio_probe() does not check for this case, which could result in a NULL pointer dereference. Add NULL check after devm_ioremap() to prevent this issue. Fixes: ba44dc043004 ("serial: Add Milbeaut serial control") Signed-off-by: Henry Martin Link: https://lore.kernel.org/r/20250403070339.64990-1-bsdhenrymartin@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/tty/serial/milbeaut_usio.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/milbeaut_usio.c b/drivers/tty/serial/milbeaut_usio.c index 70a910085e93..9de3883a4e0b 100644 --- a/drivers/tty/serial/milbeaut_usio.c +++ b/drivers/tty/serial/milbeaut_usio.c @@ -522,7 +522,10 @@ static int mlb_usio_probe(struct platform_device *pdev) } port->membase = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - + if (!port->membase) { + ret = -ENOMEM; + goto failed; + } ret = platform_get_irq_byname(pdev, "rx"); mlb_usio_irq[index][RX] = ret; From f2829faa3fd586df6c22902774b32f215ed917a8 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Fri, 11 Apr 2025 10:14:44 -0500 Subject: [PATCH 278/971] thunderbolt: Fix a logic error in wake on connect [ Upstream commit 1a760d10ded372d113a0410c42be246315bbc2ff ] commit a5cfc9d65879c ("thunderbolt: Add wake on connect/disconnect on USB4 ports") introduced a sysfs file to control wake up policy for a given USB4 port that defaulted to disabled. However when testing commit 4bfeea6ec1c02 ("thunderbolt: Use wake on connect and disconnect over suspend") I found that it was working even without making changes to the power/wakeup file (which defaults to disabled). This is because of a logic error doing a bitwise or of the wake-on-connect flag with device_may_wakeup() which should have been a logical AND. Adjust the logic so that policy is only applied when wakeup is actually enabled. Fixes: a5cfc9d65879c ("thunderbolt: Add wake on connect/disconnect on USB4 ports") Signed-off-by: Mario Limonciello Signed-off-by: Mika Westerberg Signed-off-by: Sasha Levin --- drivers/thunderbolt/usb4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c index 8db9bd32f473..e445516290f9 100644 --- a/drivers/thunderbolt/usb4.c +++ b/drivers/thunderbolt/usb4.c @@ -442,10 +442,10 @@ int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags) bool configured = val & PORT_CS_19_PC; usb4 = port->usb4; - if (((flags & TB_WAKE_ON_CONNECT) | + if (((flags & TB_WAKE_ON_CONNECT) && device_may_wakeup(&usb4->dev)) && !configured) val |= PORT_CS_19_WOC; - if (((flags & TB_WAKE_ON_DISCONNECT) | + if (((flags & TB_WAKE_ON_DISCONNECT) && device_may_wakeup(&usb4->dev)) && configured) val |= PORT_CS_19_WOD; if ((flags & TB_WAKE_ON_USB4) && configured) From 31fa7dd09a25ec639a1523f09de3a0a78bfc8e88 Mon Sep 17 00:00:00 2001 From: Sam Winchenbach Date: Fri, 28 Mar 2025 13:48:27 -0400 Subject: [PATCH 279/971] iio: filter: admv8818: fix band 4, state 15 [ Upstream commit ef0ce24f590ac075d5eda11f2d6434b303333ed6 ] Corrects the upper range of LPF Band 4 from 18.5 GHz to 18.85 GHz per the ADMV8818 datasheet Fixes: f34fe888ad05 ("iio:filter:admv8818: add support for ADMV8818") Signed-off-by: Sam Winchenbach Link: https://patch.msgid.link/20250328174831.227202-3-sam.winchenbach@framepointer.org Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- drivers/iio/filter/admv8818.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/filter/admv8818.c b/drivers/iio/filter/admv8818.c index d85b7d3de866..3d8740caa145 100644 --- a/drivers/iio/filter/admv8818.c +++ b/drivers/iio/filter/admv8818.c @@ -103,7 +103,7 @@ static const unsigned long long freq_range_lpf[4][2] = { {2050000000ULL, 3850000000ULL}, {3350000000ULL, 7250000000ULL}, {7000000000, 13000000000}, - {12550000000, 18500000000} + {12550000000, 18850000000} }; static const struct regmap_config admv8818_regmap_config = { From 61b3b2d6288828c17f8db82f8a702aa3ded2148d Mon Sep 17 00:00:00 2001 From: Sam Winchenbach Date: Fri, 28 Mar 2025 13:48:28 -0400 Subject: [PATCH 280/971] iio: filter: admv8818: fix integer overflow [ Upstream commit fb6009a28d77edec4eb548b5875dae8c79b88467 ] HZ_PER_MHZ is only unsigned long. This math overflows, leading to incorrect results. Fixes: f34fe888ad05 ("iio:filter:admv8818: add support for ADMV8818") Signed-off-by: Sam Winchenbach Link: https://patch.msgid.link/20250328174831.227202-4-sam.winchenbach@framepointer.org Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- drivers/iio/filter/admv8818.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/filter/admv8818.c b/drivers/iio/filter/admv8818.c index 3d8740caa145..cd3aff9a2f7b 100644 --- a/drivers/iio/filter/admv8818.c +++ b/drivers/iio/filter/admv8818.c @@ -154,7 +154,7 @@ static int __admv8818_hpf_select(struct admv8818_state *st, u64 freq) } /* Close HPF frequency gap between 12 and 12.5 GHz */ - if (freq >= 12000 * HZ_PER_MHZ && freq <= 12500 * HZ_PER_MHZ) { + if (freq >= 12000ULL * HZ_PER_MHZ && freq < 12500ULL * HZ_PER_MHZ) { hpf_band = 3; hpf_step = 15; } From 786cdbd4da1b28c116d51c9ca6dcc32ad5cedf63 Mon Sep 17 00:00:00 2001 From: Sam Winchenbach Date: Fri, 28 Mar 2025 13:48:29 -0400 Subject: [PATCH 281/971] iio: filter: admv8818: fix range calculation [ Upstream commit d542db7095d322bfcdc8e306db6f8c48358c9619 ] Search for the minimum error while ensuring that the LPF corner frequency is greater than the target, and the HPF corner frequency is lower than the target This fixes issues where the range calculations were suboptimal. Add two new DTS properties to set the margin between the input frequency and the calculated corner frequency Below is a generated table of the differences between the old algorithm and the new. This is a sweep from 0 to 20 GHz in 10 MHz steps. === HPF === freq = 1750 MHz, 3db: bypass => 1750 MHz freq = 3400 MHz, 3db: 3310 => 3400 MHz freq = 3410 MHz, 3db: 3310 => 3400 MHz freq = 3420 MHz, 3db: 3310 => 3400 MHz freq = 3660 MHz, 3db: 3550 => 3656 MHz freq = 6600 MHz, 3db: 6479 => 6600 MHz freq = 6610 MHz, 3db: 6479 => 6600 MHz freq = 6620 MHz, 3db: 6479 => 6600 MHz freq = 6630 MHz, 3db: 6479 => 6600 MHz freq = 6640 MHz, 3db: 6479 => 6600 MHz freq = 6650 MHz, 3db: 6479 => 6600 MHz freq = 6660 MHz, 3db: 6479 => 6600 MHz freq = 6670 MHz, 3db: 6479 => 6600 MHz freq = 6680 MHz, 3db: 6479 => 6600 MHz freq = 6690 MHz, 3db: 6479 => 6600 MHz freq = 6700 MHz, 3db: 6479 => 6600 MHz freq = 6710 MHz, 3db: 6479 => 6600 MHz freq = 6720 MHz, 3db: 6479 => 6600 MHz freq = 6730 MHz, 3db: 6479 => 6600 MHz freq = 6960 MHz, 3db: 6736 => 6960 MHz freq = 6970 MHz, 3db: 6736 => 6960 MHz freq = 6980 MHz, 3db: 6736 => 6960 MHz freq = 6990 MHz, 3db: 6736 => 6960 MHz freq = 7320 MHz, 3db: 7249 => 7320 MHz freq = 7330 MHz, 3db: 7249 => 7320 MHz freq = 7340 MHz, 3db: 7249 => 7320 MHz freq = 7350 MHz, 3db: 7249 => 7320 MHz freq = 7360 MHz, 3db: 7249 => 7320 MHz freq = 7370 MHz, 3db: 7249 => 7320 MHz freq = 7380 MHz, 3db: 7249 => 7320 MHz freq = 7390 MHz, 3db: 7249 => 7320 MHz freq = 7400 MHz, 3db: 7249 => 7320 MHz freq = 7410 MHz, 3db: 7249 => 7320 MHz freq = 7420 MHz, 3db: 7249 => 7320 MHz freq = 7430 MHz, 3db: 7249 => 7320 MHz freq = 7440 MHz, 3db: 7249 => 7320 MHz freq = 7450 MHz, 3db: 7249 => 7320 MHz freq = 7460 MHz, 3db: 7249 => 7320 MHz freq = 7470 MHz, 3db: 7249 => 7320 MHz freq = 7480 MHz, 3db: 7249 => 7320 MHz freq = 7490 MHz, 3db: 7249 => 7320 MHz freq = 7500 MHz, 3db: 7249 => 7320 MHz freq = 12500 MHz, 3db: 12000 => 12500 MHz === LPF === freq = 2050 MHz, 3db: bypass => 2050 MHz freq = 2170 MHz, 3db: 2290 => 2170 MHz freq = 2290 MHz, 3db: 2410 => 2290 MHz freq = 2410 MHz, 3db: 2530 => 2410 MHz freq = 2530 MHz, 3db: 2650 => 2530 MHz freq = 2650 MHz, 3db: 2770 => 2650 MHz freq = 2770 MHz, 3db: 2890 => 2770 MHz freq = 2890 MHz, 3db: 3010 => 2890 MHz freq = 3010 MHz, 3db: 3130 => 3010 MHz freq = 3130 MHz, 3db: 3250 => 3130 MHz freq = 3250 MHz, 3db: 3370 => 3250 MHz freq = 3260 MHz, 3db: 3370 => 3350 MHz freq = 3270 MHz, 3db: 3370 => 3350 MHz freq = 3280 MHz, 3db: 3370 => 3350 MHz freq = 3290 MHz, 3db: 3370 => 3350 MHz freq = 3300 MHz, 3db: 3370 => 3350 MHz freq = 3310 MHz, 3db: 3370 => 3350 MHz freq = 3320 MHz, 3db: 3370 => 3350 MHz freq = 3330 MHz, 3db: 3370 => 3350 MHz freq = 3340 MHz, 3db: 3370 => 3350 MHz freq = 3350 MHz, 3db: 3370 => 3350 MHz freq = 3370 MHz, 3db: 3490 => 3370 MHz freq = 3490 MHz, 3db: 3610 => 3490 MHz freq = 3610 MHz, 3db: 3730 => 3610 MHz freq = 3730 MHz, 3db: 3850 => 3730 MHz freq = 3850 MHz, 3db: 3870 => 3850 MHz freq = 3870 MHz, 3db: 4130 => 3870 MHz freq = 4130 MHz, 3db: 4390 => 4130 MHz freq = 4390 MHz, 3db: 4650 => 4390 MHz freq = 4650 MHz, 3db: 4910 => 4650 MHz freq = 4910 MHz, 3db: 5170 => 4910 MHz freq = 5170 MHz, 3db: 5430 => 5170 MHz freq = 5430 MHz, 3db: 5690 => 5430 MHz freq = 5690 MHz, 3db: 5950 => 5690 MHz freq = 5950 MHz, 3db: 6210 => 5950 MHz freq = 6210 MHz, 3db: 6470 => 6210 MHz freq = 6470 MHz, 3db: 6730 => 6470 MHz freq = 6730 MHz, 3db: 6990 => 6730 MHz freq = 6990 MHz, 3db: 7250 => 6990 MHz freq = 7000 MHz, 3db: 7250 => 7000 MHz freq = 7250 MHz, 3db: 7400 => 7250 MHz freq = 7400 MHz, 3db: 7800 => 7400 MHz freq = 7800 MHz, 3db: 8200 => 7800 MHz freq = 8200 MHz, 3db: 8600 => 8200 MHz freq = 8600 MHz, 3db: 9000 => 8600 MHz freq = 9000 MHz, 3db: 9400 => 9000 MHz freq = 9400 MHz, 3db: 9800 => 9400 MHz freq = 9800 MHz, 3db: 10200 => 9800 MHz freq = 10200 MHz, 3db: 10600 => 10200 MHz freq = 10600 MHz, 3db: 11000 => 10600 MHz freq = 11000 MHz, 3db: 11400 => 11000 MHz freq = 11400 MHz, 3db: 11800 => 11400 MHz freq = 11800 MHz, 3db: 12200 => 11800 MHz freq = 12200 MHz, 3db: 12600 => 12200 MHz freq = 12210 MHz, 3db: 12600 => 12550 MHz freq = 12220 MHz, 3db: 12600 => 12550 MHz freq = 12230 MHz, 3db: 12600 => 12550 MHz freq = 12240 MHz, 3db: 12600 => 12550 MHz freq = 12250 MHz, 3db: 12600 => 12550 MHz freq = 12260 MHz, 3db: 12600 => 12550 MHz freq = 12270 MHz, 3db: 12600 => 12550 MHz freq = 12280 MHz, 3db: 12600 => 12550 MHz freq = 12290 MHz, 3db: 12600 => 12550 MHz freq = 12300 MHz, 3db: 12600 => 12550 MHz freq = 12310 MHz, 3db: 12600 => 12550 MHz freq = 12320 MHz, 3db: 12600 => 12550 MHz freq = 12330 MHz, 3db: 12600 => 12550 MHz freq = 12340 MHz, 3db: 12600 => 12550 MHz freq = 12350 MHz, 3db: 12600 => 12550 MHz freq = 12360 MHz, 3db: 12600 => 12550 MHz freq = 12370 MHz, 3db: 12600 => 12550 MHz freq = 12380 MHz, 3db: 12600 => 12550 MHz freq = 12390 MHz, 3db: 12600 => 12550 MHz freq = 12400 MHz, 3db: 12600 => 12550 MHz freq = 12410 MHz, 3db: 12600 => 12550 MHz freq = 12420 MHz, 3db: 12600 => 12550 MHz freq = 12430 MHz, 3db: 12600 => 12550 MHz freq = 12440 MHz, 3db: 12600 => 12550 MHz freq = 12450 MHz, 3db: 12600 => 12550 MHz freq = 12460 MHz, 3db: 12600 => 12550 MHz freq = 12470 MHz, 3db: 12600 => 12550 MHz freq = 12480 MHz, 3db: 12600 => 12550 MHz freq = 12490 MHz, 3db: 12600 => 12550 MHz freq = 12500 MHz, 3db: 12600 => 12550 MHz freq = 12510 MHz, 3db: 12600 => 12550 MHz freq = 12520 MHz, 3db: 12600 => 12550 MHz freq = 12530 MHz, 3db: 12600 => 12550 MHz freq = 12540 MHz, 3db: 12600 => 12550 MHz freq = 12550 MHz, 3db: 12600 => 12550 MHz freq = 12600 MHz, 3db: 13000 => 12600 MHz freq = 12610 MHz, 3db: 13000 => 12970 MHz freq = 12620 MHz, 3db: 13000 => 12970 MHz freq = 12630 MHz, 3db: 13000 => 12970 MHz freq = 12640 MHz, 3db: 13000 => 12970 MHz freq = 12650 MHz, 3db: 13000 => 12970 MHz freq = 12660 MHz, 3db: 13000 => 12970 MHz freq = 12670 MHz, 3db: 13000 => 12970 MHz freq = 12680 MHz, 3db: 13000 => 12970 MHz freq = 12690 MHz, 3db: 13000 => 12970 MHz freq = 12700 MHz, 3db: 13000 => 12970 MHz freq = 12710 MHz, 3db: 13000 => 12970 MHz freq = 12720 MHz, 3db: 13000 => 12970 MHz freq = 12730 MHz, 3db: 13000 => 12970 MHz freq = 12740 MHz, 3db: 13000 => 12970 MHz freq = 12750 MHz, 3db: 13000 => 12970 MHz freq = 12760 MHz, 3db: 13000 => 12970 MHz freq = 12770 MHz, 3db: 13000 => 12970 MHz freq = 12780 MHz, 3db: 13000 => 12970 MHz freq = 12790 MHz, 3db: 13000 => 12970 MHz freq = 12800 MHz, 3db: 13000 => 12970 MHz freq = 12810 MHz, 3db: 13000 => 12970 MHz freq = 12820 MHz, 3db: 13000 => 12970 MHz freq = 12830 MHz, 3db: 13000 => 12970 MHz freq = 12840 MHz, 3db: 13000 => 12970 MHz freq = 12850 MHz, 3db: 13000 => 12970 MHz freq = 12860 MHz, 3db: 13000 => 12970 MHz freq = 12870 MHz, 3db: 13000 => 12970 MHz freq = 12880 MHz, 3db: 13000 => 12970 MHz freq = 12890 MHz, 3db: 13000 => 12970 MHz freq = 12900 MHz, 3db: 13000 => 12970 MHz freq = 12910 MHz, 3db: 13000 => 12970 MHz freq = 12920 MHz, 3db: 13000 => 12970 MHz freq = 12930 MHz, 3db: 13000 => 12970 MHz freq = 12940 MHz, 3db: 13000 => 12970 MHz freq = 12950 MHz, 3db: 13000 => 12970 MHz freq = 12960 MHz, 3db: 13000 => 12970 MHz freq = 12970 MHz, 3db: 13000 => 12970 MHz freq = 13000 MHz, 3db: 13390 => 13000 MHz freq = 13390 MHz, 3db: 13810 => 13390 MHz freq = 13810 MHz, 3db: 14230 => 13810 MHz freq = 14230 MHz, 3db: 14650 => 14230 MHz freq = 14650 MHz, 3db: 15070 => 14650 MHz freq = 15070 MHz, 3db: 15490 => 15070 MHz freq = 15490 MHz, 3db: 15910 => 15490 MHz freq = 15910 MHz, 3db: 16330 => 15910 MHz freq = 16330 MHz, 3db: 16750 => 16330 MHz freq = 16750 MHz, 3db: 17170 => 16750 MHz freq = 17170 MHz, 3db: 17590 => 17170 MHz freq = 17590 MHz, 3db: 18010 => 17590 MHz freq = 18010 MHz, 3db: 18430 => 18010 MHz freq = 18430 MHz, 3db: 18850 => 18430 MHz freq = 18850 MHz, 3db: bypass => 18850 MHz Fixes: f34fe888ad05 ("iio:filter:admv8818: add support for ADMV8818") Signed-off-by: Sam Winchenbach Link: https://patch.msgid.link/20250328174831.227202-5-sam.winchenbach@framepointer.org Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- drivers/iio/filter/admv8818.c | 209 +++++++++++++++++++++++++--------- 1 file changed, 154 insertions(+), 55 deletions(-) diff --git a/drivers/iio/filter/admv8818.c b/drivers/iio/filter/admv8818.c index cd3aff9a2f7b..380e119b3cf5 100644 --- a/drivers/iio/filter/admv8818.c +++ b/drivers/iio/filter/admv8818.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -70,6 +71,16 @@ #define ADMV8818_HPF_WR0_MSK GENMASK(7, 4) #define ADMV8818_LPF_WR0_MSK GENMASK(3, 0) +#define ADMV8818_BAND_BYPASS 0 +#define ADMV8818_BAND_MIN 1 +#define ADMV8818_BAND_MAX 4 +#define ADMV8818_BAND_CORNER_LOW 0 +#define ADMV8818_BAND_CORNER_HIGH 1 + +#define ADMV8818_STATE_MIN 0 +#define ADMV8818_STATE_MAX 15 +#define ADMV8818_NUM_STATES 16 + enum { ADMV8818_BW_FREQ, ADMV8818_CENTER_FREQ @@ -90,16 +101,20 @@ struct admv8818_state { struct mutex lock; unsigned int filter_mode; u64 cf_hz; + u64 lpf_margin_hz; + u64 hpf_margin_hz; }; -static const unsigned long long freq_range_hpf[4][2] = { +static const unsigned long long freq_range_hpf[5][2] = { + {0ULL, 0ULL}, /* bypass */ {1750000000ULL, 3550000000ULL}, {3400000000ULL, 7250000000ULL}, {6600000000, 12000000000}, {12500000000, 19900000000} }; -static const unsigned long long freq_range_lpf[4][2] = { +static const unsigned long long freq_range_lpf[5][2] = { + {U64_MAX, U64_MAX}, /* bypass */ {2050000000ULL, 3850000000ULL}, {3350000000ULL, 7250000000ULL}, {7000000000, 13000000000}, @@ -121,42 +136,57 @@ static const char * const admv8818_modes[] = { static int __admv8818_hpf_select(struct admv8818_state *st, u64 freq) { - unsigned int hpf_step = 0, hpf_band = 0, i, j; - u64 freq_step; - int ret; + int band, state, ret; + unsigned int hpf_state = ADMV8818_STATE_MIN, hpf_band = ADMV8818_BAND_BYPASS; + u64 freq_error, min_freq_error, freq_corner, freq_step; - if (freq < freq_range_hpf[0][0]) + if (freq < freq_range_hpf[ADMV8818_BAND_MIN][ADMV8818_BAND_CORNER_LOW]) goto hpf_write; - if (freq > freq_range_hpf[3][1]) { - hpf_step = 15; - hpf_band = 4; - + if (freq >= freq_range_hpf[ADMV8818_BAND_MAX][ADMV8818_BAND_CORNER_HIGH]) { + hpf_state = ADMV8818_STATE_MAX; + hpf_band = ADMV8818_BAND_MAX; goto hpf_write; } - for (i = 0; i < 4; i++) { - freq_step = div_u64((freq_range_hpf[i][1] - - freq_range_hpf[i][0]), 15); - - if (freq > freq_range_hpf[i][0] && - (freq < freq_range_hpf[i][1] + freq_step)) { - hpf_band = i + 1; - - for (j = 1; j <= 16; j++) { - if (freq < (freq_range_hpf[i][0] + (freq_step * j))) { - hpf_step = j - 1; - break; - } - } - break; - } - } - /* Close HPF frequency gap between 12 and 12.5 GHz */ if (freq >= 12000ULL * HZ_PER_MHZ && freq < 12500ULL * HZ_PER_MHZ) { + hpf_state = ADMV8818_STATE_MAX; hpf_band = 3; - hpf_step = 15; + goto hpf_write; + } + + min_freq_error = U64_MAX; + for (band = ADMV8818_BAND_MIN; band <= ADMV8818_BAND_MAX; band++) { + /* + * This (and therefore all other ranges) have a corner + * frequency higher than the target frequency. + */ + if (freq_range_hpf[band][ADMV8818_BAND_CORNER_LOW] > freq) + break; + + freq_step = freq_range_hpf[band][ADMV8818_BAND_CORNER_HIGH] - + freq_range_hpf[band][ADMV8818_BAND_CORNER_LOW]; + freq_step = div_u64(freq_step, ADMV8818_NUM_STATES - 1); + + for (state = ADMV8818_STATE_MIN; state <= ADMV8818_STATE_MAX; state++) { + freq_corner = freq_range_hpf[band][ADMV8818_BAND_CORNER_LOW] + + freq_step * state; + + /* + * This (and therefore all other states) have a corner + * frequency higher than the target frequency. + */ + if (freq_corner > freq) + break; + + freq_error = freq - freq_corner; + if (freq_error < min_freq_error) { + min_freq_error = freq_error; + hpf_state = state; + hpf_band = band; + } + } } hpf_write: @@ -170,7 +200,7 @@ hpf_write: return regmap_update_bits(st->regmap, ADMV8818_REG_WR0_FILTER, ADMV8818_HPF_WR0_MSK, - FIELD_PREP(ADMV8818_HPF_WR0_MSK, hpf_step)); + FIELD_PREP(ADMV8818_HPF_WR0_MSK, hpf_state)); } static int admv8818_hpf_select(struct admv8818_state *st, u64 freq) @@ -186,31 +216,52 @@ static int admv8818_hpf_select(struct admv8818_state *st, u64 freq) static int __admv8818_lpf_select(struct admv8818_state *st, u64 freq) { - unsigned int lpf_step = 0, lpf_band = 0, i, j; - u64 freq_step; - int ret; + int band, state, ret; + unsigned int lpf_state = ADMV8818_STATE_MIN, lpf_band = ADMV8818_BAND_BYPASS; + u64 freq_error, min_freq_error, freq_corner, freq_step; - if (freq > freq_range_lpf[3][1]) + if (freq > freq_range_lpf[ADMV8818_BAND_MAX][ADMV8818_BAND_CORNER_HIGH]) goto lpf_write; - if (freq < freq_range_lpf[0][0]) { - lpf_band = 1; - + if (freq < freq_range_lpf[ADMV8818_BAND_MIN][ADMV8818_BAND_CORNER_LOW]) { + lpf_state = ADMV8818_STATE_MIN; + lpf_band = ADMV8818_BAND_MIN; goto lpf_write; } - for (i = 0; i < 4; i++) { - if (freq > freq_range_lpf[i][0] && freq < freq_range_lpf[i][1]) { - lpf_band = i + 1; - freq_step = div_u64((freq_range_lpf[i][1] - freq_range_lpf[i][0]), 15); - - for (j = 0; j <= 15; j++) { - if (freq < (freq_range_lpf[i][0] + (freq_step * j))) { - lpf_step = j; - break; - } - } + min_freq_error = U64_MAX; + for (band = ADMV8818_BAND_MAX; band >= ADMV8818_BAND_MIN; --band) { + /* + * At this point the highest corner frequency of + * all remaining ranges is below the target. + * LPF corner should be >= the target. + */ + if (freq > freq_range_lpf[band][ADMV8818_BAND_CORNER_HIGH]) break; + + freq_step = freq_range_lpf[band][ADMV8818_BAND_CORNER_HIGH] - + freq_range_lpf[band][ADMV8818_BAND_CORNER_LOW]; + freq_step = div_u64(freq_step, ADMV8818_NUM_STATES - 1); + + for (state = ADMV8818_STATE_MAX; state >= ADMV8818_STATE_MIN; --state) { + + freq_corner = freq_range_lpf[band][ADMV8818_BAND_CORNER_LOW] + + state * freq_step; + + /* + * At this point all other states in range will + * place the corner frequency below the target + * LPF corner should >= the target. + */ + if (freq > freq_corner) + break; + + freq_error = freq_corner - freq; + if (freq_error < min_freq_error) { + min_freq_error = freq_error; + lpf_state = state; + lpf_band = band; + } } } @@ -225,7 +276,7 @@ lpf_write: return regmap_update_bits(st->regmap, ADMV8818_REG_WR0_FILTER, ADMV8818_LPF_WR0_MSK, - FIELD_PREP(ADMV8818_LPF_WR0_MSK, lpf_step)); + FIELD_PREP(ADMV8818_LPF_WR0_MSK, lpf_state)); } static int admv8818_lpf_select(struct admv8818_state *st, u64 freq) @@ -242,16 +293,28 @@ static int admv8818_lpf_select(struct admv8818_state *st, u64 freq) static int admv8818_rfin_band_select(struct admv8818_state *st) { int ret; + u64 hpf_corner_target, lpf_corner_target; st->cf_hz = clk_get_rate(st->clkin); + /* Check for underflow */ + if (st->cf_hz > st->hpf_margin_hz) + hpf_corner_target = st->cf_hz - st->hpf_margin_hz; + else + hpf_corner_target = 0; + + /* Check for overflow */ + lpf_corner_target = st->cf_hz + st->lpf_margin_hz; + if (lpf_corner_target < st->cf_hz) + lpf_corner_target = U64_MAX; + mutex_lock(&st->lock); - ret = __admv8818_hpf_select(st, st->cf_hz); + ret = __admv8818_hpf_select(st, hpf_corner_target); if (ret) goto exit; - ret = __admv8818_lpf_select(st, st->cf_hz); + ret = __admv8818_lpf_select(st, lpf_corner_target); exit: mutex_unlock(&st->lock); return ret; @@ -278,8 +341,11 @@ static int __admv8818_read_hpf_freq(struct admv8818_state *st, u64 *hpf_freq) hpf_state = FIELD_GET(ADMV8818_HPF_WR0_MSK, data); - *hpf_freq = div_u64(freq_range_hpf[hpf_band - 1][1] - freq_range_hpf[hpf_band - 1][0], 15); - *hpf_freq = freq_range_hpf[hpf_band - 1][0] + (*hpf_freq * hpf_state); + *hpf_freq = freq_range_hpf[hpf_band][ADMV8818_BAND_CORNER_HIGH] - + freq_range_hpf[hpf_band][ADMV8818_BAND_CORNER_LOW]; + *hpf_freq = div_u64(*hpf_freq, ADMV8818_NUM_STATES - 1); + *hpf_freq = freq_range_hpf[hpf_band][ADMV8818_BAND_CORNER_LOW] + + (*hpf_freq * hpf_state); return ret; } @@ -316,8 +382,11 @@ static int __admv8818_read_lpf_freq(struct admv8818_state *st, u64 *lpf_freq) lpf_state = FIELD_GET(ADMV8818_LPF_WR0_MSK, data); - *lpf_freq = div_u64(freq_range_lpf[lpf_band - 1][1] - freq_range_lpf[lpf_band - 1][0], 15); - *lpf_freq = freq_range_lpf[lpf_band - 1][0] + (*lpf_freq * lpf_state); + *lpf_freq = freq_range_lpf[lpf_band][ADMV8818_BAND_CORNER_HIGH] - + freq_range_lpf[lpf_band][ADMV8818_BAND_CORNER_LOW]; + *lpf_freq = div_u64(*lpf_freq, ADMV8818_NUM_STATES - 1); + *lpf_freq = freq_range_lpf[lpf_band][ADMV8818_BAND_CORNER_LOW] + + (*lpf_freq * lpf_state); return ret; } @@ -641,6 +710,32 @@ static int admv8818_clk_setup(struct admv8818_state *st) return devm_add_action_or_reset(&spi->dev, admv8818_clk_notifier_unreg, st); } +static int admv8818_read_properties(struct admv8818_state *st) +{ + struct spi_device *spi = st->spi; + u32 mhz; + int ret; + + ret = device_property_read_u32(&spi->dev, "adi,lpf-margin-mhz", &mhz); + if (ret == 0) + st->lpf_margin_hz = (u64)mhz * HZ_PER_MHZ; + else if (ret == -EINVAL) + st->lpf_margin_hz = 0; + else + return ret; + + + ret = device_property_read_u32(&spi->dev, "adi,hpf-margin-mhz", &mhz); + if (ret == 0) + st->hpf_margin_hz = (u64)mhz * HZ_PER_MHZ; + else if (ret == -EINVAL) + st->hpf_margin_hz = 0; + else if (ret < 0) + return ret; + + return 0; +} + static int admv8818_probe(struct spi_device *spi) { struct iio_dev *indio_dev; @@ -672,6 +767,10 @@ static int admv8818_probe(struct spi_device *spi) mutex_init(&st->lock); + ret = admv8818_read_properties(st); + if (ret) + return ret; + ret = admv8818_init(st); if (ret) return ret; From ca0012a63261ac36c25647e3a93a13de382c0adb Mon Sep 17 00:00:00 2001 From: Brian Pellegrino Date: Fri, 28 Mar 2025 13:48:31 -0400 Subject: [PATCH 282/971] iio: filter: admv8818: Support frequencies >= 2^32 [ Upstream commit 9016776f1301627de78a633bda7c898425a56572 ] This patch allows writing u64 values to the ADMV8818's high and low-pass filter frequencies. It includes the following changes: - Rejects negative frequencies in admv8818_write_raw. - Adds a write_raw_get_fmt function to admv8818's iio_info, returning IIO_VAL_INT_64 for the high and low-pass filter 3dB frequency channels. Fixes: f34fe888ad05 ("iio:filter:admv8818: add support for ADMV8818") Signed-off-by: Brian Pellegrino Signed-off-by: Sam Winchenbach Link: https://patch.msgid.link/20250328174831.227202-7-sam.winchenbach@framepointer.org Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- drivers/iio/filter/admv8818.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/iio/filter/admv8818.c b/drivers/iio/filter/admv8818.c index 380e119b3cf5..cc8ce0fe74e7 100644 --- a/drivers/iio/filter/admv8818.c +++ b/drivers/iio/filter/admv8818.c @@ -402,6 +402,19 @@ static int admv8818_read_lpf_freq(struct admv8818_state *st, u64 *lpf_freq) return ret; } +static int admv8818_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: + return IIO_VAL_INT_64; + default: + return -EINVAL; + } +} + static int admv8818_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long info) @@ -410,6 +423,9 @@ static int admv8818_write_raw(struct iio_dev *indio_dev, u64 freq = ((u64)val2 << 32 | (u32)val); + if ((s64)freq < 0) + return -EINVAL; + switch (info) { case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: return admv8818_lpf_select(st, freq); @@ -571,6 +587,7 @@ set_mode: static const struct iio_info admv8818_info = { .write_raw = admv8818_write_raw, + .write_raw_get_fmt = admv8818_write_raw_get_fmt, .read_raw = admv8818_read_raw, .debugfs_reg_access = &admv8818_reg_access, }; From ec20928ecb1cac4ac1c47bc2d7e442d9bf29159a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 17 Mar 2025 12:52:47 +0100 Subject: [PATCH 283/971] iio: adc: ad7124: Fix 3dB filter frequency reading MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 8712e4986e7ce42a14c762c4c350f290989986a5 ] The sinc4 filter has a factor 0.23 between Output Data Rate and f_{3dB} and for sinc3 the factor is 0.272 according to the data sheets for ad7124-4 (Rev. E.) and ad7124-8 (Rev. F). Fixes: cef2760954cf ("iio: adc: ad7124: add 3db filter") Signed-off-by: Uwe Kleine-König Reviewed-by: Marcelo Schmitt Link: https://patch.msgid.link/20250317115247.3735016-6-u.kleine-koenig@baylibre.com Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- drivers/iio/adc/ad7124.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c index 0e6baf017bfd..f631351eef97 100644 --- a/drivers/iio/adc/ad7124.c +++ b/drivers/iio/adc/ad7124.c @@ -300,9 +300,9 @@ static int ad7124_get_3db_filter_freq(struct ad7124_state *st, switch (st->channels[channel].cfg.filter_type) { case AD7124_SINC3_FILTER: - return DIV_ROUND_CLOSEST(fadc * 230, 1000); + return DIV_ROUND_CLOSEST(fadc * 272, 1000); case AD7124_SINC4_FILTER: - return DIV_ROUND_CLOSEST(fadc * 262, 1000); + return DIV_ROUND_CLOSEST(fadc * 230, 1000); default: return -EINVAL; } From 72166de0a1a55f46b485f6f23e9045411756caa3 Mon Sep 17 00:00:00 2001 From: WangYuli Date: Wed, 16 Apr 2025 11:45:48 +0800 Subject: [PATCH 284/971] MIPS: Loongson64: Add missing '#interrupt-cells' for loongson64c_ls7a MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 6d223b8ffcd1593d032b71875def2daa71c53111 ] Similar to commit 98a9e2ac3755 ("MIPS: Loongson64: DTS: Fix msi node for ls7a"). Fix follow warnings: arch/mips/boot/dts/loongson/loongson64c_4core_ls7a.dts:28.31-36.4: Warning (interrupt_provider): /bus@10000000/msi-controller@2ff00000: Missing '#interrupt-cells' in interrupt provider arch/mips/boot/dts/loongson/loongson64c_4core_ls7a.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider' Fixes: 24af105962c8 ("MIPS: Loongson64: DeviceTree for LS7A PCH") Tested-by: WangYuli Signed-off-by: WangYuli Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Thomas Bogendoerfer Signed-off-by: Sasha Levin --- arch/mips/boot/dts/loongson/loongson64c_4core_ls7a.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/boot/dts/loongson/loongson64c_4core_ls7a.dts b/arch/mips/boot/dts/loongson/loongson64c_4core_ls7a.dts index c7ea4f1c0bb2..6c277ab83d4b 100644 --- a/arch/mips/boot/dts/loongson/loongson64c_4core_ls7a.dts +++ b/arch/mips/boot/dts/loongson/loongson64c_4core_ls7a.dts @@ -29,6 +29,7 @@ compatible = "loongson,pch-msi-1.0"; reg = <0 0x2ff00000 0 0x8>; interrupt-controller; + #interrupt-cells = <1>; msi-controller; loongson,msi-base-vec = <64>; loongson,msi-num-vecs = <64>; From 32b3f3382d6c2276a4135b1dc7388ffdd350eaf8 Mon Sep 17 00:00:00 2001 From: Alexander Sverdlin Date: Mon, 31 Mar 2025 18:36:40 +0200 Subject: [PATCH 285/971] counter: interrupt-cnt: Protect enable/disable OPs with mutex [ Upstream commit 7351312632e831e51383f48957d47712fae791ef ] Enable/disable seems to be racy on SMP, consider the following scenario: CPU0 CPU1 interrupt_cnt_enable_write(true) { if (priv->enabled == enable) return 0; if (enable) { priv->enabled = true; interrupt_cnt_enable_write(false) { if (priv->enabled == enable) return 0; if (enable) { priv->enabled = true; enable_irq(priv->irq); } else { disable_irq(priv->irq) priv->enabled = false; } enable_irq(priv->irq); } else { disable_irq(priv->irq); priv->enabled = false; } The above would result in priv->enabled == false, but IRQ left enabled. Protect both write (above race) and read (to propagate the value on SMP) callbacks with a mutex. Signed-off-by: Alexander Sverdlin Fixes: a55ebd47f21f ("counter: add IRQ or GPIO based counter") Acked-by: Oleksij Rempel Link: https://lore.kernel.org/r/20250331163642.2382651-1-alexander.sverdlin@siemens.com Signed-off-by: William Breathitt Gray Signed-off-by: Sasha Levin --- drivers/counter/interrupt-cnt.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/counter/interrupt-cnt.c b/drivers/counter/interrupt-cnt.c index 229473855c5b..bc762ba87a19 100644 --- a/drivers/counter/interrupt-cnt.c +++ b/drivers/counter/interrupt-cnt.c @@ -3,12 +3,14 @@ * Copyright (c) 2021 Pengutronix, Oleksij Rempel */ +#include #include #include #include #include #include #include +#include #include #include @@ -19,6 +21,7 @@ struct interrupt_cnt_priv { struct gpio_desc *gpio; int irq; bool enabled; + struct mutex lock; struct counter_signal signals; struct counter_synapse synapses; struct counter_count cnts; @@ -41,6 +44,8 @@ static int interrupt_cnt_enable_read(struct counter_device *counter, { struct interrupt_cnt_priv *priv = counter_priv(counter); + guard(mutex)(&priv->lock); + *enable = priv->enabled; return 0; @@ -51,6 +56,8 @@ static int interrupt_cnt_enable_write(struct counter_device *counter, { struct interrupt_cnt_priv *priv = counter_priv(counter); + guard(mutex)(&priv->lock); + if (priv->enabled == enable) return 0; @@ -227,6 +234,8 @@ static int interrupt_cnt_probe(struct platform_device *pdev) if (ret) return ret; + mutex_init(&priv->lock); + ret = devm_counter_add(dev, counter); if (ret < 0) return dev_err_probe(dev, ret, "Failed to add counter\n"); From e69e2cfd8b38d9463a250e153ef4963a604d61e9 Mon Sep 17 00:00:00 2001 From: Qasim Ijaz Date: Tue, 22 Apr 2025 16:37:37 +0100 Subject: [PATCH 286/971] fpga: fix potential null pointer deref in fpga_mgr_test_img_load_sgt() [ Upstream commit 6ebf1982038af12f3588417e4fd0417d2551da28 ] fpga_mgr_test_img_load_sgt() allocates memory for sgt using kunit_kzalloc() however it does not check if the allocation failed. It then passes sgt to sg_alloc_table(), which passes it to __sg_alloc_table(). This function calls memset() on sgt in an attempt to zero it out. If the allocation fails then sgt will be NULL and the memset will trigger a NULL pointer dereference. Fix this by checking the allocation with KUNIT_ASSERT_NOT_ERR_OR_NULL(). Reviewed-by: Marco Pagani Fixes: ccbc1c302115 ("fpga: add an initial KUnit suite for the FPGA Manager") Signed-off-by: Qasim Ijaz Acked-by: Xu Yilun Link: https://lore.kernel.org/r/20250422153737.5264-1-qasdev00@gmail.com Signed-off-by: Xu Yilun Signed-off-by: Sasha Levin --- drivers/fpga/tests/fpga-mgr-test.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/fpga/tests/fpga-mgr-test.c b/drivers/fpga/tests/fpga-mgr-test.c index 6acec55b60ce..bfe25c0c0c1c 100644 --- a/drivers/fpga/tests/fpga-mgr-test.c +++ b/drivers/fpga/tests/fpga-mgr-test.c @@ -253,6 +253,7 @@ static void fpga_mgr_test_img_load_sgt(struct kunit *test) img_buf = init_test_buffer(test, IMAGE_SIZE); sgt = kunit_kzalloc(test, sizeof(*sgt), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sgt); ret = sg_alloc_table(sgt, 1, GFP_KERNEL); KUNIT_ASSERT_EQ(test, ret, 0); sg_init_one(sgt->sgl, img_buf, IMAGE_SIZE); From b3b4efa2e623aecaebd7c9b9e4171f5c659e9724 Mon Sep 17 00:00:00 2001 From: Yeoreum Yun Date: Wed, 14 May 2025 17:19:51 +0100 Subject: [PATCH 287/971] coresight: prevent deactivate active config while enabling the config [ Upstream commit 408c97c4a5e0b634dcd15bf8b8808b382e888164 ] While enable active config via cscfg_csdev_enable_active_config(), active config could be deactivated via configfs' sysfs interface. This could make UAF issue in below scenario: CPU0 CPU1 (sysfs enable) load module cscfg_load_config_sets() activate config. // sysfs (sys_active_cnt == 1) ... cscfg_csdev_enable_active_config() lock(csdev->cscfg_csdev_lock) // here load config activate by CPU1 unlock(csdev->cscfg_csdev_lock) deactivate config // sysfs (sys_activec_cnt == 0) cscfg_unload_config_sets() unload module // access to config_desc which freed // while unloading module. cscfg_csdev_enable_config To address this, use cscfg_config_desc's active_cnt as a reference count which will be holded when - activate the config. - enable the activated config. and put the module reference when config_active_cnt == 0. Fixes: f8cce2ff3c04 ("coresight: syscfg: Add API to activate and enable configurations") Suggested-by: Suzuki K Poulose Signed-off-by: Yeoreum Yun Reviewed-by: Leo Yan Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20250514161951.3427590-4-yeoreum.yun@arm.com Signed-off-by: Sasha Levin --- .../hwtracing/coresight/coresight-config.h | 2 +- .../hwtracing/coresight/coresight-syscfg.c | 49 +++++++++++++------ 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h index 6ba013975741..84cdde6f0e4d 100644 --- a/drivers/hwtracing/coresight/coresight-config.h +++ b/drivers/hwtracing/coresight/coresight-config.h @@ -228,7 +228,7 @@ struct cscfg_feature_csdev { * @feats_csdev:references to the device features to enable. */ struct cscfg_config_csdev { - const struct cscfg_config_desc *config_desc; + struct cscfg_config_desc *config_desc; struct coresight_device *csdev; bool enabled; struct list_head node; diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c index 11138a9762b0..30a561d87481 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -867,6 +867,25 @@ unlock_exit: } EXPORT_SYMBOL_GPL(cscfg_csdev_reset_feats); +static bool cscfg_config_desc_get(struct cscfg_config_desc *config_desc) +{ + if (!atomic_fetch_inc(&config_desc->active_cnt)) { + /* must ensure that config cannot be unloaded in use */ + if (unlikely(cscfg_owner_get(config_desc->load_owner))) { + atomic_dec(&config_desc->active_cnt); + return false; + } + } + + return true; +} + +static void cscfg_config_desc_put(struct cscfg_config_desc *config_desc) +{ + if (!atomic_dec_return(&config_desc->active_cnt)) + cscfg_owner_put(config_desc->load_owner); +} + /* * This activate configuration for either perf or sysfs. Perf can have multiple * active configs, selected per event, sysfs is limited to one. @@ -890,22 +909,17 @@ static int _cscfg_activate_config(unsigned long cfg_hash) if (config_desc->available == false) return -EBUSY; - /* must ensure that config cannot be unloaded in use */ - err = cscfg_owner_get(config_desc->load_owner); - if (err) + if (!cscfg_config_desc_get(config_desc)) { + err = -EINVAL; break; + } + /* * increment the global active count - control changes to * active configurations */ atomic_inc(&cscfg_mgr->sys_active_cnt); - /* - * mark the descriptor as active so enable config on a - * device instance will use it - */ - atomic_inc(&config_desc->active_cnt); - err = 0; dev_dbg(cscfg_device(), "Activate config %s.\n", config_desc->name); break; @@ -920,9 +934,8 @@ static void _cscfg_deactivate_config(unsigned long cfg_hash) list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) { if ((unsigned long)config_desc->event_ea->var == cfg_hash) { - atomic_dec(&config_desc->active_cnt); atomic_dec(&cscfg_mgr->sys_active_cnt); - cscfg_owner_put(config_desc->load_owner); + cscfg_config_desc_put(config_desc); dev_dbg(cscfg_device(), "Deactivate config %s.\n", config_desc->name); break; } @@ -1047,7 +1060,7 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev, unsigned long cfg_hash, int preset) { struct cscfg_config_csdev *config_csdev_active = NULL, *config_csdev_item; - const struct cscfg_config_desc *config_desc; + struct cscfg_config_desc *config_desc; unsigned long flags; int err = 0; @@ -1062,8 +1075,8 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev, spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags); list_for_each_entry(config_csdev_item, &csdev->config_csdev_list, node) { config_desc = config_csdev_item->config_desc; - if ((atomic_read(&config_desc->active_cnt)) && - ((unsigned long)config_desc->event_ea->var == cfg_hash)) { + if (((unsigned long)config_desc->event_ea->var == cfg_hash) && + cscfg_config_desc_get(config_desc)) { config_csdev_active = config_csdev_item; csdev->active_cscfg_ctxt = (void *)config_csdev_active; break; @@ -1097,7 +1110,11 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev, err = -EBUSY; spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags); } + + if (err) + cscfg_config_desc_put(config_desc); } + return err; } EXPORT_SYMBOL_GPL(cscfg_csdev_enable_active_config); @@ -1136,8 +1153,10 @@ void cscfg_csdev_disable_active_config(struct coresight_device *csdev) spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags); /* true if there was an enabled active config */ - if (config_csdev) + if (config_csdev) { cscfg_csdev_disable_config(config_csdev); + cscfg_config_desc_put(config_csdev->config_desc); + } } EXPORT_SYMBOL_GPL(cscfg_csdev_disable_active_config); From 7a8e87568575c53255a02674a75f2c8f91393579 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Thu, 15 May 2025 11:30:52 -0400 Subject: [PATCH 288/971] vt: remove VT_RESIZE and VT_RESIZEX from vt_compat_ioctl() [ Upstream commit c4c7ead7b86c1e7f11c64915b7e5bb6d2e242691 ] They are listed amon those cmd values that "treat 'arg' as an integer" which is wrong. They should instead fall into the default case. Probably nobody ever relied on that code since 2009 but still. Fixes: e92166517e3c ("tty: handle VT specific compat ioctls in vt driver") Signed-off-by: Nicolas Pitre Reviewed-by: Jiri Slaby Link: https://lore.kernel.org/r/pr214s15-36r8-6732-2pop-159nq85o48r7@syhkavp.arg Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/tty/vt/vt_ioctl.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 8c685b501404..5b21b60547da 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c @@ -1105,8 +1105,6 @@ long vt_compat_ioctl(struct tty_struct *tty, case VT_WAITACTIVE: case VT_RELDISP: case VT_DISALLOCATE: - case VT_RESIZE: - case VT_RESIZEX: return vt_ioctl(tty, cmd, arg); /* From 6ee70ca1fded5604a96ae764be6ff7968dc70f2f Mon Sep 17 00:00:00 2001 From: Quentin Schulz Date: Tue, 27 May 2025 13:56:23 +0200 Subject: [PATCH 289/971] net: stmmac: platform: guarantee uniqueness of bus_id [ Upstream commit eb7fd7aa35bfcc1e1fda4ecc42ccfcb526cdc780 ] bus_id is currently derived from the ethernetX alias. If one is missing for the device, 0 is used. If ethernet0 points to another stmmac device or if there are 2+ stmmac devices without an ethernet alias, then bus_id will be 0 for all of those. This is an issue because the bus_id is used to generate the mdio bus id (new_bus->id in drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c stmmac_mdio_register) and this needs to be unique. This allows to avoid needing to define ethernet aliases for devices with multiple stmmac controllers (such as the Rockchip RK3588) for multiple stmmac devices to probe properly. Obviously, the bus_id isn't guaranteed to be stable across reboots if no alias is set for the device but that is easily fixed by simply adding an alias if this is desired. Fixes: 25c83b5c2e82 ("dt:net:stmmac: Add support to dwmac version 3.610 and 3.710") Signed-off-by: Quentin Schulz Reviewed-by: Maxime Chevallier Link: https://patch.msgid.link/20250527-stmmac-mdio-bus_id-v2-1-a5ca78454e3c@cherry.de Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 4d570efd9d4b..6c684f6ee84b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -419,6 +419,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) struct device_node *np = pdev->dev.of_node; struct plat_stmmacenet_data *plat; struct stmmac_dma_cfg *dma_cfg; + static int bus_id = -ENODEV; int phy_mode; void *ret; int rc; @@ -454,8 +455,14 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) of_property_read_u32(np, "max-speed", &plat->max_speed); plat->bus_id = of_alias_get_id(np, "ethernet"); - if (plat->bus_id < 0) - plat->bus_id = 0; + if (plat->bus_id < 0) { + if (bus_id < 0) + bus_id = of_alias_get_highest_id("ethernet"); + /* No ethernet alias found, init at -1 so first bus_id is 0 */ + if (bus_id < 0) + bus_id = -1; + plat->bus_id = ++bus_id; + } /* Default to phy auto-detection */ plat->phy_addr = -1; From 633a80216a44222b7bd0d02bd94f818fd71405e3 Mon Sep 17 00:00:00 2001 From: Alok Tiwari Date: Tue, 27 May 2025 06:08:16 -0700 Subject: [PATCH 290/971] gve: Fix RX_BUFFERS_POSTED stat to report per-queue fill_cnt [ Upstream commit f41a94aade120dc60322865f363cee7865f2df01 ] Previously, the RX_BUFFERS_POSTED stat incorrectly reported the fill_cnt from RX queue 0 for all queues, resulting in inaccurate per-queue statistics. Fix this by correctly indexing priv->rx[idx].fill_cnt for each RX queue. Fixes: 24aeb56f2d38 ("gve: Add Gvnic stats AQ command and ethtool show/set-priv-flags.") Signed-off-by: Alok Tiwari Link: https://patch.msgid.link/20250527130830.1812903-1-alok.a.tiwari@oracle.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- drivers/net/ethernet/google/gve/gve_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c index 8cd098fe88ef..b4745d94cbbd 100644 --- a/drivers/net/ethernet/google/gve/gve_main.c +++ b/drivers/net/ethernet/google/gve/gve_main.c @@ -1992,7 +1992,7 @@ void gve_handle_report_stats(struct gve_priv *priv) }; stats[stats_idx++] = (struct stats) { .stat_name = cpu_to_be32(RX_BUFFERS_POSTED), - .value = cpu_to_be64(priv->rx[0].fill_cnt), + .value = cpu_to_be64(priv->rx[idx].fill_cnt), .queue_id = cpu_to_be32(idx), }; } From acab7ca5ff19889b80a8ee7dec220ee1a96dede9 Mon Sep 17 00:00:00 2001 From: Charalampos Mitrodimas Date: Tue, 27 May 2025 16:35:44 +0000 Subject: [PATCH 291/971] net: tipc: fix refcount warning in tipc_aead_encrypt [ Upstream commit f29ccaa07cf3d35990f4d25028cc55470d29372b ] syzbot reported a refcount warning [1] caused by calling get_net() on a network namespace that is being destroyed (refcount=0). This happens when a TIPC discovery timer fires during network namespace cleanup. The recently added get_net() call in commit e279024617134 ("net/tipc: fix slab-use-after-free Read in tipc_aead_encrypt_done") attempts to hold a reference to the network namespace. However, if the namespace is already being destroyed, its refcount might be zero, leading to the use-after-free warning. Replace get_net() with maybe_get_net(), which safely checks if the refcount is non-zero before incrementing it. If the namespace is being destroyed, return -ENODEV early, after releasing the bearer reference. [1]: https://lore.kernel.org/all/68342b55.a70a0220.253bc2.0091.GAE@google.com/T/#m12019cf9ae77e1954f666914640efa36d52704a2 Reported-by: syzbot+f0c4a4aba757549ae26c@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/68342b55.a70a0220.253bc2.0091.GAE@google.com/T/#m12019cf9ae77e1954f666914640efa36d52704a2 Fixes: e27902461713 ("net/tipc: fix slab-use-after-free Read in tipc_aead_encrypt_done") Signed-off-by: Charalampos Mitrodimas Reviewed-by: Tung Nguyen Link: https://patch.msgid.link/20250527-net-tipc-warning-v2-1-df3dc398a047@posteo.net Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- net/tipc/crypto.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c index 8584893b4785..79f91b6ca8c8 100644 --- a/net/tipc/crypto.c +++ b/net/tipc/crypto.c @@ -818,7 +818,11 @@ static int tipc_aead_encrypt(struct tipc_aead *aead, struct sk_buff *skb, } /* Get net to avoid freed tipc_crypto when delete namespace */ - get_net(aead->crypto->net); + if (!maybe_get_net(aead->crypto->net)) { + tipc_bearer_put(b); + rc = -ENODEV; + goto exit; + } /* Now, do encrypt */ rc = crypto_aead_encrypt(req); From 2e3d96ad954914a93764ba3eca3973bb62f5ca78 Mon Sep 17 00:00:00 2001 From: Yanqing Wang Date: Wed, 28 May 2025 15:53:51 +0800 Subject: [PATCH 292/971] driver: net: ethernet: mtk_star_emac: fix suspend/resume issue [ Upstream commit ba99c627aac85bc746fb4a6e2d79edb3ad100326 ] Identify the cause of the suspend/resume hang: netif_carrier_off() is called during link state changes and becomes stuck while executing linkwatch_work(). To resolve this issue, call netif_device_detach() during the Ethernet suspend process to temporarily detach the network device from the kernel and prevent the suspend/resume hang. Fixes: 8c7bd5a454ff ("net: ethernet: mtk-star-emac: new driver") Signed-off-by: Yanqing Wang Signed-off-by: Macpaul Lin Signed-off-by: Biao Huang Link: https://patch.msgid.link/20250528075351.593068-1-macpaul.lin@mediatek.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- drivers/net/ethernet/mediatek/mtk_star_emac.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c index c2ab87828d85..5eb7a97e7eb1 100644 --- a/drivers/net/ethernet/mediatek/mtk_star_emac.c +++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c @@ -1468,6 +1468,8 @@ static __maybe_unused int mtk_star_suspend(struct device *dev) if (netif_running(ndev)) mtk_star_disable(ndev); + netif_device_detach(ndev); + clk_bulk_disable_unprepare(MTK_STAR_NCLKS, priv->clks); return 0; @@ -1492,6 +1494,8 @@ static __maybe_unused int mtk_star_resume(struct device *dev) clk_bulk_disable_unprepare(MTK_STAR_NCLKS, priv->clks); } + netif_device_attach(ndev); + return ret; } From 1b2e54f447af9d98d3dd76af0304addbc902890f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 28 May 2025 11:11:09 +0300 Subject: [PATCH 293/971] net/mlx4_en: Prevent potential integer overflow calculating Hz [ Upstream commit 54d34165b4f786d7fea8412a18fb4a54c1eab623 ] The "freq" variable is in terms of MHz and "max_val_cycles" is in terms of Hz. The fact that "max_val_cycles" is a u64 suggests that support for high frequency is intended but the "freq_khz * 1000" would overflow the u32 type if we went above 4GHz. Use unsigned long long type for the mutliplication to prevent that. Fixes: 31c128b66e5b ("net/mlx4_en: Choose time-stamping shift value according to HW frequency") Signed-off-by: Dan Carpenter Reviewed-by: Simon Horman Link: https://patch.msgid.link/aDbFHe19juIJKjsb@stanley.mountain Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c index 9e3b76182088..2d5b86207e07 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c @@ -249,7 +249,7 @@ static const struct ptp_clock_info mlx4_en_ptp_clock_info = { static u32 freq_to_shift(u16 freq) { u32 freq_khz = freq * 1000; - u64 max_val_cycles = freq_khz * 1000 * MLX4_EN_WRAP_AROUND_SEC; + u64 max_val_cycles = freq_khz * 1000ULL * MLX4_EN_WRAP_AROUND_SEC; u64 max_val_cycles_rounded = 1ULL << fls64(max_val_cycles - 1); /* calculate max possible multiplier in order to fit in 64bit */ u64 max_mul = div64_u64(ULLONG_MAX, max_val_cycles_rounded); From d888397397017d33b0c130d6a2b379e7cc8940bf Mon Sep 17 00:00:00 2001 From: Horatiu Vultur Date: Wed, 28 May 2025 11:36:19 +0200 Subject: [PATCH 294/971] net: lan966x: Make sure to insert the vlan tags also in host mode [ Upstream commit 27eab4c644236a9324084a70fe79e511cbd07393 ] When running these commands on DUT (and similar at the other end) ip link set dev eth0 up ip link add link eth0 name eth0.10 type vlan id 10 ip addr add 10.0.0.1/24 dev eth0.10 ip link set dev eth0.10 up ping 10.0.0.2 The ping will fail. The reason why is failing is because, the network interfaces for lan966x have a flag saying that the HW can insert the vlan tags into the frames(NETIF_F_HW_VLAN_CTAG_TX). Meaning that the frames that are transmitted don't have the vlan tag inside the skb data, but they have it inside the skb. We already get that vlan tag and put it in the IFH but the problem is that we don't configure the HW to rewrite the frame when the interface is in host mode. The fix consists in actually configuring the HW to insert the vlan tag if it is different than 0. Reviewed-by: Maxime Chevallier Fixes: 6d2c186afa5d ("net: lan966x: Add vlan support.") Signed-off-by: Horatiu Vultur Link: https://patch.msgid.link/20250528093619.3738998-1-horatiu.vultur@microchip.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- .../ethernet/microchip/lan966x/lan966x_main.c | 1 + .../ethernet/microchip/lan966x/lan966x_main.h | 1 + .../microchip/lan966x/lan966x_switchdev.c | 1 + .../ethernet/microchip/lan966x/lan966x_vlan.c | 21 +++++++++++++++++++ 4 files changed, 24 insertions(+) diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c index 05f6c9227583..b424e75fd40c 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c @@ -881,6 +881,7 @@ static int lan966x_probe_port(struct lan966x *lan966x, u32 p, lan966x_vlan_port_set_vlan_aware(port, 0); lan966x_vlan_port_set_vid(port, HOST_PVID, false, false); lan966x_vlan_port_apply(port); + lan966x_vlan_port_rew_host(port); return 0; } diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h index b65d58a1552b..5a16d76eb000 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h @@ -549,6 +549,7 @@ void lan966x_vlan_port_apply(struct lan966x_port *port); bool lan966x_vlan_cpu_member_cpu_vlan_mask(struct lan966x *lan966x, u16 vid); void lan966x_vlan_port_set_vlan_aware(struct lan966x_port *port, bool vlan_aware); +void lan966x_vlan_port_rew_host(struct lan966x_port *port); int lan966x_vlan_port_set_vid(struct lan966x_port *port, u16 vid, bool pvid, diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c b/drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c index 1c88120eb291..bcb4db76b75c 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c @@ -297,6 +297,7 @@ static void lan966x_port_bridge_leave(struct lan966x_port *port, lan966x_vlan_port_set_vlan_aware(port, false); lan966x_vlan_port_set_vid(port, HOST_PVID, false, false); lan966x_vlan_port_apply(port); + lan966x_vlan_port_rew_host(port); } int lan966x_port_changeupper(struct net_device *dev, diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c b/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c index 3c44660128da..ffb245fb7d67 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c @@ -149,6 +149,27 @@ void lan966x_vlan_port_set_vlan_aware(struct lan966x_port *port, port->vlan_aware = vlan_aware; } +/* When the interface is in host mode, the interface should not be vlan aware + * but it should insert all the tags that it gets from the network stack. + * The tags are not in the data of the frame but actually in the skb and the ifh + * is configured already to get this tag. So what we need to do is to update the + * rewriter to insert the vlan tag for all frames which have a vlan tag + * different than 0. + */ +void lan966x_vlan_port_rew_host(struct lan966x_port *port) +{ + struct lan966x *lan966x = port->lan966x; + u32 val; + + /* Tag all frames except when VID=0*/ + val = REW_TAG_CFG_TAG_CFG_SET(2); + + /* Update only some bits in the register */ + lan_rmw(val, + REW_TAG_CFG_TAG_CFG, + lan966x, REW_TAG_CFG(port->chip_port)); +} + void lan966x_vlan_port_apply(struct lan966x_port *port) { struct lan966x *lan966x = port->lan966x; From 29abb7fc82443bee273ba4623ce319bf7ba1d43d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Thu, 29 May 2025 15:09:14 +0200 Subject: [PATCH 295/971] spi: bcm63xx-spi: fix shared reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 5ad20e3d8cfe3b2e42bbddc7e0ebaa74479bb589 ] Some bmips SoCs (bcm6362, bcm63268) share the same SPI reset for both SPI and HSSPI controllers, so reset shouldn't be exclusive. Fixes: 38807adeaf1e ("spi: bcm63xx-spi: add reset support") Reported-by: Jonas Gorski Signed-off-by: Álvaro Fernández Rojas Reviewed-by: Florian Fainelli Link: https://patch.msgid.link/20250529130915.2519590-2-noltari@gmail.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-bcm63xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index ef3a7226db12..a95badb7b711 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -523,7 +523,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) return PTR_ERR(clk); } - reset = devm_reset_control_get_optional_exclusive(dev, NULL); + reset = devm_reset_control_get_optional_shared(dev, NULL); if (IS_ERR(reset)) return PTR_ERR(reset); From 59d5f3134b5c265df233b7f385bbe718191411be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Thu, 29 May 2025 15:09:15 +0200 Subject: [PATCH 296/971] spi: bcm63xx-hsspi: fix shared reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 3d6d84c8f2f66d3fd6a43a1e2ce8e6b54c573960 ] Some bmips SoCs (bcm6362, bcm63268) share the same SPI reset for both SPI and HSSPI controllers, so reset shouldn't be exclusive. Fixes: 0eeadddbf09a ("spi: bcm63xx-hsspi: add reset support") Reported-by: Jonas Gorski Signed-off-by: Álvaro Fernández Rojas Reviewed-by: Florian Fainelli Link: https://patch.msgid.link/20250529130915.2519590-3-noltari@gmail.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-bcm63xx-hsspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c index 1ca857c2a4aa..8df12efeea21 100644 --- a/drivers/spi/spi-bcm63xx-hsspi.c +++ b/drivers/spi/spi-bcm63xx-hsspi.c @@ -745,7 +745,7 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev) if (IS_ERR(clk)) return PTR_ERR(clk); - reset = devm_reset_control_get_optional_exclusive(dev, NULL); + reset = devm_reset_control_get_optional_shared(dev, NULL); if (IS_ERR(reset)) return PTR_ERR(reset); From 55dd7225217c1e9cb4d2e2fb8a548cb3b76cef4d Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 28 May 2025 14:53:11 -0400 Subject: [PATCH 297/971] Bluetooth: L2CAP: Fix not responding with L2CAP_CR_LE_ENCRYPTION [ Upstream commit 03dba9cea72f977e873e4e60e220fa596959dd8f ] Depending on the security set the response to L2CAP_LE_CONN_REQ shall be just L2CAP_CR_LE_ENCRYPTION if only encryption when BT_SECURITY_MEDIUM is selected since that means security mode 2 which doesn't require authentication which is something that is covered in the qualification test L2CAP/LE/CFC/BV-25-C. Link: https://github.com/bluez/bluez/issues/1270 Fixes: 27e2d4c8d28b ("Bluetooth: Add basic LE L2CAP connect request receiving support") Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- net/bluetooth/l2cap_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 1c54e812ef1f..2744ad11687c 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -4833,7 +4833,8 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn, if (!smp_sufficient_security(conn->hcon, pchan->sec_level, SMP_ALLOW_STK)) { - result = L2CAP_CR_LE_AUTHENTICATION; + result = pchan->sec_level == BT_SECURITY_MEDIUM ? + L2CAP_CR_LE_ENCRYPTION : L2CAP_CR_LE_AUTHENTICATION; chan = NULL; goto response_unlock; } From 1d3c5d0dec6797eca3a861dab0816fa9505d9c3e Mon Sep 17 00:00:00 2001 From: Michal Kubiak Date: Tue, 13 May 2025 12:55:27 +0200 Subject: [PATCH 298/971] ice: fix Tx scheduler error handling in XDP callback [ Upstream commit 0153f36041b8e52019ebfa8629c13bf8f9b0a951 ] When the XDP program is loaded, the XDP callback adds new Tx queues. This means that the callback must update the Tx scheduler with the new queue number. In the event of a Tx scheduler failure, the XDP callback should also fail and roll back any changes previously made for XDP preparation. The previous implementation had a bug that not all changes made by the XDP callback were rolled back. This caused the crash with the following call trace: [ +9.549584] ice 0000:ca:00.0: Failed VSI LAN queue config for XDP, error: -5 [ +0.382335] Oops: general protection fault, probably for non-canonical address 0x50a2250a90495525: 0000 [#1] SMP NOPTI [ +0.010710] CPU: 103 UID: 0 PID: 0 Comm: swapper/103 Not tainted 6.14.0-net-next-mar-31+ #14 PREEMPT(voluntary) [ +0.010175] Hardware name: Intel Corporation M50CYP2SBSTD/M50CYP2SBSTD, BIOS SE5C620.86B.01.01.0005.2202160810 02/16/2022 [ +0.010946] RIP: 0010:__ice_update_sample+0x39/0xe0 [ice] [...] [ +0.002715] Call Trace: [ +0.002452] [ +0.002021] ? __die_body.cold+0x19/0x29 [ +0.003922] ? die_addr+0x3c/0x60 [ +0.003319] ? exc_general_protection+0x17c/0x400 [ +0.004707] ? asm_exc_general_protection+0x26/0x30 [ +0.004879] ? __ice_update_sample+0x39/0xe0 [ice] [ +0.004835] ice_napi_poll+0x665/0x680 [ice] [ +0.004320] __napi_poll+0x28/0x190 [ +0.003500] net_rx_action+0x198/0x360 [ +0.003752] ? update_rq_clock+0x39/0x220 [ +0.004013] handle_softirqs+0xf1/0x340 [ +0.003840] ? sched_clock_cpu+0xf/0x1f0 [ +0.003925] __irq_exit_rcu+0xc2/0xe0 [ +0.003665] common_interrupt+0x85/0xa0 [ +0.003839] [ +0.002098] [ +0.002106] asm_common_interrupt+0x26/0x40 [ +0.004184] RIP: 0010:cpuidle_enter_state+0xd3/0x690 Fix this by performing the missing unmapping of XDP queues from q_vectors and setting the XDP rings pointer back to NULL after all those queues are released. Also, add an immediate exit from the XDP callback in case of ring preparation failure. Fixes: efc2214b6047 ("ice: Add support for XDP") Reviewed-by: Dawid Osuchowski Reviewed-by: Przemek Kitszel Reviewed-by: Jacob Keller Signed-off-by: Michal Kubiak Reviewed-by: Aleksandr Loktionov Reviewed-by: Simon Horman Tested-by: Jesse Brandeburg Tested-by: Saritha Sanigani (A Contingent Worker at Intel) Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/ice/ice_main.c | 47 ++++++++++++++++------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index 0ae7bdfff83f..e1a68fb5e9ff 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -2650,6 +2650,27 @@ static void ice_vsi_assign_bpf_prog(struct ice_vsi *vsi, struct bpf_prog *prog) bpf_prog_put(old_prog); } +/** + * ice_unmap_xdp_rings - Unmap XDP rings from interrupt vectors + * @vsi: the VSI with XDP rings being unmapped + */ +static void ice_unmap_xdp_rings(struct ice_vsi *vsi) +{ + int v_idx; + + ice_for_each_q_vector(vsi, v_idx) { + struct ice_q_vector *q_vector = vsi->q_vectors[v_idx]; + struct ice_tx_ring *ring; + + ice_for_each_tx_ring(ring, q_vector->tx) + if (!ring->tx_buf || !ice_ring_is_xdp(ring)) + break; + + /* restore the value of last node prior to XDP setup */ + q_vector->tx.tx_ring = ring; + } +} + /** * ice_prepare_xdp_rings - Allocate, configure and setup Tx rings for XDP * @vsi: VSI to bring up Tx rings used by XDP @@ -2749,7 +2770,7 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog, if (status) { dev_err(dev, "Failed VSI LAN queue config for XDP, error: %d\n", status); - goto clear_xdp_rings; + goto unmap_xdp_rings; } /* assign the prog only when it's not already present on VSI; @@ -2765,6 +2786,8 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog, ice_vsi_assign_bpf_prog(vsi, prog); return 0; +unmap_xdp_rings: + ice_unmap_xdp_rings(vsi); clear_xdp_rings: ice_for_each_xdp_txq(vsi, i) if (vsi->xdp_rings[i]) { @@ -2781,6 +2804,8 @@ err_map_xdp: mutex_unlock(&pf->avail_q_mutex); devm_kfree(dev, vsi->xdp_rings); + vsi->xdp_rings = NULL; + return -ENOMEM; } @@ -2796,7 +2821,7 @@ int ice_destroy_xdp_rings(struct ice_vsi *vsi, enum ice_xdp_cfg cfg_type) { u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 }; struct ice_pf *pf = vsi->back; - int i, v_idx; + int i; /* q_vectors are freed in reset path so there's no point in detaching * rings @@ -2804,17 +2829,7 @@ int ice_destroy_xdp_rings(struct ice_vsi *vsi, enum ice_xdp_cfg cfg_type) if (cfg_type == ICE_XDP_CFG_PART) goto free_qmap; - ice_for_each_q_vector(vsi, v_idx) { - struct ice_q_vector *q_vector = vsi->q_vectors[v_idx]; - struct ice_tx_ring *ring; - - ice_for_each_tx_ring(ring, q_vector->tx) - if (!ring->tx_buf || !ice_ring_is_xdp(ring)) - break; - - /* restore the value of last node prior to XDP setup */ - q_vector->tx.tx_ring = ring; - } + ice_unmap_xdp_rings(vsi); free_qmap: mutex_lock(&pf->avail_q_mutex); @@ -2956,11 +2971,14 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog, xdp_ring_err = ice_vsi_determine_xdp_res(vsi); if (xdp_ring_err) { NL_SET_ERR_MSG_MOD(extack, "Not enough Tx resources for XDP"); + goto resume_if; } else { xdp_ring_err = ice_prepare_xdp_rings(vsi, prog, ICE_XDP_CFG_FULL); - if (xdp_ring_err) + if (xdp_ring_err) { NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Tx resources failed"); + goto resume_if; + } } xdp_features_set_redirect_target(vsi->netdev, true); /* reallocate Rx queues that are used for zero-copy */ @@ -2978,6 +2996,7 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog, NL_SET_ERR_MSG_MOD(extack, "Freeing XDP Rx resources failed"); } +resume_if: if (if_running) ret = ice_up(vsi); From d78e538b65e42771efee1d7d91cb9bf7333cb518 Mon Sep 17 00:00:00 2001 From: Michal Kubiak Date: Tue, 13 May 2025 12:55:28 +0200 Subject: [PATCH 299/971] ice: create new Tx scheduler nodes for new queues only [ Upstream commit 6fa2942578472c9cab13a8fc1dae0d830193e0a1 ] The current implementation of the Tx scheduler tree attempts to create nodes for all Tx queues, ignoring the fact that some queues may already exist in the tree. For example, if the VSI already has 128 Tx queues and the user requests for 16 new queues, the Tx scheduler will compute the tree for 272 queues (128 existing queues + 144 new queues), instead of 144 queues (128 existing queues and 16 new queues). Fix that by modifying the node count calculation algorithm to skip the queues that already exist in the tree. Fixes: 5513b920a4f7 ("ice: Update Tx scheduler tree for VSI multi-Tx queue support") Reviewed-by: Dawid Osuchowski Reviewed-by: Przemek Kitszel Reviewed-by: Jacob Keller Signed-off-by: Michal Kubiak Reviewed-by: Simon Horman Tested-by: Jesse Brandeburg Tested-by: Saritha Sanigani (A Contingent Worker at Intel) Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/ice/ice_sched.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_sched.c b/drivers/net/ethernet/intel/ice/ice_sched.c index 908bcd073803..e40a5f9a893d 100644 --- a/drivers/net/ethernet/intel/ice/ice_sched.c +++ b/drivers/net/ethernet/intel/ice/ice_sched.c @@ -1614,16 +1614,16 @@ ice_sched_get_agg_node(struct ice_port_info *pi, struct ice_sched_node *tc_node, /** * ice_sched_calc_vsi_child_nodes - calculate number of VSI child nodes * @hw: pointer to the HW struct - * @num_qs: number of queues + * @num_new_qs: number of new queues that will be added to the tree * @num_nodes: num nodes array * * This function calculates the number of VSI child nodes based on the * number of queues. */ static void -ice_sched_calc_vsi_child_nodes(struct ice_hw *hw, u16 num_qs, u16 *num_nodes) +ice_sched_calc_vsi_child_nodes(struct ice_hw *hw, u16 num_new_qs, u16 *num_nodes) { - u16 num = num_qs; + u16 num = num_new_qs; u8 i, qgl, vsil; qgl = ice_sched_get_qgrp_layer(hw); @@ -1873,8 +1873,9 @@ ice_sched_update_vsi_child_nodes(struct ice_port_info *pi, u16 vsi_handle, return status; } - if (new_numqs) - ice_sched_calc_vsi_child_nodes(hw, new_numqs, new_num_nodes); + ice_sched_calc_vsi_child_nodes(hw, new_numqs - prev_numqs, + new_num_nodes); + /* Keep the max number of queue configuration all the time. Update the * tree only if number of queues > previous number of queues. This may * leave some extra nodes in the tree if number of queues < previous From 18e648163016730e8535a7e0f4b36b48ed102edf Mon Sep 17 00:00:00 2001 From: Michal Kubiak Date: Tue, 13 May 2025 12:55:29 +0200 Subject: [PATCH 300/971] ice: fix rebuilding the Tx scheduler tree for large queue counts [ Upstream commit 73145e6d81070d34a21431c9e0d7aaf2f29ca048 ] The current implementation of the Tx scheduler allows the tree to be rebuilt as the user adds more Tx queues to the VSI. In such a case, additional child nodes are added to the tree to support the new number of queues. Unfortunately, this algorithm does not take into account that the limit of the VSI support node may be exceeded, so an additional node in the VSI layer may be required to handle all the requested queues. Such a scenario occurs when adding XDP Tx queues on machines with many CPUs. Although the driver still respects the queue limit returned by the FW, the Tx scheduler was unable to add those queues to its tree and returned one of the errors below. Such a scenario occurs when adding XDP Tx queues on machines with many CPUs (e.g. at least 321 CPUs, if there is already 128 Tx/Rx queue pairs). Although the driver still respects the queue limit returned by the FW, the Tx scheduler was unable to add those queues to its tree and returned the following errors: Failed VSI LAN queue config for XDP, error: -5 or: Failed to set LAN Tx queue context, error: -22 Fix this problem by extending the tree rebuild algorithm to check if the current VSI node can support the requested number of queues. If it cannot, create as many additional VSI support nodes as necessary to handle all the required Tx queues. Symmetrically, adjust the VSI node removal algorithm to remove all nodes associated with the given VSI. Also, make the search for the next free VSI node more restrictive. That is, add queue group nodes only to the VSI support nodes that have a matching VSI handle. Finally, fix the comment describing the tree update algorithm to better reflect the current scenario. Fixes: b0153fdd7e8a ("ice: update VSI config dynamically") Reviewed-by: Dawid Osuchowski Reviewed-by: Przemek Kitszel Signed-off-by: Michal Kubiak Reviewed-by: Simon Horman Tested-by: Jesse Brandeburg Tested-by: Saritha Sanigani (A Contingent Worker at Intel) Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/ice/ice_sched.c | 170 +++++++++++++++++---- 1 file changed, 142 insertions(+), 28 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_sched.c b/drivers/net/ethernet/intel/ice/ice_sched.c index e40a5f9a893d..c2de166f0551 100644 --- a/drivers/net/ethernet/intel/ice/ice_sched.c +++ b/drivers/net/ethernet/intel/ice/ice_sched.c @@ -84,6 +84,27 @@ ice_sched_find_node_by_teid(struct ice_sched_node *start_node, u32 teid) return NULL; } +/** + * ice_sched_find_next_vsi_node - find the next node for a given VSI + * @vsi_node: VSI support node to start search with + * + * Return: Next VSI support node, or NULL. + * + * The function returns a pointer to the next node from the VSI layer + * assigned to the given VSI, or NULL if there is no such a node. + */ +static struct ice_sched_node * +ice_sched_find_next_vsi_node(struct ice_sched_node *vsi_node) +{ + unsigned int vsi_handle = vsi_node->vsi_handle; + + while ((vsi_node = vsi_node->sibling) != NULL) + if (vsi_node->vsi_handle == vsi_handle) + break; + + return vsi_node; +} + /** * ice_aqc_send_sched_elem_cmd - send scheduling elements cmd * @hw: pointer to the HW struct @@ -1096,8 +1117,10 @@ ice_sched_add_nodes_to_layer(struct ice_port_info *pi, if (parent->num_children < max_child_nodes) { new_num_nodes = max_child_nodes - parent->num_children; } else { - /* This parent is full, try the next sibling */ - parent = parent->sibling; + /* This parent is full, + * try the next available sibling. + */ + parent = ice_sched_find_next_vsi_node(parent); /* Don't modify the first node TEID memory if the * first node was added already in the above call. * Instead send some temp memory for all other @@ -1538,12 +1561,23 @@ ice_sched_get_free_qparent(struct ice_port_info *pi, u16 vsi_handle, u8 tc, /* get the first queue group node from VSI sub-tree */ qgrp_node = ice_sched_get_first_node(pi, vsi_node, qgrp_layer); while (qgrp_node) { + struct ice_sched_node *next_vsi_node; + /* make sure the qgroup node is part of the VSI subtree */ if (ice_sched_find_node_in_subtree(pi->hw, vsi_node, qgrp_node)) if (qgrp_node->num_children < max_children && qgrp_node->owner == owner) break; qgrp_node = qgrp_node->sibling; + if (qgrp_node) + continue; + + next_vsi_node = ice_sched_find_next_vsi_node(vsi_node); + if (!next_vsi_node) + break; + + vsi_node = next_vsi_node; + qgrp_node = ice_sched_get_first_node(pi, vsi_node, qgrp_layer); } /* Select the best queue group */ @@ -1789,7 +1823,11 @@ ice_sched_add_vsi_support_nodes(struct ice_port_info *pi, u16 vsi_handle, if (!parent) return -EIO; - if (i == vsil) + /* Do not modify the VSI handle for already existing VSI nodes, + * (if no new VSI node was added to the tree). + * Assign the VSI handle only to newly added VSI nodes. + */ + if (i == vsil && num_added) parent->vsi_handle = vsi_handle; } @@ -1822,6 +1860,41 @@ ice_sched_add_vsi_to_topo(struct ice_port_info *pi, u16 vsi_handle, u8 tc) num_nodes); } +/** + * ice_sched_recalc_vsi_support_nodes - recalculate VSI support nodes count + * @hw: pointer to the HW struct + * @vsi_node: pointer to the leftmost VSI node that needs to be extended + * @new_numqs: new number of queues that has to be handled by the VSI + * @new_num_nodes: pointer to nodes count table to modify the VSI layer entry + * + * This function recalculates the number of supported nodes that need to + * be added after adding more Tx queues for a given VSI. + * The number of new VSI support nodes that shall be added will be saved + * to the @new_num_nodes table for the VSI layer. + */ +static void +ice_sched_recalc_vsi_support_nodes(struct ice_hw *hw, + struct ice_sched_node *vsi_node, + unsigned int new_numqs, u16 *new_num_nodes) +{ + u32 vsi_nodes_cnt = 1; + u32 max_queue_cnt = 1; + u32 qgl, vsil; + + qgl = ice_sched_get_qgrp_layer(hw); + vsil = ice_sched_get_vsi_layer(hw); + + for (u32 i = vsil; i <= qgl; i++) + max_queue_cnt *= hw->max_children[i]; + + while ((vsi_node = ice_sched_find_next_vsi_node(vsi_node)) != NULL) + vsi_nodes_cnt++; + + if (new_numqs > (max_queue_cnt * vsi_nodes_cnt)) + new_num_nodes[vsil] = DIV_ROUND_UP(new_numqs, max_queue_cnt) - + vsi_nodes_cnt; +} + /** * ice_sched_update_vsi_child_nodes - update VSI child nodes * @pi: port information structure @@ -1873,16 +1946,25 @@ ice_sched_update_vsi_child_nodes(struct ice_port_info *pi, u16 vsi_handle, return status; } + ice_sched_recalc_vsi_support_nodes(hw, vsi_node, + new_numqs, new_num_nodes); ice_sched_calc_vsi_child_nodes(hw, new_numqs - prev_numqs, new_num_nodes); - /* Keep the max number of queue configuration all the time. Update the - * tree only if number of queues > previous number of queues. This may + /* Never decrease the number of queues in the tree. Update the tree + * only if number of queues > previous number of queues. This may * leave some extra nodes in the tree if number of queues < previous * number but that wouldn't harm anything. Removing those extra nodes * may complicate the code if those nodes are part of SRL or * individually rate limited. + * Also, add the required VSI support nodes if the existing ones cannot + * handle the requested new number of queues. */ + status = ice_sched_add_vsi_support_nodes(pi, vsi_handle, tc_node, + new_num_nodes); + if (status) + return status; + status = ice_sched_add_vsi_child_nodes(pi, vsi_handle, tc_node, new_num_nodes, owner); if (status) @@ -2023,6 +2105,58 @@ static bool ice_sched_is_leaf_node_present(struct ice_sched_node *node) return (node->info.data.elem_type == ICE_AQC_ELEM_TYPE_LEAF); } +/** + * ice_sched_rm_vsi_subtree - remove all nodes assigned to a given VSI + * @pi: port information structure + * @vsi_node: pointer to the leftmost node of the VSI to be removed + * @owner: LAN or RDMA + * @tc: TC number + * + * Return: Zero in case of success, or -EBUSY if the VSI has leaf nodes in TC. + * + * This function removes all the VSI support nodes associated with a given VSI + * and its LAN or RDMA children nodes from the scheduler tree. + */ +static int +ice_sched_rm_vsi_subtree(struct ice_port_info *pi, + struct ice_sched_node *vsi_node, u8 owner, u8 tc) +{ + u16 vsi_handle = vsi_node->vsi_handle; + bool all_vsi_nodes_removed = true; + int j = 0; + + while (vsi_node) { + struct ice_sched_node *next_vsi_node; + + if (ice_sched_is_leaf_node_present(vsi_node)) { + ice_debug(pi->hw, ICE_DBG_SCHED, "VSI has leaf nodes in TC %d\n", tc); + return -EBUSY; + } + while (j < vsi_node->num_children) { + if (vsi_node->children[j]->owner == owner) + ice_free_sched_node(pi, vsi_node->children[j]); + else + j++; + } + + next_vsi_node = ice_sched_find_next_vsi_node(vsi_node); + + /* remove the VSI if it has no children */ + if (!vsi_node->num_children) + ice_free_sched_node(pi, vsi_node); + else + all_vsi_nodes_removed = false; + + vsi_node = next_vsi_node; + } + + /* clean up aggregator related VSI info if any */ + if (all_vsi_nodes_removed) + ice_sched_rm_agg_vsi_info(pi, vsi_handle); + + return 0; +} + /** * ice_sched_rm_vsi_cfg - remove the VSI and its children nodes * @pi: port information structure @@ -2049,7 +2183,6 @@ ice_sched_rm_vsi_cfg(struct ice_port_info *pi, u16 vsi_handle, u8 owner) ice_for_each_traffic_class(i) { struct ice_sched_node *vsi_node, *tc_node; - u8 j = 0; tc_node = ice_sched_get_tc_node(pi, i); if (!tc_node) @@ -2059,31 +2192,12 @@ ice_sched_rm_vsi_cfg(struct ice_port_info *pi, u16 vsi_handle, u8 owner) if (!vsi_node) continue; - if (ice_sched_is_leaf_node_present(vsi_node)) { - ice_debug(pi->hw, ICE_DBG_SCHED, "VSI has leaf nodes in TC %d\n", i); - status = -EBUSY; + status = ice_sched_rm_vsi_subtree(pi, vsi_node, owner, i); + if (status) goto exit_sched_rm_vsi_cfg; - } - while (j < vsi_node->num_children) { - if (vsi_node->children[j]->owner == owner) { - ice_free_sched_node(pi, vsi_node->children[j]); - /* reset the counter again since the num - * children will be updated after node removal - */ - j = 0; - } else { - j++; - } - } - /* remove the VSI if it has no children */ - if (!vsi_node->num_children) { - ice_free_sched_node(pi, vsi_node); - vsi_ctx->sched.vsi_node[i] = NULL; + vsi_ctx->sched.vsi_node[i] = NULL; - /* clean up aggregator related VSI info if any */ - ice_sched_rm_agg_vsi_info(pi, vsi_handle); - } if (owner == ICE_SCHED_NODE_OWNER_LAN) vsi_ctx->sched.max_lanq[i] = 0; else From 2e02edb66427e3b8752e1f3dd3cfc1bef3f2357b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Thu, 29 May 2025 14:44:06 +0200 Subject: [PATCH 301/971] net: dsa: tag_brcm: legacy: fix pskb_may_pull length MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit efdddc4484859082da6c7877ed144c8121c8ea55 ] BRCM_LEG_PORT_ID was incorrectly used for pskb_may_pull length. The correct check is BRCM_LEG_TAG_LEN + VLAN_HLEN, or 10 bytes. Fixes: 964dbf186eaa ("net: dsa: tag_brcm: add support for legacy tags") Signed-off-by: Álvaro Fernández Rojas Reviewed-by: Florian Fainelli Link: https://patch.msgid.link/20250529124406.2513779-1-noltari@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/dsa/tag_brcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c index cacdafb41200..146c1dbd15a9 100644 --- a/net/dsa/tag_brcm.c +++ b/net/dsa/tag_brcm.c @@ -257,7 +257,7 @@ static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb, int source_port; u8 *brcm_tag; - if (unlikely(!pskb_may_pull(skb, BRCM_LEG_PORT_ID))) + if (unlikely(!pskb_may_pull(skb, BRCM_LEG_TAG_LEN + VLAN_HLEN))) return NULL; brcm_tag = dsa_etype_header_pos_rx(skb); From b263088ee8ab14563817a8be3519af8e25225793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= Date: Thu, 29 May 2025 11:07:23 +0200 Subject: [PATCH 302/971] net: stmmac: make sure that ptp_rate is not 0 before configuring timestamping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 030ce919e114a111e83b7976ecb3597cefd33f26 ] The stmmac platform drivers that do not open-code the clk_ptp_rate value after having retrieved the default one from the device-tree can end up with 0 in clk_ptp_rate (as clk_get_rate can return 0). It will eventually propagate up to PTP initialization when bringing up the interface, leading to a divide by 0: Division by zero in kernel. CPU: 1 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.12.30-00001-g48313bd5768a #22 Hardware name: STM32 (Device Tree Support) Call trace: unwind_backtrace from show_stack+0x18/0x1c show_stack from dump_stack_lvl+0x6c/0x8c dump_stack_lvl from Ldiv0_64+0x8/0x18 Ldiv0_64 from stmmac_init_tstamp_counter+0x190/0x1a4 stmmac_init_tstamp_counter from stmmac_hw_setup+0xc1c/0x111c stmmac_hw_setup from __stmmac_open+0x18c/0x434 __stmmac_open from stmmac_open+0x3c/0xbc stmmac_open from __dev_open+0xf4/0x1ac __dev_open from __dev_change_flags+0x1cc/0x224 __dev_change_flags from dev_change_flags+0x24/0x60 dev_change_flags from ip_auto_config+0x2e8/0x11a0 ip_auto_config from do_one_initcall+0x84/0x33c do_one_initcall from kernel_init_freeable+0x1b8/0x214 kernel_init_freeable from kernel_init+0x24/0x140 kernel_init from ret_from_fork+0x14/0x28 Exception stack(0xe0815fb0 to 0xe0815ff8) Prevent this division by 0 by adding an explicit check and error log about the actual issue. While at it, remove the same check from stmmac_ptp_register, which then becomes duplicate Fixes: 19d857c9038e ("stmmac: Fix calculations for ptp counters when clock input = 50Mhz.") Signed-off-by: Alexis Lothoré Reviewed-by: Yanteng Si Reviewed-by: Maxime Chevallier Link: https://patch.msgid.link/20250529-stmmac_tstamp_div-v4-1-d73340a794d5@bootlin.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++++ drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index d3d5c01f6dcb..615d25a0e46b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -842,6 +842,11 @@ int stmmac_init_tstamp_counter(struct stmmac_priv *priv, u32 systime_flags) if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) return -EOPNOTSUPP; + if (!priv->plat->clk_ptp_rate) { + netdev_err(priv->dev, "Invalid PTP clock rate"); + return -EINVAL; + } + stmmac_config_hw_tstamping(priv, priv->ptpaddr, systime_flags); priv->systime_flags = systime_flags; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c index a04bb2e42c4e..80ecbd73333d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c @@ -295,7 +295,7 @@ void stmmac_ptp_register(struct stmmac_priv *priv) /* Calculate the clock domain crossing (CDC) error if necessary */ priv->plat->cdc_error_adj = 0; - if (priv->plat->has_gmac4 && priv->plat->clk_ptp_rate) + if (priv->plat->has_gmac4) priv->plat->cdc_error_adj = (2 * NSEC_PER_SEC) / priv->plat->clk_ptp_rate; stmmac_ptp_clock_ops.n_per_out = priv->dma_cap.pps_out_num; From 85eef1748c024da1a191aed56b30a3a65958c50c Mon Sep 17 00:00:00 2001 From: Shiming Cheng Date: Fri, 30 May 2025 09:26:08 +0800 Subject: [PATCH 303/971] net: fix udp gso skb_segment after pull from frag_list [ Upstream commit 3382a1ed7f778db841063f5d7e317ac55f9e7f72 ] Commit a1e40ac5b5e9 ("net: gso: fix udp gso fraglist segmentation after pull from frag_list") detected invalid geometry in frag_list skbs and redirects them from skb_segment_list to more robust skb_segment. But some packets with modified geometry can also hit bugs in that code. We don't know how many such cases exist. Addressing each one by one also requires touching the complex skb_segment code, which risks introducing bugs for other types of skbs. Instead, linearize all these packets that fail the basic invariants on gso fraglist skbs. That is more robust. If only part of the fraglist payload is pulled into head_skb, it will always cause exception when splitting skbs by skb_segment. For detailed call stack information, see below. Valid SKB_GSO_FRAGLIST skbs - consist of two or more segments - the head_skb holds the protocol headers plus first gso_size - one or more frag_list skbs hold exactly one segment - all but the last must be gso_size Optional datapath hooks such as NAT and BPF (bpf_skb_pull_data) can modify fraglist skbs, breaking these invariants. In extreme cases they pull one part of data into skb linear. For UDP, this causes three payloads with lengths of (11,11,10) bytes were pulled tail to become (12,10,10) bytes. The skbs no longer meets the above SKB_GSO_FRAGLIST conditions because payload was pulled into head_skb, it needs to be linearized before pass to regular skb_segment. skb_segment+0xcd0/0xd14 __udp_gso_segment+0x334/0x5f4 udp4_ufo_fragment+0x118/0x15c inet_gso_segment+0x164/0x338 skb_mac_gso_segment+0xc4/0x13c __skb_gso_segment+0xc4/0x124 validate_xmit_skb+0x9c/0x2c0 validate_xmit_skb_list+0x4c/0x80 sch_direct_xmit+0x70/0x404 __dev_queue_xmit+0x64c/0xe5c neigh_resolve_output+0x178/0x1c4 ip_finish_output2+0x37c/0x47c __ip_finish_output+0x194/0x240 ip_finish_output+0x20/0xf4 ip_output+0x100/0x1a0 NF_HOOK+0xc4/0x16c ip_forward+0x314/0x32c ip_rcv+0x90/0x118 __netif_receive_skb+0x74/0x124 process_backlog+0xe8/0x1a4 __napi_poll+0x5c/0x1f8 net_rx_action+0x154/0x314 handle_softirqs+0x154/0x4b8 [118.376811] [C201134] rxq0_pus: [name:bug&]kernel BUG at net/core/skbuff.c:4278! [118.376829] [C201134] rxq0_pus: [name:traps&]Internal error: Oops - BUG: 00000000f2000800 [#1] PREEMPT SMP [118.470774] [C201134] rxq0_pus: [name:mrdump&]Kernel Offset: 0x178cc00000 from 0xffffffc008000000 [118.470810] [C201134] rxq0_pus: [name:mrdump&]PHYS_OFFSET: 0x40000000 [118.470827] [C201134] rxq0_pus: [name:mrdump&]pstate: 60400005 (nZCv daif +PAN -UAO) [118.470848] [C201134] rxq0_pus: [name:mrdump&]pc : [0xffffffd79598aefc] skb_segment+0xcd0/0xd14 [118.470900] [C201134] rxq0_pus: [name:mrdump&]lr : [0xffffffd79598a5e8] skb_segment+0x3bc/0xd14 [118.470928] [C201134] rxq0_pus: [name:mrdump&]sp : ffffffc008013770 Fixes: a1e40ac5b5e9 ("gso: fix udp gso fraglist segmentation after pull from frag_list") Signed-off-by: Shiming Cheng Reviewed-by: Willem de Bruijn Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/ipv4/udp_offload.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index 132cfc3b2c84..3870b59f5400 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c @@ -332,6 +332,7 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb, bool copy_dtor; __sum16 check; __be16 newlen; + int ret = 0; mss = skb_shinfo(gso_skb)->gso_size; if (gso_skb->len <= sizeof(*uh) + mss) @@ -354,6 +355,10 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb, if (skb_pagelen(gso_skb) - sizeof(*uh) == skb_shinfo(gso_skb)->gso_size) return __udp_gso_segment_list(gso_skb, features, is_ipv6); + ret = __skb_linearize(gso_skb); + if (ret) + return ERR_PTR(ret); + /* Setup csum, as fraglist skips this in udp4_gro_receive. */ gso_skb->csum_start = skb_transport_header(gso_skb) - gso_skb->head; gso_skb->csum_offset = offsetof(struct udphdr, check); From cc89f457d9133a558d4e8ef26dc20843c2d12073 Mon Sep 17 00:00:00 2001 From: Jinjian Song Date: Fri, 30 May 2025 11:16:48 +0800 Subject: [PATCH 304/971] net: wwan: t7xx: Fix napi rx poll issue [ Upstream commit 905fe0845bb27e4eed2ca27ea06e6c4847f1b2b1 ] When driver handles the napi rx polling requests, the netdev might have been released by the dellink logic triggered by the disconnect operation on user plane. However, in the logic of processing skb in polling, an invalid netdev is still being used, which causes a panic. BUG: kernel NULL pointer dereference, address: 00000000000000f1 Oops: 0000 [#1] PREEMPT SMP NOPTI RIP: 0010:dev_gro_receive+0x3a/0x620 [...] Call Trace: ? __die_body+0x68/0xb0 ? page_fault_oops+0x379/0x3e0 ? exc_page_fault+0x4f/0xa0 ? asm_exc_page_fault+0x22/0x30 ? __pfx_t7xx_ccmni_recv_skb+0x10/0x10 [mtk_t7xx (HASH:1400 7)] ? dev_gro_receive+0x3a/0x620 napi_gro_receive+0xad/0x170 t7xx_ccmni_recv_skb+0x48/0x70 [mtk_t7xx (HASH:1400 7)] t7xx_dpmaif_napi_rx_poll+0x590/0x800 [mtk_t7xx (HASH:1400 7)] net_rx_action+0x103/0x470 irq_exit_rcu+0x13a/0x310 sysvec_apic_timer_interrupt+0x56/0x90 Fixes: 5545b7b9f294 ("net: wwan: t7xx: Add NAPI support") Signed-off-by: Jinjian Song Link: https://patch.msgid.link/20250530031648.5592-1-jinjian.song@fibocom.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- drivers/net/wwan/t7xx/t7xx_netdev.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/wwan/t7xx/t7xx_netdev.c b/drivers/net/wwan/t7xx/t7xx_netdev.c index 3ef4a8a4f8fd..d879424093b7 100644 --- a/drivers/net/wwan/t7xx/t7xx_netdev.c +++ b/drivers/net/wwan/t7xx/t7xx_netdev.c @@ -296,7 +296,7 @@ static int t7xx_ccmni_wwan_newlink(void *ctxt, struct net_device *dev, u32 if_id ccmni->ctlb = ctlb; ccmni->dev = dev; atomic_set(&ccmni->usage, 0); - ctlb->ccmni_inst[if_id] = ccmni; + WRITE_ONCE(ctlb->ccmni_inst[if_id], ccmni); ret = register_netdevice(dev); if (ret) @@ -318,6 +318,7 @@ static void t7xx_ccmni_wwan_dellink(void *ctxt, struct net_device *dev, struct l if (WARN_ON(ctlb->ccmni_inst[if_id] != ccmni)) return; + WRITE_ONCE(ctlb->ccmni_inst[if_id], NULL); unregister_netdevice(dev); } @@ -413,7 +414,7 @@ static void t7xx_ccmni_recv_skb(struct t7xx_ccmni_ctrl *ccmni_ctlb, struct sk_bu skb_cb = T7XX_SKB_CB(skb); netif_id = skb_cb->netif_idx; - ccmni = ccmni_ctlb->ccmni_inst[netif_id]; + ccmni = READ_ONCE(ccmni_ctlb->ccmni_inst[netif_id]); if (!ccmni) { dev_kfree_skb(skb); return; @@ -435,7 +436,7 @@ static void t7xx_ccmni_recv_skb(struct t7xx_ccmni_ctrl *ccmni_ctlb, struct sk_bu static void t7xx_ccmni_queue_tx_irq_notify(struct t7xx_ccmni_ctrl *ctlb, int qno) { - struct t7xx_ccmni *ccmni = ctlb->ccmni_inst[0]; + struct t7xx_ccmni *ccmni = READ_ONCE(ctlb->ccmni_inst[0]); struct netdev_queue *net_queue; if (netif_running(ccmni->dev) && atomic_read(&ccmni->usage) > 0) { @@ -447,7 +448,7 @@ static void t7xx_ccmni_queue_tx_irq_notify(struct t7xx_ccmni_ctrl *ctlb, int qno static void t7xx_ccmni_queue_tx_full_notify(struct t7xx_ccmni_ctrl *ctlb, int qno) { - struct t7xx_ccmni *ccmni = ctlb->ccmni_inst[0]; + struct t7xx_ccmni *ccmni = READ_ONCE(ctlb->ccmni_inst[0]); struct netdev_queue *net_queue; if (atomic_read(&ccmni->usage) > 0) { @@ -465,7 +466,7 @@ static void t7xx_ccmni_queue_state_notify(struct t7xx_pci_dev *t7xx_dev, if (ctlb->md_sta != MD_STATE_READY) return; - if (!ctlb->ccmni_inst[0]) { + if (!READ_ONCE(ctlb->ccmni_inst[0])) { dev_warn(&t7xx_dev->pdev->dev, "No netdev registered yet\n"); return; } From c07c61ef703a0fb9bb15b769d5915f058ca9eb31 Mon Sep 17 00:00:00 2001 From: Ronak Doshi Date: Fri, 30 May 2025 15:27:00 +0000 Subject: [PATCH 305/971] vmxnet3: correctly report gso type for UDP tunnels [ Upstream commit 982d30c30eaa2ec723df42e3bf526c014c1dbb88 ] Commit 3d010c8031e3 ("udp: do not accept non-tunnel GSO skbs landing in a tunnel") added checks in linux stack to not accept non-tunnel GRO packets landing in a tunnel. This exposed an issue in vmxnet3 which was not correctly reporting GRO packets for tunnel packets. This patch fixes this issue by setting correct GSO type for the tunnel packets. Currently, vmxnet3 does not support reporting inner fields for LRO tunnel packets. The issue is not seen for egress drivers that do not use skb inner fields. The workaround is to enable tnl-segmentation offload on the egress interfaces if the driver supports it. This problem pre-exists this patch fix and can be addressed as a separate future patch. Fixes: dacce2be3312 ("vmxnet3: add geneve and vxlan tunnel offload support") Signed-off-by: Ronak Doshi Acked-by: Guolin Yang Link: https://patch.msgid.link/20250530152701.70354-1-ronak.doshi@broadcom.com [pabeni@redhat.com: dropped the changelog] Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- drivers/net/vmxnet3/vmxnet3_drv.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index beebe09eb88f..afd78324f3aa 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -1499,6 +1499,30 @@ vmxnet3_get_hdr_len(struct vmxnet3_adapter *adapter, struct sk_buff *skb, return (hlen + (hdr.tcp->doff << 2)); } +static void +vmxnet3_lro_tunnel(struct sk_buff *skb, __be16 ip_proto) +{ + struct udphdr *uh = NULL; + + if (ip_proto == htons(ETH_P_IP)) { + struct iphdr *iph = (struct iphdr *)skb->data; + + if (iph->protocol == IPPROTO_UDP) + uh = (struct udphdr *)(iph + 1); + } else { + struct ipv6hdr *iph = (struct ipv6hdr *)skb->data; + + if (iph->nexthdr == IPPROTO_UDP) + uh = (struct udphdr *)(iph + 1); + } + if (uh) { + if (uh->check) + skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL_CSUM; + else + skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL; + } +} + static int vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, struct vmxnet3_adapter *adapter, int quota) @@ -1803,6 +1827,8 @@ sop_done: if (segCnt != 0 && mss != 0) { skb_shinfo(skb)->gso_type = rcd->v4 ? SKB_GSO_TCPV4 : SKB_GSO_TCPV6; + if (encap_lro) + vmxnet3_lro_tunnel(skb, skb->protocol); skb_shinfo(skb)->gso_size = mss; skb_shinfo(skb)->gso_segs = segCnt; } else if ((segCnt != 0 || skb->len > mtu) && !encap_lro) { From 9c49728b61e1ee3baec93df2ff5827ad9d6bd860 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 3 Jun 2025 18:19:27 +0200 Subject: [PATCH 306/971] PM: sleep: Fix power.is_suspended cleanup for direct-complete devices [ Upstream commit d46c4c839c20a599a0eb8d73708ce401f9c7d06d ] Commit 03f1444016b7 ("PM: sleep: Fix handling devices with direct_complete set on errors") caused power.is_suspended to be set for devices with power.direct_complete set, but it forgot to ensure the clearing of that flag for them in device_resume(), so power.is_suspended is still set for them during the next system suspend-resume cycle. If that cycle is aborted in dpm_suspend(), the subsequent invocation of dpm_resume() will trigger a device_resume() call for every device and because power.is_suspended is set for the devices in question, they will not be skipped by device_resume() as expected which causes scary error messages to be logged (as appropriate). To address this issue, move the clearing of power.is_suspended in device_resume() immediately after the power.is_suspended check so it will be always cleared for all devices processed by that function. Fixes: 03f1444016b7 ("PM: sleep: Fix handling devices with direct_complete set on errors") Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4280 Reported-and-tested-by: Chris Bainbridge Signed-off-by: Rafael J. Wysocki Reviewed-by: Mario Limonciello Link: https://patch.msgid.link/4990586.GXAFRqVoOG@rjwysocki.net Signed-off-by: Sasha Levin --- drivers/base/power/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 343d3c966e7a..baa31194cf20 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -897,6 +897,8 @@ static void __device_resume(struct device *dev, pm_message_t state, bool async) if (!dev->power.is_suspended) goto Complete; + dev->power.is_suspended = false; + if (dev->power.direct_complete) { /* Match the pm_runtime_disable() in __device_suspend(). */ pm_runtime_enable(dev); @@ -952,7 +954,6 @@ static void __device_resume(struct device *dev, pm_message_t state, bool async) End: error = dpm_run_callback(callback, dev, state, info); - dev->power.is_suspended = false; device_unlock(dev); dpm_watchdog_clear(&wd); From 7f6265fce3bd424ded666481b37f106d7915fb6b Mon Sep 17 00:00:00 2001 From: Alok Tiwari Date: Mon, 2 Jun 2025 03:34:29 -0700 Subject: [PATCH 307/971] gve: add missing NULL check for gve_alloc_pending_packet() in TX DQO [ Upstream commit 12c331b29c7397ac3b03584e12902990693bc248 ] gve_alloc_pending_packet() can return NULL, but gve_tx_add_skb_dqo() did not check for this case before dereferencing the returned pointer. Add a missing NULL check to prevent a potential NULL pointer dereference when allocation fails. This improves robustness in low-memory scenarios. Fixes: a57e5de476be ("gve: DQO: Add TX path") Signed-off-by: Alok Tiwari Reviewed-by: Mina Almasry Reviewed-by: Simon Horman Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/google/gve/gve_tx_dqo.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/google/gve/gve_tx_dqo.c b/drivers/net/ethernet/google/gve/gve_tx_dqo.c index 89b62b8d16e1..857749fef37c 100644 --- a/drivers/net/ethernet/google/gve/gve_tx_dqo.c +++ b/drivers/net/ethernet/google/gve/gve_tx_dqo.c @@ -716,6 +716,9 @@ static int gve_tx_add_skb_dqo(struct gve_tx_ring *tx, s16 completion_tag; pkt = gve_alloc_pending_packet(tx); + if (!pkt) + return -ENOMEM; + pkt->skb = skb; completion_tag = pkt - tx->dqo.pending_packets; From 39bab2d3517b5b50c609b4f8c66129bf619fffa0 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 23 May 2025 14:20:44 +0200 Subject: [PATCH 308/971] netfilter: nf_set_pipapo_avx2: fix initial map fill [ Upstream commit ea77c397bff8b6d59f6d83dae1425b08f465e8b5 ] If the first field doesn't cover the entire start map, then we must zero out the remainder, else we leak those bits into the next match round map. The early fix was incomplete and did only fix up the generic C implementation. A followup patch adds a test case to nft_concat_range.sh. Fixes: 791a615b7ad2 ("netfilter: nf_set_pipapo: fix initial map fill") Signed-off-by: Florian Westphal Reviewed-by: Stefano Brivio Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- net/netfilter/nft_set_pipapo_avx2.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nft_set_pipapo_avx2.c b/net/netfilter/nft_set_pipapo_avx2.c index c15db28c5ebc..be7c16c79f71 100644 --- a/net/netfilter/nft_set_pipapo_avx2.c +++ b/net/netfilter/nft_set_pipapo_avx2.c @@ -1113,6 +1113,25 @@ bool nft_pipapo_avx2_estimate(const struct nft_set_desc *desc, u32 features, return true; } +/** + * pipapo_resmap_init_avx2() - Initialise result map before first use + * @m: Matching data, including mapping table + * @res_map: Result map + * + * Like pipapo_resmap_init() but do not set start map bits covered by the first field. + */ +static inline void pipapo_resmap_init_avx2(const struct nft_pipapo_match *m, unsigned long *res_map) +{ + const struct nft_pipapo_field *f = m->f; + int i; + + /* Starting map doesn't need to be set to all-ones for this implementation, + * but we do need to zero the remaining bits, if any. + */ + for (i = f->bsize; i < m->bsize_max; i++) + res_map[i] = 0ul; +} + /** * nft_pipapo_avx2_lookup() - Lookup function for AVX2 implementation * @net: Network namespace @@ -1171,7 +1190,7 @@ bool nft_pipapo_avx2_lookup(const struct net *net, const struct nft_set *set, res = scratch->map + (map_index ? m->bsize_max : 0); fill = scratch->map + (map_index ? 0 : m->bsize_max); - /* Starting map doesn't need to be set for this implementation */ + pipapo_resmap_init_avx2(m, res); nft_pipapo_avx2_prepare(); From 1c7a023b0cc97e831ede8f8b68202f6bf6871b54 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 30 May 2025 12:34:02 +0200 Subject: [PATCH 309/971] netfilter: nf_nat: also check reverse tuple to obtain clashing entry [ Upstream commit 50d9ce9679dd50df2dc51ada717fa875bc248fad ] The logic added in the blamed commit was supposed to only omit nat source port allocation if neither the existing nor the new entry are subject to NAT. However, its not enough to lookup the conntrack based on the proposed tuple, we must also check the reverse direction. Otherwise there are esoteric cases where the collision is in the reverse direction because that colliding connection has a port rewrite, but the new entry doesn't. In this case, we only check the new entry and then erronously conclude that no clash exists anymore. The existing (udp) tuple is: a:p -> b:P, with nat translation to s:P, i.e. pure daddr rewrite, reverse tuple in conntrack table is s:P -> a:p. When another UDP packet is sent directly to s, i.e. a:p->s:P, this is correctly detected as a colliding entry: tuple is taken by existing reply tuple in reverse direction. But the colliding conntrack is only searched for with unreversed direction, and we can't find such entry matching a:p->s:P. The incorrect conclusion is that the clashing entry has timed out and that no port address translation is required. Such conntrack will then be discarded at nf_confirm time because the proposed reverse direction clashes with an existing mapping in the conntrack table. Search for the reverse tuple too, this will then check the NAT bits of the colliding entry and triggers port reallocation. Followp patch extends nft_nat.sh selftest to cover this scenario. The IPS_SEQ_ADJUST change is also a bug fix: Instead of checking for SEQ_ADJ this tested for SEEN_REPLY and ASSURED by accident -- _BIT is only for use with the test_bit() API. This bug has little consequence in practice, because the sequence number adjustments are only useful for TCP which doesn't support clash resolution. The existing test case (conntrack_reverse_clash.sh) exercise a race condition path (parallel conntrack creation on different CPUs), so the colliding entries have neither SEEN_REPLY nor ASSURED set. Thanks to Yafang Shao and Shaun Brady for an initial investigation of this bug. Fixes: d8f84a9bc7c4 ("netfilter: nf_nat: don't try nat source port reallocation for reverse dir clash") Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1795 Reported-by: Yafang Shao Reported-by: Shaun Brady Signed-off-by: Florian Westphal Tested-by: Yafang Shao Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- net/netfilter/nf_nat_core.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c index ccca6e3848bc..9df883d79acc 100644 --- a/net/netfilter/nf_nat_core.c +++ b/net/netfilter/nf_nat_core.c @@ -248,7 +248,7 @@ static noinline bool nf_nat_used_tuple_new(const struct nf_conntrack_tuple *tuple, const struct nf_conn *ignored_ct) { - static const unsigned long uses_nat = IPS_NAT_MASK | IPS_SEQ_ADJUST_BIT; + static const unsigned long uses_nat = IPS_NAT_MASK | IPS_SEQ_ADJUST; const struct nf_conntrack_tuple_hash *thash; const struct nf_conntrack_zone *zone; struct nf_conn *ct; @@ -287,8 +287,14 @@ nf_nat_used_tuple_new(const struct nf_conntrack_tuple *tuple, zone = nf_ct_zone(ignored_ct); thash = nf_conntrack_find_get(net, zone, tuple); - if (unlikely(!thash)) /* clashing entry went away */ - return false; + if (unlikely(!thash)) { + struct nf_conntrack_tuple reply; + + nf_ct_invert_tuple(&reply, tuple); + thash = nf_conntrack_find_get(net, zone, &reply); + if (!thash) /* clashing entry went away */ + return false; + } ct = nf_ct_tuplehash_to_ctrack(thash); From 02c03865d26a4ec372b258c4d94de5bd7697ce67 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Mon, 2 Jun 2025 21:39:50 +0200 Subject: [PATCH 310/971] net: dsa: b53: do not enable RGMII delay on bcm63xx [ Upstream commit 4af523551d876ab8b8057d1e5303a860fd736fcb ] bcm63xx's RGMII ports are always in MAC mode, never in PHY mode, so we shouldn't enable any delays and let the PHY handle any delays as necessary. This fixes using RGMII ports with normal PHYs like BCM54612E, which will handle the delay in the PHY. Fixes: ce3bf94871f7 ("net: dsa: b53: add support for BCM63xx RGMIIs") Signed-off-by: Jonas Gorski Reviewed-by: Florian Fainelli Link: https://patch.msgid.link/20250602193953.1010487-3-jonas.gorski@gmail.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- drivers/net/dsa/b53/b53_common.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index d2ff2c2fcbbf..7ca42170d866 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -1237,24 +1237,7 @@ static void b53_adjust_63xx_rgmii(struct dsa_switch *ds, int port, off = B53_RGMII_CTRL_P(port); b53_read8(dev, B53_CTRL_PAGE, off, &rgmii_ctrl); - - switch (interface) { - case PHY_INTERFACE_MODE_RGMII_ID: - rgmii_ctrl |= (RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC); - break; - case PHY_INTERFACE_MODE_RGMII_RXID: - rgmii_ctrl &= ~(RGMII_CTRL_DLL_TXC); - rgmii_ctrl |= RGMII_CTRL_DLL_RXC; - break; - case PHY_INTERFACE_MODE_RGMII_TXID: - rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC); - rgmii_ctrl |= RGMII_CTRL_DLL_TXC; - break; - case PHY_INTERFACE_MODE_RGMII: - default: - rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC); - break; - } + rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC); if (port != dev->imp_port) { if (is63268(dev)) From a21a4937726f7d2623b620b0bd6e797ae0af714c Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Mon, 2 Jun 2025 21:39:52 +0200 Subject: [PATCH 311/971] net: dsa: b53: allow RGMII for bcm63xx RGMII ports [ Upstream commit 5ea0d42c1980e6d10e5cb56a78021db5bfcebaaf ] Add RGMII to supported interfaces for BCM63xx RGMII ports so they can be actually used in RGMII mode. Without this, phylink will fail to configure them: [ 3.580000] b53-switch 10700000.switch GbE3 (uninitialized): validation of rgmii with support 0000000,00000000,00000000,000062ff and advertisement 0000000,00000000,00000000,000062ff failed: -EINVAL [ 3.600000] b53-switch 10700000.switch GbE3 (uninitialized): failed to connect to PHY: -EINVAL [ 3.610000] b53-switch 10700000.switch GbE3 (uninitialized): error -22 setting up PHY for tree 0, switch 0, port 4 Fixes: ce3bf94871f7 ("net: dsa: b53: add support for BCM63xx RGMIIs") Reviewed-by: Florian Fainelli Signed-off-by: Jonas Gorski Link: https://patch.msgid.link/20250602193953.1010487-5-jonas.gorski@gmail.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- drivers/net/dsa/b53/b53_common.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index 7ca42170d866..004d2c988ff0 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -1377,6 +1377,10 @@ static void b53_phylink_get_caps(struct dsa_switch *ds, int port, __set_bit(PHY_INTERFACE_MODE_MII, config->supported_interfaces); __set_bit(PHY_INTERFACE_MODE_REVMII, config->supported_interfaces); + /* BCM63xx RGMII ports support RGMII */ + if (is63xx(dev) && in_range(port, B53_63XX_RGMII0, 4)) + phy_interface_set_rgmii(config->supported_interfaces); + config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | MAC_10 | MAC_100; From 8c9e9cd398777fd60ba202211da1110614cb5bc5 Mon Sep 17 00:00:00 2001 From: Mirco Barone Date: Thu, 5 Jun 2025 14:06:16 +0200 Subject: [PATCH 312/971] wireguard: device: enable threaded NAPI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit db9ae3b6b43c79b1ba87eea849fd65efa05b4b2e ] Enable threaded NAPI by default for WireGuard devices in response to low performance behavior that we observed when multiple tunnels (and thus multiple wg devices) are deployed on a single host. This affects any kind of multi-tunnel deployment, regardless of whether the tunnels share the same endpoints or not (i.e., a VPN concentrator type of gateway would also be affected). The problem is caused by the fact that, in case of a traffic surge that involves multiple tunnels at the same time, the polling of the NAPI instance of all these wg devices tends to converge onto the same core, causing underutilization of the CPU and bottlenecking performance. This happens because NAPI polling is hosted by default in softirq context, but the WireGuard driver only raises this softirq after the rx peer queue has been drained, which doesn't happen during high traffic. In this case, the softirq already active on a core is reused instead of raising a new one. As a result, once two or more tunnel softirqs have been scheduled on the same core, they remain pinned there until the surge ends. In our experiments, this almost always leads to all tunnel NAPIs being handled on a single core shortly after a surge begins, limiting scalability to less than 3× the performance of a single tunnel, despite plenty of unused CPU cores being available. The proposed mitigation is to enable threaded NAPI for all WireGuard devices. This moves the NAPI polling context to a dedicated per-device kernel thread, allowing the scheduler to balance the load across all available cores. On our 32-core gateways, enabling threaded NAPI yields a ~4× performance improvement with 16 tunnels, increasing throughput from ~13 Gbps to ~48 Gbps. Meanwhile, CPU usage on the receiver (which is the bottleneck) jumps from 20% to 100%. We have found no performance regressions in any scenario we tested. Single-tunnel throughput remains unchanged. More details are available in our Netdev paper. Link: https://netdevconf.info/0x18/docs/netdev-0x18-paper23-talk-paper.pdf Signed-off-by: Mirco Barone Fixes: e7096c131e51 ("net: WireGuard secure network tunnel") Signed-off-by: Jason A. Donenfeld Link: https://patch.msgid.link/20250605120616.2808744-1-Jason@zx2c4.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/wireguard/device.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireguard/device.c b/drivers/net/wireguard/device.c index deb9636b0ecf..f98e0f027a05 100644 --- a/drivers/net/wireguard/device.c +++ b/drivers/net/wireguard/device.c @@ -369,6 +369,7 @@ static int wg_newlink(struct net *src_net, struct net_device *dev, if (ret < 0) goto err_free_handshake_queue; + dev_set_threaded(dev, true); ret = register_netdevice(dev); if (ret < 0) goto err_uninit_ratelimiter; From d2507aeea45b3c5aa24d5daae0cf3db76895c0b7 Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Wed, 4 Jun 2025 14:32:52 +0300 Subject: [PATCH 313/971] seg6: Fix validation of nexthop addresses [ Upstream commit 7632fedb266d93ed0ed9f487133e6c6314a9b2d1 ] The kernel currently validates that the length of the provided nexthop address does not exceed the specified length. This can lead to the kernel reading uninitialized memory if user space provided a shorter length than the specified one. Fix by validating that the provided length exactly matches the specified one. Fixes: d1df6fd8a1d2 ("ipv6: sr: define core operations for seg6local lightweight tunnel") Reviewed-by: Petr Machata Signed-off-by: Ido Schimmel Reviewed-by: David Ahern Link: https://patch.msgid.link/20250604113252.371528-1-idosch@nvidia.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/ipv6/seg6_local.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c index c434940131b1..7f295b9c1374 100644 --- a/net/ipv6/seg6_local.c +++ b/net/ipv6/seg6_local.c @@ -1638,10 +1638,8 @@ static const struct nla_policy seg6_local_policy[SEG6_LOCAL_MAX + 1] = { [SEG6_LOCAL_SRH] = { .type = NLA_BINARY }, [SEG6_LOCAL_TABLE] = { .type = NLA_U32 }, [SEG6_LOCAL_VRFTABLE] = { .type = NLA_U32 }, - [SEG6_LOCAL_NH4] = { .type = NLA_BINARY, - .len = sizeof(struct in_addr) }, - [SEG6_LOCAL_NH6] = { .type = NLA_BINARY, - .len = sizeof(struct in6_addr) }, + [SEG6_LOCAL_NH4] = NLA_POLICY_EXACT_LEN(sizeof(struct in_addr)), + [SEG6_LOCAL_NH6] = NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)), [SEG6_LOCAL_IIF] = { .type = NLA_U32 }, [SEG6_LOCAL_OIF] = { .type = NLA_U32 }, [SEG6_LOCAL_BPF] = { .type = NLA_NESTED }, From 0fd2ae401720e238a96d6bbd5262982802e5c864 Mon Sep 17 00:00:00 2001 From: Nitin Rawat Date: Mon, 26 May 2025 21:08:12 +0530 Subject: [PATCH 314/971] scsi: ufs: qcom: Prevent calling phy_exit() before phy_init() [ Upstream commit 7831003165d37ecb7b33843fcee05cada0359a82 ] Prevent calling phy_exit() before phy_init() to avoid abnormal power count and the following warning during boot up. [5.146763] phy phy-1d80000.phy.0: phy_power_on was called before phy_init Fixes: 7bac65687510 ("scsi: ufs: qcom: Power off the PHY if it was already powered on in ufs_qcom_power_up_sequence()") Signed-off-by: Nitin Rawat Link: https://lore.kernel.org/r/20250526153821.7918-2-quic_nitirawa@quicinc.com Reviewed-by: Konrad Dybcio Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/ufs/host/ufs-qcom.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index c6417ef074a4..c94824c999cc 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -453,10 +453,9 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba) dev_warn(hba->dev, "%s: host reset returned %d\n", __func__, ret); - if (phy->power_count) { + if (phy->power_count) phy_power_off(phy); - phy_exit(phy); - } + /* phy initialization - calibrate the phy */ ret = phy_init(phy); From 9836cc310ec19949e37fae90245acb3a0cdfd50a Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Fri, 30 May 2025 16:10:17 +0200 Subject: [PATCH 315/971] ASoC: codecs: hda: Fix RPM usage count underflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit ff0045de4ee0288dec683690f66f2f369b7d3466 ] RPM manipulation in hda_codec_probe_complete()'s error path is superfluous and leads to RPM usage count underflow if the build-controls operation fails. hda_codec_probe_complete() is called in: 1) hda_codec_probe() for all non-HDMI codecs 2) in card->late_probe() for HDMI codecs Error path for hda_codec_probe() takes care of bus' RPM already. For 2) if late_probe() fails, ASoC performs card cleanup what triggers hda_codec_remote() - same treatment is in 1). Fixes: b5df2a7dca1c ("ASoC: codecs: Add HD-Audio codec driver") Reviewed-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250530141025.2942936-2-cezary.rojewski@intel.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/hda.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/hda.c b/sound/soc/codecs/hda.c index d57b043d6bfe..42aca0a63c44 100644 --- a/sound/soc/codecs/hda.c +++ b/sound/soc/codecs/hda.c @@ -150,7 +150,7 @@ int hda_codec_probe_complete(struct hda_codec *codec) ret = snd_hda_codec_build_controls(codec); if (ret < 0) { dev_err(&hdev->dev, "unable to create controls %d\n", ret); - goto out; + return ret; } /* Bus suspended codecs as it does not manage their pm */ @@ -158,7 +158,7 @@ int hda_codec_probe_complete(struct hda_codec *codec) /* rpm was forbidden in snd_hda_codec_device_new() */ snd_hda_codec_set_power_save(codec, 2000); snd_hda_codec_register(codec); -out: + /* Complement pm_runtime_get_sync(bus) in probe */ pm_runtime_mark_last_busy(bus->dev); pm_runtime_put_autosuspend(bus->dev); From ea739a5492bd26c82cc84265f26ddf93640a154e Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Fri, 30 May 2025 16:10:18 +0200 Subject: [PATCH 316/971] ASoC: Intel: avs: Fix deadlock when the failing IPC is SET_D0IX MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 9ad1f3cd0d60444c69948854c7e50d2a61b63755 ] The procedure handling IPC timeouts and EXCEPTION_CAUGHT notification shall cancel any D0IX work before proceeding with DSP recovery. If SET_D0IX called from delayed_work is the failing IPC the procedure will deadlock. Conditionally skip cancelling the work to fix that. Fixes: 335c4cbd201d ("ASoC: Intel: avs: D0ix power state support") Reviewed-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250530141025.2942936-3-cezary.rojewski@intel.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/intel/avs/ipc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/avs/ipc.c b/sound/soc/intel/avs/ipc.c index 74f676fdfba2..afd472906ede 100644 --- a/sound/soc/intel/avs/ipc.c +++ b/sound/soc/intel/avs/ipc.c @@ -169,7 +169,9 @@ static void avs_dsp_exception_caught(struct avs_dev *adev, union avs_notify_msg dev_crit(adev->dev, "communication severed, rebooting dsp..\n"); - cancel_delayed_work_sync(&ipc->d0ix_work); + /* Avoid deadlock as the exception may be the response to SET_D0IX. */ + if (current_work() != &ipc->d0ix_work.work) + cancel_delayed_work_sync(&ipc->d0ix_work); ipc->in_d0ix = false; /* Re-enabled on recovery completion. */ pm_runtime_disable(adev->dev); From cc03c899e6d9812b25c3754c9a95c3830c4aec26 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Fri, 30 May 2025 16:10:23 +0200 Subject: [PATCH 317/971] ASoC: Intel: avs: Verify content returned by parse_int_array() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 93e246b6769bdacb09cfff4ea0f00fe5ab4f0d7a ] The first element of the returned array stores its length. If it is 0, any manipulation beyond the element at index 0 ends with null-ptr-deref. Fixes: 5a565ba23abe ("ASoC: Intel: avs: Probing and firmware tracing over debugfs") Reviewed-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250530141025.2942936-8-cezary.rojewski@intel.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/intel/avs/debugfs.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/avs/debugfs.c b/sound/soc/intel/avs/debugfs.c index bdd388ec01ea..26d0c3a5a954 100644 --- a/sound/soc/intel/avs/debugfs.c +++ b/sound/soc/intel/avs/debugfs.c @@ -371,7 +371,10 @@ static ssize_t trace_control_write(struct file *file, const char __user *from, s return ret; num_elems = *array; - resource_mask = array[1]; + if (!num_elems) { + ret = -EINVAL; + goto free_array; + } /* * Disable if just resource mask is provided - no log priority flags. @@ -379,6 +382,7 @@ static ssize_t trace_control_write(struct file *file, const char __user *from, s * Enable input format: mask, prio1, .., prioN * Where 'N' equals number of bits set in the 'mask'. */ + resource_mask = array[1]; if (num_elems == 1) { ret = disable_logs(adev, resource_mask); } else { From 3aed255ae4a357f89c711a327e858347e0d9cf99 Mon Sep 17 00:00:00 2001 From: Yuuki NAGAO Date: Sat, 31 May 2025 23:13:41 +0900 Subject: [PATCH 318/971] ASoC: ti: omap-hdmi: Re-add dai_link->platform to fix card init [ Upstream commit bae071aa7bcd034054cec91666c80f812adeccd9 ] The removed dai_link->platform component cause a fail which is exposed at runtime. (ex: when a sound tool is used) This patch re-adds the dai_link->platform component to have a full card registered. Before this patch: $ aplay -l **** List of PLAYBACK Hardware Devices **** card 1: HDMI [HDMI], device 0: HDMI snd-soc-dummy-dai-0 [] Subdevices: 1/1 Subdevice #0: subdevice #0 $ speaker-test -D plughw:1,0 -t sine speaker-test 1.2.8 Playback device is plughw:1,0 Stream parameters are 48000Hz, S16_LE, 1 channels Sine wave rate is 440.0000Hz Playback open error: -22,Invalid argument After this patch which restores the platform component: $ aplay -l **** List of PLAYBACK Hardware Devices **** card 0: HDMI [HDMI], device 0: HDMI snd-soc-dummy-dai-0 [HDMI snd-soc-dummy-dai-0] Subdevices: 0/1 Subdevice #0: subdevice #0 -> Resolve the playback error. Fixes: 3b0db249cf8f ("ASoC: ti: remove unnecessary dai_link->platform") Signed-off-by: Yuuki NAGAO Link: https://patch.msgid.link/20250531141341.81164-1-wf.yn386@gmail.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/ti/omap-hdmi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sound/soc/ti/omap-hdmi.c b/sound/soc/ti/omap-hdmi.c index 0a731b21e5a5..72fabf22a02e 100644 --- a/sound/soc/ti/omap-hdmi.c +++ b/sound/soc/ti/omap-hdmi.c @@ -361,17 +361,20 @@ static int omap_hdmi_audio_probe(struct platform_device *pdev) if (!card->dai_link) return -ENOMEM; - compnent = devm_kzalloc(dev, sizeof(*compnent), GFP_KERNEL); + compnent = devm_kzalloc(dev, 2 * sizeof(*compnent), GFP_KERNEL); if (!compnent) return -ENOMEM; - card->dai_link->cpus = compnent; + card->dai_link->cpus = &compnent[0]; card->dai_link->num_cpus = 1; card->dai_link->codecs = &asoc_dummy_dlc; card->dai_link->num_codecs = 1; + card->dai_link->platforms = &compnent[1]; + card->dai_link->num_platforms = 1; card->dai_link->name = card->name; card->dai_link->stream_name = card->name; card->dai_link->cpus->dai_name = dev_name(ad->dssdev); + card->dai_link->platforms->name = dev_name(ad->dssdev); card->num_links = 1; card->dev = dev; From 3b699b94727a43739bd41c414bf100c17dfe3cfb Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 1 Jun 2025 14:02:26 -0400 Subject: [PATCH 319/971] path_overmount(): avoid false negatives [ Upstream commit 5f31c549382bcddbbd754c72c5433b19420d485d ] Holding namespace_sem is enough to make sure that result remains valid. It is *not* enough to avoid false negatives from __lookup_mnt(). Mounts can be unhashed outside of namespace_sem (stuck children getting detached on final mntput() of lazy-umounted mount) and having an unrelated mount removed from the hash chain while we traverse it may end up with false negative from __lookup_mnt(). We need to sample and recheck the seqlock component of mount_lock... Bug predates the introduction of path_overmount() - it had come from the code in finish_automount() that got abstracted into that helper. Reviewed-by: Christian Brauner Fixes: 26df6034fdb2 ("fix automount/automount race properly") Fixes: 6ac392815628 ("fs: allow to mount beneath top mount") Signed-off-by: Al Viro Signed-off-by: Sasha Levin --- fs/namespace.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index ef3b2ae2957e..7942a33451ba 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -3020,18 +3020,25 @@ out: * Check if path is overmounted, i.e., if there's a mount on top of * @path->mnt with @path->dentry as mountpoint. * - * Context: This function expects namespace_lock() to be held. + * Context: namespace_sem must be held at least shared. + * MUST NOT be called under lock_mount_hash() (there one should just + * call __lookup_mnt() and check if it returns NULL). * Return: If path is overmounted true is returned, false if not. */ static inline bool path_overmounted(const struct path *path) { + unsigned seq = read_seqbegin(&mount_lock); + bool no_child; + rcu_read_lock(); - if (unlikely(__lookup_mnt(path->mnt, path->dentry))) { - rcu_read_unlock(); - return true; - } + no_child = !__lookup_mnt(path->mnt, path->dentry); rcu_read_unlock(); - return false; + if (need_seqretry(&mount_lock, seq)) { + read_seqlock_excl(&mount_lock); + no_child = !__lookup_mnt(path->mnt, path->dentry); + read_sequnlock_excl(&mount_lock); + } + return unlikely(!no_child); } /** From 3d1ea8e048acc2a482154c89487f5e803ac189f8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 3 Jun 2025 17:57:27 -0400 Subject: [PATCH 320/971] fix propagation graph breakage by MOVE_MOUNT_SET_GROUP move_mount(2) [ Upstream commit d8cc0362f918d020ca1340d7694f07062dc30f36 ] 9ffb14ef61ba "move_mount: allow to add a mount into an existing group" breaks assertions on ->mnt_share/->mnt_slave. For once, the data structures in question are actually documented. Documentation/filesystem/sharedsubtree.rst: All vfsmounts in a peer group have the same ->mnt_master. If it is non-NULL, they form a contiguous (ordered) segment of slave list. do_set_group() puts a mount into the same place in propagation graph as the old one. As the result, if old mount gets events from somewhere and is not a pure event sink, new one needs to be placed next to the old one in the slave list the old one's on. If it is a pure event sink, we only need to make sure the new one doesn't end up in the middle of some peer group. "move_mount: allow to add a mount into an existing group" ends up putting the new one in the beginning of list; that's definitely not going to be in the middle of anything, so that's fine for case when old is not marked shared. In case when old one _is_ marked shared (i.e. is not a pure event sink), that breaks the assumptions of propagation graph iterators. Put the new mount next to the old one on the list - that does the right thing in "old is marked shared" case and is just as correct as the current behaviour if old is not marked shared (kudos to Pavel for pointing that out - my original suggested fix changed behaviour in the "nor marked" case, which complicated things for no good reason). Reviewed-by: Christian Brauner Fixes: 9ffb14ef61ba ("move_mount: allow to add a mount into an existing group") Signed-off-by: Al Viro Signed-off-by: Sasha Levin --- fs/namespace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/namespace.c b/fs/namespace.c index 7942a33451ba..4d8afd0e1eb8 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2995,7 +2995,7 @@ static int do_set_group(struct path *from_path, struct path *to_path) if (IS_MNT_SLAVE(from)) { struct mount *m = from->mnt_master; - list_add(&to->mnt_slave, &m->mnt_slave_list); + list_add(&to->mnt_slave, &from->mnt_slave); to->mnt_master = m; } From 4f091ad0862b02dc42a19a120b7048de848561f8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 4 Jun 2025 12:27:08 -0400 Subject: [PATCH 321/971] do_change_type(): refuse to operate on unmounted/not ours mounts [ Upstream commit 12f147ddd6de7382dad54812e65f3f08d05809fc ] Ensure that propagation settings can only be changed for mounts located in the caller's mount namespace. This change aligns permission checking with the rest of mount(2). Reviewed-by: Christian Brauner Fixes: 07b20889e305 ("beginning of the shared-subtree proper") Reported-by: "Orlando, Noah" Signed-off-by: Al Viro Signed-off-by: Sasha Levin --- fs/namespace.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/namespace.c b/fs/namespace.c index 4d8afd0e1eb8..eab9185e2285 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2557,6 +2557,10 @@ static int do_change_type(struct path *path, int ms_flags) return -EINVAL; namespace_lock(); + if (!check_mnt(mnt)) { + err = -EINVAL; + goto out_unlock; + } if (type == MS_SHARED) { err = invent_group_ids(mnt, recurse); if (err) From 73b8f31337fbce01dcb195e4f2a47c1181f0549d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 8 May 2025 09:29:23 +0300 Subject: [PATCH 322/971] pmdomain: core: Fix error checking in genpd_dev_pm_attach_by_id() [ Upstream commit 0f5757667ec0aaf2456c3b76fcf0c6c3ea3591fe ] The error checking for of_count_phandle_with_args() does not handle negative error codes correctly. The problem is that "index" is a u32 so in the condition "if (index >= num_domains)" negative error codes stored in "num_domains" are type promoted to very high positive values and "index" is always going to be valid. Test for negative error codes first and then test if "index" is valid. Fixes: 3ccf3f0cd197 ("PM / Domains: Enable genpd_dev_pm_attach_by_id|name() for single PM domain") Signed-off-by: Dan Carpenter Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/aBxPQ8AI8N5v-7rL@stanley.mountain Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin --- drivers/base/power/domain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index d9d339b8b571..d1dae47f3534 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -2856,7 +2856,7 @@ struct device *genpd_dev_pm_attach_by_id(struct device *dev, /* Verify that the index is within a valid range. */ num_domains = of_count_phandle_with_args(dev->of_node, "power-domains", "#power-domain-cells"); - if (index >= num_domains) + if (num_domains < 0 || index >= num_domains) return NULL; /* Allocate and register device on the genpd bus. */ From 91d14d9961b715cea652cd417555cfc2297329a9 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 5 May 2025 15:49:59 -0700 Subject: [PATCH 323/971] Input: synaptics-rmi - fix crash with unsupported versions of F34 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit ca39500f6af9cfe6823dc5aa8fbaed788d6e35b2 ] Sysfs interface for updating firmware for RMI devices is available even when F34 probe fails. The code checks for presence of F34 "container" pointer and then tries to use the function data attached to the sub-device. F34 assigns the function data early, before it knows if probe will succeed, leaving behind a stale pointer. Fix this by expanding checks to not only test for presence of F34 "container" but also check if there is driver data assigned to the sub-device, and call dev_set_drvdata() only after we are certain that probe is successful. This is not a complete fix, since F34 will be freed during firmware update, so there is still a race when fetching and accessing this pointer. This race will be addressed in follow-up changes. Reported-by: Hanno Böck Fixes: 29fd0ec2bdbe ("Input: synaptics-rmi4 - add support for F34 device reflash") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/aBlAl6sGulam-Qcx@google.com Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin --- drivers/input/rmi4/rmi_f34.c | 133 ++++++++++++++++++++--------------- 1 file changed, 75 insertions(+), 58 deletions(-) diff --git a/drivers/input/rmi4/rmi_f34.c b/drivers/input/rmi4/rmi_f34.c index 0d9a5756e3f5..cae1e4166492 100644 --- a/drivers/input/rmi4/rmi_f34.c +++ b/drivers/input/rmi4/rmi_f34.c @@ -4,6 +4,7 @@ * Copyright (C) 2016 Zodiac Inflight Innovations */ +#include "linux/device.h" #include #include #include @@ -298,39 +299,30 @@ out: return ret; } -static int rmi_f34_status(struct rmi_function *fn) -{ - struct f34_data *f34 = dev_get_drvdata(&fn->dev); - - /* - * The status is the percentage complete, or once complete, - * zero for success or a negative return code. - */ - return f34->update_status; -} - static ssize_t rmi_driver_bootloader_id_show(struct device *dev, struct device_attribute *dattr, char *buf) { struct rmi_driver_data *data = dev_get_drvdata(dev); - struct rmi_function *fn = data->f34_container; + struct rmi_function *fn; struct f34_data *f34; - if (fn) { - f34 = dev_get_drvdata(&fn->dev); + fn = data->f34_container; + if (!fn) + return -ENODEV; - if (f34->bl_version == 5) - return sysfs_emit(buf, "%c%c\n", - f34->bootloader_id[0], - f34->bootloader_id[1]); - else - return sysfs_emit(buf, "V%d.%d\n", - f34->bootloader_id[1], - f34->bootloader_id[0]); - } + f34 = dev_get_drvdata(&fn->dev); + if (!f34) + return -ENODEV; - return 0; + if (f34->bl_version == 5) + return sysfs_emit(buf, "%c%c\n", + f34->bootloader_id[0], + f34->bootloader_id[1]); + else + return sysfs_emit(buf, "V%d.%d\n", + f34->bootloader_id[1], + f34->bootloader_id[0]); } static DEVICE_ATTR(bootloader_id, 0444, rmi_driver_bootloader_id_show, NULL); @@ -343,13 +335,16 @@ static ssize_t rmi_driver_configuration_id_show(struct device *dev, struct rmi_function *fn = data->f34_container; struct f34_data *f34; - if (fn) { - f34 = dev_get_drvdata(&fn->dev); + fn = data->f34_container; + if (!fn) + return -ENODEV; - return sysfs_emit(buf, "%s\n", f34->configuration_id); - } + f34 = dev_get_drvdata(&fn->dev); + if (!f34) + return -ENODEV; - return 0; + + return sysfs_emit(buf, "%s\n", f34->configuration_id); } static DEVICE_ATTR(configuration_id, 0444, @@ -365,10 +360,14 @@ static int rmi_firmware_update(struct rmi_driver_data *data, if (!data->f34_container) { dev_warn(dev, "%s: No F34 present!\n", __func__); - return -EINVAL; + return -ENODEV; } f34 = dev_get_drvdata(&data->f34_container->dev); + if (!f34) { + dev_warn(dev, "%s: No valid F34 present!\n", __func__); + return -ENODEV; + } if (f34->bl_version >= 7) { if (data->pdt_props & HAS_BSR) { @@ -494,10 +493,18 @@ static ssize_t rmi_driver_update_fw_status_show(struct device *dev, char *buf) { struct rmi_driver_data *data = dev_get_drvdata(dev); - int update_status = 0; + struct f34_data *f34; + int update_status = -ENODEV; - if (data->f34_container) - update_status = rmi_f34_status(data->f34_container); + /* + * The status is the percentage complete, or once complete, + * zero for success or a negative return code. + */ + if (data->f34_container) { + f34 = dev_get_drvdata(&data->f34_container->dev); + if (f34) + update_status = f34->update_status; + } return sysfs_emit(buf, "%d\n", update_status); } @@ -517,33 +524,21 @@ static const struct attribute_group rmi_firmware_attr_group = { .attrs = rmi_firmware_attrs, }; -static int rmi_f34_probe(struct rmi_function *fn) +static int rmi_f34v5_probe(struct f34_data *f34) { - struct f34_data *f34; - unsigned char f34_queries[9]; + struct rmi_function *fn = f34->fn; + u8 f34_queries[9]; bool has_config_id; - u8 version = fn->fd.function_version; - int ret; - - f34 = devm_kzalloc(&fn->dev, sizeof(struct f34_data), GFP_KERNEL); - if (!f34) - return -ENOMEM; - - f34->fn = fn; - dev_set_drvdata(&fn->dev, f34); - - /* v5 code only supported version 0, try V7 probe */ - if (version > 0) - return rmi_f34v7_probe(f34); + int error; f34->bl_version = 5; - ret = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr, - f34_queries, sizeof(f34_queries)); - if (ret) { + error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr, + f34_queries, sizeof(f34_queries)); + if (error) { dev_err(&fn->dev, "%s: Failed to query properties\n", __func__); - return ret; + return error; } snprintf(f34->bootloader_id, sizeof(f34->bootloader_id), @@ -569,11 +564,11 @@ static int rmi_f34_probe(struct rmi_function *fn) f34->v5.config_blocks); if (has_config_id) { - ret = rmi_read_block(fn->rmi_dev, fn->fd.control_base_addr, - f34_queries, sizeof(f34_queries)); - if (ret) { + error = rmi_read_block(fn->rmi_dev, fn->fd.control_base_addr, + f34_queries, sizeof(f34_queries)); + if (error) { dev_err(&fn->dev, "Failed to read F34 config ID\n"); - return ret; + return error; } snprintf(f34->configuration_id, sizeof(f34->configuration_id), @@ -582,12 +577,34 @@ static int rmi_f34_probe(struct rmi_function *fn) f34_queries[2], f34_queries[3]); rmi_dbg(RMI_DEBUG_FN, &fn->dev, "Configuration ID: %s\n", - f34->configuration_id); + f34->configuration_id); } return 0; } +static int rmi_f34_probe(struct rmi_function *fn) +{ + struct f34_data *f34; + u8 version = fn->fd.function_version; + int error; + + f34 = devm_kzalloc(&fn->dev, sizeof(struct f34_data), GFP_KERNEL); + if (!f34) + return -ENOMEM; + + f34->fn = fn; + + /* v5 code only supported version 0 */ + error = version == 0 ? rmi_f34v5_probe(f34) : rmi_f34v7_probe(f34); + if (error) + return error; + + dev_set_drvdata(&fn->dev, f34); + + return 0; +} + int rmi_f34_create_sysfs(struct rmi_device *rmi_dev) { return sysfs_create_group(&rmi_dev->dev.kobj, &rmi_firmware_attr_group); From c789d2c138ca575aee6ab5adead7a922686cc193 Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Fri, 6 Oct 2023 17:18:44 +0200 Subject: [PATCH 324/971] kasan: use unchecked __memset internally [ Upstream commit 01a5ad81637672940844052404678678a0ec8854 ] KASAN code is supposed to use the unchecked __memset implementation when accessing its metadata. Change uses of memset to __memset in mm/kasan/. Link: https://lkml.kernel.org/r/6f621966c6f52241b5aaa7220c348be90c075371.1696605143.git.andreyknvl@google.com Fixes: 59e6e098d1c1 ("kasan: introduce kasan_complete_mode_report_info") Fixes: 3c5c3cfb9ef4 ("kasan: support backing vmalloc space with real shadow memory") Signed-off-by: Andrey Konovalov Reviewed-by: Marco Elver Cc: Alexander Potapenko Cc: Andrey Ryabinin Cc: Dmitry Vyukov Cc: kernel test robot Signed-off-by: Andrew Morton Stable-dep-of: b6ea95a34cbd ("kasan: avoid sleepable page allocation from atomic context") Signed-off-by: Sasha Levin --- mm/kasan/report.c | 4 ++-- mm/kasan/shadow.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mm/kasan/report.c b/mm/kasan/report.c index ecced40e5103..465e6a53b3bf 100644 --- a/mm/kasan/report.c +++ b/mm/kasan/report.c @@ -538,7 +538,7 @@ void kasan_report_invalid_free(void *ptr, unsigned long ip, enum kasan_report_ty start_report(&flags, true); - memset(&info, 0, sizeof(info)); + __memset(&info, 0, sizeof(info)); info.type = type; info.access_addr = ptr; info.access_size = 0; @@ -576,7 +576,7 @@ bool kasan_report(const void *addr, size_t size, bool is_write, start_report(&irq_flags, true); - memset(&info, 0, sizeof(info)); + __memset(&info, 0, sizeof(info)); info.type = KASAN_REPORT_ACCESS; info.access_addr = addr; info.access_size = size; diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c index dd772f9d0f08..d687f09a7ae3 100644 --- a/mm/kasan/shadow.c +++ b/mm/kasan/shadow.c @@ -324,7 +324,7 @@ static int kasan_populate_vmalloc_pte(pte_t *ptep, unsigned long addr, if (!page) return -ENOMEM; - memset((void *)page, KASAN_VMALLOC_INVALID, PAGE_SIZE); + __memset((void *)page, KASAN_VMALLOC_INVALID, PAGE_SIZE); pte = pfn_pte(PFN_DOWN(__pa(page)), PAGE_KERNEL); spin_lock(&init_mm.page_table_lock); From 869aafe49c6bfdd7197345cdaa9cc8f5f516d72e Mon Sep 17 00:00:00 2001 From: Judith Mendez Date: Tue, 23 Apr 2024 10:17:28 -0500 Subject: [PATCH 325/971] arm64: dts: ti: k3-am65-main: Fix sdhci node properties [ Upstream commit 8ffe9cb889f2b831a9d5bbb1f7ad42d30e31170f ] Update otap-del-sel properties as per datasheet [0]. Add missing clkbuf-sel and itap-del-sel values also as per datasheet [0]. Move clkbuf-sel and ti,trm-icp above the otap-del-sel properties so the sdhci nodes could be more uniform across platforms. [0] https://www.ti.com/lit/ds/symlink/am6548.pdf Fixes: eac99d38f861 ("arm64: dts: ti: k3-am654-main: Update otap-del-sel values") Fixes: d7600d070fb0 ("arm64: dts: ti: k3-am65-main: Add support for sdhci1") Signed-off-by: Judith Mendez Link: https://lore.kernel.org/r/20240423151732.3541894-2-jm@ti.com Signed-off-by: Nishanth Menon Stable-dep-of: f55c9f087cc2 ("arm64: dts: ti: k3-am65-main: Add missing taps to sdhci0") Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi index 57befcce93b9..9c5de448351e 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi @@ -436,6 +436,8 @@ interrupts = ; mmc-ddr-1_8v; mmc-hs200-1_8v; + ti,clkbuf-sel = <0x7>; + ti,trm-icp = <0x8>; ti,otap-del-sel-legacy = <0x0>; ti,otap-del-sel-mmc-hs = <0x0>; ti,otap-del-sel-sd-hs = <0x0>; @@ -446,8 +448,7 @@ ti,otap-del-sel-ddr50 = <0x5>; ti,otap-del-sel-ddr52 = <0x5>; ti,otap-del-sel-hs200 = <0x5>; - ti,otap-del-sel-hs400 = <0x0>; - ti,trm-icp = <0x8>; + ti,itap-del-sel-ddr52 = <0x0>; dma-coherent; }; @@ -458,18 +459,22 @@ clocks = <&k3_clks 48 0>, <&k3_clks 48 1>; clock-names = "clk_ahb", "clk_xin"; interrupts = ; + ti,clkbuf-sel = <0x7>; + ti,trm-icp = <0x8>; ti,otap-del-sel-legacy = <0x0>; ti,otap-del-sel-mmc-hs = <0x0>; ti,otap-del-sel-sd-hs = <0x0>; - ti,otap-del-sel-sdr12 = <0x0>; - ti,otap-del-sel-sdr25 = <0x0>; + ti,otap-del-sel-sdr12 = <0xf>; + ti,otap-del-sel-sdr25 = <0xf>; ti,otap-del-sel-sdr50 = <0x8>; ti,otap-del-sel-sdr104 = <0x7>; ti,otap-del-sel-ddr50 = <0x4>; ti,otap-del-sel-ddr52 = <0x4>; ti,otap-del-sel-hs200 = <0x7>; - ti,clkbuf-sel = <0x7>; - ti,trm-icp = <0x8>; + ti,itap-del-sel-legacy = <0xa>; + ti,itap-del-sel-sd-hs = <0x1>; + ti,itap-del-sel-sdr12 = <0xa>; + ti,itap-del-sel-sdr25 = <0x1>; dma-coherent; }; From 1e3db0a98cbd441af43bdf0fae97074e1cd1229a Mon Sep 17 00:00:00 2001 From: Judith Mendez Date: Tue, 29 Apr 2025 12:30:08 -0500 Subject: [PATCH 326/971] arm64: dts: ti: k3-am65-main: Add missing taps to sdhci0 [ Upstream commit f55c9f087cc2e2252d44ffd9d58def2066fc176e ] For am65x, add missing ITAPDLYSEL values for Default Speed and High Speed SDR modes to sdhci0 node according to the device datasheet [0]. [0] https://www.ti.com/lit/gpn/am6548 Fixes: eac99d38f861 ("arm64: dts: ti: k3-am654-main: Update otap-del-sel values") Cc: stable@vger.kernel.org Signed-off-by: Judith Mendez Reviewed-by: Moteen Shah Link: https://lore.kernel.org/r/20250429173009.33994-1-jm@ti.com Signed-off-by: Nishanth Menon Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi index 9c5de448351e..0523bd0da80c 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi @@ -448,6 +448,8 @@ ti,otap-del-sel-ddr50 = <0x5>; ti,otap-del-sel-ddr52 = <0x5>; ti,otap-del-sel-hs200 = <0x5>; + ti,itap-del-sel-legacy = <0xa>; + ti,itap-del-sel-mmc-hs = <0x1>; ti,itap-del-sel-ddr52 = <0x0>; dma-coherent; }; From b18568bae6c72d6ecb6b86614437542e037a9232 Mon Sep 17 00:00:00 2001 From: Vaishnav Achath Date: Thu, 15 Feb 2024 14:25:14 +0530 Subject: [PATCH 327/971] arm64: dts: ti: k3-j721e-sk: Model CSI2RX connector mux [ Upstream commit f87c88947396674586a42a163b72efa3999e3dee ] J721E SK has the CSI2RX routed to a MIPI CSI connector and to 15-pin RPi camera connector through an analog mux with GPIO control, model that so that an overlay can control the mux state according to connected cameras. Also provide labels to the I2C mux bus instances so that a generic overlay can be used across multiple platforms. J721E SK schematics: https://www.ti.com/lit/zip/sprr438 Signed-off-by: Vaishnav Achath Reviewed-by: Jai Luthra Link: https://lore.kernel.org/r/20240215085518.552692-6-vaishnav.a@ti.com Signed-off-by: Vignesh Raghavendra Stable-dep-of: 97b67cc102dc ("arm64: dts: ti: k3-j721e-sk: Add DT nodes for power regulators") Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/ti/k3-j721e-sk.dts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts index ccacb65683b5..d967b384071c 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts +++ b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts @@ -286,6 +286,15 @@ }; }; }; + + csi_mux: mux-controller { + compatible = "gpio-mux"; + #mux-state-cells = <1>; + mux-gpios = <&main_gpio0 88 GPIO_ACTIVE_HIGH>; + idle-state = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&main_csi_mux_sel_pins_default>; + }; }; &main_pmx0 { @@ -352,6 +361,12 @@ >; }; + main_csi_mux_sel_pins_default: main-csi-mux-sel-default-pins { + pinctrl-single,pins = < + J721E_IOPAD(0x164, PIN_OUTPUT, 7) /* (V29) RGMII5_TD2 */ + >; + }; + dp0_pins_default: dp0-default-pins { pinctrl-single,pins = < J721E_IOPAD(0x1c4, PIN_INPUT, 5) /* SPI0_CS1.DP0_HPD */ @@ -707,14 +722,14 @@ reg = <0x70>; /* CSI0 I2C */ - i2c@0 { + cam0_i2c: i2c@0 { #address-cells = <1>; #size-cells = <0>; reg = <0>; }; /* CSI1 I2C */ - i2c@1 { + cam1_i2c: i2c@1 { #address-cells = <1>; #size-cells = <0>; reg = <1>; From 9333ced86ca775ecd5ba1c91525c7f7875ef240d Mon Sep 17 00:00:00 2001 From: Beleswar Padhi Date: Tue, 30 Apr 2024 18:45:12 +0530 Subject: [PATCH 328/971] arm64: dts: ti: k3-j721e-sk: Add support for multiple CAN instances [ Upstream commit 021d3d5f0741e5393a7a110ac909fc746b1e0a4d ] CAN instance 0 in the mcu domain is brought on the J721E-SK board through header J1. Thus, add its respective transceiver 1 dt node to add support for this CAN instance. CAN instances 0, 5 and 9 in the main domain are brought on the J721E-SK board through headers J5, J6 and J2 respectively. Thus, add their respective transceivers 2, 3 and 4 dt nodes to add support for these CAN instances. Signed-off-by: Beleswar Padhi Reviewed-by: Bhavya Kapoor Link: https://lore.kernel.org/r/20240430131512.1327283-1-b-padhi@ti.com Signed-off-by: Vignesh Raghavendra Stable-dep-of: 97b67cc102dc ("arm64: dts: ti: k3-j721e-sk: Add DT nodes for power regulators") Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/ti/k3-j721e-sk.dts | 116 +++++++++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts index d967b384071c..5e03a7f58faa 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts +++ b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts @@ -210,6 +210,42 @@ <3300000 0x1>; }; + transceiver1: can-phy1 { + compatible = "ti,tcan1042"; + #phy-cells = <0>; + max-bitrate = <5000000>; + pinctrl-names = "default"; + pinctrl-0 = <&mcu_mcan0_gpio_pins_default>; + standby-gpios = <&wkup_gpio0 3 GPIO_ACTIVE_HIGH>; + }; + + transceiver2: can-phy2 { + compatible = "ti,tcan1042"; + #phy-cells = <0>; + max-bitrate = <5000000>; + pinctrl-names = "default"; + pinctrl-0 = <&main_mcan0_gpio_pins_default>; + standby-gpios = <&main_gpio0 65 GPIO_ACTIVE_HIGH>; + }; + + transceiver3: can-phy3 { + compatible = "ti,tcan1042"; + #phy-cells = <0>; + max-bitrate = <5000000>; + pinctrl-names = "default"; + pinctrl-0 = <&main_mcan5_gpio_pins_default>; + standby-gpios = <&main_gpio0 66 GPIO_ACTIVE_HIGH>; + }; + + transceiver4: can-phy4 { + compatible = "ti,tcan1042"; + #phy-cells = <0>; + max-bitrate = <5000000>; + pinctrl-names = "default"; + pinctrl-0 = <&main_mcan9_gpio_pins_default>; + standby-gpios = <&main_gpio0 67 GPIO_ACTIVE_HIGH>; + }; + dp_pwr_3v3: fixedregulator-dp-prw { compatible = "regulator-fixed"; regulator-name = "dp-pwr"; @@ -367,6 +403,45 @@ >; }; + main_mcan0_pins_default: main-mcan0-default-pins { + pinctrl-single,pins = < + J721E_IOPAD(0x208, PIN_INPUT, 0) /* (W5) MCAN0_RX */ + J721E_IOPAD(0x20c, PIN_OUTPUT, 0) /* (W6) MCAN0_TX */ + >; + }; + + main_mcan0_gpio_pins_default: main-mcan0-gpio-default-pins { + pinctrl-single,pins = < + J721E_IOPAD(0x108, PIN_INPUT, 7) /* (AD27) PRG0_PRU1_GPO2.GPIO0_65 */ + >; + }; + + main_mcan5_pins_default: main-mcan5-default-pins { + pinctrl-single,pins = < + J721E_IOPAD(0x050, PIN_INPUT, 6) /* (AE21) PRG1_PRU0_GPO18.MCAN5_RX */ + J721E_IOPAD(0x04c, PIN_OUTPUT, 6) /* (AJ21) PRG1_PRU0_GPO17.MCAN5_TX */ + >; + }; + + main_mcan5_gpio_pins_default: main-mcan5-gpio-default-pins { + pinctrl-single,pins = < + J721E_IOPAD(0x10c, PIN_INPUT, 7) /* (AC25) PRG0_PRU1_GPO3.GPIO0_66 */ + >; + }; + + main_mcan9_pins_default: main-mcan9-default-pins { + pinctrl-single,pins = < + J721E_IOPAD(0x0d0, PIN_INPUT, 6) /* (AC27) PRG0_PRU0_GPO8.MCAN9_RX */ + J721E_IOPAD(0x0cc, PIN_OUTPUT, 6) /* (AC28) PRG0_PRU0_GPO7.MCAN9_TX */ + >; + }; + + main_mcan9_gpio_pins_default: main-mcan9-gpio-default-pins { + pinctrl-single,pins = < + J721E_IOPAD(0x110, PIN_INPUT, 7) /* (AD29) PRG0_PRU1_GPO4.GPIO0_67 */ + >; + }; + dp0_pins_default: dp0-default-pins { pinctrl-single,pins = < J721E_IOPAD(0x1c4, PIN_INPUT, 5) /* SPI0_CS1.DP0_HPD */ @@ -549,6 +624,19 @@ >; }; + mcu_mcan0_pins_default: mcu-mcan0-default-pins { + pinctrl-single,pins = < + J721E_WKUP_IOPAD(0x0ac, PIN_INPUT, 0) /* (C29) MCU_MCAN0_RX */ + J721E_WKUP_IOPAD(0x0a8, PIN_OUTPUT, 0) /* (D29) MCU_MCAN0_TX */ + >; + }; + + mcu_mcan0_gpio_pins_default: mcu-mcan0-gpio-default-pins { + pinctrl-single,pins = < + J721E_WKUP_IOPAD(0x0bc, PIN_INPUT, 7) /* (F27) WKUP_GPIO0_3 */ + >; + }; + /* Reset for M.2 M Key slot on PCIe1 */ mkey_reset_pins_default: mkey-reset-pns-default-pins { pinctrl-single,pins = < @@ -957,6 +1045,34 @@ num-lanes = <2>; }; +&mcu_mcan0 { + pinctrl-names = "default"; + pinctrl-0 = <&mcu_mcan0_pins_default>; + phys = <&transceiver1>; + status = "okay"; +}; + +&main_mcan0 { + pinctrl-names = "default"; + pinctrl-0 = <&main_mcan0_pins_default>; + phys = <&transceiver2>; + status = "okay"; +}; + +&main_mcan5 { + pinctrl-names = "default"; + pinctrl-0 = <&main_mcan5_pins_default>; + phys = <&transceiver3>; + status = "okay"; +}; + +&main_mcan9 { + pinctrl-names = "default"; + pinctrl-0 = <&main_mcan9_pins_default>; + phys = <&transceiver4>; + status = "okay"; +}; + &ufs_wrapper { status = "disabled"; }; From 6b60251cab3f9a266d3f8639f1424474f63cc7b0 Mon Sep 17 00:00:00 2001 From: Yemike Abhilash Chandra Date: Tue, 15 Apr 2025 16:43:22 +0530 Subject: [PATCH 329/971] arm64: dts: ti: k3-j721e-sk: Add DT nodes for power regulators [ Upstream commit 97b67cc102dc2cc8aa39a569c22a196e21af5a21 ] Add device tree nodes for two power regulators on the J721E SK board. vsys_5v0: A fixed regulator representing the 5V supply output from the LM61460 and vdd_sd_dv: A GPIO-controlled TLV71033 regulator. J721E-SK schematics: https://www.ti.com/lit/zip/sprr438 Fixes: 1bfda92a3a36 ("arm64: dts: ti: Add support for J721E SK") Cc: stable@vger.kernel.org Signed-off-by: Yemike Abhilash Chandra Reviewed-by: Udit Kumar Link: https://lore.kernel.org/r/20250415111328.3847502-2-y-abhilashchandra@ti.com Signed-off-by: Nishanth Menon Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/ti/k3-j721e-sk.dts | 31 ++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts index 5e03a7f58faa..952d2c72628e 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts +++ b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts @@ -183,6 +183,17 @@ regulator-boot-on; }; + vsys_5v0: fixedregulator-vsys5v0 { + /* Output of LM61460 */ + compatible = "regulator-fixed"; + regulator-name = "vsys_5v0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vusb_main>; + regulator-always-on; + regulator-boot-on; + }; + vdd_mmc1: fixedregulator-sd { compatible = "regulator-fixed"; pinctrl-names = "default"; @@ -210,6 +221,20 @@ <3300000 0x1>; }; + vdd_sd_dv: gpio-regulator-TLV71033 { + compatible = "regulator-gpio"; + pinctrl-names = "default"; + pinctrl-0 = <&vdd_sd_dv_pins_default>; + regulator-name = "tlv71033"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + vin-supply = <&vsys_5v0>; + gpios = <&main_gpio0 118 GPIO_ACTIVE_HIGH>; + states = <1800000 0x0>, + <3300000 0x1>; + }; + transceiver1: can-phy1 { compatible = "ti,tcan1042"; #phy-cells = <0>; @@ -601,6 +626,12 @@ >; }; + vdd_sd_dv_pins_default: vdd-sd-dv-default-pins { + pinctrl-single,pins = < + J721E_IOPAD(0x1dc, PIN_OUTPUT, 7) /* (Y1) SPI1_CLK.GPIO0_118 */ + >; + }; + wkup_uart0_pins_default: wkup-uart0-default-pins { pinctrl-single,pins = < J721E_WKUP_IOPAD(0xa0, PIN_INPUT, 0) /* (J29) WKUP_UART0_RXD */ From f8f07ea23116393d33747dd10be02a9f13419a98 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Wed, 11 Jun 2025 08:05:49 +0300 Subject: [PATCH 330/971] serial: sh-sci: Check if TX data was written to device in .tx_empty() commit 7cc0e0a43a91052477c2921f924a37d9c3891f0c upstream. On the Renesas RZ/G3S, when doing suspend to RAM, the uart_suspend_port() is called. The uart_suspend_port() calls 3 times the struct uart_port::ops::tx_empty() before shutting down the port. According to the documentation, the struct uart_port::ops::tx_empty() API tests whether the transmitter FIFO and shifter for the port is empty. The Renesas RZ/G3S SCIFA IP reports the number of data units stored in the transmit FIFO through the FDR (FIFO Data Count Register). The data units in the FIFOs are written in the shift register and transmitted from there. The TEND bit in the Serial Status Register reports if the data was transmitted from the shift register. In the previous code, in the tx_empty() API implemented by the sh-sci driver, it is considered that the TX is empty if the hardware reports the TEND bit set and the number of data units in the FIFO is zero. According to the HW manual, the TEND bit has the following meaning: 0: Transmission is in the waiting state or in progress. 1: Transmission is completed. It has been noticed that when opening the serial device w/o using it and then switch to a power saving mode, the tx_empty() call in the uart_port_suspend() function fails, leading to the "Unable to drain transmitter" message being printed on the console. This is because the TEND=0 if nothing has been transmitted and the FIFOs are empty. As the TEND=0 has double meaning (waiting state, in progress) we can't determined the scenario described above. Add a software workaround for this. This sets a variable if any data has been sent on the serial console (when using PIO) or if the DMA callback has been called (meaning something has been transmitted). In the tx_empty() API the status of the DMA transaction is also checked and if it is completed or in progress the code falls back in checking the hardware registers instead of relying on the software variable. Fixes: 73a19e4c0301 ("serial: sh-sci: Add DMA support.") Cc: stable@vger.kernel.org Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20241125115856.513642-1-claudiu.beznea.uj@bp.renesas.com Signed-off-by: Greg Kroah-Hartman [claudiu.beznea: fixed conflict by: - keeping serial_port_out() instead of sci_port_out() in sci_transmit_chars() - keeping !uart_circ_empty(xmit) condition in sci_dma_tx_complete(), after s->tx_occurred = true; assignement] Signed-off-by: Claudiu Beznea Signed-off-by: Sasha Levin --- drivers/tty/serial/sh-sci.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 61d8f50676b1..d57fa80b6f52 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -174,6 +174,7 @@ struct sci_port { bool has_rtscts; bool autorts; + bool tx_occurred; }; #define SCI_NPORTS CONFIG_SERIAL_SH_SCI_NR_UARTS @@ -838,6 +839,7 @@ static void sci_transmit_chars(struct uart_port *port) { struct circ_buf *xmit = &port->state->xmit; unsigned int stopped = uart_tx_stopped(port); + struct sci_port *s = to_sci_port(port); unsigned short status; unsigned short ctrl; int count; @@ -874,6 +876,7 @@ static void sci_transmit_chars(struct uart_port *port) } serial_port_out(port, SCxTDR, c); + s->tx_occurred = true; port->icount.tx++; } while (--count > 0); @@ -1230,6 +1233,8 @@ static void sci_dma_tx_complete(void *arg) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); + s->tx_occurred = true; + if (!uart_circ_empty(xmit)) { s->cookie_tx = 0; schedule_work(&s->work_tx); @@ -1719,6 +1724,19 @@ static void sci_flush_buffer(struct uart_port *port) s->cookie_tx = -EINVAL; } } + +static void sci_dma_check_tx_occurred(struct sci_port *s) +{ + struct dma_tx_state state; + enum dma_status status; + + if (!s->chan_tx) + return; + + status = dmaengine_tx_status(s->chan_tx, s->cookie_tx, &state); + if (status == DMA_COMPLETE || status == DMA_IN_PROGRESS) + s->tx_occurred = true; +} #else /* !CONFIG_SERIAL_SH_SCI_DMA */ static inline void sci_request_dma(struct uart_port *port) { @@ -1728,6 +1746,10 @@ static inline void sci_free_dma(struct uart_port *port) { } +static void sci_dma_check_tx_occurred(struct sci_port *s) +{ +} + #define sci_flush_buffer NULL #endif /* !CONFIG_SERIAL_SH_SCI_DMA */ @@ -2064,6 +2086,12 @@ static unsigned int sci_tx_empty(struct uart_port *port) { unsigned short status = serial_port_in(port, SCxSR); unsigned short in_tx_fifo = sci_txfill(port); + struct sci_port *s = to_sci_port(port); + + sci_dma_check_tx_occurred(s); + + if (!s->tx_occurred) + return TIOCSER_TEMT; return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0; } @@ -2234,6 +2262,7 @@ static int sci_startup(struct uart_port *port) dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); + s->tx_occurred = false; sci_request_dma(port); ret = sci_request_irq(s); From 9d50955bf215c5de3e515b699c4341fd25ec2b1e Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Wed, 11 Jun 2025 08:05:50 +0300 Subject: [PATCH 331/971] serial: sh-sci: Move runtime PM enable to sci_probe_single() commit 239f11209e5f282e16f5241b99256e25dd0614b6 upstream. Relocate the runtime PM enable operation to sci_probe_single(). This change prepares the codebase for upcoming fixes. While at it, replace the existing logic with a direct call to devm_pm_runtime_enable() and remove sci_cleanup_single(). The devm_pm_runtime_enable() function automatically handles disabling runtime PM during driver removal. Reviewed-by: Geert Uytterhoeven Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20250116182249.3828577-3-claudiu.beznea.uj@bp.renesas.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Claudiu Beznea Signed-off-by: Sasha Levin --- drivers/tty/serial/sh-sci.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index d57fa80b6f52..0071cb3043e1 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -3043,10 +3043,6 @@ static int sci_init_single(struct platform_device *dev, ret = sci_init_clocks(sci_port, &dev->dev); if (ret < 0) return ret; - - port->dev = &dev->dev; - - pm_runtime_enable(&dev->dev); } port->type = p->type; @@ -3076,11 +3072,6 @@ static int sci_init_single(struct platform_device *dev, return 0; } -static void sci_cleanup_single(struct sci_port *port) -{ - pm_runtime_disable(port->port.dev); -} - #if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) || \ defined(CONFIG_SERIAL_SH_SCI_EARLYCON) static void serial_console_putchar(struct uart_port *port, unsigned char ch) @@ -3250,8 +3241,6 @@ static int sci_remove(struct platform_device *dev) sci_ports_in_use &= ~BIT(port->port.line); uart_remove_one_port(&sci_uart_driver, &port->port); - sci_cleanup_single(port); - if (port->port.fifosize > 1) device_remove_file(&dev->dev, &dev_attr_rx_fifo_trigger); if (type == PORT_SCIFA || type == PORT_SCIFB || type == PORT_HSCIF) @@ -3414,6 +3403,11 @@ static int sci_probe_single(struct platform_device *dev, if (ret) return ret; + sciport->port.dev = &dev->dev; + ret = devm_pm_runtime_enable(&dev->dev); + if (ret) + return ret; + sciport->gpios = mctrl_gpio_init(&sciport->port, 0); if (IS_ERR(sciport->gpios)) return PTR_ERR(sciport->gpios); @@ -3427,13 +3421,7 @@ static int sci_probe_single(struct platform_device *dev, sciport->port.flags |= UPF_HARD_FLOW; } - ret = uart_add_one_port(&sci_uart_driver, &sciport->port); - if (ret) { - sci_cleanup_single(sciport); - return ret; - } - - return 0; + return uart_add_one_port(&sci_uart_driver, &sciport->port); } static int sci_probe(struct platform_device *dev) From 44ab21d74f6173f79cc0e3d18a0db41655511cd2 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Wed, 11 Jun 2025 08:05:51 +0300 Subject: [PATCH 332/971] serial: sh-sci: Clean sci_ports[0] after at earlycon exit commit 5f1017069933489add0c08659673443c9905659e upstream. The early_console_setup() function initializes sci_ports[0].port with an object of type struct uart_port obtained from the struct earlycon_device passed as an argument to early_console_setup(). Later, during serial port probing, the serial port used as earlycon (e.g., port A) might be remapped to a different position in the sci_ports[] array, and a different serial port (e.g., port B) might be assigned to slot 0. For example: sci_ports[0] = port B sci_ports[X] = port A In this scenario, the new port mapped at index zero (port B) retains the data associated with the earlycon configuration. Consequently, after the Linux boot process, any access to the serial port now mapped to sci_ports[0] (port B) will block the original earlycon port (port A). To address this, introduce an early_console_exit() function to clean up sci_ports[0] when earlycon is exited. To prevent the cleanup of sci_ports[0] while the serial device is still being used by earlycon, introduce the struct sci_port::probing flag and account for it in early_console_exit(). Fixes: 0b0cced19ab1 ("serial: sh-sci: Add CONFIG_SERIAL_EARLYCON support") Cc: stable@vger.kernel.org Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20250116182249.3828577-5-claudiu.beznea.uj@bp.renesas.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Claudiu Beznea Signed-off-by: Sasha Levin --- drivers/tty/serial/sh-sci.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 0071cb3043e1..be7e57e1d1e3 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -183,6 +183,7 @@ static struct sci_port sci_ports[SCI_NPORTS]; static unsigned long sci_ports_in_use; static struct uart_driver sci_uart_driver; static bool sci_uart_earlycon; +static bool sci_uart_earlycon_dev_probing; static inline struct sci_port * to_sci_port(struct uart_port *uart) @@ -3374,7 +3375,8 @@ static struct plat_sci_port *sci_parse_dt(struct platform_device *pdev, static int sci_probe_single(struct platform_device *dev, unsigned int index, struct plat_sci_port *p, - struct sci_port *sciport) + struct sci_port *sciport, + struct resource *sci_res) { int ret; @@ -3421,6 +3423,14 @@ static int sci_probe_single(struct platform_device *dev, sciport->port.flags |= UPF_HARD_FLOW; } + if (sci_uart_earlycon && sci_ports[0].port.mapbase == sci_res->start) { + /* + * Skip cleanup the sci_port[0] in early_console_exit(), this + * port is the same as the earlycon one. + */ + sci_uart_earlycon_dev_probing = true; + } + return uart_add_one_port(&sci_uart_driver, &sciport->port); } @@ -3479,7 +3489,7 @@ static int sci_probe(struct platform_device *dev) platform_set_drvdata(dev, sp); - ret = sci_probe_single(dev, dev_id, p, sp); + ret = sci_probe_single(dev, dev_id, p, sp, res); if (ret) return ret; @@ -3636,6 +3646,22 @@ sh_early_platform_init_buffer("earlyprintk", &sci_driver, #ifdef CONFIG_SERIAL_SH_SCI_EARLYCON static struct plat_sci_port port_cfg; +static int early_console_exit(struct console *co) +{ + struct sci_port *sci_port = &sci_ports[0]; + + /* + * Clean the slot used by earlycon. A new SCI device might + * map to this slot. + */ + if (!sci_uart_earlycon_dev_probing) { + memset(sci_port, 0, sizeof(*sci_port)); + sci_uart_earlycon = false; + } + + return 0; +} + static int __init early_console_setup(struct earlycon_device *device, int type) { @@ -3655,6 +3681,8 @@ static int __init early_console_setup(struct earlycon_device *device, SCSCR_RE | SCSCR_TE | port_cfg.scscr); device->con->write = serial_console_write; + device->con->exit = early_console_exit; + return 0; } static int __init sci_early_console_setup(struct earlycon_device *device, From 21f071261f946c5ca1adf378f818082a112b34d2 Mon Sep 17 00:00:00 2001 From: Sanjeev Yadav Date: Fri, 23 May 2025 13:14:01 -0700 Subject: [PATCH 333/971] scsi: core: ufs: Fix a hang in the error handler [ Upstream commit 8a3514d348de87a9d5e2ac00fbac4faae0b97996 ] ufshcd_err_handling_prepare() calls ufshcd_rpm_get_sync(). The latter function can only succeed if UFSHCD_EH_IN_PROGRESS is not set because resuming involves submitting a SCSI command and ufshcd_queuecommand() returns SCSI_MLQUEUE_HOST_BUSY if UFSHCD_EH_IN_PROGRESS is set. Fix this hang by setting UFSHCD_EH_IN_PROGRESS after ufshcd_rpm_get_sync() has been called instead of before. Backtrace: __switch_to+0x174/0x338 __schedule+0x600/0x9e4 schedule+0x7c/0xe8 schedule_timeout+0xa4/0x1c8 io_schedule_timeout+0x48/0x70 wait_for_common_io+0xa8/0x160 //waiting on START_STOP wait_for_completion_io_timeout+0x10/0x20 blk_execute_rq+0xe4/0x1e4 scsi_execute_cmd+0x108/0x244 ufshcd_set_dev_pwr_mode+0xe8/0x250 __ufshcd_wl_resume+0x94/0x354 ufshcd_wl_runtime_resume+0x3c/0x174 scsi_runtime_resume+0x64/0xa4 rpm_resume+0x15c/0xa1c __pm_runtime_resume+0x4c/0x90 // Runtime resume ongoing ufshcd_err_handler+0x1a0/0xd08 process_one_work+0x174/0x808 worker_thread+0x15c/0x490 kthread+0xf4/0x1ec ret_from_fork+0x10/0x20 Signed-off-by: Sanjeev Yadav [ bvanassche: rewrote patch description ] Fixes: 62694735ca95 ("[SCSI] ufs: Add runtime PM support for UFS host controller driver") Signed-off-by: Bart Van Assche Link: https://lore.kernel.org/r/20250523201409.1676055-1-bvanassche@acm.org Reviewed-by: Peter Wang Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/ufs/core/ufshcd.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 2346a1fc72b5..9dabc03675b0 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -6500,9 +6500,14 @@ static void ufshcd_err_handler(struct work_struct *work) up(&hba->host_sem); return; } + spin_unlock_irqrestore(hba->host->host_lock, flags); + + ufshcd_err_handling_prepare(hba); + + spin_lock_irqsave(hba->host->host_lock, flags); ufshcd_set_eh_in_progress(hba); spin_unlock_irqrestore(hba->host->host_lock, flags); - ufshcd_err_handling_prepare(hba); + /* Complete requests that have door-bell cleared by h/w */ ufshcd_complete_requests(hba, false); spin_lock_irqsave(hba->host->host_lock, flags); From 6edb171845edc7bcbed6940002e232ad617822ab Mon Sep 17 00:00:00 2001 From: Pauli Virtanen Date: Sat, 31 May 2025 18:24:58 +0300 Subject: [PATCH 334/971] Bluetooth: hci_core: fix list_for_each_entry_rcu usage [ Upstream commit 308a3a8ce8ea41b26c46169f3263e50f5997c28e ] Releasing + re-acquiring RCU lock inside list_for_each_entry_rcu() loop body is not correct. Fix by taking the update-side hdev->lock instead. Fixes: c7eaf80bfb0c ("Bluetooth: Fix hci_link_tx_to RCU lock usage") Signed-off-by: Pauli Virtanen Reviewed-by: Paul Menzel Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- net/bluetooth/hci_core.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 30519d47e8a6..febfd389ecf4 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -3380,23 +3380,18 @@ static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) bt_dev_err(hdev, "link tx timeout"); - rcu_read_lock(); + hci_dev_lock(hdev); /* Kill stalled connections */ - list_for_each_entry_rcu(c, &h->list, list) { + list_for_each_entry(c, &h->list, list) { if (c->type == type && c->sent) { bt_dev_err(hdev, "killing stalled connection %pMR", &c->dst); - /* hci_disconnect might sleep, so, we have to release - * the RCU read lock before calling it. - */ - rcu_read_unlock(); hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); - rcu_read_lock(); } } - rcu_read_unlock(); + hci_dev_unlock(hdev); } static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, From 9f66b6531c2b4e996bb61720ee94adb4b2e8d1be Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 3 Jun 2025 16:12:39 -0400 Subject: [PATCH 335/971] Bluetooth: MGMT: Fix UAF on mgmt_remove_adv_monitor_complete [ Upstream commit e6ed54e86aae9e4f7286ce8d5c73780f91b48d1c ] This reworks MGMT_OP_REMOVE_ADV_MONITOR to not use mgmt_pending_add to avoid crashes like bellow: ================================================================== BUG: KASAN: slab-use-after-free in mgmt_remove_adv_monitor_complete+0xe5/0x540 net/bluetooth/mgmt.c:5406 Read of size 8 at addr ffff88801c53f318 by task kworker/u5:5/5341 CPU: 0 UID: 0 PID: 5341 Comm: kworker/u5:5 Not tainted 6.15.0-syzkaller-10402-g4cb6c8af8591 #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 Workqueue: hci0 hci_cmd_sync_work Call Trace: dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:408 [inline] print_report+0xd2/0x2b0 mm/kasan/report.c:521 kasan_report+0x118/0x150 mm/kasan/report.c:634 mgmt_remove_adv_monitor_complete+0xe5/0x540 net/bluetooth/mgmt.c:5406 hci_cmd_sync_work+0x261/0x3a0 net/bluetooth/hci_sync.c:334 process_one_work kernel/workqueue.c:3238 [inline] process_scheduled_works+0xade/0x17b0 kernel/workqueue.c:3321 worker_thread+0x8a0/0xda0 kernel/workqueue.c:3402 kthread+0x711/0x8a0 kernel/kthread.c:464 ret_from_fork+0x3fc/0x770 arch/x86/kernel/process.c:148 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 Allocated by task 5987: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x3e/0x80 mm/kasan/common.c:68 poison_kmalloc_redzone mm/kasan/common.c:377 [inline] __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:394 kasan_kmalloc include/linux/kasan.h:260 [inline] __kmalloc_cache_noprof+0x230/0x3d0 mm/slub.c:4358 kmalloc_noprof include/linux/slab.h:905 [inline] kzalloc_noprof include/linux/slab.h:1039 [inline] mgmt_pending_new+0x65/0x240 net/bluetooth/mgmt_util.c:252 mgmt_pending_add+0x34/0x120 net/bluetooth/mgmt_util.c:279 remove_adv_monitor+0x103/0x1b0 net/bluetooth/mgmt.c:5454 hci_mgmt_cmd+0x9c9/0xef0 net/bluetooth/hci_sock.c:1719 hci_sock_sendmsg+0x6ca/0xef0 net/bluetooth/hci_sock.c:1839 sock_sendmsg_nosec net/socket.c:712 [inline] __sock_sendmsg+0x219/0x270 net/socket.c:727 sock_write_iter+0x258/0x330 net/socket.c:1131 new_sync_write fs/read_write.c:593 [inline] vfs_write+0x548/0xa90 fs/read_write.c:686 ksys_write+0x145/0x250 fs/read_write.c:738 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 5989: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x3e/0x80 mm/kasan/common.c:68 kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:576 poison_slab_object mm/kasan/common.c:247 [inline] __kasan_slab_free+0x62/0x70 mm/kasan/common.c:264 kasan_slab_free include/linux/kasan.h:233 [inline] slab_free_hook mm/slub.c:2380 [inline] slab_free mm/slub.c:4642 [inline] kfree+0x18e/0x440 mm/slub.c:4841 mgmt_pending_foreach+0xc9/0x120 net/bluetooth/mgmt_util.c:242 mgmt_index_removed+0x10d/0x2f0 net/bluetooth/mgmt.c:9366 hci_sock_bind+0xbe9/0x1000 net/bluetooth/hci_sock.c:1314 __sys_bind_socket net/socket.c:1810 [inline] __sys_bind+0x2c3/0x3e0 net/socket.c:1841 __do_sys_bind net/socket.c:1846 [inline] __se_sys_bind net/socket.c:1844 [inline] __x64_sys_bind+0x7a/0x90 net/socket.c:1844 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f Fixes: 66bd095ab5d4 ("Bluetooth: advmon offload MSFT remove monitor") Closes: https://syzkaller.appspot.com/bug?extid=feb0dc579bbe30a13190 Reported-by: syzbot+feb0dc579bbe30a13190@syzkaller.appspotmail.com Tested-by: syzbot+feb0dc579bbe30a13190@syzkaller.appspotmail.com Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- include/net/bluetooth/hci_core.h | 1 - net/bluetooth/hci_core.c | 4 +--- net/bluetooth/mgmt.c | 37 ++++++++++---------------------- 3 files changed, 12 insertions(+), 30 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index e9214ccfde2d..130487781313 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -2305,7 +2305,6 @@ void mgmt_advertising_added(struct sock *sk, struct hci_dev *hdev, u8 instance); void mgmt_advertising_removed(struct sock *sk, struct hci_dev *hdev, u8 instance); -void mgmt_adv_monitor_removed(struct hci_dev *hdev, u16 handle); int mgmt_phy_configuration_changed(struct hci_dev *hdev, struct sock *skip); void mgmt_adv_monitor_device_lost(struct hci_dev *hdev, u16 handle, bdaddr_t *bdaddr, u8 addr_type); diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index febfd389ecf4..023ad47a385b 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1862,10 +1862,8 @@ void hci_free_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor) if (monitor->handle) idr_remove(&hdev->adv_monitors_idr, monitor->handle); - if (monitor->state != ADV_MONITOR_STATE_NOT_REGISTERED) { + if (monitor->state != ADV_MONITOR_STATE_NOT_REGISTERED) hdev->adv_monitors_cnt--; - mgmt_adv_monitor_removed(hdev, monitor->handle); - } kfree(monitor); } diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 589c3a481e4c..fda492bf0cd4 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -5165,24 +5165,14 @@ static void mgmt_adv_monitor_added(struct sock *sk, struct hci_dev *hdev, mgmt_event(MGMT_EV_ADV_MONITOR_ADDED, hdev, &ev, sizeof(ev), sk); } -void mgmt_adv_monitor_removed(struct hci_dev *hdev, u16 handle) +static void mgmt_adv_monitor_removed(struct sock *sk, struct hci_dev *hdev, + u16 handle) { struct mgmt_ev_adv_monitor_removed ev; - struct mgmt_pending_cmd *cmd; - struct sock *sk_skip = NULL; - struct mgmt_cp_remove_adv_monitor *cp; - - cmd = pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev); - if (cmd) { - cp = cmd->param; - - if (cp->monitor_handle) - sk_skip = cmd->sk; - } ev.monitor_handle = cpu_to_le16(handle); - mgmt_event(MGMT_EV_ADV_MONITOR_REMOVED, hdev, &ev, sizeof(ev), sk_skip); + mgmt_event(MGMT_EV_ADV_MONITOR_REMOVED, hdev, &ev, sizeof(ev), sk); } static int read_adv_mon_features(struct sock *sk, struct hci_dev *hdev, @@ -5284,8 +5274,7 @@ static int __add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev, if (pending_find(MGMT_OP_SET_LE, hdev) || pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR, hdev) || - pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, hdev) || - pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev)) { + pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, hdev)) { status = MGMT_STATUS_BUSY; goto unlock; } @@ -5455,8 +5444,7 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev, struct mgmt_pending_cmd *cmd = data; struct mgmt_cp_remove_adv_monitor *cp; - if (status == -ECANCELED || - cmd != pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev)) + if (status == -ECANCELED) return; hci_dev_lock(hdev); @@ -5465,12 +5453,14 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev, rp.monitor_handle = cp->monitor_handle; - if (!status) + if (!status) { + mgmt_adv_monitor_removed(cmd->sk, hdev, cp->monitor_handle); hci_update_passive_scan(hdev); + } mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(status), &rp, sizeof(rp)); - mgmt_pending_remove(cmd); + mgmt_pending_free(cmd); hci_dev_unlock(hdev); bt_dev_dbg(hdev, "remove monitor %d complete, status %d", @@ -5480,10 +5470,6 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev, static int mgmt_remove_adv_monitor_sync(struct hci_dev *hdev, void *data) { struct mgmt_pending_cmd *cmd = data; - - if (cmd != pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev)) - return -ECANCELED; - struct mgmt_cp_remove_adv_monitor *cp = cmd->param; u16 handle = __le16_to_cpu(cp->monitor_handle); @@ -5502,14 +5488,13 @@ static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev, hci_dev_lock(hdev); if (pending_find(MGMT_OP_SET_LE, hdev) || - pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev) || pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR, hdev) || pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, hdev)) { status = MGMT_STATUS_BUSY; goto unlock; } - cmd = mgmt_pending_add(sk, MGMT_OP_REMOVE_ADV_MONITOR, hdev, data, len); + cmd = mgmt_pending_new(sk, MGMT_OP_REMOVE_ADV_MONITOR, hdev, data, len); if (!cmd) { status = MGMT_STATUS_NO_RESOURCES; goto unlock; @@ -5519,7 +5504,7 @@ static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev, mgmt_remove_adv_monitor_complete); if (err) { - mgmt_pending_remove(cmd); + mgmt_pending_free(cmd); if (err == -ENOMEM) status = MGMT_STATUS_NO_RESOURCES; From 5e64376da212e05715fd34ab10f40eb8e3cd7753 Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Mon, 27 Jan 2025 21:37:15 +0000 Subject: [PATCH 336/971] Bluetooth: MGMT: Remove unused mgmt_pending_find_data [ Upstream commit 276af34d82f13bda0b2a4d9786c90b8bbf1cd064 ] mgmt_pending_find_data() last use was removed in 2021 by commit 5a7501374664 ("Bluetooth: hci_sync: Convert MGMT_OP_GET_CLOCK_INFO") Remove it. Signed-off-by: Dr. David Alan Gilbert Reviewed-by: Simon Horman Signed-off-by: Luiz Augusto von Dentz Stable-dep-of: 6fe26f694c82 ("Bluetooth: MGMT: Protect mgmt_pending list with its own lock") Signed-off-by: Sasha Levin --- net/bluetooth/mgmt_util.c | 17 ----------------- net/bluetooth/mgmt_util.h | 4 ---- 2 files changed, 21 deletions(-) diff --git a/net/bluetooth/mgmt_util.c b/net/bluetooth/mgmt_util.c index 17e32605d9b0..dba6a0d66500 100644 --- a/net/bluetooth/mgmt_util.c +++ b/net/bluetooth/mgmt_util.c @@ -229,23 +229,6 @@ struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode, return NULL; } -struct mgmt_pending_cmd *mgmt_pending_find_data(unsigned short channel, - u16 opcode, - struct hci_dev *hdev, - const void *data) -{ - struct mgmt_pending_cmd *cmd; - - list_for_each_entry(cmd, &hdev->mgmt_pending, list) { - if (cmd->user_data != data) - continue; - if (cmd->opcode == opcode) - return cmd; - } - - return NULL; -} - void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, void (*cb)(struct mgmt_pending_cmd *cmd, void *data), void *data) diff --git a/net/bluetooth/mgmt_util.h b/net/bluetooth/mgmt_util.h index bdf978605d5a..f2ba994ab1d8 100644 --- a/net/bluetooth/mgmt_util.h +++ b/net/bluetooth/mgmt_util.h @@ -54,10 +54,6 @@ int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode, struct hci_dev *hdev); -struct mgmt_pending_cmd *mgmt_pending_find_data(unsigned short channel, - u16 opcode, - struct hci_dev *hdev, - const void *data); void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, void (*cb)(struct mgmt_pending_cmd *cmd, void *data), void *data); From bdd56875c6926d8009914f427df71797693e90d4 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 20 May 2025 15:42:21 -0400 Subject: [PATCH 337/971] Bluetooth: MGMT: Protect mgmt_pending list with its own lock [ Upstream commit 6fe26f694c824b8a4dbf50c635bee1302e3f099c ] This uses a mutex to protect from concurrent access of mgmt_pending list which can cause crashes like: ================================================================== BUG: KASAN: slab-use-after-free in hci_sock_get_channel+0x60/0x68 net/bluetooth/hci_sock.c:91 Read of size 2 at addr ffff0000c48885b2 by task syz.4.334/7318 CPU: 0 UID: 0 PID: 7318 Comm: syz.4.334 Not tainted 6.15.0-rc7-syzkaller-g187899f4124a #0 PREEMPT Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2025 Call trace: show_stack+0x2c/0x3c arch/arm64/kernel/stacktrace.c:466 (C) __dump_stack+0x30/0x40 lib/dump_stack.c:94 dump_stack_lvl+0xd8/0x12c lib/dump_stack.c:120 print_address_description+0xa8/0x254 mm/kasan/report.c:408 print_report+0x68/0x84 mm/kasan/report.c:521 kasan_report+0xb0/0x110 mm/kasan/report.c:634 __asan_report_load2_noabort+0x20/0x2c mm/kasan/report_generic.c:379 hci_sock_get_channel+0x60/0x68 net/bluetooth/hci_sock.c:91 mgmt_pending_find+0x7c/0x140 net/bluetooth/mgmt_util.c:223 pending_find net/bluetooth/mgmt.c:947 [inline] remove_adv_monitor+0x44/0x1a4 net/bluetooth/mgmt.c:5445 hci_mgmt_cmd+0x780/0xc00 net/bluetooth/hci_sock.c:1712 hci_sock_sendmsg+0x544/0xbb0 net/bluetooth/hci_sock.c:1832 sock_sendmsg_nosec net/socket.c:712 [inline] __sock_sendmsg net/socket.c:727 [inline] sock_write_iter+0x25c/0x378 net/socket.c:1131 new_sync_write fs/read_write.c:591 [inline] vfs_write+0x62c/0x97c fs/read_write.c:684 ksys_write+0x120/0x210 fs/read_write.c:736 __do_sys_write fs/read_write.c:747 [inline] __se_sys_write fs/read_write.c:744 [inline] __arm64_sys_write+0x7c/0x90 fs/read_write.c:744 __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline] invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:49 el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:132 do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:151 el0_svc+0x58/0x17c arch/arm64/kernel/entry-common.c:767 el0t_64_sync_handler+0x78/0x108 arch/arm64/kernel/entry-common.c:786 el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:600 Allocated by task 7037: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x40/0x78 mm/kasan/common.c:68 kasan_save_alloc_info+0x44/0x54 mm/kasan/generic.c:562 poison_kmalloc_redzone mm/kasan/common.c:377 [inline] __kasan_kmalloc+0x9c/0xb4 mm/kasan/common.c:394 kasan_kmalloc include/linux/kasan.h:260 [inline] __do_kmalloc_node mm/slub.c:4327 [inline] __kmalloc_noprof+0x2fc/0x4c8 mm/slub.c:4339 kmalloc_noprof include/linux/slab.h:909 [inline] sk_prot_alloc+0xc4/0x1f0 net/core/sock.c:2198 sk_alloc+0x44/0x3ac net/core/sock.c:2254 bt_sock_alloc+0x4c/0x300 net/bluetooth/af_bluetooth.c:148 hci_sock_create+0xa8/0x194 net/bluetooth/hci_sock.c:2202 bt_sock_create+0x14c/0x24c net/bluetooth/af_bluetooth.c:132 __sock_create+0x43c/0x91c net/socket.c:1541 sock_create net/socket.c:1599 [inline] __sys_socket_create net/socket.c:1636 [inline] __sys_socket+0xd4/0x1c0 net/socket.c:1683 __do_sys_socket net/socket.c:1697 [inline] __se_sys_socket net/socket.c:1695 [inline] __arm64_sys_socket+0x7c/0x94 net/socket.c:1695 __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline] invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:49 el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:132 do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:151 el0_svc+0x58/0x17c arch/arm64/kernel/entry-common.c:767 el0t_64_sync_handler+0x78/0x108 arch/arm64/kernel/entry-common.c:786 el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:600 Freed by task 6607: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x40/0x78 mm/kasan/common.c:68 kasan_save_free_info+0x58/0x70 mm/kasan/generic.c:576 poison_slab_object mm/kasan/common.c:247 [inline] __kasan_slab_free+0x68/0x88 mm/kasan/common.c:264 kasan_slab_free include/linux/kasan.h:233 [inline] slab_free_hook mm/slub.c:2380 [inline] slab_free mm/slub.c:4642 [inline] kfree+0x17c/0x474 mm/slub.c:4841 sk_prot_free net/core/sock.c:2237 [inline] __sk_destruct+0x4f4/0x760 net/core/sock.c:2332 sk_destruct net/core/sock.c:2360 [inline] __sk_free+0x320/0x430 net/core/sock.c:2371 sk_free+0x60/0xc8 net/core/sock.c:2382 sock_put include/net/sock.h:1944 [inline] mgmt_pending_free+0x88/0x118 net/bluetooth/mgmt_util.c:290 mgmt_pending_remove+0xec/0x104 net/bluetooth/mgmt_util.c:298 mgmt_set_powered_complete+0x418/0x5cc net/bluetooth/mgmt.c:1355 hci_cmd_sync_work+0x204/0x33c net/bluetooth/hci_sync.c:334 process_one_work+0x7e8/0x156c kernel/workqueue.c:3238 process_scheduled_works kernel/workqueue.c:3319 [inline] worker_thread+0x958/0xed8 kernel/workqueue.c:3400 kthread+0x5fc/0x75c kernel/kthread.c:464 ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:847 Fixes: a380b6cff1a2 ("Bluetooth: Add generic mgmt helper API") Closes: https://syzkaller.appspot.com/bug?extid=0a7039d5d9986ff4ecec Closes: https://syzkaller.appspot.com/bug?extid=cc0cc52e7f43dc9e6df1 Reported-by: syzbot+0a7039d5d9986ff4ecec@syzkaller.appspotmail.com Tested-by: syzbot+0a7039d5d9986ff4ecec@syzkaller.appspotmail.com Tested-by: syzbot+cc0cc52e7f43dc9e6df1@syzkaller.appspotmail.com Signed-off-by: Dmitry Antipov Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- include/net/bluetooth/hci_core.h | 1 + net/bluetooth/hci_core.c | 1 + net/bluetooth/mgmt.c | 101 +++++++++++++++---------------- net/bluetooth/mgmt_util.c | 32 ++++++++-- net/bluetooth/mgmt_util.h | 4 +- 5 files changed, 80 insertions(+), 59 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 130487781313..d63af08c6cdc 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -542,6 +542,7 @@ struct hci_dev { struct hci_conn_hash conn_hash; struct list_head mesh_pending; + struct mutex mgmt_pending_lock; struct list_head mgmt_pending; struct list_head reject_list; struct list_head accept_list; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 023ad47a385b..32f7bd0e8916 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2490,6 +2490,7 @@ struct hci_dev *hci_alloc_dev_priv(int sizeof_priv) mutex_init(&hdev->lock); mutex_init(&hdev->req_lock); + mutex_init(&hdev->mgmt_pending_lock); ida_init(&hdev->unset_handle_ida); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index fda492bf0cd4..44174f59b31e 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1433,22 +1433,17 @@ static void settings_rsp(struct mgmt_pending_cmd *cmd, void *data) send_settings_rsp(cmd->sk, cmd->opcode, match->hdev); - list_del(&cmd->list); - if (match->sk == NULL) { match->sk = cmd->sk; sock_hold(match->sk); } - - mgmt_pending_free(cmd); } static void cmd_status_rsp(struct mgmt_pending_cmd *cmd, void *data) { u8 *status = data; - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, *status); - mgmt_pending_remove(cmd); + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, *status); } static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data) @@ -1462,8 +1457,6 @@ static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data) if (cmd->cmd_complete) { cmd->cmd_complete(cmd, match->mgmt_status); - mgmt_pending_remove(cmd); - return; } @@ -1472,13 +1465,13 @@ static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data) static int generic_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status) { - return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, + return mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, cmd->param, cmd->param_len); } static int addr_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status) { - return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, + return mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, cmd->param, sizeof(struct mgmt_addr_info)); } @@ -1518,7 +1511,7 @@ static void mgmt_set_discoverable_complete(struct hci_dev *hdev, void *data, if (err) { u8 mgmt_err = mgmt_status(err); - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err); hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE); goto done; } @@ -1693,7 +1686,7 @@ static void mgmt_set_connectable_complete(struct hci_dev *hdev, void *data, if (err) { u8 mgmt_err = mgmt_status(err); - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err); goto done; } @@ -1930,8 +1923,8 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err) new_settings(hdev, NULL); } - mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, cmd_status_rsp, - &mgmt_err); + mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, true, + cmd_status_rsp, &mgmt_err); return; } @@ -1941,7 +1934,7 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err) changed = hci_dev_test_and_clear_flag(hdev, HCI_SSP_ENABLED); } - mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, settings_rsp, &match); + mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, true, settings_rsp, &match); if (changed) new_settings(hdev, match.sk); @@ -2061,12 +2054,12 @@ static void set_le_complete(struct hci_dev *hdev, void *data, int err) bt_dev_dbg(hdev, "err %d", err); if (status) { - mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, cmd_status_rsp, - &status); + mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, true, cmd_status_rsp, + &status); return; } - mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, settings_rsp, &match); + mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, true, settings_rsp, &match); new_settings(hdev, match.sk); @@ -2125,7 +2118,7 @@ static void set_mesh_complete(struct hci_dev *hdev, void *data, int err) struct sock *sk = cmd->sk; if (status) { - mgmt_pending_foreach(MGMT_OP_SET_MESH_RECEIVER, hdev, + mgmt_pending_foreach(MGMT_OP_SET_MESH_RECEIVER, hdev, true, cmd_status_rsp, &status); return; } @@ -2566,7 +2559,7 @@ static void mgmt_class_complete(struct hci_dev *hdev, void *data, int err) bt_dev_dbg(hdev, "err %d", err); - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err), hdev->dev_class, 3); mgmt_pending_free(cmd); @@ -3354,7 +3347,7 @@ static int pairing_complete(struct mgmt_pending_cmd *cmd, u8 status) bacpy(&rp.addr.bdaddr, &conn->dst); rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type); - err = mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, + err = mgmt_cmd_complete(cmd->sk, cmd->hdev->id, MGMT_OP_PAIR_DEVICE, status, &rp, sizeof(rp)); /* So we don't get further callbacks for this connection */ @@ -5243,7 +5236,7 @@ static void mgmt_add_adv_patterns_monitor_complete(struct hci_dev *hdev, hci_update_passive_scan(hdev); } - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(status), &rp, sizeof(rp)); mgmt_pending_remove(cmd); @@ -5458,7 +5451,7 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev, hci_update_passive_scan(hdev); } - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(status), &rp, sizeof(rp)); mgmt_pending_free(cmd); @@ -5857,7 +5850,7 @@ static void start_discovery_complete(struct hci_dev *hdev, void *data, int err) cmd != pending_find(MGMT_OP_START_SERVICE_DISCOVERY, hdev)) return; - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err), + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err), cmd->param, 1); mgmt_pending_remove(cmd); @@ -6095,7 +6088,7 @@ static void stop_discovery_complete(struct hci_dev *hdev, void *data, int err) bt_dev_dbg(hdev, "err %d", err); - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err), + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err), cmd->param, 1); mgmt_pending_remove(cmd); @@ -6320,7 +6313,7 @@ static void set_advertising_complete(struct hci_dev *hdev, void *data, int err) u8 status = mgmt_status(err); if (status) { - mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, + mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, true, cmd_status_rsp, &status); return; } @@ -6330,7 +6323,7 @@ static void set_advertising_complete(struct hci_dev *hdev, void *data, int err) else hci_dev_clear_flag(hdev, HCI_ADVERTISING); - mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, settings_rsp, + mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, true, settings_rsp, &match); new_settings(hdev, match.sk); @@ -6674,7 +6667,7 @@ static void set_bredr_complete(struct hci_dev *hdev, void *data, int err) */ hci_dev_clear_flag(hdev, HCI_BREDR_ENABLED); - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err); } else { send_settings_rsp(cmd->sk, MGMT_OP_SET_BREDR, hdev); new_settings(hdev, cmd->sk); @@ -6811,7 +6804,7 @@ static void set_secure_conn_complete(struct hci_dev *hdev, void *data, int err) if (err) { u8 mgmt_err = mgmt_status(err); - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err); goto done; } @@ -7258,7 +7251,7 @@ static void get_conn_info_complete(struct hci_dev *hdev, void *data, int err) rp.max_tx_power = HCI_TX_POWER_INVALID; } - mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_GET_CONN_INFO, status, + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, MGMT_OP_GET_CONN_INFO, status, &rp, sizeof(rp)); mgmt_pending_free(cmd); @@ -7418,7 +7411,7 @@ static void get_clock_info_complete(struct hci_dev *hdev, void *data, int err) } complete: - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, &rp, + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, &rp, sizeof(rp)); mgmt_pending_free(cmd); @@ -8622,10 +8615,10 @@ static void add_advertising_complete(struct hci_dev *hdev, void *data, int err) rp.instance = cp->instance; if (err) - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err)); else - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err), &rp, sizeof(rp)); add_adv_complete(hdev, cmd->sk, cp->instance, err); @@ -8813,10 +8806,10 @@ static void add_ext_adv_params_complete(struct hci_dev *hdev, void *data, hci_remove_adv_instance(hdev, cp->instance); - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err)); } else { - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err), &rp, sizeof(rp)); } @@ -8964,10 +8957,10 @@ static void add_ext_adv_data_complete(struct hci_dev *hdev, void *data, int err) rp.instance = cp->instance; if (err) - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err)); else - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err), &rp, sizeof(rp)); mgmt_pending_free(cmd); @@ -9126,10 +9119,10 @@ static void remove_advertising_complete(struct hci_dev *hdev, void *data, rp.instance = cp->instance; if (err) - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err)); else - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, MGMT_STATUS_SUCCESS, &rp, sizeof(rp)); mgmt_pending_free(cmd); @@ -9400,7 +9393,7 @@ void mgmt_index_removed(struct hci_dev *hdev) if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) return; - mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match); + mgmt_pending_foreach(0, hdev, true, cmd_complete_rsp, &match); if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { mgmt_index_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev, NULL, 0, @@ -9438,7 +9431,8 @@ void mgmt_power_on(struct hci_dev *hdev, int err) hci_update_passive_scan(hdev); } - mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); + mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, true, settings_rsp, + &match); new_settings(hdev, match.sk); @@ -9453,7 +9447,8 @@ void __mgmt_power_off(struct hci_dev *hdev) struct cmd_lookup match = { NULL, hdev }; u8 zero_cod[] = { 0, 0, 0 }; - mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); + mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, true, settings_rsp, + &match); /* If the power off is because of hdev unregistration let * use the appropriate INVALID_INDEX status. Otherwise use @@ -9467,7 +9462,7 @@ void __mgmt_power_off(struct hci_dev *hdev) else match.mgmt_status = MGMT_STATUS_NOT_POWERED; - mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match); + mgmt_pending_foreach(0, hdev, true, cmd_complete_rsp, &match); if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0) { mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, @@ -9708,7 +9703,6 @@ static void unpair_device_rsp(struct mgmt_pending_cmd *cmd, void *data) device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, cmd->sk); cmd->cmd_complete(cmd, 0); - mgmt_pending_remove(cmd); } bool mgmt_powering_down(struct hci_dev *hdev) @@ -9761,8 +9755,8 @@ void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, struct mgmt_cp_disconnect *cp; struct mgmt_pending_cmd *cmd; - mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp, - hdev); + mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, true, + unpair_device_rsp, hdev); cmd = pending_find(MGMT_OP_DISCONNECT, hdev); if (!cmd) @@ -9955,7 +9949,7 @@ void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status) if (status) { u8 mgmt_err = mgmt_status(status); - mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, + mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, true, cmd_status_rsp, &mgmt_err); return; } @@ -9965,8 +9959,8 @@ void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status) else changed = hci_dev_test_and_clear_flag(hdev, HCI_LINK_SECURITY); - mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, settings_rsp, - &match); + mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, true, + settings_rsp, &match); if (changed) new_settings(hdev, match.sk); @@ -9990,9 +9984,12 @@ void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, { struct cmd_lookup match = { NULL, hdev, mgmt_status(status) }; - mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, sk_lookup, &match); - mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, sk_lookup, &match); - mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, sk_lookup, &match); + mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, false, sk_lookup, + &match); + mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, false, sk_lookup, + &match); + mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, false, sk_lookup, + &match); if (!status) { mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, dev_class, diff --git a/net/bluetooth/mgmt_util.c b/net/bluetooth/mgmt_util.c index dba6a0d66500..4ba500c377a4 100644 --- a/net/bluetooth/mgmt_util.c +++ b/net/bluetooth/mgmt_util.c @@ -217,30 +217,47 @@ int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode, struct hci_dev *hdev) { - struct mgmt_pending_cmd *cmd; + struct mgmt_pending_cmd *cmd, *tmp; - list_for_each_entry(cmd, &hdev->mgmt_pending, list) { + mutex_lock(&hdev->mgmt_pending_lock); + + list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) { if (hci_sock_get_channel(cmd->sk) != channel) continue; - if (cmd->opcode == opcode) + + if (cmd->opcode == opcode) { + mutex_unlock(&hdev->mgmt_pending_lock); return cmd; + } } + mutex_unlock(&hdev->mgmt_pending_lock); + return NULL; } -void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, +void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, bool remove, void (*cb)(struct mgmt_pending_cmd *cmd, void *data), void *data) { struct mgmt_pending_cmd *cmd, *tmp; + mutex_lock(&hdev->mgmt_pending_lock); + list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) { if (opcode > 0 && cmd->opcode != opcode) continue; + if (remove) + list_del(&cmd->list); + cb(cmd, data); + + if (remove) + mgmt_pending_free(cmd); } + + mutex_unlock(&hdev->mgmt_pending_lock); } struct mgmt_pending_cmd *mgmt_pending_new(struct sock *sk, u16 opcode, @@ -254,7 +271,7 @@ struct mgmt_pending_cmd *mgmt_pending_new(struct sock *sk, u16 opcode, return NULL; cmd->opcode = opcode; - cmd->index = hdev->id; + cmd->hdev = hdev; cmd->param = kmemdup(data, len, GFP_KERNEL); if (!cmd->param) { @@ -280,7 +297,9 @@ struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, if (!cmd) return NULL; + mutex_lock(&hdev->mgmt_pending_lock); list_add_tail(&cmd->list, &hdev->mgmt_pending); + mutex_unlock(&hdev->mgmt_pending_lock); return cmd; } @@ -294,7 +313,10 @@ void mgmt_pending_free(struct mgmt_pending_cmd *cmd) void mgmt_pending_remove(struct mgmt_pending_cmd *cmd) { + mutex_lock(&cmd->hdev->mgmt_pending_lock); list_del(&cmd->list); + mutex_unlock(&cmd->hdev->mgmt_pending_lock); + mgmt_pending_free(cmd); } diff --git a/net/bluetooth/mgmt_util.h b/net/bluetooth/mgmt_util.h index f2ba994ab1d8..024e51dd6937 100644 --- a/net/bluetooth/mgmt_util.h +++ b/net/bluetooth/mgmt_util.h @@ -33,7 +33,7 @@ struct mgmt_mesh_tx { struct mgmt_pending_cmd { struct list_head list; u16 opcode; - int index; + struct hci_dev *hdev; void *param; size_t param_len; struct sock *sk; @@ -54,7 +54,7 @@ int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode, struct hci_dev *hdev); -void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, +void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, bool remove, void (*cb)(struct mgmt_pending_cmd *cmd, void *data), void *data); struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, From 259119595227fd20f6aa29d85abe086b6fdd9eb1 Mon Sep 17 00:00:00 2001 From: Jeongjun Park Date: Wed, 21 May 2025 01:07:17 +0900 Subject: [PATCH 338/971] ptp: remove ptp->n_vclocks check logic in ptp_vclock_in_use() [ Upstream commit 87f7ce260a3c838b49e1dc1ceedf1006795157a2 ] There is no disagreement that we should check both ptp->is_virtual_clock and ptp->n_vclocks to check if the ptp virtual clock is in use. However, when we acquire ptp->n_vclocks_mux to read ptp->n_vclocks in ptp_vclock_in_use(), we observe a recursive lock in the call trace starting from n_vclocks_store(). ============================================ WARNING: possible recursive locking detected 6.15.0-rc6 #1 Not tainted -------------------------------------------- syz.0.1540/13807 is trying to acquire lock: ffff888035a24868 (&ptp->n_vclocks_mux){+.+.}-{4:4}, at: ptp_vclock_in_use drivers/ptp/ptp_private.h:103 [inline] ffff888035a24868 (&ptp->n_vclocks_mux){+.+.}-{4:4}, at: ptp_clock_unregister+0x21/0x250 drivers/ptp/ptp_clock.c:415 but task is already holding lock: ffff888030704868 (&ptp->n_vclocks_mux){+.+.}-{4:4}, at: n_vclocks_store+0xf1/0x6d0 drivers/ptp/ptp_sysfs.c:215 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&ptp->n_vclocks_mux); lock(&ptp->n_vclocks_mux); *** DEADLOCK *** .... ============================================ The best way to solve this is to remove the logic that checks ptp->n_vclocks in ptp_vclock_in_use(). The reason why this is appropriate is that any path that uses ptp->n_vclocks must unconditionally check if ptp->n_vclocks is greater than 0 before unregistering vclocks, and all functions are already written this way. And in the function that uses ptp->n_vclocks, we already get ptp->n_vclocks_mux before unregistering vclocks. Therefore, we need to remove the redundant check for ptp->n_vclocks in ptp_vclock_in_use() to prevent recursive locking. Fixes: 73f37068d540 ("ptp: support ptp physical/virtual clocks conversion") Signed-off-by: Jeongjun Park Acked-by: Richard Cochran Link: https://patch.msgid.link/20250520160717.7350-1-aha310510@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/ptp/ptp_private.h | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h index b8d4f61f14be..d0eb4555720e 100644 --- a/drivers/ptp/ptp_private.h +++ b/drivers/ptp/ptp_private.h @@ -89,17 +89,7 @@ static inline int queue_cnt(const struct timestamp_event_queue *q) /* Check if ptp virtual clock is in use */ static inline bool ptp_vclock_in_use(struct ptp_clock *ptp) { - bool in_use = false; - - if (mutex_lock_interruptible(&ptp->n_vclocks_mux)) - return true; - - if (!ptp->is_virtual_clock && ptp->n_vclocks) - in_use = true; - - mutex_unlock(&ptp->n_vclocks_mux); - - return in_use; + return !ptp->is_virtual_clock; } /* Check if ptp clock shall be free running */ From 748da2fc1c3c116885c206b26e0299349331a3e7 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Tue, 18 Mar 2025 20:50:27 +0000 Subject: [PATCH 339/971] ath10k: snoc: fix unbalanced IRQ enable in crash recovery [ Upstream commit 1650d32b92b01db03a1a95d69ee74fcbc34d4b00 ] In ath10k_snoc_hif_stop() we skip disabling the IRQs in the crash recovery flow, but we still unconditionally call enable again in ath10k_snoc_hif_start(). We can't check the ATH10K_FLAG_CRASH_FLUSH bit since it is cleared before hif_start() is called, so instead check the ATH10K_SNOC_FLAG_RECOVERY flag and skip enabling the IRQs during crash recovery. This fixes unbalanced IRQ enable splats that happen after recovering from a crash. Fixes: 0e622f67e041 ("ath10k: add support for WCN3990 firmware crash recovery") Signed-off-by: Caleb Connolly Tested-by: Loic Poulain Link: https://patch.msgid.link/20250318205043.1043148-1-caleb.connolly@linaro.org Signed-off-by: Jeff Johnson Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath10k/snoc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c index 2c39bad7ebfb..1d06d4125992 100644 --- a/drivers/net/wireless/ath/ath10k/snoc.c +++ b/drivers/net/wireless/ath/ath10k/snoc.c @@ -937,7 +937,9 @@ static int ath10k_snoc_hif_start(struct ath10k *ar) dev_set_threaded(&ar->napi_dev, true); ath10k_core_napi_enable(ar); - ath10k_snoc_irq_enable(ar); + /* IRQs are left enabled when we restart due to a firmware crash */ + if (!test_bit(ATH10K_SNOC_FLAG_RECOVERY, &ar_snoc->flags)) + ath10k_snoc_irq_enable(ar); ath10k_snoc_rx_post(ar); clear_bit(ATH10K_SNOC_FLAG_RECOVERY, &ar_snoc->flags); From d66fd9591ff4807fab85f8e69a60590c91ad985a Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Tue, 5 Mar 2024 07:14:00 -0800 Subject: [PATCH 340/971] wifi: ath11k: fix soc_dp_stats debugfs file permission [ Upstream commit fa645e663165d69f05f95a0c3aa3b3d08f4fdeda ] Currently the soc_dp_stats debugfs file has the following permissions: # ls -l /sys/kernel/debug/ath11k/pci-0000:03:00.0/soc_dp_stats -rw------- 1 root root 0 Mar 4 15:04 /sys/kernel/debug/ath11k/pci-0000:03:00.0/soc_dp_stats However this file does not actually support write operations -- no .write() method is registered. Therefore use the correct permissions when creating the file. After the change: # ls -l /sys/kernel/debug/ath11k/pci-0000:03:00.0/soc_dp_stats -r-------- 1 root root 0 Mar 4 15:15 /sys/kernel/debug/ath11k/pci-0000:03:00.0/soc_dp_stats Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30 Signed-off-by: Jeff Johnson Signed-off-by: Kalle Valo Link: https://msgid.link/20240305-fix-soc_dp_stats-permission-v1-1-2ec10b42f755@quicinc.com Stable-dep-of: 9f6e82d11bb9 ("wifi: ath11k: avoid burning CPU in ath11k_debugfs_fw_stats_request()") Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath11k/debugfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/debugfs.c b/drivers/net/wireless/ath/ath11k/debugfs.c index 8cda73b78ebf..34aa04d27a1d 100644 --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -980,7 +980,7 @@ int ath11k_debugfs_pdev_create(struct ath11k_base *ab) debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab, &fops_simulate_fw_crash); - debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab, + debugfs_create_file("soc_dp_stats", 0400, ab->debugfs_soc, ab, &fops_soc_dp_stats); if (ab->hw_params.sram_dump.start != 0) From 452f55761513c5723a579db0173b7a19e26b1edd Mon Sep 17 00:00:00 2001 From: Easwar Hariharan Date: Tue, 10 Dec 2024 22:02:45 +0000 Subject: [PATCH 341/971] wifi: ath11k: convert timeouts to secs_to_jiffies() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit b29425972c5234a59b6fb634125420ed74266377 ] Commit b35108a51cf7 ("jiffies: Define secs_to_jiffies()") introduced secs_to_jiffies(). As the value here is a multiple of 1000, use secs_to_jiffies() instead of msecs_to_jiffies to avoid the multiplication. This is converted using scripts/coccinelle/misc/secs_to_jiffies.cocci with the following Coccinelle rules: @@ constant C; @@ - msecs_to_jiffies(C * 1000) + secs_to_jiffies(C) @@ constant C; @@ - msecs_to_jiffies(C * MSEC_PER_SEC) + secs_to_jiffies(C) Link: https://lkml.kernel.org/r/20241210-converge-secs-to-jiffies-v3-14-ddfefd7e9f2a@linux.microsoft.com Acked-by: Jeff Johnson Signed-off-by: Easwar Hariharan Cc: Alexander Gordeev Cc: Andrew Lunn Cc: Anna-Maria Behnsen Cc: Catalin Marinas Cc: Christian Borntraeger Cc: Christophe Leroy Cc: Daniel Mack Cc: David Airlie Cc: David S. Miller Cc: Dick Kennedy Cc: Eric Dumazet Cc: Florian Fainelli Cc: Greg Kroah-Hartman Cc: Haojian Zhuang Cc: Heiko Carstens Cc: Ilya Dryomov Cc: Jack Wang Cc: Jakub Kicinski Cc: James Bottomley Cc: James Smart Cc: Jaroslav Kysela Cc: Jeff Johnson Cc: Jens Axboe Cc: Jeroen de Borst Cc: Jiri Kosina Cc: Joe Lawrence Cc: Johan Hedberg Cc: Josh Poimboeuf Cc: Jozsef Kadlecsik Cc: Julia Lawall Cc: Kalle Valo Cc: Louis Peens Cc: Lucas De Marchi Cc: Luiz Augusto von Dentz Cc: Maarten Lankhorst Cc: Madhavan Srinivasan Cc: Marcel Holtmann Cc: Martin K. Petersen Cc: Maxime Ripard Cc: Michael Ellerman Cc: Miroslav Benes Cc: Naveen N Rao Cc: Nicholas Piggin Cc: Nicolas Palix Cc: Oded Gabbay Cc: Ofir Bitton Cc: Pablo Neira Ayuso Cc: Paolo Abeni Cc: Petr Mladek Cc: Praveen Kaligineedi Cc: Ray Jui Cc: Robert Jarzmik Cc: Rodrigo Vivi Cc: Roger Pau Monné Cc: Russell King Cc: Scott Branden Cc: Shailend Chand Cc: Simona Vetter Cc: Simon Horman Cc: Sven Schnelle Cc: Takashi Iwai Cc: Thomas Hellström Cc: Thomas Zimmermann Cc: Vasily Gorbik Cc: Xiubo Li Signed-off-by: Andrew Morton Stable-dep-of: 9f6e82d11bb9 ("wifi: ath11k: avoid burning CPU in ath11k_debugfs_fw_stats_request()") Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath11k/debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/debugfs.c b/drivers/net/wireless/ath/ath11k/debugfs.c index 34aa04d27a1d..a8bd944f76d9 100644 --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c @@ -178,7 +178,7 @@ static int ath11k_debugfs_fw_stats_request(struct ath11k *ar, * received 'update stats' event, we keep a 3 seconds timeout in case, * fw_stats_done is not marked yet */ - timeout = jiffies + msecs_to_jiffies(3 * 1000); + timeout = jiffies + secs_to_jiffies(3); ath11k_debugfs_fw_stats_reset(ar); From e57c74d76076b0fd6479427402ca9178b5b71bc3 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Thu, 20 Feb 2025 16:24:42 +0800 Subject: [PATCH 342/971] wifi: ath11k: avoid burning CPU in ath11k_debugfs_fw_stats_request() [ Upstream commit 9f6e82d11bb9692a90d20b10f87345598945c803 ] We get report [1] that CPU is running a hot loop in ath11k_debugfs_fw_stats_request(): 94.60% 0.00% i3status [kernel.kallsyms] [k] do_syscall_64 | --94.60%--do_syscall_64 | --94.55%--__sys_sendmsg ___sys_sendmsg ____sys_sendmsg netlink_sendmsg netlink_unicast genl_rcv netlink_rcv_skb genl_rcv_msg | --94.55%--genl_family_rcv_msg_dumpit __netlink_dump_start netlink_dump genl_dumpit nl80211_dump_station | --94.55%--ieee80211_dump_station sta_set_sinfo | --94.55%--ath11k_mac_op_sta_statistics ath11k_debugfs_get_fw_stats | --94.55%--ath11k_debugfs_fw_stats_request | |--41.73%--_raw_spin_lock_bh | |--22.74%--__local_bh_enable_ip | |--9.22%--_raw_spin_unlock_bh | --6.66%--srso_alias_safe_ret This is because, if for whatever reason ar->fw_stats_done is not set by ath11k_update_stats_event(), ath11k_debugfs_fw_stats_request() won't yield CPU before an up to 3s timeout. Change to completion mechanism to avoid CPU burning. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37 Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") Reported-by: Yury Vostrikov Closes: https://lore.kernel.org/all/7324ac7a-8b7a-42a5-aa19-de52138ff638@app.fastmail.com/ # [1] Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20250220082448.31039-2-quic_bqiang@quicinc.com Signed-off-by: Jeff Johnson Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath11k/core.c | 1 + drivers/net/wireless/ath/ath11k/core.h | 2 +- drivers/net/wireless/ath/ath11k/debugfs.c | 38 +++++++++-------------- drivers/net/wireless/ath/ath11k/mac.c | 2 +- drivers/net/wireless/ath/ath11k/wmi.c | 2 +- 5 files changed, 18 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index f9870ba651d8..12c5f50f61f9 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -748,6 +748,7 @@ void ath11k_fw_stats_init(struct ath11k *ar) INIT_LIST_HEAD(&ar->fw_stats.bcn); init_completion(&ar->fw_stats_complete); + init_completion(&ar->fw_stats_done); } void ath11k_fw_stats_free(struct ath11k_fw_stats *stats) diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index b04447762483..41ccf59a4fd9 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -732,7 +732,7 @@ struct ath11k { u8 alpha2[REG_ALPHA2_LEN + 1]; struct ath11k_fw_stats fw_stats; struct completion fw_stats_complete; - bool fw_stats_done; + struct completion fw_stats_done; /* protected by conf_mutex */ bool ps_state_enable; diff --git a/drivers/net/wireless/ath/ath11k/debugfs.c b/drivers/net/wireless/ath/ath11k/debugfs.c index a8bd944f76d9..a5791155fe06 100644 --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -96,7 +96,6 @@ void ath11k_debugfs_add_dbring_entry(struct ath11k *ar, static void ath11k_debugfs_fw_stats_reset(struct ath11k *ar) { spin_lock_bh(&ar->data_lock); - ar->fw_stats_done = false; ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs); ath11k_fw_stats_vdevs_free(&ar->fw_stats.vdevs); spin_unlock_bh(&ar->data_lock); @@ -114,7 +113,7 @@ void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats * /* WMI_REQUEST_PDEV_STAT request has been already processed */ if (stats->stats_id == WMI_REQUEST_RSSI_PER_CHAIN_STAT) { - ar->fw_stats_done = true; + complete(&ar->fw_stats_done); return; } @@ -138,7 +137,7 @@ void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats * &ar->fw_stats.vdevs); if (is_end) { - ar->fw_stats_done = true; + complete(&ar->fw_stats_done); num_vdev = 0; } return; @@ -158,7 +157,7 @@ void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats * &ar->fw_stats.bcn); if (is_end) { - ar->fw_stats_done = true; + complete(&ar->fw_stats_done); num_bcn = 0; } } @@ -168,21 +167,15 @@ static int ath11k_debugfs_fw_stats_request(struct ath11k *ar, struct stats_request_params *req_param) { struct ath11k_base *ab = ar->ab; - unsigned long timeout, time_left; + unsigned long time_left; int ret; lockdep_assert_held(&ar->conf_mutex); - /* FW stats can get split when exceeding the stats data buffer limit. - * In that case, since there is no end marking for the back-to-back - * received 'update stats' event, we keep a 3 seconds timeout in case, - * fw_stats_done is not marked yet - */ - timeout = jiffies + secs_to_jiffies(3); - ath11k_debugfs_fw_stats_reset(ar); reinit_completion(&ar->fw_stats_complete); + reinit_completion(&ar->fw_stats_done); ret = ath11k_wmi_send_stats_request_cmd(ar, req_param); @@ -193,21 +186,18 @@ static int ath11k_debugfs_fw_stats_request(struct ath11k *ar, } time_left = wait_for_completion_timeout(&ar->fw_stats_complete, 1 * HZ); - if (!time_left) return -ETIMEDOUT; - for (;;) { - if (time_after(jiffies, timeout)) - break; + /* FW stats can get split when exceeding the stats data buffer limit. + * In that case, since there is no end marking for the back-to-back + * received 'update stats' event, we keep a 3 seconds timeout in case, + * fw_stats_done is not marked yet + */ + time_left = wait_for_completion_timeout(&ar->fw_stats_done, 3 * HZ); + if (!time_left) + return -ETIMEDOUT; - spin_lock_bh(&ar->data_lock); - if (ar->fw_stats_done) { - spin_unlock_bh(&ar->data_lock); - break; - } - spin_unlock_bh(&ar->data_lock); - } return 0; } diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 4247c0f840a4..c3bfbc40273d 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -9010,11 +9010,11 @@ static int ath11k_fw_stats_request(struct ath11k *ar, lockdep_assert_held(&ar->conf_mutex); spin_lock_bh(&ar->data_lock); - ar->fw_stats_done = false; ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs); spin_unlock_bh(&ar->data_lock); reinit_completion(&ar->fw_stats_complete); + reinit_completion(&ar->fw_stats_done); ret = ath11k_wmi_send_stats_request_cmd(ar, req_param); if (ret) { diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 2cc13e60f422..9a829b828242 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -8183,7 +8183,7 @@ static void ath11k_update_stats_event(struct ath11k_base *ab, struct sk_buff *sk */ if (stats.stats_id == WMI_REQUEST_PDEV_STAT) { list_splice_tail_init(&stats.pdevs, &ar->fw_stats.pdevs); - ar->fw_stats_done = true; + complete(&ar->fw_stats_done); goto complete; } From a0ec9e39cbf7c3e19ba40075223858b729e1d1a2 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Thu, 20 Feb 2025 16:24:43 +0800 Subject: [PATCH 343/971] wifi: ath11k: don't use static variables in ath11k_debugfs_fw_stats_process() [ Upstream commit 2bcf73b2612dda7432f2c2eaad6679bd291791f2 ] Currently ath11k_debugfs_fw_stats_process() is using static variables to count firmware stat events. Taking num_vdev as an example, if for whatever reason ( say ar->num_started_vdevs is 0 or firmware bug etc.) the following condition (++num_vdev) == total_vdevs_started is not met, is_end is not set thus num_vdev won't be cleared. Next time when firmware stats is requested again, even if everything is working fine, we will fail due to the condition above will never be satisfied. The same applies to num_bcn as well. Change to use non-static counters so that we have a chance to clear them each time firmware stats is requested. Currently only ath11k_fw_stats_request() and ath11k_debugfs_fw_stats_request() are requesting firmware stats, so clear counters there. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37 Fixes: da3a9d3c1576 ("ath11k: refactor debugfs code into debugfs.c") Signed-off-by: Baochen Qiang Acked-by: Kalle Valo Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20250220082448.31039-3-quic_bqiang@quicinc.com Signed-off-by: Jeff Johnson Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath11k/core.h | 2 ++ drivers/net/wireless/ath/ath11k/debugfs.c | 16 +++++++--------- drivers/net/wireless/ath/ath11k/mac.c | 2 ++ 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 41ccf59a4fd9..555deafd8399 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -550,6 +550,8 @@ struct ath11k_fw_stats { struct list_head pdevs; struct list_head vdevs; struct list_head bcn; + u32 num_vdev_recvd; + u32 num_bcn_recvd; }; struct ath11k_dbg_htt_stats { diff --git a/drivers/net/wireless/ath/ath11k/debugfs.c b/drivers/net/wireless/ath/ath11k/debugfs.c index a5791155fe06..5a375d668059 100644 --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c @@ -98,6 +98,8 @@ static void ath11k_debugfs_fw_stats_reset(struct ath11k *ar) spin_lock_bh(&ar->data_lock); ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs); ath11k_fw_stats_vdevs_free(&ar->fw_stats.vdevs); + ar->fw_stats.num_vdev_recvd = 0; + ar->fw_stats.num_bcn_recvd = 0; spin_unlock_bh(&ar->data_lock); } @@ -106,7 +108,6 @@ void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats * struct ath11k_base *ab = ar->ab; struct ath11k_pdev *pdev; bool is_end; - static unsigned int num_vdev, num_bcn; size_t total_vdevs_started = 0; int i; @@ -131,15 +132,14 @@ void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats * total_vdevs_started += ar->num_started_vdevs; } - is_end = ((++num_vdev) == total_vdevs_started); + is_end = ((++ar->fw_stats.num_vdev_recvd) == total_vdevs_started); list_splice_tail_init(&stats->vdevs, &ar->fw_stats.vdevs); - if (is_end) { + if (is_end) complete(&ar->fw_stats_done); - num_vdev = 0; - } + return; } @@ -151,15 +151,13 @@ void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats * /* Mark end until we reached the count of all started VDEVs * within the PDEV */ - is_end = ((++num_bcn) == ar->num_started_vdevs); + is_end = ((++ar->fw_stats.num_bcn_recvd) == ar->num_started_vdevs); list_splice_tail_init(&stats->bcn, &ar->fw_stats.bcn); - if (is_end) { + if (is_end) complete(&ar->fw_stats_done); - num_bcn = 0; - } } } diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index c3bfbc40273d..9df3f6449f76 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -9011,6 +9011,8 @@ static int ath11k_fw_stats_request(struct ath11k *ar, spin_lock_bh(&ar->data_lock); ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs); + ar->fw_stats.num_vdev_recvd = 0; + ar->fw_stats.num_bcn_recvd = 0; spin_unlock_bh(&ar->data_lock); reinit_completion(&ar->fw_stats_complete); From e8e4057570049168489a321174abd2df3eb7359d Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Thu, 20 Feb 2025 16:24:44 +0800 Subject: [PATCH 344/971] wifi: ath11k: don't wait when there is no vdev started [ Upstream commit 3b6d00fa883075dcaf49221538230e038a9c0b43 ] For WMI_REQUEST_VDEV_STAT request, firmware might split response into multiple events dut to buffer limit, hence currently in ath11k_debugfs_fw_stats_process() we wait until all events received. In case there is no vdev started, this results in that below condition would never get satisfied ((++ar->fw_stats.num_vdev_recvd) == total_vdevs_started) finally the requestor would be blocked until wait time out. The same applies to WMI_REQUEST_BCN_STAT request as well due to: ((++ar->fw_stats.num_bcn_recvd) == ar->num_started_vdevs) Change to check the number of started vdev first: if it is zero, finish wait directly; if not, follow the old way. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37 Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20250220082448.31039-4-quic_bqiang@quicinc.com Signed-off-by: Jeff Johnson Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath11k/debugfs.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/debugfs.c b/drivers/net/wireless/ath/ath11k/debugfs.c index 5a375d668059..50bc17127e68 100644 --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c @@ -107,7 +107,7 @@ void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats * { struct ath11k_base *ab = ar->ab; struct ath11k_pdev *pdev; - bool is_end; + bool is_end = true; size_t total_vdevs_started = 0; int i; @@ -132,7 +132,9 @@ void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats * total_vdevs_started += ar->num_started_vdevs; } - is_end = ((++ar->fw_stats.num_vdev_recvd) == total_vdevs_started); + if (total_vdevs_started) + is_end = ((++ar->fw_stats.num_vdev_recvd) == + total_vdevs_started); list_splice_tail_init(&stats->vdevs, &ar->fw_stats.vdevs); @@ -151,7 +153,9 @@ void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats * /* Mark end until we reached the count of all started VDEVs * within the PDEV */ - is_end = ((++ar->fw_stats.num_bcn_recvd) == ar->num_started_vdevs); + if (ar->num_started_vdevs) + is_end = ((++ar->fw_stats.num_bcn_recvd) == + ar->num_started_vdevs); list_splice_tail_init(&stats->bcn, &ar->fw_stats.bcn); From 6e329771144cd7af8dbcbc1cc068454e1f654966 Mon Sep 17 00:00:00 2001 From: Rodrigo Gobbi Date: Thu, 22 May 2025 17:01:12 -0300 Subject: [PATCH 345/971] wifi: ath11k: validate ath11k_crypto_mode on top of ath11k_core_qmi_firmware_ready [ Upstream commit b0d226a60856a1b765bb9a3848c7b2322fd08c47 ] if ath11k_crypto_mode is invalid (not ATH11K_CRYPT_MODE_SW/ATH11K_CRYPT_MODE_HW), ath11k_core_qmi_firmware_ready() will not undo some actions that was previously started/configured. Do the validation as soon as possible in order to avoid undoing actions in that case and also to fix the following smatch warning: drivers/net/wireless/ath/ath11k/core.c:2166 ath11k_core_qmi_firmware_ready() warn: missing unwind goto? Signed-off-by: Rodrigo Gobbi Reported-by: kernel test robot Reported-by: Dan Carpenter Closes: https://lore.kernel.org/r/202304151955.oqAetVFd-lkp@intel.com/ Fixes: aa2092a9bab3 ("ath11k: add raw mode and software crypto support") Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250522200519.16858-1-rodrigo.gobbi.7@gmail.com Signed-off-by: Jeff Johnson Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath11k/core.c | 28 +++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 12c5f50f61f9..609d8387c41f 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -1638,6 +1638,20 @@ int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab) { int ret; + switch (ath11k_crypto_mode) { + case ATH11K_CRYPT_MODE_SW: + set_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags); + set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags); + break; + case ATH11K_CRYPT_MODE_HW: + clear_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags); + clear_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags); + break; + default: + ath11k_info(ab, "invalid crypto_mode: %d\n", ath11k_crypto_mode); + return -EINVAL; + } + ret = ath11k_core_start_firmware(ab, ab->fw_mode); if (ret) { ath11k_err(ab, "failed to start firmware: %d\n", ret); @@ -1656,20 +1670,6 @@ int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab) goto err_firmware_stop; } - switch (ath11k_crypto_mode) { - case ATH11K_CRYPT_MODE_SW: - set_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags); - set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags); - break; - case ATH11K_CRYPT_MODE_HW: - clear_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags); - clear_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags); - break; - default: - ath11k_info(ab, "invalid crypto_mode: %d\n", ath11k_crypto_mode); - return -EINVAL; - } - if (ath11k_frame_mode == ATH11K_HW_TXRX_RAW) set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags); From de2adfaa95149e25e519e5a6f750b769bf4d060e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 27 May 2025 08:44:14 +0300 Subject: [PATCH 346/971] regulator: max20086: Fix refcount leak in max20086_parse_regulators_dt() [ Upstream commit 06118ae36855b7d3d22688298e74a766ccf0cb7a ] There is a missing call to of_node_put() if devm_kcalloc() fails. Fix this by changing the code to use cleanup.h magic to drop the refcount. Fixes: 6b0cd72757c6 ("regulator: max20086: fix invalid memory access") Signed-off-by: Dan Carpenter Link: https://patch.msgid.link/aDVRLqgJWMxYU03G@stanley.mountain Reviewed-by: Laurent Pinchart Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/regulator/max20086-regulator.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/regulator/max20086-regulator.c b/drivers/regulator/max20086-regulator.c index ebfbcadbca52..1cf04d1efb33 100644 --- a/drivers/regulator/max20086-regulator.c +++ b/drivers/regulator/max20086-regulator.c @@ -5,6 +5,7 @@ // Copyright (C) 2022 Laurent Pinchart // Copyright (C) 2018 Avnet, Inc. +#include #include #include #include @@ -133,11 +134,11 @@ static int max20086_regulators_register(struct max20086 *chip) static int max20086_parse_regulators_dt(struct max20086 *chip, bool *boot_on) { struct of_regulator_match *matches; - struct device_node *node; unsigned int i; int ret; - node = of_get_child_by_name(chip->dev->of_node, "regulators"); + struct device_node *node __free(device_node) = + of_get_child_by_name(chip->dev->of_node, "regulators"); if (!node) { dev_err(chip->dev, "regulators node not found\n"); return -ENODEV; @@ -153,7 +154,6 @@ static int max20086_parse_regulators_dt(struct max20086 *chip, bool *boot_on) ret = of_regulator_match(chip->dev, node, matches, chip->info->num_outputs); - of_node_put(node); if (ret < 0) { dev_err(chip->dev, "Failed to match regulators\n"); return -EINVAL; From 581b7c3d802545f2fef31a77074f64bd25fb73c1 Mon Sep 17 00:00:00 2001 From: Wojciech Slenska Date: Fri, 23 May 2025 12:14:37 +0200 Subject: [PATCH 347/971] pinctrl: qcom: pinctrl-qcm2290: Add missing pins [ Upstream commit 315345610faee8a0568b522dba9e35067d1732ab ] Added the missing pins to the qcm2290_pins table. Signed-off-by: Wojciech Slenska Fixes: 48e049ef1238 ("pinctrl: qcom: Add QCM2290 pinctrl driver") Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/20250523101437.59092-1-wojciech.slenska@gmail.com Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin --- drivers/pinctrl/qcom/pinctrl-qcm2290.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/pinctrl/qcom/pinctrl-qcm2290.c b/drivers/pinctrl/qcom/pinctrl-qcm2290.c index f5c1c427b44e..61b7c22e963c 100644 --- a/drivers/pinctrl/qcom/pinctrl-qcm2290.c +++ b/drivers/pinctrl/qcom/pinctrl-qcm2290.c @@ -165,6 +165,10 @@ static const struct pinctrl_pin_desc qcm2290_pins[] = { PINCTRL_PIN(62, "GPIO_62"), PINCTRL_PIN(63, "GPIO_63"), PINCTRL_PIN(64, "GPIO_64"), + PINCTRL_PIN(65, "GPIO_65"), + PINCTRL_PIN(66, "GPIO_66"), + PINCTRL_PIN(67, "GPIO_67"), + PINCTRL_PIN(68, "GPIO_68"), PINCTRL_PIN(69, "GPIO_69"), PINCTRL_PIN(70, "GPIO_70"), PINCTRL_PIN(71, "GPIO_71"), @@ -179,12 +183,17 @@ static const struct pinctrl_pin_desc qcm2290_pins[] = { PINCTRL_PIN(80, "GPIO_80"), PINCTRL_PIN(81, "GPIO_81"), PINCTRL_PIN(82, "GPIO_82"), + PINCTRL_PIN(83, "GPIO_83"), + PINCTRL_PIN(84, "GPIO_84"), + PINCTRL_PIN(85, "GPIO_85"), PINCTRL_PIN(86, "GPIO_86"), PINCTRL_PIN(87, "GPIO_87"), PINCTRL_PIN(88, "GPIO_88"), PINCTRL_PIN(89, "GPIO_89"), PINCTRL_PIN(90, "GPIO_90"), PINCTRL_PIN(91, "GPIO_91"), + PINCTRL_PIN(92, "GPIO_92"), + PINCTRL_PIN(93, "GPIO_93"), PINCTRL_PIN(94, "GPIO_94"), PINCTRL_PIN(95, "GPIO_95"), PINCTRL_PIN(96, "GPIO_96"), From d4cbcf274c516cb97e6cd2987e4fb7b5a9952fb9 Mon Sep 17 00:00:00 2001 From: Alok Tiwari Date: Fri, 30 May 2025 12:29:35 -0700 Subject: [PATCH 348/971] scsi: iscsi: Fix incorrect error path labels for flashnode operations [ Upstream commit 9b17621366d210ffee83262a8754086ebbde5e55 ] Correct the error handling goto labels used when host lookup fails in various flashnode-related event handlers: - iscsi_new_flashnode() - iscsi_del_flashnode() - iscsi_login_flashnode() - iscsi_logout_flashnode() - iscsi_logout_flashnode_sid() scsi_host_put() is not required when shost is NULL, so jumping to the correct label avoids unnecessary operations. These functions previously jumped to the wrong goto label (put_host), which did not match the intended cleanup logic. Use the correct exit labels (exit_new_fnode, exit_del_fnode, etc.) to ensure proper error handling. Also remove the unused put_host label under iscsi_new_flashnode() as it is no longer needed. No functional changes beyond accurate error path correction. Fixes: c6a4bb2ef596 ("[SCSI] scsi_transport_iscsi: Add flash node mgmt support") Signed-off-by: Alok Tiwari Link: https://lore.kernel.org/r/20250530193012.3312911-1-alok.a.tiwari@oracle.com Reviewed-by: Mike Christie Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/scsi_transport_iscsi.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 0c30fec55547..f2c31e74d8ed 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -3525,7 +3525,7 @@ static int iscsi_new_flashnode(struct iscsi_transport *transport, pr_err("%s could not find host no %u\n", __func__, ev->u.new_flashnode.host_no); err = -ENODEV; - goto put_host; + goto exit_new_fnode; } index = transport->new_flashnode(shost, data, len); @@ -3535,7 +3535,6 @@ static int iscsi_new_flashnode(struct iscsi_transport *transport, else err = -EIO; -put_host: scsi_host_put(shost); exit_new_fnode: @@ -3560,7 +3559,7 @@ static int iscsi_del_flashnode(struct iscsi_transport *transport, pr_err("%s could not find host no %u\n", __func__, ev->u.del_flashnode.host_no); err = -ENODEV; - goto put_host; + goto exit_del_fnode; } idx = ev->u.del_flashnode.flashnode_idx; @@ -3602,7 +3601,7 @@ static int iscsi_login_flashnode(struct iscsi_transport *transport, pr_err("%s could not find host no %u\n", __func__, ev->u.login_flashnode.host_no); err = -ENODEV; - goto put_host; + goto exit_login_fnode; } idx = ev->u.login_flashnode.flashnode_idx; @@ -3654,7 +3653,7 @@ static int iscsi_logout_flashnode(struct iscsi_transport *transport, pr_err("%s could not find host no %u\n", __func__, ev->u.logout_flashnode.host_no); err = -ENODEV; - goto put_host; + goto exit_logout_fnode; } idx = ev->u.logout_flashnode.flashnode_idx; @@ -3704,7 +3703,7 @@ static int iscsi_logout_flashnode_sid(struct iscsi_transport *transport, pr_err("%s could not find host no %u\n", __func__, ev->u.logout_flashnode.host_no); err = -ENODEV; - goto put_host; + goto exit_logout_sid; } session = iscsi_session_lookup(ev->u.logout_flashnode_sid.sid); From b4e9bab6011b9559b7c157b16b91ae46d4d8c533 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 6 Jun 2025 16:51:27 +0000 Subject: [PATCH 349/971] net_sched: sch_sfq: fix a potential crash on gso_skb handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 82ffbe7776d0ac084031f114167712269bf3d832 ] SFQ has an assumption of always being able to queue at least one packet. However, after the blamed commit, sch->q.len can be inflated by packets in sch->gso_skb, and an enqueue() on an empty SFQ qdisc can be followed by an immediate drop. Fix sfq_drop() to properly clear q->tail in this situation. Tested: ip netns add lb ip link add dev to-lb type veth peer name in-lb netns lb ethtool -K to-lb tso off # force qdisc to requeue gso_skb ip netns exec lb ethtool -K in-lb gro on # enable NAPI ip link set dev to-lb up ip -netns lb link set dev in-lb up ip addr add dev to-lb 192.168.20.1/24 ip -netns lb addr add dev in-lb 192.168.20.2/24 tc qdisc replace dev to-lb root sfq limit 100 ip netns exec lb netserver netperf -H 192.168.20.2 -l 100 & netperf -H 192.168.20.2 -l 100 & netperf -H 192.168.20.2 -l 100 & netperf -H 192.168.20.2 -l 100 & Fixes: a53851e2c321 ("net: sched: explicit locking in gso_cpu fallback") Reported-by: Marcus Wichelmann Closes: https://lore.kernel.org/netdev/9da42688-bfaa-4364-8797-e9271f3bdaef@hetzner-cloud.de/ Signed-off-by: Eric Dumazet Reviewed-by: Toke Høiland-Jørgensen Link: https://patch.msgid.link/20250606165127.3629486-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/sched/sch_sfq.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 002941d35b64..d564675a8be4 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -310,7 +310,10 @@ drop: /* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */ x = q->tail->next; slot = &q->slots[x]; - q->tail->next = slot->next; + if (slot->next == x) + q->tail = NULL; /* no more active slots */ + else + q->tail->next = slot->next; q->ht[slot->hash] = SFQ_EMPTY_SLOT; goto drop; } From 8635e325b85dfb9ddebdfaa6b5605d40d16cd147 Mon Sep 17 00:00:00 2001 From: "Ritesh Harjani (IBM)" Date: Tue, 10 Jun 2025 07:42:26 +0530 Subject: [PATCH 350/971] powerpc/powernv/memtrace: Fix out of bounds issue in memtrace mmap [ Upstream commit cd097df4596f3a1e9d75eb8520162de1eb8485b2 ] memtrace mmap issue has an out of bounds issue. This patch fixes the by checking that the requested mapping region size should stay within the allocated region size. Reported-by: Jonathan Greental Fixes: 08a022ad3dfa ("powerpc/powernv/memtrace: Allow mmaping trace buffers") Signed-off-by: Ritesh Harjani (IBM) Signed-off-by: Madhavan Srinivasan Link: https://patch.msgid.link/20250610021227.361980-1-maddy@linux.ibm.com Signed-off-by: Sasha Levin --- arch/powerpc/platforms/powernv/memtrace.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/powernv/memtrace.c b/arch/powerpc/platforms/powernv/memtrace.c index 877720c64515..35471b679638 100644 --- a/arch/powerpc/platforms/powernv/memtrace.c +++ b/arch/powerpc/platforms/powernv/memtrace.c @@ -48,11 +48,15 @@ static ssize_t memtrace_read(struct file *filp, char __user *ubuf, static int memtrace_mmap(struct file *filp, struct vm_area_struct *vma) { struct memtrace_entry *ent = filp->private_data; + unsigned long ent_nrpages = ent->size >> PAGE_SHIFT; + unsigned long vma_nrpages = vma_pages(vma); - if (ent->size < vma->vm_end - vma->vm_start) + /* The requested page offset should be within object's page count */ + if (vma->vm_pgoff >= ent_nrpages) return -EINVAL; - if (vma->vm_pgoff << PAGE_SHIFT >= ent->size) + /* The requested mapping range should remain within the bounds */ + if (vma_nrpages > ent_nrpages - vma->vm_pgoff) return -EINVAL; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); From d2fc85c90b411b45449fadbcacd7f3f97303dd79 Mon Sep 17 00:00:00 2001 From: Haren Myneni Date: Tue, 10 Jun 2025 07:42:27 +0530 Subject: [PATCH 351/971] powerpc/vas: Return -EINVAL if the offset is non-zero in mmap() [ Upstream commit 0d67f0dee6c9176bc09a5482dd7346e3a0f14d0b ] The user space calls mmap() to map VAS window paste address and the kernel returns the complete mapped page for each window. So return -EINVAL if non-zero is passed for offset parameter to mmap(). See Documentation/arch/powerpc/vas-api.rst for mmap() restrictions. Co-developed-by: Jonathan Greental Signed-off-by: Jonathan Greental Reported-by: Jonathan Greental Fixes: dda44eb29c23 ("powerpc/vas: Add VAS user space API") Signed-off-by: Haren Myneni Signed-off-by: Madhavan Srinivasan Link: https://patch.msgid.link/20250610021227.361980-2-maddy@linux.ibm.com Signed-off-by: Sasha Levin --- arch/powerpc/platforms/book3s/vas-api.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/powerpc/platforms/book3s/vas-api.c b/arch/powerpc/platforms/book3s/vas-api.c index 0b6365d85d11..dc6f75d3ac6e 100644 --- a/arch/powerpc/platforms/book3s/vas-api.c +++ b/arch/powerpc/platforms/book3s/vas-api.c @@ -521,6 +521,15 @@ static int coproc_mmap(struct file *fp, struct vm_area_struct *vma) return -EINVAL; } + /* + * Map complete page to the paste address. So the user + * space should pass 0ULL to the offset parameter. + */ + if (vma->vm_pgoff) { + pr_debug("Page offset unsupported to map paste address\n"); + return -EINVAL; + } + /* Ensure instance has an open send window */ if (!txwin) { pr_err("No send window open?\n"); From 1f8d03fb90ed252cc4ee17dc62a72d58fb455f43 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Mon, 21 Apr 2025 22:13:00 +0200 Subject: [PATCH 352/971] drm/meson: use unsigned long long / Hz for frequency types [ Upstream commit 1017560164b6bbcbc93579266926e6e96675262a ] Christian reports that 4K output using YUV420 encoding fails with the following error: Fatal Error, invalid HDMI vclk freq 593406 Modetest shows the following: 3840x2160 59.94 3840 4016 4104 4400 2160 2168 2178 2250 593407 flags: xxxx, xxxx, drm calculated value -------------------------------------^ This indicates that there's a (1kHz) mismatch between the clock calculated by the drm framework and the meson driver. Relevant function call stack: (drm framework) -> meson_encoder_hdmi_atomic_enable() -> meson_encoder_hdmi_set_vclk() -> meson_vclk_setup() The video clock requested by the drm framework is 593407kHz. This is passed by meson_encoder_hdmi_atomic_enable() to meson_encoder_hdmi_set_vclk() and the following formula is applied: - the frequency is halved (which would be 296703.5kHz) and rounded down to the next full integer, which is 296703kHz - TMDS clock is calculated (296703kHz * 10) - video encoder clock is calculated - this needs to match a table from meson_vclk.c and so it doubles the previously halved value again (resulting in 593406kHz) - meson_vclk_setup() can't find (either directly, or by deriving it from 594000kHz * 1000 / 1001 and rounding to the closest integer value - which is 593407kHz as originally requested by the drm framework) a matching clock in it's internal table and errors out with "invalid HDMI vclk freq" Fix the division precision by switching the whole meson driver to use unsigned long long (64-bit) Hz values for clock frequencies instead of unsigned int (32-bit) kHz to fix the rouding error. Fixes: e5fab2ec9ca4 ("drm/meson: vclk: add support for YUV420 setup") Reported-by: Christian Hewitt Signed-off-by: Martin Blumenstingl Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20250421201300.778955-3-martin.blumenstingl@googlemail.com Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20250421201300.778955-3-martin.blumenstingl@googlemail.com Stable-dep-of: d17e61ab63fb ("drm/meson: fix debug log statement when setting the HDMI clocks") Signed-off-by: Sasha Levin --- drivers/gpu/drm/meson/meson_drv.c | 2 +- drivers/gpu/drm/meson/meson_drv.h | 2 +- drivers/gpu/drm/meson/meson_encoder_hdmi.c | 29 +-- drivers/gpu/drm/meson/meson_vclk.c | 195 +++++++++++---------- drivers/gpu/drm/meson/meson_vclk.h | 13 +- 5 files changed, 126 insertions(+), 115 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 095f634ff7c7..27441e571630 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -168,7 +168,7 @@ static const struct meson_drm_soc_attr meson_drm_soc_attrs[] = { /* S805X/S805Y HDMI PLL won't lock for HDMI PHY freq > 1,65GHz */ { .limits = { - .max_hdmi_phy_freq = 1650000, + .max_hdmi_phy_freq = 1650000000, }, .attrs = (const struct soc_device_attribute []) { { .soc_id = "GXL (S805*)", }, diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h index 3f9345c14f31..be4b0e4df6e1 100644 --- a/drivers/gpu/drm/meson/meson_drv.h +++ b/drivers/gpu/drm/meson/meson_drv.h @@ -37,7 +37,7 @@ struct meson_drm_match_data { }; struct meson_drm_soc_limits { - unsigned int max_hdmi_phy_freq; + unsigned long long max_hdmi_phy_freq; }; struct meson_drm { diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c index c4686568c9ca..cd0e9e2d59ee 100644 --- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c +++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c @@ -70,12 +70,12 @@ static void meson_encoder_hdmi_set_vclk(struct meson_encoder_hdmi *encoder_hdmi, { struct meson_drm *priv = encoder_hdmi->priv; int vic = drm_match_cea_mode(mode); - unsigned int phy_freq; - unsigned int vclk_freq; - unsigned int venc_freq; - unsigned int hdmi_freq; + unsigned long long phy_freq; + unsigned long long vclk_freq; + unsigned long long venc_freq; + unsigned long long hdmi_freq; - vclk_freq = mode->clock; + vclk_freq = mode->clock * 1000; /* For 420, pixel clock is half unlike venc clock */ if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) @@ -107,7 +107,8 @@ static void meson_encoder_hdmi_set_vclk(struct meson_encoder_hdmi *encoder_hdmi, if (mode->flags & DRM_MODE_FLAG_DBLCLK) venc_freq /= 2; - dev_dbg(priv->dev, "vclk:%d phy=%d venc=%d hdmi=%d enci=%d\n", + dev_dbg(priv->dev, + "vclk:%lluHz phy=%lluHz venc=%lluHz hdmi=%lluHz enci=%d\n", phy_freq, vclk_freq, venc_freq, hdmi_freq, priv->venc.hdmi_use_enci); @@ -122,10 +123,11 @@ static enum drm_mode_status meson_encoder_hdmi_mode_valid(struct drm_bridge *bri struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge); struct meson_drm *priv = encoder_hdmi->priv; bool is_hdmi2_sink = display_info->hdmi.scdc.supported; - unsigned int phy_freq; - unsigned int vclk_freq; - unsigned int venc_freq; - unsigned int hdmi_freq; + unsigned long long clock = mode->clock * 1000; + unsigned long long phy_freq; + unsigned long long vclk_freq; + unsigned long long venc_freq; + unsigned long long hdmi_freq; int vic = drm_match_cea_mode(mode); enum drm_mode_status status; @@ -144,12 +146,12 @@ static enum drm_mode_status meson_encoder_hdmi_mode_valid(struct drm_bridge *bri if (status != MODE_OK) return status; - return meson_vclk_dmt_supported_freq(priv, mode->clock); + return meson_vclk_dmt_supported_freq(priv, clock); /* Check against supported VIC modes */ } else if (!meson_venc_hdmi_supported_vic(vic)) return MODE_BAD; - vclk_freq = mode->clock; + vclk_freq = clock; /* For 420, pixel clock is half unlike venc clock */ if (drm_mode_is_420_only(display_info, mode) || @@ -179,7 +181,8 @@ static enum drm_mode_status meson_encoder_hdmi_mode_valid(struct drm_bridge *bri if (mode->flags & DRM_MODE_FLAG_DBLCLK) venc_freq /= 2; - dev_dbg(priv->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n", + dev_dbg(priv->dev, + "%s: vclk:%lluHz phy=%lluHz venc=%lluHz hdmi=%lluHz\n", __func__, phy_freq, vclk_freq, venc_freq, hdmi_freq); return meson_vclk_vic_supported_freq(priv, phy_freq, vclk_freq); diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c index 2a82119eb58e..3325580d885d 100644 --- a/drivers/gpu/drm/meson/meson_vclk.c +++ b/drivers/gpu/drm/meson/meson_vclk.c @@ -110,7 +110,10 @@ #define HDMI_PLL_LOCK BIT(31) #define HDMI_PLL_LOCK_G12A (3 << 30) -#define FREQ_1000_1001(_freq) DIV_ROUND_CLOSEST(_freq * 1000, 1001) +#define PIXEL_FREQ_1000_1001(_freq) \ + DIV_ROUND_CLOSEST_ULL((_freq) * 1000ULL, 1001ULL) +#define PHY_FREQ_1000_1001(_freq) \ + (PIXEL_FREQ_1000_1001(DIV_ROUND_DOWN_ULL(_freq, 10ULL)) * 10) /* VID PLL Dividers */ enum { @@ -360,11 +363,11 @@ enum { }; struct meson_vclk_params { - unsigned int pll_freq; - unsigned int phy_freq; - unsigned int vclk_freq; - unsigned int venc_freq; - unsigned int pixel_freq; + unsigned long long pll_freq; + unsigned long long phy_freq; + unsigned long long vclk_freq; + unsigned long long venc_freq; + unsigned long long pixel_freq; unsigned int pll_od1; unsigned int pll_od2; unsigned int pll_od3; @@ -372,11 +375,11 @@ struct meson_vclk_params { unsigned int vclk_div; } params[] = { [MESON_VCLK_HDMI_ENCI_54000] = { - .pll_freq = 4320000, - .phy_freq = 270000, - .vclk_freq = 54000, - .venc_freq = 54000, - .pixel_freq = 54000, + .pll_freq = 4320000000, + .phy_freq = 270000000, + .vclk_freq = 54000000, + .venc_freq = 54000000, + .pixel_freq = 54000000, .pll_od1 = 4, .pll_od2 = 4, .pll_od3 = 1, @@ -384,11 +387,11 @@ struct meson_vclk_params { .vclk_div = 1, }, [MESON_VCLK_HDMI_DDR_54000] = { - .pll_freq = 4320000, - .phy_freq = 270000, - .vclk_freq = 54000, - .venc_freq = 54000, - .pixel_freq = 27000, + .pll_freq = 4320000000, + .phy_freq = 270000000, + .vclk_freq = 54000000, + .venc_freq = 54000000, + .pixel_freq = 27000000, .pll_od1 = 4, .pll_od2 = 4, .pll_od3 = 1, @@ -396,11 +399,11 @@ struct meson_vclk_params { .vclk_div = 1, }, [MESON_VCLK_HDMI_DDR_148500] = { - .pll_freq = 2970000, - .phy_freq = 742500, - .vclk_freq = 148500, - .venc_freq = 148500, - .pixel_freq = 74250, + .pll_freq = 2970000000, + .phy_freq = 742500000, + .vclk_freq = 148500000, + .venc_freq = 148500000, + .pixel_freq = 74250000, .pll_od1 = 4, .pll_od2 = 1, .pll_od3 = 1, @@ -408,11 +411,11 @@ struct meson_vclk_params { .vclk_div = 1, }, [MESON_VCLK_HDMI_74250] = { - .pll_freq = 2970000, - .phy_freq = 742500, - .vclk_freq = 74250, - .venc_freq = 74250, - .pixel_freq = 74250, + .pll_freq = 2970000000, + .phy_freq = 742500000, + .vclk_freq = 74250000, + .venc_freq = 74250000, + .pixel_freq = 74250000, .pll_od1 = 2, .pll_od2 = 2, .pll_od3 = 2, @@ -420,11 +423,11 @@ struct meson_vclk_params { .vclk_div = 1, }, [MESON_VCLK_HDMI_148500] = { - .pll_freq = 2970000, - .phy_freq = 1485000, - .vclk_freq = 148500, - .venc_freq = 148500, - .pixel_freq = 148500, + .pll_freq = 2970000000, + .phy_freq = 1485000000, + .vclk_freq = 148500000, + .venc_freq = 148500000, + .pixel_freq = 148500000, .pll_od1 = 1, .pll_od2 = 2, .pll_od3 = 2, @@ -432,11 +435,11 @@ struct meson_vclk_params { .vclk_div = 1, }, [MESON_VCLK_HDMI_297000] = { - .pll_freq = 5940000, - .phy_freq = 2970000, - .venc_freq = 297000, - .vclk_freq = 297000, - .pixel_freq = 297000, + .pll_freq = 5940000000, + .phy_freq = 2970000000, + .venc_freq = 297000000, + .vclk_freq = 297000000, + .pixel_freq = 297000000, .pll_od1 = 2, .pll_od2 = 1, .pll_od3 = 1, @@ -444,11 +447,11 @@ struct meson_vclk_params { .vclk_div = 2, }, [MESON_VCLK_HDMI_594000] = { - .pll_freq = 5940000, - .phy_freq = 5940000, - .venc_freq = 594000, - .vclk_freq = 594000, - .pixel_freq = 594000, + .pll_freq = 5940000000, + .phy_freq = 5940000000, + .venc_freq = 594000000, + .vclk_freq = 594000000, + .pixel_freq = 594000000, .pll_od1 = 1, .pll_od2 = 1, .pll_od3 = 2, @@ -456,11 +459,11 @@ struct meson_vclk_params { .vclk_div = 1, }, [MESON_VCLK_HDMI_594000_YUV420] = { - .pll_freq = 5940000, - .phy_freq = 2970000, - .venc_freq = 594000, - .vclk_freq = 594000, - .pixel_freq = 297000, + .pll_freq = 5940000000, + .phy_freq = 2970000000, + .venc_freq = 594000000, + .vclk_freq = 594000000, + .pixel_freq = 297000000, .pll_od1 = 2, .pll_od2 = 1, .pll_od3 = 1, @@ -617,16 +620,16 @@ static void meson_hdmi_pll_set_params(struct meson_drm *priv, unsigned int m, 3 << 20, pll_od_to_reg(od3) << 20); } -#define XTAL_FREQ 24000 +#define XTAL_FREQ (24 * 1000 * 1000) static unsigned int meson_hdmi_pll_get_m(struct meson_drm *priv, - unsigned int pll_freq) + unsigned long long pll_freq) { /* The GXBB PLL has a /2 pre-multiplier */ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) - pll_freq /= 2; + pll_freq = DIV_ROUND_DOWN_ULL(pll_freq, 2); - return pll_freq / XTAL_FREQ; + return DIV_ROUND_DOWN_ULL(pll_freq, XTAL_FREQ); } #define HDMI_FRAC_MAX_GXBB 4096 @@ -635,12 +638,13 @@ static unsigned int meson_hdmi_pll_get_m(struct meson_drm *priv, static unsigned int meson_hdmi_pll_get_frac(struct meson_drm *priv, unsigned int m, - unsigned int pll_freq) + unsigned long long pll_freq) { - unsigned int parent_freq = XTAL_FREQ; + unsigned long long parent_freq = XTAL_FREQ; unsigned int frac_max = HDMI_FRAC_MAX_GXL; unsigned int frac_m; unsigned int frac; + u32 remainder; /* The GXBB PLL has a /2 pre-multiplier and a larger FRAC width */ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) { @@ -652,11 +656,11 @@ static unsigned int meson_hdmi_pll_get_frac(struct meson_drm *priv, frac_max = HDMI_FRAC_MAX_G12A; /* We can have a perfect match !*/ - if (pll_freq / m == parent_freq && - pll_freq % m == 0) + if (div_u64_rem(pll_freq, m, &remainder) == parent_freq && + remainder == 0) return 0; - frac = div_u64((u64)pll_freq * (u64)frac_max, parent_freq); + frac = mul_u64_u64_div_u64(pll_freq, frac_max, parent_freq); frac_m = m * frac_max; if (frac_m > frac) return frac_max; @@ -666,7 +670,7 @@ static unsigned int meson_hdmi_pll_get_frac(struct meson_drm *priv, } static bool meson_hdmi_pll_validate_params(struct meson_drm *priv, - unsigned int m, + unsigned long long m, unsigned int frac) { if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) { @@ -694,7 +698,7 @@ static bool meson_hdmi_pll_validate_params(struct meson_drm *priv, } static bool meson_hdmi_pll_find_params(struct meson_drm *priv, - unsigned int freq, + unsigned long long freq, unsigned int *m, unsigned int *frac, unsigned int *od) @@ -706,7 +710,7 @@ static bool meson_hdmi_pll_find_params(struct meson_drm *priv, continue; *frac = meson_hdmi_pll_get_frac(priv, *m, freq * *od); - DRM_DEBUG_DRIVER("PLL params for %dkHz: m=%x frac=%x od=%d\n", + DRM_DEBUG_DRIVER("PLL params for %lluHz: m=%x frac=%x od=%d\n", freq, *m, *frac, *od); if (meson_hdmi_pll_validate_params(priv, *m, *frac)) @@ -718,7 +722,7 @@ static bool meson_hdmi_pll_find_params(struct meson_drm *priv, /* pll_freq is the frequency after the OD dividers */ enum drm_mode_status -meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq) +meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned long long freq) { unsigned int od, m, frac; @@ -741,7 +745,7 @@ EXPORT_SYMBOL_GPL(meson_vclk_dmt_supported_freq); /* pll_freq is the frequency after the OD dividers */ static void meson_hdmi_pll_generic_set(struct meson_drm *priv, - unsigned int pll_freq) + unsigned long long pll_freq) { unsigned int od, m, frac, od1, od2, od3; @@ -756,7 +760,7 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv, od1 = od / od2; } - DRM_DEBUG_DRIVER("PLL params for %dkHz: m=%x frac=%x od=%d/%d/%d\n", + DRM_DEBUG_DRIVER("PLL params for %lluHz: m=%x frac=%x od=%d/%d/%d\n", pll_freq, m, frac, od1, od2, od3); meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3); @@ -764,17 +768,18 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv, return; } - DRM_ERROR("Fatal, unable to find parameters for PLL freq %d\n", + DRM_ERROR("Fatal, unable to find parameters for PLL freq %lluHz\n", pll_freq); } enum drm_mode_status -meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq, - unsigned int vclk_freq) +meson_vclk_vic_supported_freq(struct meson_drm *priv, + unsigned long long phy_freq, + unsigned long long vclk_freq) { int i; - DRM_DEBUG_DRIVER("phy_freq = %d vclk_freq = %d\n", + DRM_DEBUG_DRIVER("phy_freq = %lluHz vclk_freq = %lluHz\n", phy_freq, vclk_freq); /* Check against soc revision/package limits */ @@ -785,19 +790,19 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq, } for (i = 0 ; params[i].pixel_freq ; ++i) { - DRM_DEBUG_DRIVER("i = %d pixel_freq = %d alt = %d\n", + DRM_DEBUG_DRIVER("i = %d pixel_freq = %lluHz alt = %lluHz\n", i, params[i].pixel_freq, - FREQ_1000_1001(params[i].pixel_freq)); - DRM_DEBUG_DRIVER("i = %d phy_freq = %d alt = %d\n", + PIXEL_FREQ_1000_1001(params[i].pixel_freq)); + DRM_DEBUG_DRIVER("i = %d phy_freq = %lluHz alt = %lluHz\n", i, params[i].phy_freq, - FREQ_1000_1001(params[i].phy_freq/10)*10); + PHY_FREQ_1000_1001(params[i].phy_freq)); /* Match strict frequency */ if (phy_freq == params[i].phy_freq && vclk_freq == params[i].vclk_freq) return MODE_OK; /* Match 1000/1001 variant */ - if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/10)*10) && - vclk_freq == FREQ_1000_1001(params[i].vclk_freq)) + if (phy_freq == PHY_FREQ_1000_1001(params[i].phy_freq) && + vclk_freq == PIXEL_FREQ_1000_1001(params[i].vclk_freq)) return MODE_OK; } @@ -805,8 +810,9 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq, } EXPORT_SYMBOL_GPL(meson_vclk_vic_supported_freq); -static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, - unsigned int od1, unsigned int od2, unsigned int od3, +static void meson_vclk_set(struct meson_drm *priv, + unsigned long long pll_base_freq, unsigned int od1, + unsigned int od2, unsigned int od3, unsigned int vid_pll_div, unsigned int vclk_div, unsigned int hdmi_tx_div, unsigned int venc_div, bool hdmi_use_enci, bool vic_alternate_clock) @@ -826,15 +832,15 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, meson_hdmi_pll_generic_set(priv, pll_base_freq); } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) { switch (pll_base_freq) { - case 2970000: + case 2970000000: m = 0x3d; frac = vic_alternate_clock ? 0xd02 : 0xe00; break; - case 4320000: + case 4320000000: m = vic_alternate_clock ? 0x59 : 0x5a; frac = vic_alternate_clock ? 0xe8f : 0; break; - case 5940000: + case 5940000000: m = 0x7b; frac = vic_alternate_clock ? 0xa05 : 0xc00; break; @@ -844,15 +850,15 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) || meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) { switch (pll_base_freq) { - case 2970000: + case 2970000000: m = 0x7b; frac = vic_alternate_clock ? 0x281 : 0x300; break; - case 4320000: + case 4320000000: m = vic_alternate_clock ? 0xb3 : 0xb4; frac = vic_alternate_clock ? 0x347 : 0; break; - case 5940000: + case 5940000000: m = 0xf7; frac = vic_alternate_clock ? 0x102 : 0x200; break; @@ -861,15 +867,15 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3); } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { switch (pll_base_freq) { - case 2970000: + case 2970000000: m = 0x7b; frac = vic_alternate_clock ? 0x140b4 : 0x18000; break; - case 4320000: + case 4320000000: m = vic_alternate_clock ? 0xb3 : 0xb4; frac = vic_alternate_clock ? 0x1a3ee : 0; break; - case 5940000: + case 5940000000: m = 0xf7; frac = vic_alternate_clock ? 0x8148 : 0x10000; break; @@ -1025,14 +1031,14 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, } void meson_vclk_setup(struct meson_drm *priv, unsigned int target, - unsigned int phy_freq, unsigned int vclk_freq, - unsigned int venc_freq, unsigned int dac_freq, + unsigned long long phy_freq, unsigned long long vclk_freq, + unsigned long long venc_freq, unsigned long long dac_freq, bool hdmi_use_enci) { bool vic_alternate_clock = false; - unsigned int freq; - unsigned int hdmi_tx_div; - unsigned int venc_div; + unsigned long long freq; + unsigned long long hdmi_tx_div; + unsigned long long venc_div; if (target == MESON_VCLK_TARGET_CVBS) { meson_venci_cvbs_clock_config(priv); @@ -1052,27 +1058,27 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, return; } - hdmi_tx_div = vclk_freq / dac_freq; + hdmi_tx_div = DIV_ROUND_DOWN_ULL(vclk_freq, dac_freq); if (hdmi_tx_div == 0) { - pr_err("Fatal Error, invalid HDMI-TX freq %d\n", + pr_err("Fatal Error, invalid HDMI-TX freq %lluHz\n", dac_freq); return; } - venc_div = vclk_freq / venc_freq; + venc_div = DIV_ROUND_DOWN_ULL(vclk_freq, venc_freq); if (venc_div == 0) { - pr_err("Fatal Error, invalid HDMI venc freq %d\n", + pr_err("Fatal Error, invalid HDMI venc freq %lluHz\n", venc_freq); return; } for (freq = 0 ; params[freq].pixel_freq ; ++freq) { if ((phy_freq == params[freq].phy_freq || - phy_freq == FREQ_1000_1001(params[freq].phy_freq/10)*10) && + phy_freq == PHY_FREQ_1000_1001(params[freq].phy_freq)) && (vclk_freq == params[freq].vclk_freq || - vclk_freq == FREQ_1000_1001(params[freq].vclk_freq))) { + vclk_freq == PIXEL_FREQ_1000_1001(params[freq].vclk_freq))) { if (vclk_freq != params[freq].vclk_freq) vic_alternate_clock = true; else @@ -1098,7 +1104,8 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, } if (!params[freq].pixel_freq) { - pr_err("Fatal Error, invalid HDMI vclk freq %d\n", vclk_freq); + pr_err("Fatal Error, invalid HDMI vclk freq %lluHz\n", + vclk_freq); return; } diff --git a/drivers/gpu/drm/meson/meson_vclk.h b/drivers/gpu/drm/meson/meson_vclk.h index 60617aaf18dd..7ac55744e574 100644 --- a/drivers/gpu/drm/meson/meson_vclk.h +++ b/drivers/gpu/drm/meson/meson_vclk.h @@ -20,17 +20,18 @@ enum { }; /* 27MHz is the CVBS Pixel Clock */ -#define MESON_VCLK_CVBS 27000 +#define MESON_VCLK_CVBS (27 * 1000 * 1000) enum drm_mode_status -meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq); +meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned long long freq); enum drm_mode_status -meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq, - unsigned int vclk_freq); +meson_vclk_vic_supported_freq(struct meson_drm *priv, + unsigned long long phy_freq, + unsigned long long vclk_freq); void meson_vclk_setup(struct meson_drm *priv, unsigned int target, - unsigned int phy_freq, unsigned int vclk_freq, - unsigned int venc_freq, unsigned int dac_freq, + unsigned long long phy_freq, unsigned long long vclk_freq, + unsigned long long venc_freq, unsigned long long dac_freq, bool hdmi_use_enci); #endif /* __MESON_VCLK_H */ From e9a5fe7817480f48e15f720e8eaa12e78332ea32 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Fri, 6 Jun 2025 22:37:29 +0200 Subject: [PATCH 353/971] drm/meson: fix debug log statement when setting the HDMI clocks [ Upstream commit d17e61ab63fb7747b340d6a66bf1408cd5c6562b ] The "phy" and "vclk" frequency labels were swapped, making it more difficult to debug driver errors. Swap the label order to make them match with the actual frequencies printed to correct this. Fixes: e5fab2ec9ca4 ("drm/meson: vclk: add support for YUV420 setup") Signed-off-by: Martin Blumenstingl Reviewed-by: Neil Armstrong Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20250606203729.3311592-1-martin.blumenstingl@googlemail.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/meson/meson_encoder_hdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c index cd0e9e2d59ee..73ec7ae48510 100644 --- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c +++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c @@ -108,7 +108,7 @@ static void meson_encoder_hdmi_set_vclk(struct meson_encoder_hdmi *encoder_hdmi, venc_freq /= 2; dev_dbg(priv->dev, - "vclk:%lluHz phy=%lluHz venc=%lluHz hdmi=%lluHz enci=%d\n", + "phy:%lluHz vclk=%lluHz venc=%lluHz hdmi=%lluHz enci=%d\n", phy_freq, vclk_freq, venc_freq, hdmi_freq, priv->venc.hdmi_use_enci); From 81331229971a953c7fadfba191609c155ffcd0f3 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sat, 7 Jun 2025 00:10:31 +0200 Subject: [PATCH 354/971] drm/meson: use vclk_freq instead of pixel_freq in debug print [ Upstream commit faf2f8382088e8c74bd6eeb236c8c9190e61615e ] meson_vclk_vic_supported_freq() has a debug print which includes the pixel freq. However, within the whole function the pixel freq is irrelevant, other than checking the end of the params array. Switch to printing the vclk_freq which is being compared / matched against the inputs to the function to avoid confusion when analyzing error reports from users. Fixes: e5fab2ec9ca4 ("drm/meson: vclk: add support for YUV420 setup") Signed-off-by: Martin Blumenstingl Reviewed-by: Neil Armstrong Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20250606221031.3419353-1-martin.blumenstingl@googlemail.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/meson/meson_vclk.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c index 3325580d885d..c4123bb958e4 100644 --- a/drivers/gpu/drm/meson/meson_vclk.c +++ b/drivers/gpu/drm/meson/meson_vclk.c @@ -790,9 +790,9 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, } for (i = 0 ; params[i].pixel_freq ; ++i) { - DRM_DEBUG_DRIVER("i = %d pixel_freq = %lluHz alt = %lluHz\n", - i, params[i].pixel_freq, - PIXEL_FREQ_1000_1001(params[i].pixel_freq)); + DRM_DEBUG_DRIVER("i = %d vclk_freq = %lluHz alt = %lluHz\n", + i, params[i].vclk_freq, + PIXEL_FREQ_1000_1001(params[i].vclk_freq)); DRM_DEBUG_DRIVER("i = %d phy_freq = %lluHz alt = %lluHz\n", i, params[i].phy_freq, PHY_FREQ_1000_1001(params[i].phy_freq)); From dc5fc562f1c4c7c43e24d8bf38b0f1e9093d1196 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Mon, 9 Jun 2025 22:27:51 +0200 Subject: [PATCH 355/971] drm/meson: fix more rounding issues with 59.94Hz modes [ Upstream commit 0cee6c4d3518b2e757aedae78771f17149f57653 ] Commit 1017560164b6 ("drm/meson: use unsigned long long / Hz for frequency types") attempts to resolve video playback using 59.94Hz. using YUV420 by changing the clock calculation to use Hz instead of kHz (thus yielding more precision). The basic calculation itself is correct, however the comparisions in meson_vclk_vic_supported_freq() and meson_vclk_setup() don't work anymore for 59.94Hz modes (using the freq * 1000 / 1001 logic). For example, drm/edid specifies a 593407kHz clock for 3840x2160@59.94Hz. With the mentioend commit we convert this to Hz. Then meson_vclk tries to find a matchig "params" entry (as the clock setup code currently only supports specific frequencies) by taking the venc_freq from the params and calculating the "alt frequency" (used for the 59.94Hz modes) from it, which is: (594000000Hz * 1000) / 1001 = 593406593Hz Similar calculation is applied to the phy_freq (TMDS clock), which is 10 times the pixel clock. Implement a new meson_vclk_freqs_are_matching_param() function whose purpose is to compare if the requested and calculated frequencies. They may not match exactly (for the reasons mentioned above). Allow the clocks to deviate slightly to make the 59.94Hz modes again. Fixes: 1017560164b6 ("drm/meson: use unsigned long long / Hz for frequency types") Reported-by: Christian Hewitt Signed-off-by: Martin Blumenstingl Reviewed-by: Neil Armstrong Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20250609202751.962208-1-martin.blumenstingl@googlemail.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/meson/meson_vclk.c | 55 ++++++++++++++++++------------ 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c index c4123bb958e4..dfe0c28a0f05 100644 --- a/drivers/gpu/drm/meson/meson_vclk.c +++ b/drivers/gpu/drm/meson/meson_vclk.c @@ -110,10 +110,7 @@ #define HDMI_PLL_LOCK BIT(31) #define HDMI_PLL_LOCK_G12A (3 << 30) -#define PIXEL_FREQ_1000_1001(_freq) \ - DIV_ROUND_CLOSEST_ULL((_freq) * 1000ULL, 1001ULL) -#define PHY_FREQ_1000_1001(_freq) \ - (PIXEL_FREQ_1000_1001(DIV_ROUND_DOWN_ULL(_freq, 10ULL)) * 10) +#define FREQ_1000_1001(_freq) DIV_ROUND_CLOSEST_ULL((_freq) * 1000ULL, 1001ULL) /* VID PLL Dividers */ enum { @@ -772,6 +769,36 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv, pll_freq); } +static bool meson_vclk_freqs_are_matching_param(unsigned int idx, + unsigned long long phy_freq, + unsigned long long vclk_freq) +{ + DRM_DEBUG_DRIVER("i = %d vclk_freq = %lluHz alt = %lluHz\n", + idx, params[idx].vclk_freq, + FREQ_1000_1001(params[idx].vclk_freq)); + DRM_DEBUG_DRIVER("i = %d phy_freq = %lluHz alt = %lluHz\n", + idx, params[idx].phy_freq, + FREQ_1000_1001(params[idx].phy_freq)); + + /* Match strict frequency */ + if (phy_freq == params[idx].phy_freq && + vclk_freq == params[idx].vclk_freq) + return true; + + /* Match 1000/1001 variant: vclk deviation has to be less than 1kHz + * (drm EDID is defined in 1kHz steps, so everything smaller must be + * rounding error) and the PHY freq deviation has to be less than + * 10kHz (as the TMDS clock is 10 times the pixel clock, so anything + * smaller must be rounding error as well). + */ + if (abs(vclk_freq - FREQ_1000_1001(params[idx].vclk_freq)) < 1000 && + abs(phy_freq - FREQ_1000_1001(params[idx].phy_freq)) < 10000) + return true; + + /* no match */ + return false; +} + enum drm_mode_status meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned long long phy_freq, @@ -790,19 +817,7 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, } for (i = 0 ; params[i].pixel_freq ; ++i) { - DRM_DEBUG_DRIVER("i = %d vclk_freq = %lluHz alt = %lluHz\n", - i, params[i].vclk_freq, - PIXEL_FREQ_1000_1001(params[i].vclk_freq)); - DRM_DEBUG_DRIVER("i = %d phy_freq = %lluHz alt = %lluHz\n", - i, params[i].phy_freq, - PHY_FREQ_1000_1001(params[i].phy_freq)); - /* Match strict frequency */ - if (phy_freq == params[i].phy_freq && - vclk_freq == params[i].vclk_freq) - return MODE_OK; - /* Match 1000/1001 variant */ - if (phy_freq == PHY_FREQ_1000_1001(params[i].phy_freq) && - vclk_freq == PIXEL_FREQ_1000_1001(params[i].vclk_freq)) + if (meson_vclk_freqs_are_matching_param(i, phy_freq, vclk_freq)) return MODE_OK; } @@ -1075,10 +1090,8 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, } for (freq = 0 ; params[freq].pixel_freq ; ++freq) { - if ((phy_freq == params[freq].phy_freq || - phy_freq == PHY_FREQ_1000_1001(params[freq].phy_freq)) && - (vclk_freq == params[freq].vclk_freq || - vclk_freq == PIXEL_FREQ_1000_1001(params[freq].vclk_freq))) { + if (meson_vclk_freqs_are_matching_param(freq, phy_freq, + vclk_freq)) { if (vclk_freq != params[freq].vclk_freq) vic_alternate_clock = true; else From dd184939f41eb2ad5577d8498d4c53588c785555 Mon Sep 17 00:00:00 2001 From: Robert Malz Date: Tue, 20 May 2025 10:31:51 +0200 Subject: [PATCH 356/971] i40e: return false from i40e_reset_vf if reset is in progress [ Upstream commit a2c90d63b71223d69a813333c1abf4fdacddbbe5 ] The function i40e_vc_reset_vf attempts, up to 20 times, to handle a VF reset request, using the return value of i40e_reset_vf as an indicator of whether the reset was successfully triggered. Currently, i40e_reset_vf always returns true, which causes new reset requests to be ignored if a different VF reset is already in progress. This patch updates the return value of i40e_reset_vf to reflect when another VF reset is in progress, allowing the caller to properly use the retry mechanism. Fixes: 52424f974bc5 ("i40e: Fix VF hang when reset is triggered on another VF") Signed-off-by: Robert Malz Tested-by: Rafal Romanowski Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index d5509bc16d0d..348869f05020 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -1552,8 +1552,8 @@ static void i40e_cleanup_reset_vf(struct i40e_vf *vf) * @vf: pointer to the VF structure * @flr: VFLR was issued or not * - * Returns true if the VF is in reset, resets successfully, or resets - * are disabled and false otherwise. + * Return: True if reset was performed successfully or if resets are disabled. + * False if reset is already in progress. **/ bool i40e_reset_vf(struct i40e_vf *vf, bool flr) { @@ -1572,7 +1572,7 @@ bool i40e_reset_vf(struct i40e_vf *vf, bool flr) /* If VF is being reset already we don't need to continue. */ if (test_and_set_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) - return true; + return false; i40e_trigger_vf_reset(vf, flr); From 987c3b8859d6b67990b0c42adfeffec1c466c5d4 Mon Sep 17 00:00:00 2001 From: Robert Malz Date: Tue, 20 May 2025 10:31:52 +0200 Subject: [PATCH 357/971] i40e: retry VFLR handling if there is ongoing VF reset [ Upstream commit fb4e9239e029954a37a00818b21e837cebf2aa10 ] When a VFLR interrupt is received during a VF reset initiated from a different source, the VFLR may be not fully handled. This can leave the VF in an undefined state. To address this, set the I40E_VFLR_EVENT_PENDING bit again during VFLR handling if the reset is not yet complete. This ensures the driver will properly complete the VF reset in such scenarios. Fixes: 52424f974bc5 ("i40e: Fix VF hang when reset is triggered on another VF") Signed-off-by: Robert Malz Tested-by: Rafal Romanowski Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 348869f05020..80036942dc76 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -4332,7 +4332,10 @@ int i40e_vc_process_vflr_event(struct i40e_pf *pf) reg = rd32(hw, I40E_GLGEN_VFLRSTAT(reg_idx)); if (reg & BIT(bit_idx)) /* i40e_reset_vf will clear the bit in GLGEN_VFLRSTAT */ - i40e_reset_vf(vf, true); + if (!i40e_reset_vf(vf, true)) { + /* At least one VF did not finish resetting, retry next time */ + set_bit(__I40E_VFLR_EVENT_PENDING, pf->state); + } } return 0; From c6dad167aade4bf0bef9130f2f149f4249fc4ad0 Mon Sep 17 00:00:00 2001 From: Yunhui Cui Date: Wed, 4 Jun 2025 10:30:36 +0800 Subject: [PATCH 358/971] ACPI: CPPC: Fix NULL pointer dereference when nosmp is used [ Upstream commit 15eece6c5b05e5f9db0711978c3e3b7f1a2cfe12 ] With nosmp in cmdline, other CPUs are not brought up, leaving their cpc_desc_ptr NULL. CPU0's iteration via for_each_possible_cpu() dereferences these NULL pointers, causing panic. Panic backtrace: [ 0.401123] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000b8 ... [ 0.403255] [] cppc_allow_fast_switch+0x6a/0xd4 ... Kernel panic - not syncing: Attempted to kill init! Fixes: 3cc30dd00a58 ("cpufreq: CPPC: Enable fast_switch") Reported-by: Xu Lu Signed-off-by: Yunhui Cui Link: https://patch.msgid.link/20250604023036.99553-1-cuiyunhui@bytedance.com [ rjw: New subject ] Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/cppc_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index ed02a2a9970a..10d531427ba7 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -461,7 +461,7 @@ bool cppc_allow_fast_switch(void) struct cpc_desc *cpc_ptr; int cpu; - for_each_possible_cpu(cpu) { + for_each_present_cpu(cpu) { cpc_ptr = per_cpu(cpc_desc_ptr, cpu); desired_reg = &cpc_ptr->cpc_regs[DESIRED_PERF]; if (!CPC_IN_SYSTEM_MEMORY(desired_reg) && From ff55c85a923e043d59d26b20a673a1b4a219c310 Mon Sep 17 00:00:00 2001 From: Michal Luczaj Date: Mon, 9 Jun 2025 19:08:03 +0200 Subject: [PATCH 359/971] net: Fix TOCTOU issue in sk_is_readable() [ Upstream commit 2660a544fdc0940bba15f70508a46cf9a6491230 ] sk->sk_prot->sock_is_readable is a valid function pointer when sk resides in a sockmap. After the last sk_psock_put() (which usually happens when socket is removed from sockmap), sk->sk_prot gets restored and sk->sk_prot->sock_is_readable becomes NULL. This makes sk_is_readable() racy, if the value of sk->sk_prot is reloaded after the initial check. Which in turn may lead to a null pointer dereference. Ensure the function pointer does not turn NULL after the check. Fixes: 8934ce2fd081 ("bpf: sockmap redirect ingress support") Suggested-by: Jakub Sitnicki Signed-off-by: Michal Luczaj Reviewed-by: Willem de Bruijn Link: https://patch.msgid.link/20250609-skisreadable-toctou-v1-1-d0dfb2d62c37@rbox.co Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- include/net/sock.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index dc625f94ee37..e15bea43b2ec 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -3043,8 +3043,11 @@ int sock_ioctl_inout(struct sock *sk, unsigned int cmd, int sk_ioctl(struct sock *sk, unsigned int cmd, void __user *arg); static inline bool sk_is_readable(struct sock *sk) { - if (sk->sk_prot->sock_is_readable) - return sk->sk_prot->sock_is_readable(sk); + const struct proto *prot = READ_ONCE(sk->sk_prot); + + if (prot->sock_is_readable) + return prot->sock_is_readable(sk); + return false; } #endif /* _SOCK_H */ From 7bafe26d73149b70ab88d2b0bcfaa1a1c60844f0 Mon Sep 17 00:00:00 2001 From: Carlos Fernandez Date: Mon, 9 Jun 2025 09:26:26 +0200 Subject: [PATCH 360/971] macsec: MACsec SCI assignment for ES = 0 [ Upstream commit d9816ec74e6d6aa29219d010bba3f780ba1d9d75 ] According to 802.1AE standard, when ES and SC flags in TCI are zero, used SCI should be the current active SC_RX. Current code uses the header MAC address. Without this patch, when ES flag is 0 (using a bridge or switch), header MAC will not fit the SCI and MACSec frames will be discarted. In order to test this issue, MACsec link should be stablished between two interfaces, setting SC and ES flags to zero and a port identifier different than one. For example, using ip macsec tools: ip link add link $ETH0 macsec0 type macsec port 11 send_sci off end_station off ip macsec add macsec0 tx sa 0 pn 2 on key 01 $ETH1_KEY ip macsec add macsec0 rx port 11 address $ETH1_MAC ip macsec add macsec0 rx port 11 address $ETH1_MAC sa 0 pn 2 on key 02 ip link set dev macsec0 up ip link add link $ETH1 macsec1 type macsec port 11 send_sci off end_station off ip macsec add macsec1 tx sa 0 pn 2 on key 01 $ETH0_KEY ip macsec add macsec1 rx port 11 address $ETH0_MAC ip macsec add macsec1 rx port 11 address $ETH0_MAC sa 0 pn 2 on key 02 ip link set dev macsec1 up Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver") Co-developed-by: Andreu Montiel Signed-off-by: Andreu Montiel Signed-off-by: Carlos Fernandez Reviewed-by: Subbaraya Sundeep Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/macsec.c | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 7c96493a367b..767053d6c6b6 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -243,15 +243,39 @@ static sci_t make_sci(const u8 *addr, __be16 port) return sci; } -static sci_t macsec_frame_sci(struct macsec_eth_header *hdr, bool sci_present) +static sci_t macsec_active_sci(struct macsec_secy *secy) { - sci_t sci; + struct macsec_rx_sc *rx_sc = rcu_dereference_bh(secy->rx_sc); - if (sci_present) + /* Case single RX SC */ + if (rx_sc && !rcu_dereference_bh(rx_sc->next)) + return (rx_sc->active) ? rx_sc->sci : 0; + /* Case no RX SC or multiple */ + else + return 0; +} + +static sci_t macsec_frame_sci(struct macsec_eth_header *hdr, bool sci_present, + struct macsec_rxh_data *rxd) +{ + struct macsec_dev *macsec; + sci_t sci = 0; + + /* SC = 1 */ + if (sci_present) { memcpy(&sci, hdr->secure_channel_id, sizeof(hdr->secure_channel_id)); - else + /* SC = 0; ES = 0 */ + } else if ((!(hdr->tci_an & (MACSEC_TCI_ES | MACSEC_TCI_SC))) && + (list_is_singular(&rxd->secys))) { + /* Only one SECY should exist on this scenario */ + macsec = list_first_or_null_rcu(&rxd->secys, struct macsec_dev, + secys); + if (macsec) + return macsec_active_sci(&macsec->secy); + } else { sci = make_sci(hdr->eth.h_source, MACSEC_PORT_ES); + } return sci; } @@ -1105,7 +1129,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) struct macsec_rxh_data *rxd; struct macsec_dev *macsec; unsigned int len; - sci_t sci; + sci_t sci = 0; u32 hdr_pn; bool cbit; struct pcpu_rx_sc_stats *rxsc_stats; @@ -1152,11 +1176,14 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) macsec_skb_cb(skb)->has_sci = !!(hdr->tci_an & MACSEC_TCI_SC); macsec_skb_cb(skb)->assoc_num = hdr->tci_an & MACSEC_AN_MASK; - sci = macsec_frame_sci(hdr, macsec_skb_cb(skb)->has_sci); rcu_read_lock(); rxd = macsec_data_rcu(skb->dev); + sci = macsec_frame_sci(hdr, macsec_skb_cb(skb)->has_sci, rxd); + if (!sci) + goto drop_nosc; + list_for_each_entry_rcu(macsec, &rxd->secys, secys) { struct macsec_rx_sc *sc = find_rx_sc(&macsec->secy, sci); @@ -1279,6 +1306,7 @@ drop: macsec_rxsa_put(rx_sa); drop_nosa: macsec_rxsc_put(rx_sc); +drop_nosc: rcu_read_unlock(); drop_direct: kfree_skb(skb); From bab6bca0834cbb5be2a7cfe59ec6ad016ec72608 Mon Sep 17 00:00:00 2001 From: Jakub Raczynski Date: Mon, 9 Jun 2025 17:31:46 +0200 Subject: [PATCH 361/971] net/mdiobus: Fix potential out-of-bounds read/write access [ Upstream commit 0e629694126ca388916f059453a1c36adde219c4 ] When using publicly available tools like 'mdio-tools' to read/write data from/to network interface and its PHY via mdiobus, there is no verification of parameters passed to the ioctl and it accepts any mdio address. Currently there is support for 32 addresses in kernel via PHY_MAX_ADDR define, but it is possible to pass higher value than that via ioctl. While read/write operation should generally fail in this case, mdiobus provides stats array, where wrong address may allow out-of-bounds read/write. Fix that by adding address verification before read/write operation. While this excludes this access from any statistics, it improves security of read/write operation. Fixes: 080bb352fad00 ("net: phy: Maintain MDIO device and bus statistics") Signed-off-by: Jakub Raczynski Reported-by: Wenjing Shan Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/phy/mdio_bus.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 25dcaa49ab8b..103998969d44 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -850,6 +850,9 @@ int __mdiobus_read(struct mii_bus *bus, int addr, u32 regnum) lockdep_assert_held_once(&bus->mdio_lock); + if (addr >= PHY_MAX_ADDR) + return -ENXIO; + if (bus->read) retval = bus->read(bus, addr, regnum); else @@ -879,6 +882,9 @@ int __mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val) lockdep_assert_held_once(&bus->mdio_lock); + if (addr >= PHY_MAX_ADDR) + return -ENXIO; + if (bus->write) err = bus->write(bus, addr, regnum, val); else From abb0605ca00979a49572a6516f6db22c3dc57223 Mon Sep 17 00:00:00 2001 From: Jakub Raczynski Date: Mon, 9 Jun 2025 17:31:47 +0200 Subject: [PATCH 362/971] net/mdiobus: Fix potential out-of-bounds clause 45 read/write access [ Upstream commit 260388f79e94fb3026c419a208ece8358bb7b555 ] When using publicly available tools like 'mdio-tools' to read/write data from/to network interface and its PHY via C45 (clause 45) mdiobus, there is no verification of parameters passed to the ioctl and it accepts any mdio address. Currently there is support for 32 addresses in kernel via PHY_MAX_ADDR define, but it is possible to pass higher value than that via ioctl. While read/write operation should generally fail in this case, mdiobus provides stats array, where wrong address may allow out-of-bounds read/write. Fix that by adding address verification before C45 read/write operation. While this excludes this access from any statistics, it improves security of read/write operation. Fixes: 4e4aafcddbbf ("net: mdio: Add dedicated C45 API to MDIO bus drivers") Signed-off-by: Jakub Raczynski Reported-by: Wenjing Shan Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/phy/mdio_bus.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 103998969d44..e02706b7cc1e 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -946,6 +946,9 @@ int __mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum) lockdep_assert_held_once(&bus->mdio_lock); + if (addr >= PHY_MAX_ADDR) + return -ENXIO; + if (bus->read_c45) retval = bus->read_c45(bus, addr, devad, regnum); else @@ -977,6 +980,9 @@ int __mdiobus_c45_write(struct mii_bus *bus, int addr, int devad, u32 regnum, lockdep_assert_held_once(&bus->mdio_lock); + if (addr >= PHY_MAX_ADDR) + return -ENXIO; + if (bus->write_c45) err = bus->write_c45(bus, addr, devad, regnum, val); else From 4bf29910570666e668a60d953f8da78e95bb7fa2 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 5 Jun 2025 11:14:25 -0400 Subject: [PATCH 363/971] Bluetooth: Fix NULL pointer deference on eir_get_service_data [ Upstream commit 20a2aa01f5aeb6daad9aeaa7c33dd512c58d81eb ] The len parameter is considered optional so it can be NULL so it cannot be used for skipping to next entry of EIR_SERVICE_DATA. Fixes: 8f9ae5b3ae80 ("Bluetooth: eir: Add helpers for managing service data") Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- net/bluetooth/eir.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/bluetooth/eir.c b/net/bluetooth/eir.c index 1bc51e2b05a3..3e1713673ecc 100644 --- a/net/bluetooth/eir.c +++ b/net/bluetooth/eir.c @@ -366,17 +366,19 @@ u8 eir_create_scan_rsp(struct hci_dev *hdev, u8 instance, u8 *ptr) void *eir_get_service_data(u8 *eir, size_t eir_len, u16 uuid, size_t *len) { - while ((eir = eir_get_data(eir, eir_len, EIR_SERVICE_DATA, len))) { + size_t dlen; + + while ((eir = eir_get_data(eir, eir_len, EIR_SERVICE_DATA, &dlen))) { u16 value = get_unaligned_le16(eir); if (uuid == value) { if (len) - *len -= 2; + *len = dlen - 2; return &eir[2]; } - eir += *len; - eir_len -= *len; + eir += dlen; + eir_len -= dlen; } return NULL; From c621211b308816889f0a3246de448bfcef8ab3ab Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 5 Jun 2025 11:15:16 -0400 Subject: [PATCH 364/971] Bluetooth: hci_sync: Fix broadcast/PA when using an existing instance [ Upstream commit 5725bc608252050ed8a4d47d59225b7dd73474c8 ] When using and existing adv_info instance for broadcast source it needs to be updated to periodic first before it can be reused, also in case the existing instance already have data hci_set_adv_instance_data cannot be used directly since it would overwrite the existing data so this reappend the original data after the Broadcast ID, if one was generated. Example: bluetoothctl># Add PBP to EA so it can be later referenced as the BIS ID bluetoothctl> advertise.service 0x1856 0x00 0x00 bluetoothctl> advertise on ... < HCI Command: LE Set Extended Advertising Data (0x08|0x0037) plen 13 Handle: 0x01 Operation: Complete extended advertising data (0x03) Fragment preference: Minimize fragmentation (0x01) Data length: 0x09 Service Data: Public Broadcast Announcement (0x1856) Data[2]: 0000 Flags: 0x06 LE General Discoverable Mode BR/EDR Not Supported ... bluetoothctl># Attempt to acquire Broadcast Source transport bluetoothctl>transport.acquire /org/bluez/hci0/pac_bcast0/fd0 ... < HCI Command: LE Set Extended Advertising Data (0x08|0x0037) plen 255 Handle: 0x01 Operation: Complete extended advertising data (0x03) Fragment preference: Minimize fragmentation (0x01) Data length: 0x0e Service Data: Broadcast Audio Announcement (0x1852) Broadcast ID: 11371620 (0xad8464) Service Data: Public Broadcast Announcement (0x1856) Data[2]: 0000 Flags: 0x06 LE General Discoverable Mode BR/EDR Not Supported Link: https://github.com/bluez/bluez/issues/1117 Fixes: eca0ae4aea66 ("Bluetooth: Add initial implementation of BIS connections") Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- net/bluetooth/hci_sync.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index d6f40806ee51..e92bc4ceb5ad 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -1586,7 +1586,8 @@ static int hci_enable_per_advertising_sync(struct hci_dev *hdev, u8 instance) static int hci_adv_bcast_annoucement(struct hci_dev *hdev, struct adv_info *adv) { u8 bid[3]; - u8 ad[4 + 3]; + u8 ad[HCI_MAX_EXT_AD_LENGTH]; + u8 len; /* Skip if NULL adv as instance 0x00 is used for general purpose * advertising so it cannot used for the likes of Broadcast Announcement @@ -1612,8 +1613,10 @@ static int hci_adv_bcast_annoucement(struct hci_dev *hdev, struct adv_info *adv) /* Generate Broadcast ID */ get_random_bytes(bid, sizeof(bid)); - eir_append_service_data(ad, 0, 0x1852, bid, sizeof(bid)); - hci_set_adv_instance_data(hdev, adv->instance, sizeof(ad), ad, 0, NULL); + len = eir_append_service_data(ad, 0, 0x1852, bid, sizeof(bid)); + memcpy(ad + len, adv->adv_data, adv->adv_data_len); + hci_set_adv_instance_data(hdev, adv->instance, len + adv->adv_data_len, + ad, 0, NULL); return hci_update_adv_data_sync(hdev, adv->instance); } @@ -1630,8 +1633,15 @@ int hci_start_per_adv_sync(struct hci_dev *hdev, u8 instance, u8 data_len, if (instance) { adv = hci_find_adv_instance(hdev, instance); - /* Create an instance if that could not be found */ - if (!adv) { + if (adv) { + /* Turn it into periodic advertising */ + adv->periodic = true; + adv->per_adv_data_len = data_len; + if (data) + memcpy(adv->per_adv_data, data, data_len); + adv->flags = flags; + } else if (!adv) { + /* Create an instance if that could not be found */ adv = hci_add_per_instance(hdev, instance, flags, data_len, data, sync_interval, From 3c40cfcbf18aa354496797108d8d902cfe114561 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 11 Jun 2025 16:36:27 -0400 Subject: [PATCH 365/971] Bluetooth: MGMT: Fix sparse errors [ Upstream commit 7dd38ba4acbea9875b4ee061e20a26413e39d9f4 ] This fixes the following errors: net/bluetooth/mgmt.c:5400:59: sparse: sparse: incorrect type in argument 3 (different base types) @@ expected unsigned short [usertype] handle @@ got restricted __le16 [usertype] monitor_handle @@ net/bluetooth/mgmt.c:5400:59: sparse: expected unsigned short [usertype] handle net/bluetooth/mgmt.c:5400:59: sparse: got restricted __le16 [usertype] monitor_handle Fixes: e6ed54e86aae ("Bluetooth: MGMT: Fix UAF on mgmt_remove_adv_monitor_complete") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202506060347.ux2O1p7L-lkp@intel.com/ Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- net/bluetooth/mgmt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 44174f59b31e..853d217cabc9 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -5159,11 +5159,11 @@ static void mgmt_adv_monitor_added(struct sock *sk, struct hci_dev *hdev, } static void mgmt_adv_monitor_removed(struct sock *sk, struct hci_dev *hdev, - u16 handle) + __le16 handle) { struct mgmt_ev_adv_monitor_removed ev; - ev.monitor_handle = cpu_to_le16(handle); + ev.monitor_handle = handle; mgmt_event(MGMT_EV_ADV_MONITOR_REMOVED, hdev, &ev, sizeof(ev), sk); } From 7fb33ed59867dd4954b48dba78ef452df589e5eb Mon Sep 17 00:00:00 2001 From: Moshe Shemesh Date: Tue, 10 Jun 2025 18:15:06 +0300 Subject: [PATCH 366/971] net/mlx5: Ensure fw pages are always allocated on same NUMA [ Upstream commit f37258133c1e95e61db532e14067e28b4881bf24 ] When firmware asks the driver to allocate more pages, using event of give_pages, the driver should always allocate it from same NUMA, the original device NUMA. Current code uses dev_to_node() which can result in different NUMA as it is changed by other driver flows, such as mlx5_dma_zalloc_coherent_node(). Instead, use saved numa node for allocating firmware pages. Fixes: 311c7c71c9bb ("net/mlx5e: Allocate DMA coherent memory on reader NUMA node") Signed-off-by: Moshe Shemesh Reviewed-by: Tariq Toukan Signed-off-by: Mark Bloch Link: https://patch.msgid.link/20250610151514.1094735-2-mbloch@nvidia.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c index dcf58efac159..e0581c6f9cec 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c @@ -291,7 +291,7 @@ static void free_4k(struct mlx5_core_dev *dev, u64 addr, u32 function) static int alloc_system_page(struct mlx5_core_dev *dev, u32 function) { struct device *device = mlx5_core_dma_dev(dev); - int nid = dev_to_node(device); + int nid = dev->priv.numa_node; struct page *page; u64 zero_addr = 1; u64 addr; From 5953ae44dfe5dbad374318875be834c3b7b71ee6 Mon Sep 17 00:00:00 2001 From: Amir Tzin Date: Tue, 10 Jun 2025 18:15:07 +0300 Subject: [PATCH 367/971] net/mlx5: Fix ECVF vports unload on shutdown flow [ Upstream commit 687560d8a9a2d654829ad0da1ec24242f1de711d ] Fix shutdown flow UAF when a virtual function is created on the embedded chip (ECVF) of a BlueField device. In such case the vport acl ingress table is not properly destroyed. ECVF functionality is independent of ecpf_vport_exists capability and thus functions mlx5_eswitch_(enable|disable)_pf_vf_vports() should not test it when enabling/disabling ECVF vports. kernel log: [] refcount_t: underflow; use-after-free. [] WARNING: CPU: 3 PID: 1 at lib/refcount.c:28 refcount_warn_saturate+0x124/0x220 ---------------- [] Call trace: [] refcount_warn_saturate+0x124/0x220 [] tree_put_node+0x164/0x1e0 [mlx5_core] [] mlx5_destroy_flow_table+0x98/0x2c0 [mlx5_core] [] esw_acl_ingress_table_destroy+0x28/0x40 [mlx5_core] [] esw_acl_ingress_lgcy_cleanup+0x80/0xf4 [mlx5_core] [] esw_legacy_vport_acl_cleanup+0x44/0x60 [mlx5_core] [] esw_vport_cleanup+0x64/0x90 [mlx5_core] [] mlx5_esw_vport_disable+0xc0/0x1d0 [mlx5_core] [] mlx5_eswitch_unload_ec_vf_vports+0xcc/0x150 [mlx5_core] [] mlx5_eswitch_disable_sriov+0x198/0x2a0 [mlx5_core] [] mlx5_device_disable_sriov+0xb8/0x1e0 [mlx5_core] [] mlx5_sriov_detach+0x40/0x50 [mlx5_core] [] mlx5_unload+0x40/0xc4 [mlx5_core] [] mlx5_unload_one_devl_locked+0x6c/0xe4 [mlx5_core] [] mlx5_unload_one+0x3c/0x60 [mlx5_core] [] shutdown+0x7c/0xa4 [mlx5_core] [] pci_device_shutdown+0x3c/0xa0 [] device_shutdown+0x170/0x340 [] __do_sys_reboot+0x1f4/0x2a0 [] __arm64_sys_reboot+0x2c/0x40 [] invoke_syscall+0x78/0x100 [] el0_svc_common.constprop.0+0x54/0x184 [] do_el0_svc+0x30/0xac [] el0_svc+0x48/0x160 [] el0t_64_sync_handler+0xa4/0x12c [] el0t_64_sync+0x1a4/0x1a8 [] --[ end trace 9c4601d68c70030e ]--- Fixes: a7719b29a821 ("net/mlx5: Add management of EC VF vports") Reviewed-by: Daniel Jurgens Reviewed-by: Moshe Shemesh Signed-off-by: Amir Tzin Signed-off-by: Mark Bloch Link: https://patch.msgid.link/20250610151514.1094735-3-mbloch@nvidia.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- .../net/ethernet/mellanox/mlx5/core/eswitch.c | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index f6022c135ec0..914b380fd3ee 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c @@ -1295,12 +1295,15 @@ mlx5_eswitch_enable_pf_vf_vports(struct mlx5_eswitch *esw, ret = mlx5_eswitch_load_pf_vf_vport(esw, MLX5_VPORT_ECPF, enabled_events); if (ret) goto ecpf_err; - if (mlx5_core_ec_sriov_enabled(esw->dev)) { - ret = mlx5_eswitch_load_ec_vf_vports(esw, esw->esw_funcs.num_ec_vfs, - enabled_events); - if (ret) - goto ec_vf_err; - } + } + + /* Enable ECVF vports */ + if (mlx5_core_ec_sriov_enabled(esw->dev)) { + ret = mlx5_eswitch_load_ec_vf_vports(esw, + esw->esw_funcs.num_ec_vfs, + enabled_events); + if (ret) + goto ec_vf_err; } /* Enable VF vports */ @@ -1331,9 +1334,11 @@ void mlx5_eswitch_disable_pf_vf_vports(struct mlx5_eswitch *esw) { mlx5_eswitch_unload_vf_vports(esw, esw->esw_funcs.num_vfs); + if (mlx5_core_ec_sriov_enabled(esw->dev)) + mlx5_eswitch_unload_ec_vf_vports(esw, + esw->esw_funcs.num_ec_vfs); + if (mlx5_ecpf_vport_exists(esw->dev)) { - if (mlx5_core_ec_sriov_enabled(esw->dev)) - mlx5_eswitch_unload_ec_vf_vports(esw, esw->esw_funcs.num_vfs); mlx5_eswitch_unload_pf_vf_vport(esw, MLX5_VPORT_ECPF); } From a810e484778d16c34d16650246b105e619557f36 Mon Sep 17 00:00:00 2001 From: Patrisious Haddad Date: Tue, 10 Jun 2025 18:15:08 +0300 Subject: [PATCH 368/971] net/mlx5: Fix return value when searching for existing flow group [ Upstream commit 8ec40e3f1f72bf8f8accf18020d487caa99f46a4 ] When attempting to add a rule to an existing flow group, if a matching flow group exists but is not active, the error code returned should be EAGAIN, so that the rule can be added to the matching flow group once it is active, rather than ENOENT, which indicates that no matching flow group was found. Fixes: bd71b08ec2ee ("net/mlx5: Support multiple updates of steering rules in parallel") Signed-off-by: Gavi Teitz Signed-off-by: Roi Dayan Signed-off-by: Patrisious Haddad Reviewed-by: Tariq Toukan Signed-off-by: Mark Bloch Link: https://patch.msgid.link/20250610151514.1094735-4-mbloch@nvidia.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index d2dc375f5e49..5f35a6fc0305 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -1984,6 +1984,7 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft, struct mlx5_flow_handle *rule; struct match_list *iter; bool take_write = false; + bool try_again = false; struct fs_fte *fte; u64 version = 0; int err; @@ -2043,6 +2044,7 @@ skip_search: nested_down_write_ref_node(&g->node, FS_LOCK_PARENT); if (!g->node.active) { + try_again = true; up_write_ref_node(&g->node, false); continue; } @@ -2064,7 +2066,8 @@ skip_search: tree_put_node(&fte->node, false); return rule; } - rule = ERR_PTR(-ENOENT); + err = try_again ? -EAGAIN : -ENOENT; + rule = ERR_PTR(err); out: kmem_cache_free(steering->ftes_cache, fte); return rule; From 77a72d749701940ad1c56de82d4cd9c4d1b220af Mon Sep 17 00:00:00 2001 From: Jianbo Liu Date: Tue, 10 Jun 2025 18:15:13 +0300 Subject: [PATCH 369/971] net/mlx5e: Fix leak of Geneve TLV option object [ Upstream commit aa9c44b842096c553871bc68a8cebc7861fa192b ] Previously, a unique tunnel id was added for the matching on TC non-zero chains, to support inner header rewrite with goto action. Later, it was used to support VF tunnel offload for vxlan, then for Geneve and GRE. To support VF tunnel, a temporary mlx5_flow_spec is used to parse tunnel options. For Geneve, if there is TLV option, a object is created, or refcnt is added if already exists. But the temporary mlx5_flow_spec is directly freed after parsing, which causes the leak because no information regarding the object is saved in flow's mlx5_flow_spec, which is used to free the object when deleting the flow. To fix the leak, call mlx5_geneve_tlv_option_del() before free the temporary spec if it has TLV object. Fixes: 521933cdc4aa ("net/mlx5e: Support Geneve and GRE with VF tunnel offload") Signed-off-by: Jianbo Liu Reviewed-by: Tariq Toukan Reviewed-by: Alex Lazar Signed-off-by: Mark Bloch Link: https://patch.msgid.link/20250610151514.1094735-9-mbloch@nvidia.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index dc9b157a4499..2be9c69daad5 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -1915,9 +1915,8 @@ err_out: return err; } -static bool mlx5_flow_has_geneve_opt(struct mlx5e_tc_flow *flow) +static bool mlx5_flow_has_geneve_opt(struct mlx5_flow_spec *spec) { - struct mlx5_flow_spec *spec = &flow->attr->parse_attr->spec; void *headers_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, misc_parameters_3); @@ -1956,7 +1955,7 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv, } complete_all(&flow->del_hw_done); - if (mlx5_flow_has_geneve_opt(flow)) + if (mlx5_flow_has_geneve_opt(&attr->parse_attr->spec)) mlx5_geneve_tlv_option_del(priv->mdev->geneve); if (flow->decap_route) @@ -2456,12 +2455,13 @@ static int parse_tunnel_attr(struct mlx5e_priv *priv, err = mlx5e_tc_tun_parse(filter_dev, priv, tmp_spec, f, match_level); if (err) { - kvfree(tmp_spec); NL_SET_ERR_MSG_MOD(extack, "Failed to parse tunnel attributes"); netdev_warn(priv->netdev, "Failed to parse tunnel attributes"); - return err; + } else { + err = mlx5e_tc_set_attr_rx_tun(flow, tmp_spec); } - err = mlx5e_tc_set_attr_rx_tun(flow, tmp_spec); + if (mlx5_flow_has_geneve_opt(tmp_spec)) + mlx5_geneve_tlv_option_del(priv->mdev->geneve); kvfree(tmp_spec); if (err) return err; From 46c15c9d0f65c9ba857d63f53264f4b17e8a715f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 11 Jun 2025 11:15:11 +0000 Subject: [PATCH 370/971] net_sched: prio: fix a race in prio_tune() [ Upstream commit d35acc1be3480505b5931f17e4ea9b7617fea4d3 ] Gerrard Tai reported a race condition in PRIO, whenever SFQ perturb timer fires at the wrong time. The race is as follows: CPU 0 CPU 1 [1]: lock root [2]: qdisc_tree_flush_backlog() [3]: unlock root | | [5]: lock root | [6]: rehash | [7]: qdisc_tree_reduce_backlog() | [4]: qdisc_put() This can be abused to underflow a parent's qlen. Calling qdisc_purge_queue() instead of qdisc_tree_flush_backlog() should fix the race, because all packets will be purged from the qdisc before releasing the lock. Fixes: 7b8e0b6e6599 ("net: sched: prio: delay destroying child qdiscs on change") Reported-by: Gerrard Tai Suggested-by: Gerrard Tai Signed-off-by: Eric Dumazet Link: https://patch.msgid.link/20250611111515.1983366-2-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/sched/sch_prio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index fdc5ef52c3ee..fdd9caa41e80 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c @@ -211,7 +211,7 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt, memcpy(q->prio2band, qopt->priomap, TC_PRIO_MAX+1); for (i = q->bands; i < oldbands; i++) - qdisc_tree_flush_backlog(q->queues[i]); + qdisc_purge_queue(q->queues[i]); for (i = oldbands; i < q->bands; i++) { q->queues[i] = queues[i]; From 2a71924ca4af59ffc00f0444732b6cd54b153d0e Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 11 Jun 2025 11:15:12 +0000 Subject: [PATCH 371/971] net_sched: red: fix a race in __red_change() [ Upstream commit 85a3e0ede38450ea3053b8c45d28cf55208409b8 ] Gerrard Tai reported a race condition in RED, whenever SFQ perturb timer fires at the wrong time. The race is as follows: CPU 0 CPU 1 [1]: lock root [2]: qdisc_tree_flush_backlog() [3]: unlock root | | [5]: lock root | [6]: rehash | [7]: qdisc_tree_reduce_backlog() | [4]: qdisc_put() This can be abused to underflow a parent's qlen. Calling qdisc_purge_queue() instead of qdisc_tree_flush_backlog() should fix the race, because all packets will be purged from the qdisc before releasing the lock. Fixes: 0c8d13ac9607 ("net: sched: red: delay destroying child qdisc on replace") Reported-by: Gerrard Tai Suggested-by: Gerrard Tai Signed-off-by: Eric Dumazet Link: https://patch.msgid.link/20250611111515.1983366-3-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/sched/sch_red.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c index 16277b6a0238..3c6b4460cf2c 100644 --- a/net/sched/sch_red.c +++ b/net/sched/sch_red.c @@ -283,7 +283,7 @@ static int __red_change(struct Qdisc *sch, struct nlattr **tb, q->userbits = userbits; q->limit = ctl->limit; if (child) { - qdisc_tree_flush_backlog(q->qdisc); + qdisc_purge_queue(q->qdisc); old_child = q->qdisc; q->qdisc = child; } From 057f7a61b04b6320f68006362059cc7fc4f70623 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 11 Jun 2025 11:15:13 +0000 Subject: [PATCH 372/971] net_sched: tbf: fix a race in tbf_change() [ Upstream commit 43eb466041216d25dedaef1c383ad7bd89929cbc ] Gerrard Tai reported a race condition in TBF, whenever SFQ perturb timer fires at the wrong time. The race is as follows: CPU 0 CPU 1 [1]: lock root [2]: qdisc_tree_flush_backlog() [3]: unlock root | | [5]: lock root | [6]: rehash | [7]: qdisc_tree_reduce_backlog() | [4]: qdisc_put() This can be abused to underflow a parent's qlen. Calling qdisc_purge_queue() instead of qdisc_tree_flush_backlog() should fix the race, because all packets will be purged from the qdisc before releasing the lock. Fixes: b05972f01e7d ("net: sched: tbf: don't call qdisc_put() while holding tree lock") Reported-by: Gerrard Tai Suggested-by: Gerrard Tai Signed-off-by: Eric Dumazet Cc: Zhengchao Shao Link: https://patch.msgid.link/20250611111515.1983366-4-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/sched/sch_tbf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index f92174008499..61dd5c8f2310 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c @@ -452,7 +452,7 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt, sch_tree_lock(sch); if (child) { - qdisc_tree_flush_backlog(q->qdisc); + qdisc_purge_queue(q->qdisc); old = q->qdisc; q->qdisc = child; } From 0383b25488a545be168744336847549d4a2d3d6c Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 11 Jun 2025 11:15:14 +0000 Subject: [PATCH 373/971] net_sched: ets: fix a race in ets_qdisc_change() [ Upstream commit d92adacdd8c2960be856e0b82acc5b7c5395fddb ] Gerrard Tai reported a race condition in ETS, whenever SFQ perturb timer fires at the wrong time. The race is as follows: CPU 0 CPU 1 [1]: lock root [2]: qdisc_tree_flush_backlog() [3]: unlock root | | [5]: lock root | [6]: rehash | [7]: qdisc_tree_reduce_backlog() | [4]: qdisc_put() This can be abused to underflow a parent's qlen. Calling qdisc_purge_queue() instead of qdisc_tree_flush_backlog() should fix the race, because all packets will be purged from the qdisc before releasing the lock. Fixes: b05972f01e7d ("net: sched: tbf: don't call qdisc_put() while holding tree lock") Reported-by: Gerrard Tai Suggested-by: Gerrard Tai Signed-off-by: Eric Dumazet Link: https://patch.msgid.link/20250611111515.1983366-5-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/sched/sch_ets.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c index 9da86db4d2c2..3ee46f6e005d 100644 --- a/net/sched/sch_ets.c +++ b/net/sched/sch_ets.c @@ -661,7 +661,7 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt, for (i = q->nbands; i < oldbands; i++) { if (i >= q->nstrict && q->classes[i].qdisc->q.qlen) list_del_init(&q->classes[i].alist); - qdisc_tree_flush_backlog(q->classes[i].qdisc); + qdisc_purge_queue(q->classes[i].qdisc); } q->nstrict = nstrict; memcpy(q->prio2band, priomap, sizeof(priomap)); From 84ead78a3cf8a0ffad72b6c6e19891a41c90b91c Mon Sep 17 00:00:00 2001 From: Zijun Hu Date: Thu, 10 Apr 2025 19:45:27 +0800 Subject: [PATCH 374/971] fs/filesystems: Fix potential unsigned integer underflow in fs_name() [ Upstream commit 1363c134ade81e425873b410566e957fecebb261 ] fs_name() has @index as unsigned int, so there is underflow risk for operation '@index--'. Fix by breaking the for loop when '@index == 0' which is also more proper than '@index <= 0' for unsigned integer comparison. Signed-off-by: Zijun Hu Link: https://lore.kernel.org/20250410-fix_fs-v1-1-7c14ccc8ebaa@quicinc.com Signed-off-by: Christian Brauner Signed-off-by: Sasha Levin --- fs/filesystems.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/fs/filesystems.c b/fs/filesystems.c index 58b9067b2391..95e5256821a5 100644 --- a/fs/filesystems.c +++ b/fs/filesystems.c @@ -156,15 +156,19 @@ static int fs_index(const char __user * __name) static int fs_name(unsigned int index, char __user * buf) { struct file_system_type * tmp; - int len, res; + int len, res = -EINVAL; read_lock(&file_systems_lock); - for (tmp = file_systems; tmp; tmp = tmp->next, index--) - if (index <= 0 && try_module_get(tmp->owner)) + for (tmp = file_systems; tmp; tmp = tmp->next, index--) { + if (index == 0) { + if (try_module_get(tmp->owner)) + res = 0; break; + } + } read_unlock(&file_systems_lock); - if (!tmp) - return -EINVAL; + if (res) + return res; /* OK, we got the reference, so we can safely block */ len = strlen(tmp->name) + 1; From efcd52ba648b8015f15ba7b3387bb50f2a96786d Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Wed, 7 May 2025 14:23:03 +0200 Subject: [PATCH 375/971] nvmet-fcloop: access fcpreq only when holding reqlock [ Upstream commit 47a827cd7929d0550c3496d70b417fcb5649b27b ] The abort handling logic expects that the state and the fcpreq are only accessed when holding the reqlock lock. While at it, only handle the aborts in the abort handler. Signed-off-by: Daniel Wagner Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin --- drivers/nvme/target/fcloop.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/nvme/target/fcloop.c b/drivers/nvme/target/fcloop.c index 4b35bdcac185..aeeb7455fc2e 100644 --- a/drivers/nvme/target/fcloop.c +++ b/drivers/nvme/target/fcloop.c @@ -613,12 +613,13 @@ fcloop_fcp_recv_work(struct work_struct *work) { struct fcloop_fcpreq *tfcp_req = container_of(work, struct fcloop_fcpreq, fcp_rcv_work); - struct nvmefc_fcp_req *fcpreq = tfcp_req->fcpreq; + struct nvmefc_fcp_req *fcpreq; unsigned long flags; int ret = 0; bool aborted = false; spin_lock_irqsave(&tfcp_req->reqlock, flags); + fcpreq = tfcp_req->fcpreq; switch (tfcp_req->inistate) { case INI_IO_START: tfcp_req->inistate = INI_IO_ACTIVE; @@ -633,16 +634,19 @@ fcloop_fcp_recv_work(struct work_struct *work) } spin_unlock_irqrestore(&tfcp_req->reqlock, flags); - if (unlikely(aborted)) - ret = -ECANCELED; - else { - if (likely(!check_for_drop(tfcp_req))) - ret = nvmet_fc_rcv_fcp_req(tfcp_req->tport->targetport, - &tfcp_req->tgt_fcp_req, - fcpreq->cmdaddr, fcpreq->cmdlen); - else - pr_info("%s: dropped command ********\n", __func__); + if (unlikely(aborted)) { + /* the abort handler will call fcloop_call_host_done */ + return; } + + if (unlikely(check_for_drop(tfcp_req))) { + pr_info("%s: dropped command ********\n", __func__); + return; + } + + ret = nvmet_fc_rcv_fcp_req(tfcp_req->tport->targetport, + &tfcp_req->tgt_fcp_req, + fcpreq->cmdaddr, fcpreq->cmdlen); if (ret) fcloop_call_host_done(fcpreq, tfcp_req, ret); } @@ -657,9 +661,10 @@ fcloop_fcp_abort_recv_work(struct work_struct *work) unsigned long flags; spin_lock_irqsave(&tfcp_req->reqlock, flags); - fcpreq = tfcp_req->fcpreq; switch (tfcp_req->inistate) { case INI_IO_ABORTED: + fcpreq = tfcp_req->fcpreq; + tfcp_req->fcpreq = NULL; break; case INI_IO_COMPLETED: completed = true; @@ -681,10 +686,6 @@ fcloop_fcp_abort_recv_work(struct work_struct *work) nvmet_fc_rcv_fcp_abort(tfcp_req->tport->targetport, &tfcp_req->tgt_fcp_req); - spin_lock_irqsave(&tfcp_req->reqlock, flags); - tfcp_req->fcpreq = NULL; - spin_unlock_irqrestore(&tfcp_req->reqlock, flags); - fcloop_call_host_done(fcpreq, tfcp_req, -ECANCELED); /* call_host_done releases reference for abort downcall */ } From 51c695986fa1eee8279c78351c31a92ab7225ee9 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 17 Jan 2025 10:54:50 +0100 Subject: [PATCH 376/971] perf: Ensure bpf_perf_link path is properly serialized [ Upstream commit 7ed9138a72829d2035ecbd8dbd35b1bc3c137c40 ] Ravi reported that the bpf_perf_link_attach() usage of perf_event_set_bpf_prog() is not serialized by ctx->mutex, unlike the PERF_EVENT_IOC_SET_BPF case. Reported-by: Ravi Bangoria Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Ravi Bangoria Link: https://lkml.kernel.org/r/20250307193305.486326750@infradead.org Signed-off-by: Sasha Levin --- kernel/events/core.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 6460f79280ed..563f39518f7f 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -5913,6 +5913,9 @@ static int perf_event_set_output(struct perf_event *event, static int perf_event_set_filter(struct perf_event *event, void __user *arg); static int perf_copy_attr(struct perf_event_attr __user *uattr, struct perf_event_attr *attr); +static int __perf_event_set_bpf_prog(struct perf_event *event, + struct bpf_prog *prog, + u64 bpf_cookie); static long _perf_ioctl(struct perf_event *event, unsigned int cmd, unsigned long arg) { @@ -5981,7 +5984,7 @@ static long _perf_ioctl(struct perf_event *event, unsigned int cmd, unsigned lon if (IS_ERR(prog)) return PTR_ERR(prog); - err = perf_event_set_bpf_prog(event, prog, 0); + err = __perf_event_set_bpf_prog(event, prog, 0); if (err) { bpf_prog_put(prog); return err; @@ -10583,8 +10586,9 @@ static inline bool perf_event_is_tracing(struct perf_event *event) return false; } -int perf_event_set_bpf_prog(struct perf_event *event, struct bpf_prog *prog, - u64 bpf_cookie) +static int __perf_event_set_bpf_prog(struct perf_event *event, + struct bpf_prog *prog, + u64 bpf_cookie) { bool is_kprobe, is_uprobe, is_tracepoint, is_syscall_tp; @@ -10622,6 +10626,20 @@ int perf_event_set_bpf_prog(struct perf_event *event, struct bpf_prog *prog, return perf_event_attach_bpf_prog(event, prog, bpf_cookie); } +int perf_event_set_bpf_prog(struct perf_event *event, + struct bpf_prog *prog, + u64 bpf_cookie) +{ + struct perf_event_context *ctx; + int ret; + + ctx = perf_event_ctx_lock(event); + ret = __perf_event_set_bpf_prog(event, prog, bpf_cookie); + perf_event_ctx_unlock(event, ctx); + + return ret; +} + void perf_event_free_bpf_prog(struct perf_event *event) { if (!perf_event_is_tracing(event)) { @@ -10641,7 +10659,15 @@ static void perf_event_free_filter(struct perf_event *event) { } -int perf_event_set_bpf_prog(struct perf_event *event, struct bpf_prog *prog, +static int __perf_event_set_bpf_prog(struct perf_event *event, + struct bpf_prog *prog, + u64 bpf_cookie) +{ + return -ENOENT; +} + +int perf_event_set_bpf_prog(struct perf_event *event, + struct bpf_prog *prog, u64 bpf_cookie) { return -ENOENT; From 9e263d94593b733b0fc4cb123c31027b37ab5e37 Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Thu, 12 Jun 2025 15:41:25 +0100 Subject: [PATCH 377/971] bio: Fix bio_first_folio() for SPARSEMEM without VMEMMAP [ Upstream commit f826ec7966a63d48e16e0868af4e038bf9a1a3ae ] It is possible for physically contiguous folios to have discontiguous struct pages if SPARSEMEM is enabled and SPARSEMEM_VMEMMAP is not. This is correctly handled by folio_page_idx(), so remove this open-coded implementation. Fixes: 640d1930bef4 (block: Add bio_for_each_folio_all()) Signed-off-by: Matthew Wilcox (Oracle) Link: https://lore.kernel.org/r/20250612144126.2849931-1-willy@infradead.org Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- include/linux/bio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/bio.h b/include/linux/bio.h index b893418c3cc0..f193aef4fac0 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -294,7 +294,7 @@ static inline void bio_first_folio(struct folio_iter *fi, struct bio *bio, fi->folio = page_folio(bvec->bv_page); fi->offset = bvec->bv_offset + - PAGE_SIZE * (bvec->bv_page - &fi->folio->page); + PAGE_SIZE * folio_page_idx(fi->folio, bvec->bv_page); fi->_seg_count = bvec->bv_len; fi->length = min(folio_size(fi->folio) - fi->offset, fi->_seg_count); fi->_next = folio_next(fi->folio); From c9a2e81583d9f55fe6e0e899dd5760cfe6bd99bc Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Thu, 12 Jun 2025 15:42:53 +0100 Subject: [PATCH 378/971] block: Fix bvec_set_folio() for very large folios [ Upstream commit 5e223e06ee7c6d8f630041a0645ac90e39a42cc6 ] Similarly to 26064d3e2b4d ("block: fix adding folio to bio"), if we attempt to add a folio that is larger than 4GB, we'll silently truncate the offset and len. Widen the parameters to size_t, assert that the length is less than 4GB and set the first page that contains the interesting data rather than the first page of the folio. Fixes: 26db5ee15851 (block: add a bvec_set_folio helper) Signed-off-by: Matthew Wilcox (Oracle) Link: https://lore.kernel.org/r/20250612144255.2850278-1-willy@infradead.org Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- include/linux/bvec.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/linux/bvec.h b/include/linux/bvec.h index bd1e361b351c..99ab7b2bba27 100644 --- a/include/linux/bvec.h +++ b/include/linux/bvec.h @@ -57,9 +57,12 @@ static inline void bvec_set_page(struct bio_vec *bv, struct page *page, * @offset: offset into the folio */ static inline void bvec_set_folio(struct bio_vec *bv, struct folio *folio, - unsigned int len, unsigned int offset) + size_t len, size_t offset) { - bvec_set_page(bv, &folio->page, len, offset); + unsigned long nr = offset / PAGE_SIZE; + + WARN_ON_ONCE(len > UINT_MAX); + bvec_set_page(bv, folio_page(folio, nr), len, offset % PAGE_SIZE); } /** From 37a75cd83ddee0cb724c1713114c611d9857243b Mon Sep 17 00:00:00 2001 From: Suleiman Souhlal Date: Fri, 6 Jun 2025 16:45:38 +0900 Subject: [PATCH 379/971] tools/resolve_btfids: Fix build when cross compiling kernel with clang. commit a298bbab903e3fb4cbe16d36d6195e68fad1b776 upstream. When cross compiling the kernel with clang, we need to override CLANG_CROSS_FLAGS when preparing the step libraries. Prior to commit d1d096312176 ("tools: fix annoying "mkdir -p ..." logs when building tools in parallel"), MAKEFLAGS would have been set to a value that wouldn't set a value for CLANG_CROSS_FLAGS, hiding the fact that we weren't properly overriding it. Fixes: 56a2df7615fa ("tools/resolve_btfids: Compile resolve_btfids as host program") Signed-off-by: Suleiman Souhlal Signed-off-by: Andrii Nakryiko Acked-by: Jiri Olsa Cc: stable@vger.kernel.org Link: https://lore.kernel.org/bpf/20250606074538.1608546-1-suleiman@google.com Signed-off-by: Greg Kroah-Hartman --- tools/bpf/resolve_btfids/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/bpf/resolve_btfids/Makefile b/tools/bpf/resolve_btfids/Makefile index 4b8079f294f6..b0072e64b010 100644 --- a/tools/bpf/resolve_btfids/Makefile +++ b/tools/bpf/resolve_btfids/Makefile @@ -19,7 +19,7 @@ endif # Overrides for the prepare step libraries. HOST_OVERRIDES := AR="$(HOSTAR)" CC="$(HOSTCC)" LD="$(HOSTLD)" ARCH="$(HOSTARCH)" \ - CROSS_COMPILE="" EXTRA_CFLAGS="$(HOSTCFLAGS)" + CROSS_COMPILE="" CLANG_CROSS_FLAGS="" EXTRA_CFLAGS="$(HOSTCFLAGS)" RM ?= rm HOSTCC ?= gcc From dd4b8e05f2a251b05bc3b2130095d87e98199866 Mon Sep 17 00:00:00 2001 From: David Heimann Date: Sun, 1 Jun 2025 12:41:16 -0400 Subject: [PATCH 380/971] ALSA: usb-audio: Add implicit feedback quirk for RODE AI-1 commit 6a3439a417b910e662c666993798e0691bc81147 upstream. The RODE AI-1 audio interface requires implicit feedback sync between playback endpoint 0x03 and feedback endpoint 0x84 on interface 3, but doesn't advertise this in its USB descriptors. Without this quirk, the device receives audio data but produces no output. Signed-off-by: David Heimann Cc: Link: https://patch.msgid.link/084dc88c-1193-4a94-a002-5599adff936c@app.fastmail.com Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/usb/implicit.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/usb/implicit.c b/sound/usb/implicit.c index 4727043fd745..77f06da93151 100644 --- a/sound/usb/implicit.c +++ b/sound/usb/implicit.c @@ -57,6 +57,7 @@ static const struct snd_usb_implicit_fb_match playback_implicit_fb_quirks[] = { IMPLICIT_FB_FIXED_DEV(0x31e9, 0x0002, 0x81, 2), /* Solid State Logic SSL2+ */ IMPLICIT_FB_FIXED_DEV(0x0499, 0x172f, 0x81, 2), /* Steinberg UR22C */ IMPLICIT_FB_FIXED_DEV(0x0d9a, 0x00df, 0x81, 2), /* RTX6001 */ + IMPLICIT_FB_FIXED_DEV(0x19f7, 0x000a, 0x84, 3), /* RODE AI-1 */ IMPLICIT_FB_FIXED_DEV(0x22f0, 0x0006, 0x81, 3), /* Allen&Heath Qu-16 */ IMPLICIT_FB_FIXED_DEV(0x1686, 0xf029, 0x82, 2), /* Zoom UAC-2 */ IMPLICIT_FB_FIXED_DEV(0x2466, 0x8003, 0x86, 2), /* Fractal Audio Axe-Fx II */ From 4fa7831cf0ac71a0a345369d1a6084f2b096e55e Mon Sep 17 00:00:00 2001 From: Terry Junge Date: Wed, 12 Mar 2025 15:23:31 -0700 Subject: [PATCH 381/971] HID: usbhid: Eliminate recurrent out-of-bounds bug in usbhid_parse() commit fe7f7ac8e0c708446ff017453add769ffc15deed upstream. Update struct hid_descriptor to better reflect the mandatory and optional parts of the HID Descriptor as per USB HID 1.11 specification. Note: the kernel currently does not parse any optional HID class descriptors, only the mandatory report descriptor. Update all references to member element desc[0] to rpt_desc. Add test to verify bLength and bNumDescriptors values are valid. Replace the for loop with direct access to the mandatory HID class descriptor member for the report descriptor. This eliminates the possibility of getting an out-of-bounds fault. Add a warning message if the HID descriptor contains any unsupported optional HID class descriptors. Reported-by: syzbot+c52569baf0c843f35495@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=c52569baf0c843f35495 Fixes: f043bfc98c19 ("HID: usbhid: fix out-of-bounds bug") Cc: stable@vger.kernel.org Signed-off-by: Terry Junge Reviewed-by: Michael Kelley Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-hyperv.c | 4 ++-- drivers/hid/usbhid/hid-core.c | 25 ++++++++++++++----------- drivers/usb/gadget/function/f_hid.c | 12 ++++++------ include/linux/hid.h | 3 ++- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c index 0fb210e40a41..9eafff0b6ea4 100644 --- a/drivers/hid/hid-hyperv.c +++ b/drivers/hid/hid-hyperv.c @@ -192,7 +192,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device, goto cleanup; input_device->report_desc_size = le16_to_cpu( - desc->desc[0].wDescriptorLength); + desc->rpt_desc.wDescriptorLength); if (input_device->report_desc_size == 0) { input_device->dev_info_status = -EINVAL; goto cleanup; @@ -210,7 +210,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device, memcpy(input_device->report_desc, ((unsigned char *)desc) + desc->bLength, - le16_to_cpu(desc->desc[0].wDescriptorLength)); + le16_to_cpu(desc->rpt_desc.wDescriptorLength)); /* Send the ack */ memset(&ack, 0, sizeof(struct mousevsc_prt_msg)); diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 257dd73e37bf..a8e8da002b9b 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -982,12 +982,11 @@ static int usbhid_parse(struct hid_device *hid) struct usb_host_interface *interface = intf->cur_altsetting; struct usb_device *dev = interface_to_usbdev (intf); struct hid_descriptor *hdesc; + struct hid_class_descriptor *hcdesc; u32 quirks = 0; unsigned int rsize = 0; char *rdesc; - int ret, n; - int num_descriptors; - size_t offset = offsetof(struct hid_descriptor, desc); + int ret; quirks = hid_lookup_quirk(hid); @@ -1009,20 +1008,19 @@ static int usbhid_parse(struct hid_device *hid) return -ENODEV; } - if (hdesc->bLength < sizeof(struct hid_descriptor)) { - dbg_hid("hid descriptor is too short\n"); + if (!hdesc->bNumDescriptors || + hdesc->bLength != sizeof(*hdesc) + + (hdesc->bNumDescriptors - 1) * sizeof(*hcdesc)) { + dbg_hid("hid descriptor invalid, bLen=%hhu bNum=%hhu\n", + hdesc->bLength, hdesc->bNumDescriptors); return -EINVAL; } hid->version = le16_to_cpu(hdesc->bcdHID); hid->country = hdesc->bCountryCode; - num_descriptors = min_t(int, hdesc->bNumDescriptors, - (hdesc->bLength - offset) / sizeof(struct hid_class_descriptor)); - - for (n = 0; n < num_descriptors; n++) - if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) - rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); + if (hdesc->rpt_desc.bDescriptorType == HID_DT_REPORT) + rsize = le16_to_cpu(hdesc->rpt_desc.wDescriptorLength); if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) { dbg_hid("weird size of report descriptor (%u)\n", rsize); @@ -1050,6 +1048,11 @@ static int usbhid_parse(struct hid_device *hid) goto err; } + if (hdesc->bNumDescriptors > 1) + hid_warn(intf, + "%u unsupported optional hid class descriptors\n", + (int)(hdesc->bNumDescriptors - 1)); + hid->quirks |= quirks; return 0; diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 2db01e03bfbf..2f1ec03d17d6 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -118,8 +118,8 @@ static struct hid_descriptor hidg_desc = { .bcdHID = cpu_to_le16(0x0101), .bCountryCode = 0x00, .bNumDescriptors = 0x1, - /*.desc[0].bDescriptorType = DYNAMIC */ - /*.desc[0].wDescriptorLenght = DYNAMIC */ + /*.rpt_desc.bDescriptorType = DYNAMIC */ + /*.rpt_desc.wDescriptorLength = DYNAMIC */ }; /* Super-Speed Support */ @@ -728,8 +728,8 @@ static int hidg_setup(struct usb_function *f, struct hid_descriptor hidg_desc_copy = hidg_desc; VDBG(cdev, "USB_REQ_GET_DESCRIPTOR: HID\n"); - hidg_desc_copy.desc[0].bDescriptorType = HID_DT_REPORT; - hidg_desc_copy.desc[0].wDescriptorLength = + hidg_desc_copy.rpt_desc.bDescriptorType = HID_DT_REPORT; + hidg_desc_copy.rpt_desc.wDescriptorLength = cpu_to_le16(hidg->report_desc_length); length = min_t(unsigned short, length, @@ -970,8 +970,8 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) * We can use hidg_desc struct here but we should not relay * that its content won't change after returning from this function. */ - hidg_desc.desc[0].bDescriptorType = HID_DT_REPORT; - hidg_desc.desc[0].wDescriptorLength = + hidg_desc.rpt_desc.bDescriptorType = HID_DT_REPORT; + hidg_desc.rpt_desc.wDescriptorLength = cpu_to_le16(hidg->report_desc_length); hidg_hs_in_ep_desc.bEndpointAddress = diff --git a/include/linux/hid.h b/include/linux/hid.h index 38e161a827bd..5d37e2349fae 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -736,8 +736,9 @@ struct hid_descriptor { __le16 bcdHID; __u8 bCountryCode; __u8 bNumDescriptors; + struct hid_class_descriptor rpt_desc; - struct hid_class_descriptor desc[1]; + struct hid_class_descriptor opt_descs[]; } __attribute__ ((packed)); #define HID_DEVICE(b, g, ven, prod) \ From 90e11232a62bbd85e18c579c4b6b24030aa23d63 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sun, 28 Jan 2024 20:08:24 -0700 Subject: [PATCH 382/971] io_uring: add io_file_can_poll() helper Commit 95041b93e90a06bb613ec4bef9cd4d61570f68e4 upstream. This adds a flag to avoid dipping dereferencing file and then f_op to figure out if the file has a poll handler defined or not. We generally call this at least twice for networked workloads, and if using ring provided buffers, we do it on every buffer selection. Particularly the latter is troublesome, as it's otherwise a very fast operation. Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- include/linux/io_uring_types.h | 3 +++ io_uring/io_uring.c | 2 +- io_uring/io_uring.h | 12 ++++++++++++ io_uring/kbuf.c | 3 +-- io_uring/poll.c | 2 +- io_uring/rw.c | 4 ++-- 6 files changed, 20 insertions(+), 6 deletions(-) diff --git a/include/linux/io_uring_types.h b/include/linux/io_uring_types.h index 0fadef2983e0..dad2f9e4d53d 100644 --- a/include/linux/io_uring_types.h +++ b/include/linux/io_uring_types.h @@ -416,6 +416,7 @@ enum { /* keep async read/write and isreg together and in order */ REQ_F_SUPPORT_NOWAIT_BIT, REQ_F_ISREG_BIT, + REQ_F_CAN_POLL_BIT, /* not a real bit, just to check we're not overflowing the space */ __REQ_F_LAST_BIT, @@ -483,6 +484,8 @@ enum { REQ_F_CLEAR_POLLIN = BIT(REQ_F_CLEAR_POLLIN_BIT), /* hashed into ->cancel_hash_locked, protected by ->uring_lock */ REQ_F_HASH_LOCKED = BIT(REQ_F_HASH_LOCKED_BIT), + /* file is pollable */ + REQ_F_CAN_POLL = BIT(REQ_F_CAN_POLL_BIT), }; typedef void (*io_req_tw_func_t)(struct io_kiocb *req, struct io_tw_state *ts); diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 43b46098279a..9c383afeaf8e 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -1953,7 +1953,7 @@ fail: if (req->flags & REQ_F_FORCE_ASYNC) { bool opcode_poll = def->pollin || def->pollout; - if (opcode_poll && file_can_poll(req->file)) { + if (opcode_poll && io_file_can_poll(req)) { needs_poll = true; issue_flags |= IO_URING_F_NONBLOCK; } diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h index 0ffec66deee7..59f5f71037ff 100644 --- a/io_uring/io_uring.h +++ b/io_uring/io_uring.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include "io-wq.h" @@ -410,4 +411,15 @@ static inline size_t uring_sqe_size(struct io_ring_ctx *ctx) return 2 * sizeof(struct io_uring_sqe); return sizeof(struct io_uring_sqe); } + +static inline bool io_file_can_poll(struct io_kiocb *req) +{ + if (req->flags & REQ_F_CAN_POLL) + return true; + if (file_can_poll(req->file)) { + req->flags |= REQ_F_CAN_POLL; + return true; + } + return false; +} #endif diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c index 8c6611fe4f46..addd7c973657 100644 --- a/io_uring/kbuf.c +++ b/io_uring/kbuf.c @@ -148,8 +148,7 @@ static void __user *io_ring_buffer_select(struct io_kiocb *req, size_t *len, req->buf_list = bl; req->buf_index = buf->bid; - if (issue_flags & IO_URING_F_UNLOCKED || - (req->file && !file_can_poll(req->file))) { + if (issue_flags & IO_URING_F_UNLOCKED || !io_file_can_poll(req)) { /* * If we came in unlocked, we have no choice but to consume the * buffer here, otherwise nothing ensures that the buffer won't diff --git a/io_uring/poll.c b/io_uring/poll.c index cf8e86bc96de..2390bf5f1710 100644 --- a/io_uring/poll.c +++ b/io_uring/poll.c @@ -717,7 +717,7 @@ int io_arm_poll_handler(struct io_kiocb *req, unsigned issue_flags) if (!def->pollin && !def->pollout) return IO_APOLL_ABORTED; - if (!file_can_poll(req->file)) + if (!io_file_can_poll(req)) return IO_APOLL_ABORTED; if (!(req->flags & REQ_F_APOLL_MULTISHOT)) mask |= EPOLLONESHOT; diff --git a/io_uring/rw.c b/io_uring/rw.c index 75b001febb4d..230f553d1428 100644 --- a/io_uring/rw.c +++ b/io_uring/rw.c @@ -629,7 +629,7 @@ static bool io_rw_should_retry(struct io_kiocb *req) * just use poll if we can, and don't attempt if the fs doesn't * support callback based unlocks */ - if (file_can_poll(req->file) || !(req->file->f_mode & FMODE_BUF_RASYNC)) + if (io_file_can_poll(req) || !(req->file->f_mode & FMODE_BUF_RASYNC)) return false; wait->wait.func = io_async_buf_func; @@ -783,7 +783,7 @@ static int __io_read(struct io_kiocb *req, unsigned int issue_flags) if (ret == -EAGAIN || (req->flags & REQ_F_REISSUE)) { req->flags &= ~REQ_F_REISSUE; /* if we can poll, just do that */ - if (req->opcode == IORING_OP_READ && file_can_poll(req->file)) + if (req->opcode == IORING_OP_READ && io_file_can_poll(req)) return -EAGAIN; /* IOPOLL retry should happen for io-wq threads */ if (!force_nonblock && !(req->ctx->flags & IORING_SETUP_IOPOLL)) From 62d5d980b513d6cf7881faf6f527934c361109c2 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sun, 6 Oct 2024 10:40:36 -0600 Subject: [PATCH 383/971] io_uring/rw: allow pollable non-blocking attempts for !FMODE_NOWAIT Commit f7c9134385331c5ef36252895130aa01a92de907 upstream. The checking for whether or not io_uring can do a non-blocking read or write attempt is gated on FMODE_NOWAIT. However, if the file is pollable, it's feasible to just check if it's currently in a state in which it can sanely receive or send _some_ data. This avoids unnecessary io-wq punts, and repeated worthless retries before doing that punt, by assuming that some data can get delivered or received if poll tells us that is true. It also allows multishot reads to properly work with these types of files, enabling a bit of a cleanup of the logic that: c9d952b9103b ("io_uring/rw: fix cflags posting for single issue multishot read") had to put in place. Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- io_uring/rw.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/io_uring/rw.c b/io_uring/rw.c index 230f553d1428..6344006cf718 100644 --- a/io_uring/rw.c +++ b/io_uring/rw.c @@ -28,9 +28,19 @@ struct io_rw { rwf_t flags; }; -static inline bool io_file_supports_nowait(struct io_kiocb *req) +static bool io_file_supports_nowait(struct io_kiocb *req, __poll_t mask) { - return req->flags & REQ_F_SUPPORT_NOWAIT; + /* If FMODE_NOWAIT is set for a file, we're golden */ + if (req->flags & REQ_F_SUPPORT_NOWAIT) + return true; + /* No FMODE_NOWAIT, if we can poll, check the status */ + if (io_file_can_poll(req)) { + struct poll_table_struct pt = { ._key = mask }; + + return vfs_poll(req->file, &pt) & mask; + } + /* No FMODE_NOWAIT support, and file isn't pollable. Tough luck. */ + return false; } #ifdef CONFIG_COMPAT @@ -685,8 +695,8 @@ static int io_rw_init_file(struct io_kiocb *req, fmode_t mode) * supports async. Otherwise it's impossible to use O_NONBLOCK files * reliably. If not, or it IOCB_NOWAIT is set, don't retry. */ - if ((kiocb->ki_flags & IOCB_NOWAIT) || - ((file->f_flags & O_NONBLOCK) && !io_file_supports_nowait(req))) + if (kiocb->ki_flags & IOCB_NOWAIT || + ((file->f_flags & O_NONBLOCK && (req->flags & REQ_F_SUPPORT_NOWAIT)))) req->flags |= REQ_F_NOWAIT; if (ctx->flags & IORING_SETUP_IOPOLL) { @@ -752,7 +762,7 @@ static int __io_read(struct io_kiocb *req, unsigned int issue_flags) if (force_nonblock) { /* If the file doesn't support async, just async punt */ - if (unlikely(!io_file_supports_nowait(req))) { + if (unlikely(!io_file_supports_nowait(req, EPOLLIN))) { ret = io_setup_async_rw(req, iovec, s, true); return ret ?: -EAGAIN; } @@ -927,7 +937,7 @@ int io_write(struct io_kiocb *req, unsigned int issue_flags) if (force_nonblock) { /* If the file doesn't support async, just async punt */ - if (unlikely(!io_file_supports_nowait(req))) + if (unlikely(!io_file_supports_nowait(req, EPOLLOUT))) goto copy_iov; /* File path supports NOWAIT for non-direct_IO only for block devices. */ From 029d39ae7ecfb8e2908bdedb8aeafe6bfef68026 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sat, 19 Oct 2024 09:16:51 -0600 Subject: [PATCH 384/971] io_uring/rw: fix wrong NOWAIT check in io_rw_init_file() Commit ae6a888a4357131c01d85f4c91fb32552dd0bf70 upstream. A previous commit improved how !FMODE_NOWAIT is dealt with, but inadvertently negated a check whilst doing so. This caused -EAGAIN to be returned from reading files with O_NONBLOCK set. Fix up the check for REQ_F_SUPPORT_NOWAIT. Reported-by: Julian Orth Link: https://github.com/axboe/liburing/issues/1270 Fixes: f7c913438533 ("io_uring/rw: allow pollable non-blocking attempts for !FMODE_NOWAIT") Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- io_uring/rw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/io_uring/rw.c b/io_uring/rw.c index 6344006cf718..4ff3442ac2ee 100644 --- a/io_uring/rw.c +++ b/io_uring/rw.c @@ -696,7 +696,7 @@ static int io_rw_init_file(struct io_kiocb *req, fmode_t mode) * reliably. If not, or it IOCB_NOWAIT is set, don't retry. */ if (kiocb->ki_flags & IOCB_NOWAIT || - ((file->f_flags & O_NONBLOCK && (req->flags & REQ_F_SUPPORT_NOWAIT)))) + ((file->f_flags & O_NONBLOCK && !(req->flags & REQ_F_SUPPORT_NOWAIT)))) req->flags |= REQ_F_NOWAIT; if (ctx->flags & IORING_SETUP_IOPOLL) { From 99bc5248a4795216424cef2e33e560a4d9bb1329 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 17 Jun 2025 15:32:22 +0200 Subject: [PATCH 385/971] Revert "io_uring: ensure deferred completions are posted for multishot" This reverts commit 746e7d285dcb96caa1845fbbb62b14bf4010cdfb which is commit 687b2bae0efff9b25e071737d6af5004e6e35af5 upstream. Jens writes: There's some missing dependencies that makes this not work right, I'll bring it back in a series instead. Link: https://lore.kernel.org/r/906ba919-32e6-4534-bbad-2cd18e1098ca@kernel.dk Reported-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- io_uring/io_uring.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 9c383afeaf8e..ff1a93d405e9 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -920,14 +920,6 @@ static bool __io_post_aux_cqe(struct io_ring_ctx *ctx, u64 user_data, s32 res, u { bool filled; - /* - * If multishot has already posted deferred completions, ensure that - * those are flushed first before posting this one. If not, CQEs - * could get reordered. - */ - if (!wq_list_empty(&ctx->submit_state.compl_reqs)) - __io_submit_flush_completions(ctx); - io_cq_lock(ctx); filled = io_fill_cqe_aux(ctx, user_data, res, cflags); if (!filled && allow_overflow) From 2c72fe18cc5f9f1750f5bc148cf1c94c29e106ff Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 13 Jun 2025 19:26:50 +0200 Subject: [PATCH 386/971] posix-cpu-timers: fix race between handle_posix_cpu_timers() and posix_cpu_timer_del() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit f90fff1e152dedf52b932240ebbd670d83330eca upstream. If an exiting non-autoreaping task has already passed exit_notify() and calls handle_posix_cpu_timers() from IRQ, it can be reaped by its parent or debugger right after unlock_task_sighand(). If a concurrent posix_cpu_timer_del() runs at that moment, it won't be able to detect timer->it.cpu.firing != 0: cpu_timer_task_rcu() and/or lock_task_sighand() will fail. Add the tsk->exit_state check into run_posix_cpu_timers() to fix this. This fix is not needed if CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y, because exit_task_work() is called before exit_notify(). But the check still makes sense, task_work_add(&tsk->posix_cputimers_work.work) will fail anyway in this case. Cc: stable@vger.kernel.org Reported-by: Benoît Sevens Fixes: 0bdd2ed4138e ("sched: run_posix_cpu_timers: Don't check ->exit_state, use lock_task_sighand()") Signed-off-by: Oleg Nesterov Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- kernel/time/posix-cpu-timers.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c index e9c6f9d0e42c..9af1f2a72a0a 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -1437,6 +1437,15 @@ void run_posix_cpu_timers(void) lockdep_assert_irqs_disabled(); + /* + * Ensure that release_task(tsk) can't happen while + * handle_posix_cpu_timers() is running. Otherwise, a concurrent + * posix_cpu_timer_del() may fail to lock_task_sighand(tsk) and + * miss timer->it.cpu.firing != 0. + */ + if (tsk->exit_state) + return; + /* * If the actual expiry is deferred to task work context and the * work is already scheduled there is no point to do anything here. From b0630d18451a751c5b5ae66674da9456520d0a32 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 6 May 2025 14:02:01 -0700 Subject: [PATCH 387/971] kbuild: Disable -Wdefault-const-init-unsafe commit d0afcfeb9e3810ec89d1ffde1a0e36621bb75dca upstream. A new on by default warning in clang [1] aims to flags instances where const variables without static or thread local storage or const members in aggregate types are not initialized because it can lead to an indeterminate value. This is quite noisy for the kernel due to instances originating from header files such as: drivers/gpu/drm/i915/gt/intel_ring.h:62:2: error: default initialization of an object of type 'typeof (ring->size)' (aka 'const unsigned int') leaves the object uninitialized [-Werror,-Wdefault-const-init-var-unsafe] 62 | typecheck(typeof(ring->size), next); | ^ include/linux/typecheck.h:10:9: note: expanded from macro 'typecheck' 10 | ({ type __dummy; \ | ^ include/net/ip.h:478:14: error: default initialization of an object of type 'typeof (rt->dst.expires)' (aka 'const unsigned long') leaves the object uninitialized [-Werror,-Wdefault-const-init-var-unsafe] 478 | if (mtu && time_before(jiffies, rt->dst.expires)) | ^ include/linux/jiffies.h:138:26: note: expanded from macro 'time_before' 138 | #define time_before(a,b) time_after(b,a) | ^ include/linux/jiffies.h:128:3: note: expanded from macro 'time_after' 128 | (typecheck(unsigned long, a) && \ | ^ include/linux/typecheck.h:11:12: note: expanded from macro 'typecheck' 11 | typeof(x) __dummy2; \ | ^ include/linux/list.h:409:27: warning: default initialization of an object of type 'union (unnamed union at include/linux/list.h:409:27)' with const member leaves the object uninitialized [-Wdefault-const-init-field-unsafe] 409 | struct list_head *next = smp_load_acquire(&head->next); | ^ include/asm-generic/barrier.h:176:29: note: expanded from macro 'smp_load_acquire' 176 | #define smp_load_acquire(p) __smp_load_acquire(p) | ^ arch/arm64/include/asm/barrier.h:164:59: note: expanded from macro '__smp_load_acquire' 164 | union { __unqual_scalar_typeof(*p) __val; char __c[1]; } __u; \ | ^ include/linux/list.h:409:27: note: member '__val' declared 'const' here crypto/scatterwalk.c:66:22: error: default initialization of an object of type 'struct scatter_walk' with const member leaves the object uninitialized [-Werror,-Wdefault-const-init-field-unsafe] 66 | struct scatter_walk walk; | ^ include/crypto/algapi.h:112:15: note: member 'addr' declared 'const' here 112 | void *const addr; | ^ fs/hugetlbfs/inode.c:733:24: error: default initialization of an object of type 'struct vm_area_struct' with const member leaves the object uninitialized [-Werror,-Wdefault-const-init-field-unsafe] 733 | struct vm_area_struct pseudo_vma; | ^ include/linux/mm_types.h:803:20: note: member 'vm_flags' declared 'const' here 803 | const vm_flags_t vm_flags; | ^ Silencing the instances from typecheck.h is difficult because '= {}' is not available in older but supported compilers and '= {0}' would cause warnings about a literal 0 being treated as NULL. While it might be possible to come up with a local hack to silence the warning for clang-21+, it may not be worth it since -Wuninitialized will still trigger if an uninitialized const variable is actually used. In all audited cases of the "field" variant of the warning, the members are either not used in the particular call path, modified through other means such as memset() / memcpy() because the containing object is not const, or are within a union with other non-const members. Since this warning does not appear to have a high signal to noise ratio, just disable it. Cc: stable@vger.kernel.org Link: https://github.com/llvm/llvm-project/commit/576161cb6069e2c7656a8ef530727a0f4aefff30 [1] Reported-by: Linux Kernel Functional Testing Closes: https://lore.kernel.org/CA+G9fYuNjKcxFKS_MKPRuga32XbndkLGcY-PVuoSwzv6VWbY=w@mail.gmail.com/ Reported-by: Marcus Seyfarth Closes: https://github.com/ClangBuiltLinux/linux/issues/2088 Signed-off-by: Nathan Chancellor Signed-off-by: Masahiro Yamada Signed-off-by: Greg Kroah-Hartman --- scripts/Makefile.extrawarn | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index 0ea3281a92e1..570f64e2ddf1 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -29,6 +29,18 @@ KBUILD_CFLAGS-$(CONFIG_CC_NO_ARRAY_BOUNDS) += -Wno-array-bounds ifdef CONFIG_CC_IS_CLANG # The kernel builds with '-std=gnu11' so use of GNU extensions is acceptable. KBUILD_CFLAGS += -Wno-gnu + +# Clang may emit a warning when a const variable, such as the dummy variables +# in typecheck(), or const member of an aggregate type are not initialized, +# which can result in unexpected behavior. However, in many audited cases of +# the "field" variant of the warning, this is intentional because the field is +# never used within a particular call path, the field is within a union with +# other non-const members, or the containing object is not const so the field +# can be modified via memcpy() / memset(). While the variable warning also gets +# disabled with this same switch, there should not be too much coverage lost +# because -Wuninitialized will still flag when an uninitialized const variable +# is used. +KBUILD_CFLAGS += $(call cc-disable-warning, default-const-init-unsafe) else # gcc inanely warns about local variables called 'main' From 97f5b57eca7dfdf344cfa75605aea8f1a8dad7c0 Mon Sep 17 00:00:00 2001 From: Dave Penkler Date: Wed, 21 May 2025 14:16:55 +0200 Subject: [PATCH 388/971] usb: usbtmc: Fix read_stb function and get_stb ioctl commit acb3dac2805d3342ded7dbbd164add32bbfdf21c upstream. The usbtmc488_ioctl_read_stb function relied on a positive return from usbtmc_get_stb to reset the srq condition in the driver. The USBTMC_IOCTL_GET_STB case tested for a positive return to return the stb to the user. Commit: ("usb: usbtmc: Fix erroneous get_stb ioctl error returns") changed the return value of usbtmc_get_stb to 0 on success instead of returning the value of usb_control_msg which is positive in the normal case. This change caused the function usbtmc488_ioctl_read_stb and the USBTMC_IOCTL_GET_STB ioctl to no longer function correctly. Change the test in usbtmc488_ioctl_read_stb to test for failure first and return the failure code immediately. Change the test for the USBTMC_IOCTL_GET_STB ioctl to test for 0 instead of a positive value. Fixes: cac01bd178d6 ("usb: usbtmc: Fix erroneous get_stb ioctl error returns") Cc: stable@vger.kernel.org Signed-off-by: Dave Penkler Link: https://lore.kernel.org/r/20250521121656.18174-3-dpenkler@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/usbtmc.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 629ef749dafc..ee45f3c74aec 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -565,14 +565,15 @@ static int usbtmc488_ioctl_read_stb(struct usbtmc_file_data *file_data, rv = usbtmc_get_stb(file_data, &stb); - if (rv > 0) { - srq_asserted = atomic_xchg(&file_data->srq_asserted, - srq_asserted); - if (srq_asserted) - stb |= 0x40; /* Set RQS bit */ + if (rv < 0) + return rv; + + srq_asserted = atomic_xchg(&file_data->srq_asserted, srq_asserted); + if (srq_asserted) + stb |= 0x40; /* Set RQS bit */ + + rv = put_user(stb, (__u8 __user *)arg); - rv = put_user(stb, (__u8 __user *)arg); - } return rv; } @@ -2201,7 +2202,7 @@ static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case USBTMC_IOCTL_GET_STB: retval = usbtmc_get_stb(file_data, &tmp_byte); - if (retval > 0) + if (!retval) retval = put_user(tmp_byte, (__u8 __user *)arg); break; From 6e3af836805ed1d7a699f76ec798626198917aa4 Mon Sep 17 00:00:00 2001 From: Wupeng Ma Date: Sat, 10 May 2025 11:30:40 +0800 Subject: [PATCH 389/971] VMCI: fix race between vmci_host_setup_notify and vmci_ctx_unset_notify commit 1bd6406fb5f36c2bb1e96e27d4c3e9f4d09edde4 upstream. During our test, it is found that a warning can be trigger in try_grab_folio as follow: ------------[ cut here ]------------ WARNING: CPU: 0 PID: 1678 at mm/gup.c:147 try_grab_folio+0x106/0x130 Modules linked in: CPU: 0 UID: 0 PID: 1678 Comm: syz.3.31 Not tainted 6.15.0-rc5 #163 PREEMPT(undef) RIP: 0010:try_grab_folio+0x106/0x130 Call Trace: follow_huge_pmd+0x240/0x8e0 follow_pmd_mask.constprop.0.isra.0+0x40b/0x5c0 follow_pud_mask.constprop.0.isra.0+0x14a/0x170 follow_page_mask+0x1c2/0x1f0 __get_user_pages+0x176/0x950 __gup_longterm_locked+0x15b/0x1060 ? gup_fast+0x120/0x1f0 gup_fast_fallback+0x17e/0x230 get_user_pages_fast+0x5f/0x80 vmci_host_unlocked_ioctl+0x21c/0xf80 RIP: 0033:0x54d2cd ---[ end trace 0000000000000000 ]--- Digging into the source, context->notify_page may init by get_user_pages_fast and can be seen in vmci_ctx_unset_notify which will try to put_page. However get_user_pages_fast is not finished here and lead to following try_grab_folio warning. The race condition is shown as follow: cpu0 cpu1 vmci_host_do_set_notify vmci_host_setup_notify get_user_pages_fast(uva, 1, FOLL_WRITE, &context->notify_page); lockless_pages_from_mm gup_pgd_range gup_huge_pmd // update &context->notify_page vmci_host_do_set_notify vmci_ctx_unset_notify notify_page = context->notify_page; if (notify_page) put_page(notify_page); // page is freed __gup_longterm_locked __get_user_pages follow_trans_huge_pmd try_grab_folio // warn here To slove this, use local variable page to make notify_page can be seen after finish get_user_pages_fast. Fixes: a1d88436d53a ("VMCI: Fix two UVA mapping bugs") Cc: stable Closes: https://lore.kernel.org/all/e91da589-ad57-3969-d979-879bbd10dddd@huawei.com/ Signed-off-by: Wupeng Ma Link: https://lore.kernel.org/r/20250510033040.901582-1-mawupeng1@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/vmw_vmci/vmci_host.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/misc/vmw_vmci/vmci_host.c b/drivers/misc/vmw_vmci/vmci_host.c index abe79f6fd2a7..b64944367ac5 100644 --- a/drivers/misc/vmw_vmci/vmci_host.c +++ b/drivers/misc/vmw_vmci/vmci_host.c @@ -227,6 +227,7 @@ static int drv_cp_harray_to_user(void __user *user_buf_uva, static int vmci_host_setup_notify(struct vmci_ctx *context, unsigned long uva) { + struct page *page; int retval; if (context->notify_page) { @@ -243,13 +244,11 @@ static int vmci_host_setup_notify(struct vmci_ctx *context, /* * Lock physical page backing a given user VA. */ - retval = get_user_pages_fast(uva, 1, FOLL_WRITE, &context->notify_page); - if (retval != 1) { - context->notify_page = NULL; + retval = get_user_pages_fast(uva, 1, FOLL_WRITE, &page); + if (retval != 1) return VMCI_ERROR_GENERIC; - } - if (context->notify_page == NULL) - return VMCI_ERROR_UNAVAILABLE; + + context->notify_page = page; /* * Map the locked page and set up notify pointer. From 81dc3db4c3ac6d3ca5016a76ee8881c67ceb0cb9 Mon Sep 17 00:00:00 2001 From: Pawel Laszczak Date: Tue, 13 May 2025 05:30:09 +0000 Subject: [PATCH 390/971] usb: cdnsp: Fix issue with detecting command completion event commit f4ecdc352646f7d23f348e5c544dbe3212c94fc8 upstream. In some cases, there is a small-time gap in which CMD_RING_BUSY can be cleared by controller but adding command completion event to event ring will be delayed. As the result driver will return error code. This behavior has been detected on usbtest driver (test 9) with configuration including ep1in/ep1out bulk and ep2in/ep2out isoc endpoint. Probably this gap occurred because controller was busy with adding some other events to event ring. The CMD_RING_BUSY is cleared to '0' when the Command Descriptor has been executed and not when command completion event has been added to event ring. To fix this issue for this test the small delay is sufficient less than 10us) but to make sure the problem doesn't happen again in the future the patch introduces 10 retries to check with delay about 20us before returning error code. Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver") Cc: stable Signed-off-by: Pawel Laszczak Acked-by: Peter Chen Link: https://lore.kernel.org/r/PH7PR07MB9538AA45362ACCF1B94EE9B7DD96A@PH7PR07MB9538.namprd07.prod.outlook.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/cdns3/cdnsp-gadget.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/usb/cdns3/cdnsp-gadget.c b/drivers/usb/cdns3/cdnsp-gadget.c index 601a60a28022..1ef7ee5a47c7 100644 --- a/drivers/usb/cdns3/cdnsp-gadget.c +++ b/drivers/usb/cdns3/cdnsp-gadget.c @@ -546,6 +546,7 @@ int cdnsp_wait_for_cmd_compl(struct cdnsp_device *pdev) dma_addr_t cmd_deq_dma; union cdnsp_trb *event; u32 cycle_state; + u32 retry = 10; int ret, val; u64 cmd_dma; u32 flags; @@ -577,8 +578,23 @@ int cdnsp_wait_for_cmd_compl(struct cdnsp_device *pdev) flags = le32_to_cpu(event->event_cmd.flags); /* Check the owner of the TRB. */ - if ((flags & TRB_CYCLE) != cycle_state) + if ((flags & TRB_CYCLE) != cycle_state) { + /* + * Give some extra time to get chance controller + * to finish command before returning error code. + * Checking CMD_RING_BUSY is not sufficient because + * this bit is cleared to '0' when the Command + * Descriptor has been executed by controller + * and not when command completion event has + * be added to event ring. + */ + if (retry--) { + udelay(20); + continue; + } + return -EINVAL; + } cmd_dma = le64_to_cpu(event->event_cmd.cmd_trb); From c40b5e0aad1fe99fbcc721209364a9ebe0276b5f Mon Sep 17 00:00:00 2001 From: Pawel Laszczak Date: Tue, 13 May 2025 06:54:03 +0000 Subject: [PATCH 391/971] usb: cdnsp: Fix issue with detecting USB 3.2 speed commit 2852788cfbe9ca1ab68509d65804413871f741f9 upstream. Patch adds support for detecting SuperSpeedPlus Gen1 x2 and SuperSpeedPlus Gen2 x2 speed. Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver") Cc: stable Signed-off-by: Pawel Laszczak Acked-by: Peter Chen Link: https://lore.kernel.org/r/PH7PR07MB95387AD98EDCA695FECE52BADD96A@PH7PR07MB9538.namprd07.prod.outlook.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/cdns3/cdnsp-gadget.c | 3 ++- drivers/usb/cdns3/cdnsp-gadget.h | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/usb/cdns3/cdnsp-gadget.c b/drivers/usb/cdns3/cdnsp-gadget.c index 1ef7ee5a47c7..132885fbb98f 100644 --- a/drivers/usb/cdns3/cdnsp-gadget.c +++ b/drivers/usb/cdns3/cdnsp-gadget.c @@ -28,7 +28,8 @@ unsigned int cdnsp_port_speed(unsigned int port_status) { /*Detect gadget speed based on PORTSC register*/ - if (DEV_SUPERSPEEDPLUS(port_status)) + if (DEV_SUPERSPEEDPLUS(port_status) || + DEV_SSP_GEN1x2(port_status) || DEV_SSP_GEN2x2(port_status)) return USB_SPEED_SUPER_PLUS; else if (DEV_SUPERSPEED(port_status)) return USB_SPEED_SUPER; diff --git a/drivers/usb/cdns3/cdnsp-gadget.h b/drivers/usb/cdns3/cdnsp-gadget.h index ed84dbb9fd6f..909cee01772a 100644 --- a/drivers/usb/cdns3/cdnsp-gadget.h +++ b/drivers/usb/cdns3/cdnsp-gadget.h @@ -285,11 +285,15 @@ struct cdnsp_port_regs { #define XDEV_HS (0x3 << 10) #define XDEV_SS (0x4 << 10) #define XDEV_SSP (0x5 << 10) +#define XDEV_SSP1x2 (0x6 << 10) +#define XDEV_SSP2x2 (0x7 << 10) #define DEV_UNDEFSPEED(p) (((p) & DEV_SPEED_MASK) == (0x0 << 10)) #define DEV_FULLSPEED(p) (((p) & DEV_SPEED_MASK) == XDEV_FS) #define DEV_HIGHSPEED(p) (((p) & DEV_SPEED_MASK) == XDEV_HS) #define DEV_SUPERSPEED(p) (((p) & DEV_SPEED_MASK) == XDEV_SS) #define DEV_SUPERSPEEDPLUS(p) (((p) & DEV_SPEED_MASK) == XDEV_SSP) +#define DEV_SSP_GEN1x2(p) (((p) & DEV_SPEED_MASK) == XDEV_SSP1x2) +#define DEV_SSP_GEN2x2(p) (((p) & DEV_SPEED_MASK) == XDEV_SSP2x2) #define DEV_SUPERSPEED_ANY(p) (((p) & DEV_SPEED_MASK) >= XDEV_SS) #define DEV_PORT_SPEED(p) (((p) >> 10) & 0x0f) /* Port Link State Write Strobe - set this when changing link state */ From 3c7e52cfa86de527d00e2b8a3456f6229acbbacd Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Wed, 14 May 2025 16:25:20 +0300 Subject: [PATCH 392/971] usb: Flush altsetting 0 endpoints before reinitializating them after reset. commit 89bb3dc13ac29a563f4e4c555e422882f64742bd upstream. usb core avoids sending a Set-Interface altsetting 0 request after device reset, and instead relies on calling usb_disable_interface() and usb_enable_interface() to flush and reset host-side of those endpoints. xHCI hosts allocate and set up endpoint ring buffers and host_ep->hcpriv during usb_hcd_alloc_bandwidth() callback, which in this case is called before flushing the endpoint in usb_disable_interface(). Call usb_disable_interface() before usb_hcd_alloc_bandwidth() to ensure URBs are flushed before new ring buffers for the endpoints are allocated. Otherwise host driver will attempt to find and remove old stale URBs from a freshly allocated new ringbuffer. Cc: stable Fixes: 4fe0387afa89 ("USB: don't send Set-Interface after reset") Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20250514132520.225345-1-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 760283a541b4..855356752380 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -6103,6 +6103,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) struct usb_hub *parent_hub; struct usb_hcd *hcd = bus_to_hcd(udev->bus); struct usb_device_descriptor descriptor; + struct usb_interface *intf; struct usb_host_bos *bos; int i, j, ret = 0; int port1 = udev->portnum; @@ -6160,6 +6161,18 @@ static int usb_reset_and_verify_device(struct usb_device *udev) if (!udev->actconfig) goto done; + /* + * Some devices can't handle setting default altsetting 0 with a + * Set-Interface request. Disable host-side endpoints of those + * interfaces here. Enable and reset them back after host has set + * its internal endpoint structures during usb_hcd_alloc_bandwith() + */ + for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { + intf = udev->actconfig->interface[i]; + if (intf->cur_altsetting->desc.bAlternateSetting == 0) + usb_disable_interface(udev, intf, true); + } + mutex_lock(hcd->bandwidth_mutex); ret = usb_hcd_alloc_bandwidth(udev, udev->actconfig, NULL, NULL); if (ret < 0) { @@ -6191,12 +6204,11 @@ static int usb_reset_and_verify_device(struct usb_device *udev) */ for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { struct usb_host_config *config = udev->actconfig; - struct usb_interface *intf = config->interface[i]; struct usb_interface_descriptor *desc; + intf = config->interface[i]; desc = &intf->cur_altsetting->desc; if (desc->bAlternateSetting == 0) { - usb_disable_interface(udev, intf, true); usb_enable_interface(udev, intf, true); ret = 0; } else { From b0e35d56391770258e04e97b206b1e7a4bc9dbe2 Mon Sep 17 00:00:00 2001 From: Amit Sunil Dhamne Date: Fri, 2 May 2025 16:57:03 -0700 Subject: [PATCH 393/971] usb: typec: tcpm/tcpci_maxim: Fix bounds check in process_rx() commit 0736299d090f5c6a1032678705c4bc0a9511a3db upstream. Register read of TCPC_RX_BYTE_CNT returns the total size consisting of: PD message (pending read) size + 1 Byte for Frame Type (SOP*) This is validated against the max PD message (`struct pd_message`) size without accounting for the extra byte for the frame type. Note that the struct pd_message does not contain a field for the frame_type. This results in false negatives when the "PD message (pending read)" is equal to the max PD message size. Fixes: 6f413b559f86 ("usb: typec: tcpci_maxim: Chip level TCPC driver") Signed-off-by: Amit Sunil Dhamne Signed-off-by: Badhri Jagan Sridharan Reviewed-by: Kyle Tso Cc: stable Link: https://lore.kernel.org/stable/20250502-b4-new-fix-pd-rx-count-v1-1-e5711ed09b3d%40google.com Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20250502-b4-new-fix-pd-rx-count-v1-1-e5711ed09b3d@google.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/tcpm/tcpci_maxim_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/typec/tcpm/tcpci_maxim_core.c b/drivers/usb/typec/tcpm/tcpci_maxim_core.c index 9454b12a073c..e460b956ab71 100644 --- a/drivers/usb/typec/tcpm/tcpci_maxim_core.c +++ b/drivers/usb/typec/tcpm/tcpci_maxim_core.c @@ -145,7 +145,8 @@ static void process_rx(struct max_tcpci_chip *chip, u16 status) return; } - if (count > sizeof(struct pd_message) || count + 1 > TCPC_RECEIVE_BUFFER_LEN) { + if (count > sizeof(struct pd_message) + 1 || + count + 1 > TCPC_RECEIVE_BUFFER_LEN) { dev_err(chip->dev, "Invalid TCPC_RX_BYTE_CNT %d\n", count); return; } From 8884c41bae3967b3fa7b6762590edc5e7055d5a9 Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Mon, 12 May 2025 14:54:52 -0700 Subject: [PATCH 394/971] xen/arm: call uaccess_ttbr0_enable for dm_op hypercall commit 7f9bbc1140ff8796230bc2634055763e271fd692 upstream. dm_op hypercalls might come from userspace and pass memory addresses as parameters. The memory addresses typically correspond to buffers allocated in userspace to hold extra hypercall parameters. On ARM, when CONFIG_ARM64_SW_TTBR0_PAN is enabled, they might not be accessible by Xen, as a result ioreq hypercalls might fail. See the existing comment in arch/arm64/xen/hypercall.S regarding privcmd_call for reference. For privcmd_call, Linux calls uaccess_ttbr0_enable before issuing the hypercall thanks to commit 9cf09d68b89a. We need to do the same for dm_op. This resolves the problem. Cc: stable@kernel.org Fixes: 9cf09d68b89a ("arm64: xen: Enable user access before a privcmd hvc call") Signed-off-by: Stefano Stabellini Reviewed-by: Juergen Gross Message-ID: Signed-off-by: Juergen Gross Signed-off-by: Greg Kroah-Hartman --- arch/arm64/xen/hypercall.S | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/arch/arm64/xen/hypercall.S b/arch/arm64/xen/hypercall.S index 9d01361696a1..ae551b857137 100644 --- a/arch/arm64/xen/hypercall.S +++ b/arch/arm64/xen/hypercall.S @@ -83,7 +83,26 @@ HYPERCALL3(vcpu_op); HYPERCALL1(platform_op_raw); HYPERCALL2(multicall); HYPERCALL2(vm_assist); -HYPERCALL3(dm_op); + +SYM_FUNC_START(HYPERVISOR_dm_op) + mov x16, #__HYPERVISOR_dm_op; \ + /* + * dm_op hypercalls are issued by the userspace. The kernel needs to + * enable access to TTBR0_EL1 as the hypervisor would issue stage 1 + * translations to user memory via AT instructions. Since AT + * instructions are not affected by the PAN bit (ARMv8.1), we only + * need the explicit uaccess_enable/disable if the TTBR0 PAN emulation + * is enabled (it implies that hardware UAO and PAN disabled). + */ + uaccess_ttbr0_enable x6, x7, x8 + hvc XEN_IMM + + /* + * Disable userspace access from kernel once the hyp call completed. + */ + uaccess_ttbr0_disable x6, x7 + ret +SYM_FUNC_END(HYPERVISOR_dm_op); SYM_FUNC_START(privcmd_call) mov x16, x0 From 2cfcbe1554c119402e7382de974c26b0549899fe Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 26 Feb 2025 16:01:57 +0100 Subject: [PATCH 395/971] x86/iopl: Cure TIF_IO_BITMAP inconsistencies commit 8b68e978718f14fdcb080c2a7791c52a0d09bc6d upstream. io_bitmap_exit() is invoked from exit_thread() when a task exists or when a fork fails. In the latter case the exit_thread() cleans up resources which were allocated during fork(). io_bitmap_exit() invokes task_update_io_bitmap(), which in turn ends up in tss_update_io_bitmap(). tss_update_io_bitmap() operates on the current task. If current has TIF_IO_BITMAP set, but no bitmap installed, tss_update_io_bitmap() crashes with a NULL pointer dereference. There are two issues, which lead to that problem: 1) io_bitmap_exit() should not invoke task_update_io_bitmap() when the task, which is cleaned up, is not the current task. That's a clear indicator for a cleanup after a failed fork(). 2) A task should not have TIF_IO_BITMAP set and neither a bitmap installed nor IOPL emulation level 3 activated. This happens when a kernel thread is created in the context of a user space thread, which has TIF_IO_BITMAP set as the thread flags are copied and the IO bitmap pointer is cleared. Other than in the failed fork() case this has no impact because kernel threads including IO workers never return to user space and therefore never invoke tss_update_io_bitmap(). Cure this by adding the missing cleanups and checks: 1) Prevent io_bitmap_exit() to invoke task_update_io_bitmap() if the to be cleaned up task is not the current task. 2) Clear TIF_IO_BITMAP in copy_thread() unconditionally. For user space forks it is set later, when the IO bitmap is inherited in io_bitmap_share(). For paranoia sake, add a warning into tss_update_io_bitmap() to catch the case, when that code is invoked with inconsistent state. Fixes: ea5f1cd7ab49 ("x86/ioperm: Remove bitmap if all permissions dropped") Reported-by: syzbot+e2b1803445d236442e54@syzkaller.appspotmail.com Signed-off-by: Thomas Gleixner Signed-off-by: Borislav Petkov (AMD) Cc: stable@vger.kernel.org Link: https://lore.kernel.org/87wmdceom2.ffs@tglx Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/ioport.c | 13 +++++++++---- arch/x86/kernel/process.c | 6 ++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c index e2fab3ceb09f..9a101150376d 100644 --- a/arch/x86/kernel/ioport.c +++ b/arch/x86/kernel/ioport.c @@ -33,8 +33,9 @@ void io_bitmap_share(struct task_struct *tsk) set_tsk_thread_flag(tsk, TIF_IO_BITMAP); } -static void task_update_io_bitmap(struct task_struct *tsk) +static void task_update_io_bitmap(void) { + struct task_struct *tsk = current; struct thread_struct *t = &tsk->thread; if (t->iopl_emul == 3 || t->io_bitmap) { @@ -54,7 +55,12 @@ void io_bitmap_exit(struct task_struct *tsk) struct io_bitmap *iobm = tsk->thread.io_bitmap; tsk->thread.io_bitmap = NULL; - task_update_io_bitmap(tsk); + /* + * Don't touch the TSS when invoked on a failed fork(). TSS + * reflects the state of @current and not the state of @tsk. + */ + if (tsk == current) + task_update_io_bitmap(); if (iobm && refcount_dec_and_test(&iobm->refcnt)) kfree(iobm); } @@ -192,8 +198,7 @@ SYSCALL_DEFINE1(iopl, unsigned int, level) } t->iopl_emul = level; - task_update_io_bitmap(current); - + task_update_io_bitmap(); return 0; } diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 8a398acfdea2..33c235e9d0d3 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -180,6 +180,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) frame->ret_addr = (unsigned long) ret_from_fork_asm; p->thread.sp = (unsigned long) fork_frame; p->thread.io_bitmap = NULL; + clear_tsk_thread_flag(p, TIF_IO_BITMAP); p->thread.iopl_warn = 0; memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps)); @@ -468,6 +469,11 @@ void native_tss_update_io_bitmap(void) } else { struct io_bitmap *iobm = t->io_bitmap; + if (WARN_ON_ONCE(!iobm)) { + clear_thread_flag(TIF_IO_BITMAP); + native_tss_invalidate_io_bitmap(); + } + /* * Only copy bitmap data when the sequence number differs. The * update time is accounted to the incoming task. From 1380f68517a7478253c650cdce5b6a075d1c165f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 4 Jun 2025 13:38:26 +0000 Subject: [PATCH 396/971] calipso: unlock rcu before returning -EAFNOSUPPORT commit 3cae906e1a6184cdc9e4d260e4dbdf9a118d94ad upstream. syzbot reported that a recent patch forgot to unlock rcu in the error path. Adopt the convention that netlbl_conn_setattr() is already using. Fixes: 6e9f2df1c550 ("calipso: Don't call calipso functions for AF_INET sk.") Reported-by: syzbot Signed-off-by: Eric Dumazet Cc: Kuniyuki Iwashima Acked-by: Paul Moore Link: https://patch.msgid.link/20250604133826.1667664-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/netlabel/netlabel_kapi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index 75b645c1928d..daef0eeaea2c 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c @@ -1140,8 +1140,10 @@ int netlbl_conn_setattr(struct sock *sk, break; #if IS_ENABLED(CONFIG_IPV6) case AF_INET6: - if (sk->sk_family != AF_INET6) - return -EAFNOSUPPORT; + if (sk->sk_family != AF_INET6) { + ret_val = -EAFNOSUPPORT; + goto conn_setattr_return; + } addr6 = (struct sockaddr_in6 *)addr; entry = netlbl_domhsh_getentry_af6(secattr->domain, From 0fcfc93576bcda87701898cfc5b597f546149344 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?= Date: Wed, 14 May 2025 08:36:06 -0400 Subject: [PATCH 397/971] regulator: dt-bindings: mt6357: Drop fixed compatible requirement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 9cfdd7752ba5f8cc9b8191e8c9aeeec246241fa4 upstream. Some of the regulators on the MT6357 PMIC currently reference the fixed-regulator dt-binding, which enforces the presence of a regulator-fixed compatible. However since all regulators on the MT6357 PMIC are handled by a single mt6357-regulator driver, probed through MFD, the compatibles don't serve any purpose. In fact they cause failures in the DT kselftest since they aren't probed by the fixed regulator driver as would be expected. Furthermore this is the only dt-binding in this family like this: mt6359-regulator and mt6358-regulator don't require those compatibles. Commit d77e89b7b03f ("arm64: dts: mediatek: mt6357: Drop regulator-fixed compatibles") removed the compatibles from Devicetree, but missed updating the binding, which still requires them, introducing dt-binding errors. Remove the compatible requirement by referencing the plain regulator dt-binding instead to fix the dt-binding errors. Fixes: d77e89b7b03f ("arm64: dts: mediatek: mt6357: Drop regulator-fixed compatibles") Signed-off-by: Nícolas F. R. A. Prado Link: https://patch.msgid.link/20250514-mt6357-regulator-fixed-compatibles-removal-bindings-v1-1-2421e9cc6cc7@collabora.com Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- .../regulator/mediatek,mt6357-regulator.yaml | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/Documentation/devicetree/bindings/regulator/mediatek,mt6357-regulator.yaml b/Documentation/devicetree/bindings/regulator/mediatek,mt6357-regulator.yaml index 6327bb2f6ee0..698266c09e25 100644 --- a/Documentation/devicetree/bindings/regulator/mediatek,mt6357-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/mediatek,mt6357-regulator.yaml @@ -33,7 +33,7 @@ patternProperties: "^ldo-v(camio18|aud28|aux18|io18|io28|rf12|rf18|cn18|cn28|fe28)$": type: object - $ref: fixed-regulator.yaml# + $ref: regulator.yaml# unevaluatedProperties: false description: Properties for single fixed LDO regulator. @@ -112,7 +112,6 @@ examples: regulator-enable-ramp-delay = <220>; }; mt6357_vfe28_reg: ldo-vfe28 { - compatible = "regulator-fixed"; regulator-name = "vfe28"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; @@ -125,14 +124,12 @@ examples: regulator-enable-ramp-delay = <110>; }; mt6357_vrf18_reg: ldo-vrf18 { - compatible = "regulator-fixed"; regulator-name = "vrf18"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-enable-ramp-delay = <110>; }; mt6357_vrf12_reg: ldo-vrf12 { - compatible = "regulator-fixed"; regulator-name = "vrf12"; regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; @@ -157,14 +154,12 @@ examples: regulator-enable-ramp-delay = <264>; }; mt6357_vcn28_reg: ldo-vcn28 { - compatible = "regulator-fixed"; regulator-name = "vcn28"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; regulator-enable-ramp-delay = <264>; }; mt6357_vcn18_reg: ldo-vcn18 { - compatible = "regulator-fixed"; regulator-name = "vcn18"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; @@ -183,7 +178,6 @@ examples: regulator-enable-ramp-delay = <264>; }; mt6357_vcamio_reg: ldo-vcamio18 { - compatible = "regulator-fixed"; regulator-name = "vcamio"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; @@ -212,28 +206,24 @@ examples: regulator-always-on; }; mt6357_vaux18_reg: ldo-vaux18 { - compatible = "regulator-fixed"; regulator-name = "vaux18"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-enable-ramp-delay = <264>; }; mt6357_vaud28_reg: ldo-vaud28 { - compatible = "regulator-fixed"; regulator-name = "vaud28"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; regulator-enable-ramp-delay = <264>; }; mt6357_vio28_reg: ldo-vio28 { - compatible = "regulator-fixed"; regulator-name = "vio28"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; regulator-enable-ramp-delay = <264>; }; mt6357_vio18_reg: ldo-vio18 { - compatible = "regulator-fixed"; regulator-name = "vio18"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; From 65e20c5d99d1d34c6d02ad0880358affd7d2bfb7 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Wed, 28 May 2025 13:03:54 +0200 Subject: [PATCH 398/971] net: usb: aqc111: debug info before sanitation commit d3faab9b5a6a0477d69c38bd11c43aa5e936f929 upstream. If we sanitize error returns, the debug statements need to come before that so that we don't lose information. Signed-off-by: Oliver Neukum Fixes: 405b0d610745 ("net: usb: aqc111: fix error handling of usbnet read calls") Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/aqc111.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c index 04d5573123be..3ebb1f84d302 100644 --- a/drivers/net/usb/aqc111.c +++ b/drivers/net/usb/aqc111.c @@ -31,11 +31,11 @@ static int aqc111_read_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value, USB_RECIP_DEVICE, value, index, data, size); if (unlikely(ret < size)) { - ret = ret < 0 ? ret : -ENODATA; - netdev_warn(dev->net, "Failed to read(0x%x) reg index 0x%04x: %d\n", cmd, index, ret); + + ret = ret < 0 ? ret : -ENODATA; } return ret; @@ -50,11 +50,11 @@ static int aqc111_read_cmd(struct usbnet *dev, u8 cmd, u16 value, USB_RECIP_DEVICE, value, index, data, size); if (unlikely(ret < size)) { - ret = ret < 0 ? ret : -ENODATA; - netdev_warn(dev->net, "Failed to read(0x%x) reg index 0x%04x: %d\n", cmd, index, ret); + + ret = ret < 0 ? ret : -ENODATA; } return ret; From d0e22b854ac62fedcb1c747ce7ef98e7b099dc16 Mon Sep 17 00:00:00 2001 From: I Hsin Cheng Date: Tue, 6 May 2025 02:43:38 +0800 Subject: [PATCH 399/971] drm/meson: Use 1000ULL when operating with mode->clock commit eb0851e14432f3b87c77b704c835ac376deda03a upstream. Coverity scan reported the usage of "mode->clock * 1000" may lead to integer overflow. Use "1000ULL" instead of "1000" when utilizing it to avoid potential integer overflow issue. Link: https://scan5.scan.coverity.com/#/project-view/10074/10063?selectedIssue=1646759 Signed-off-by: I Hsin Cheng Reviewed-by: Martin Blumenstingl Fixes: 1017560164b6 ("drm/meson: use unsigned long long / Hz for frequency types") Link: https://lore.kernel.org/r/20250505184338.678540-1-richard120310@gmail.com Signed-off-by: Neil Armstrong Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/meson/meson_encoder_hdmi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c index 73ec7ae48510..0b7e8e0ba4fc 100644 --- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c +++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c @@ -75,7 +75,7 @@ static void meson_encoder_hdmi_set_vclk(struct meson_encoder_hdmi *encoder_hdmi, unsigned long long venc_freq; unsigned long long hdmi_freq; - vclk_freq = mode->clock * 1000; + vclk_freq = mode->clock * 1000ULL; /* For 420, pixel clock is half unlike venc clock */ if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) @@ -123,7 +123,7 @@ static enum drm_mode_status meson_encoder_hdmi_mode_valid(struct drm_bridge *bri struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge); struct meson_drm *priv = encoder_hdmi->priv; bool is_hdmi2_sink = display_info->hdmi.scdc.supported; - unsigned long long clock = mode->clock * 1000; + unsigned long long clock = mode->clock * 1000ULL; unsigned long long phy_freq; unsigned long long vclk_freq; unsigned long long venc_freq; From 6282921b6825fef6a1243e1c80063421d41e2576 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 19 Jun 2025 15:28:47 +0200 Subject: [PATCH 400/971] Linux 6.6.94 Link: https://lore.kernel.org/r/20250617152338.212798615@linuxfoundation.org Tested-by: Florian Fainelli Tested-by: Shuah Khan Tested-by: Peter Schneider Tested-by: Ron Economos Tested-by: Jon Hunter Tested-by: Linux Kernel Functional Testing Tested-by: Mark Brown Tested-by: Miguel Ojeda Tested-by: Hardik Garg Tested-by: Harshit Mogalapalli Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c9a1e2286b3a..9625d9072c77 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 6 PATCHLEVEL = 6 -SUBLEVEL = 93 +SUBLEVEL = 94 EXTRAVERSION = NAME = Pinguïn Aangedreven From 0df5e4c7de27dde3601e132632bb094afd464339 Mon Sep 17 00:00:00 2001 From: Zijun Hu Date: Wed, 7 May 2025 19:50:26 +0800 Subject: [PATCH 401/971] configfs: Do not override creating attribute file failure in populate_attrs() commit f830edbae247b89228c3e09294151b21e0dc849c upstream. populate_attrs() may override failure for creating attribute files by success for creating subsequent bin attribute files, and have wrong return value. Fix by creating bin attribute files under successfully creating attribute files. Fixes: 03607ace807b ("configfs: implement binary attributes") Cc: stable@vger.kernel.org Reviewed-by: Joel Becker Reviewed-by: Breno Leitao Signed-off-by: Zijun Hu Link: https://lore.kernel.org/r/20250507-fix_configfs-v3-2-fe2d96de8dc4@quicinc.com Signed-off-by: Andreas Hindborg Signed-off-by: Greg Kroah-Hartman --- fs/configfs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 18677cd4e62f..2df99cd1034d 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -593,7 +593,7 @@ static int populate_attrs(struct config_item *item) break; } } - if (t->ct_bin_attrs) { + if (!error && t->ct_bin_attrs) { for (i = 0; (bin_attr = t->ct_bin_attrs[i]) != NULL; i++) { error = configfs_create_bin_file(item, bin_attr); if (error) From f5b9144715da249a5b5e0c211b50bec1c702e68a Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 8 May 2025 13:22:16 +0800 Subject: [PATCH 402/971] crypto: marvell/cesa - Do not chain submitted requests commit 0413bcf0fc460a68a2a7a8354aee833293d7d693 upstream. This driver tries to chain requests together before submitting them to hardware in order to reduce completion interrupts. However, it even extends chains that have already been submitted to hardware. This is dangerous because there is no way of knowing whether the hardware has already read the DMA memory in question or not. Fix this by splitting the chain list into two. One for submitted requests and one for requests that have not yet been submitted. Only extend the latter. Reported-by: Klaus Kudielka Fixes: 85030c5168f1 ("crypto: marvell - Add support for chaining crypto requests in TDMA mode") Cc: Signed-off-by: Herbert Xu Signed-off-by: Greg Kroah-Hartman --- drivers/crypto/marvell/cesa/cesa.c | 2 +- drivers/crypto/marvell/cesa/cesa.h | 9 +++-- drivers/crypto/marvell/cesa/tdma.c | 53 ++++++++++++++++++------------ 3 files changed, 39 insertions(+), 25 deletions(-) diff --git a/drivers/crypto/marvell/cesa/cesa.c b/drivers/crypto/marvell/cesa/cesa.c index b61e35b932e5..76f34b81258d 100644 --- a/drivers/crypto/marvell/cesa/cesa.c +++ b/drivers/crypto/marvell/cesa/cesa.c @@ -94,7 +94,7 @@ static int mv_cesa_std_process(struct mv_cesa_engine *engine, u32 status) static int mv_cesa_int_process(struct mv_cesa_engine *engine, u32 status) { - if (engine->chain.first && engine->chain.last) + if (engine->chain_hw.first && engine->chain_hw.last) return mv_cesa_tdma_process(engine, status); return mv_cesa_std_process(engine, status); diff --git a/drivers/crypto/marvell/cesa/cesa.h b/drivers/crypto/marvell/cesa/cesa.h index d215a6bed6bc..50ca1039fdaa 100644 --- a/drivers/crypto/marvell/cesa/cesa.h +++ b/drivers/crypto/marvell/cesa/cesa.h @@ -440,8 +440,10 @@ struct mv_cesa_dev { * SRAM * @queue: fifo of the pending crypto requests * @load: engine load counter, useful for load balancing - * @chain: list of the current tdma descriptors being processed - * by this engine. + * @chain_hw: list of the current tdma descriptors being processed + * by the hardware. + * @chain_sw: list of the current tdma descriptors that will be + * submitted to the hardware. * @complete_queue: fifo of the processed requests by the engine * * Structure storing CESA engine information. @@ -463,7 +465,8 @@ struct mv_cesa_engine { struct gen_pool *pool; struct crypto_queue queue; atomic_t load; - struct mv_cesa_tdma_chain chain; + struct mv_cesa_tdma_chain chain_hw; + struct mv_cesa_tdma_chain chain_sw; struct list_head complete_queue; int irq; }; diff --git a/drivers/crypto/marvell/cesa/tdma.c b/drivers/crypto/marvell/cesa/tdma.c index 388a06e180d6..243305354420 100644 --- a/drivers/crypto/marvell/cesa/tdma.c +++ b/drivers/crypto/marvell/cesa/tdma.c @@ -38,6 +38,15 @@ void mv_cesa_dma_step(struct mv_cesa_req *dreq) { struct mv_cesa_engine *engine = dreq->engine; + spin_lock_bh(&engine->lock); + if (engine->chain_sw.first == dreq->chain.first) { + engine->chain_sw.first = NULL; + engine->chain_sw.last = NULL; + } + engine->chain_hw.first = dreq->chain.first; + engine->chain_hw.last = dreq->chain.last; + spin_unlock_bh(&engine->lock); + writel_relaxed(0, engine->regs + CESA_SA_CFG); mv_cesa_set_int_mask(engine, CESA_SA_INT_ACC0_IDMA_DONE); @@ -96,25 +105,27 @@ void mv_cesa_dma_prepare(struct mv_cesa_req *dreq, void mv_cesa_tdma_chain(struct mv_cesa_engine *engine, struct mv_cesa_req *dreq) { - if (engine->chain.first == NULL && engine->chain.last == NULL) { - engine->chain.first = dreq->chain.first; - engine->chain.last = dreq->chain.last; - } else { - struct mv_cesa_tdma_desc *last; + struct mv_cesa_tdma_desc *last = engine->chain_sw.last; - last = engine->chain.last; + /* + * Break the DMA chain if the request being queued needs the IV + * regs to be set before lauching the request. + */ + if (!last || dreq->chain.first->flags & CESA_TDMA_SET_STATE) + engine->chain_sw.first = dreq->chain.first; + else { last->next = dreq->chain.first; - engine->chain.last = dreq->chain.last; - - /* - * Break the DMA chain if the CESA_TDMA_BREAK_CHAIN is set on - * the last element of the current chain, or if the request - * being queued needs the IV regs to be set before lauching - * the request. - */ - if (!(last->flags & CESA_TDMA_BREAK_CHAIN) && - !(dreq->chain.first->flags & CESA_TDMA_SET_STATE)) - last->next_dma = cpu_to_le32(dreq->chain.first->cur_dma); + last->next_dma = cpu_to_le32(dreq->chain.first->cur_dma); + } + last = dreq->chain.last; + engine->chain_sw.last = last; + /* + * Break the DMA chain if the CESA_TDMA_BREAK_CHAIN is set on + * the last element of the current chain. + */ + if (last->flags & CESA_TDMA_BREAK_CHAIN) { + engine->chain_sw.first = NULL; + engine->chain_sw.last = NULL; } } @@ -127,7 +138,7 @@ int mv_cesa_tdma_process(struct mv_cesa_engine *engine, u32 status) tdma_cur = readl(engine->regs + CESA_TDMA_CUR); - for (tdma = engine->chain.first; tdma; tdma = next) { + for (tdma = engine->chain_hw.first; tdma; tdma = next) { spin_lock_bh(&engine->lock); next = tdma->next; spin_unlock_bh(&engine->lock); @@ -149,12 +160,12 @@ int mv_cesa_tdma_process(struct mv_cesa_engine *engine, u32 status) &backlog); /* Re-chaining to the next request */ - engine->chain.first = tdma->next; + engine->chain_hw.first = tdma->next; tdma->next = NULL; /* If this is the last request, clear the chain */ - if (engine->chain.first == NULL) - engine->chain.last = NULL; + if (engine->chain_hw.first == NULL) + engine->chain_hw.last = NULL; spin_unlock_bh(&engine->lock); ctx = crypto_tfm_ctx(req->tfm); From 40aefac870c14a74f249922e53233782101bb5ba Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 31 Mar 2025 19:03:24 -0400 Subject: [PATCH 403/971] gfs2: move msleep to sleepable context commit ac5ee087d31ed93b6e45d2968a66828c6f621d8c upstream. This patch moves the msleep_interruptible() out of the non-sleepable context by moving the ls->ls_recover_spin spinlock around so msleep_interruptible() will be called in a sleepable context. Cc: stable@vger.kernel.org Fixes: 4a7727725dc7 ("GFS2: Fix recovery issues for spectators") Suggested-by: Andreas Gruenbacher Signed-off-by: Alexander Aring Signed-off-by: Andreas Gruenbacher Signed-off-by: Greg Kroah-Hartman --- fs/gfs2/lock_dlm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c index e028e55e67d9..07aac73377d8 100644 --- a/fs/gfs2/lock_dlm.c +++ b/fs/gfs2/lock_dlm.c @@ -959,14 +959,15 @@ locks_done: if (sdp->sd_args.ar_spectator) { fs_info(sdp, "Recovery is required. Waiting for a " "non-spectator to mount.\n"); + spin_unlock(&ls->ls_recover_spin); msleep_interruptible(1000); } else { fs_info(sdp, "control_mount wait1 block %u start %u " "mount %u lvb %u flags %lx\n", block_gen, start_gen, mount_gen, lvb_gen, ls->ls_recover_flags); + spin_unlock(&ls->ls_recover_spin); } - spin_unlock(&ls->ls_recover_spin); goto restart; } From 3895a7590e6e3eebd8e3945acd0662a3ac331f2c Mon Sep 17 00:00:00 2001 From: Wentao Liang Date: Mon, 19 May 2025 15:57:39 +0800 Subject: [PATCH 404/971] ASoC: qcom: sdm845: Add error handling in sdm845_slim_snd_hw_params() commit 688abe2860fd9c644705b9e11cb9649eb891b879 upstream. The function sdm845_slim_snd_hw_params() calls the functuion snd_soc_dai_set_channel_map() but does not check its return value. A proper implementation can be found in msm_snd_hw_params(). Add error handling for snd_soc_dai_set_channel_map(). If the function fails and it is not a unsupported error, return the error code immediately. Fixes: 5caf64c633a3 ("ASoC: qcom: sdm845: add support to DB845c and Lenovo Yoga") Cc: stable@vger.kernel.org # v5.6 Signed-off-by: Wentao Liang Reviewed-by: Dmitry Baryshkov Link: https://patch.msgid.link/20250519075739.1458-1-vulab@iscas.ac.cn Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- sound/soc/qcom/sdm845.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c index 3eb29645a637..39d22304ce43 100644 --- a/sound/soc/qcom/sdm845.c +++ b/sound/soc/qcom/sdm845.c @@ -90,6 +90,10 @@ static int sdm845_slim_snd_hw_params(struct snd_pcm_substream *substream, else ret = snd_soc_dai_set_channel_map(cpu_dai, tx_ch_cnt, tx_ch, 0, NULL); + if (ret != 0 && ret != -ENOTSUPP) { + dev_err(rtd->dev, "failed to set cpu chan map, err:%d\n", ret); + return ret; + } } return 0; From abf80985f4d667644d0959887e7e132f6761568f Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sat, 19 Apr 2025 23:34:48 +0200 Subject: [PATCH 405/971] ASoC: meson: meson-card-utils: use of_property_present() for DT parsing commit 171eb6f71e9e3ba6a7410a1d93f3ac213f39dae2 upstream. Commit c141ecc3cecd ("of: Warn when of_property_read_bool() is used on non-boolean properties") added a warning when trying to parse a property with a value (boolean properties are defined as: absent = false, present without any value = true). This causes a warning from meson-card-utils. meson-card-utils needs to know about the existence of the "audio-routing" and/or "audio-widgets" properties in order to properly parse them. Switch to of_property_present() in order to silence the following warning messages during boot: OF: /sound: Read of boolean property 'audio-routing' with a value. OF: /sound: Read of boolean property 'audio-widgets' with a value. Fixes: 7864a79f37b5 ("ASoC: meson: add axg sound card support") Tested-by: Christian Hewitt Cc: stable@vger.kernel.org Signed-off-by: Martin Blumenstingl Link: https://patch.msgid.link/20250419213448.59647-1-martin.blumenstingl@googlemail.com Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- sound/soc/meson/meson-card-utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/meson/meson-card-utils.c b/sound/soc/meson/meson-card-utils.c index f7fd9c013e19..1adaf0041a48 100644 --- a/sound/soc/meson/meson-card-utils.c +++ b/sound/soc/meson/meson-card-utils.c @@ -231,7 +231,7 @@ static int meson_card_parse_of_optional(struct snd_soc_card *card, const char *p)) { /* If property is not provided, don't fail ... */ - if (!of_property_read_bool(card->dev->of_node, propname)) + if (!of_property_present(card->dev->of_node, propname)) return 0; /* ... but do fail if it is provided and the parsing fails */ From a8b5ef355477348861a3bff9567d2cc5d0515b7c Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Fri, 9 May 2025 12:12:47 +0100 Subject: [PATCH 406/971] io_uring: account drain memory to cgroup commit f979c20547e72568e3c793bc92c7522bc3166246 upstream. Account drain allocations against memcg. It's not a big problem as each such allocation is paired with a request, which is accounted, but it's nicer to follow the limits more closely. Cc: stable@vger.kernel.org # 6.1 Signed-off-by: Pavel Begunkov Link: https://lore.kernel.org/r/f8dfdbd755c41fd9c75d12b858af07dfba5bbb68.1746788718.git.asml.silence@gmail.com Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- io_uring/io_uring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index ff1a93d405e9..897f07014c01 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -1808,7 +1808,7 @@ queue: spin_unlock(&ctx->completion_lock); io_prep_async_link(req); - de = kmalloc(sizeof(*de), GFP_KERNEL); + de = kmalloc(sizeof(*de), GFP_KERNEL_ACCOUNT); if (!de) { ret = -ENOMEM; io_req_defer_failed(req, ret); From 0257c26bbca5c3d3b51a66b09b75eee66d929fc5 Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Tue, 13 May 2025 18:26:46 +0100 Subject: [PATCH 407/971] io_uring/kbuf: account ring io_buffer_list memory commit 475a8d30371604a6363da8e304a608a5959afc40 upstream. Follow the non-ringed pbuf struct io_buffer_list allocations and account it against the memcg. There is low chance of that being an actual problem as ring provided buffer should either pin user memory or allocate it, which is already accounted. Cc: stable@vger.kernel.org # 6.1 Signed-off-by: Pavel Begunkov Link: https://lore.kernel.org/r/3985218b50d341273cafff7234e1a7e6d0db9808.1747150490.git.asml.silence@gmail.com Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- io_uring/kbuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c index addd7c973657..b2c381634393 100644 --- a/io_uring/kbuf.c +++ b/io_uring/kbuf.c @@ -560,7 +560,7 @@ int io_register_pbuf_ring(struct io_ring_ctx *ctx, void __user *arg) io_destroy_bl(ctx, bl); } - free_bl = bl = kzalloc(sizeof(*bl), GFP_KERNEL); + free_bl = bl = kzalloc(sizeof(*bl), GFP_KERNEL_ACCOUNT); if (!bl) return -ENOMEM; From bf70b3c3df5f5645d8dee63a1a62495f840f0dd7 Mon Sep 17 00:00:00 2001 From: Gautam Menghani Date: Wed, 5 Mar 2025 14:32:36 +0530 Subject: [PATCH 408/971] powerpc/pseries/msi: Avoid reading PCI device registers in reduced power states commit 9cc0eafd28c7faef300822992bb08d79cab2a36c upstream. When a system is being suspended to RAM, the PCI devices are also suspended and the PPC code ends up calling pseries_msi_compose_msg() and this triggers the BUG_ON() in __pci_read_msi_msg() because the device at this point is in reduced power state. In reduced power state, the memory mapped registers of the PCI device are not accessible. To replicate the bug: 1. Make sure deep sleep is selected # cat /sys/power/mem_sleep s2idle [deep] 2. Make sure console is not suspended (so that dmesg logs are visible) echo N > /sys/module/printk/parameters/console_suspend 3. Suspend the system echo mem > /sys/power/state To fix this behaviour, read the cached msi message of the device when the device is not in PCI_D0 power state instead of touching the hardware. Fixes: a5f3d2c17b07 ("powerpc/pseries/pci: Add MSI domains") Cc: stable@vger.kernel.org # v5.15+ Signed-off-by: Gautam Menghani Tested-by: Venkat Rao Bagalkote Reviewed-by: Vaibhav Jain Signed-off-by: Madhavan Srinivasan Link: https://patch.msgid.link/20250305090237.294633-1-gautam@linux.ibm.com Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/platforms/pseries/msi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index 423ee1d5bd94..fdcf10cd4d12 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -519,7 +519,12 @@ static struct msi_domain_info pseries_msi_domain_info = { static void pseries_msi_compose_msg(struct irq_data *data, struct msi_msg *msg) { - __pci_read_msi_msg(irq_data_get_msi_desc(data), msg); + struct pci_dev *dev = msi_desc_to_pci_dev(irq_data_get_msi_desc(data)); + + if (dev->current_state == PCI_D0) + __pci_read_msi_msg(irq_data_get_msi_desc(data), msg); + else + get_cached_msi_msg(data->irq, msg); } static struct irq_chip pseries_msi_irq_chip = { From 420f6942f109a68d20a9b372735daf2e20b06b39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Paulo=20Gon=C3=A7alves?= Date: Sun, 20 Apr 2025 15:28:01 -0300 Subject: [PATCH 409/971] regulator: max20086: Fix MAX200086 chip id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 71406b6d1155d883c80c1b4405939a52f723aa05 upstream. >From MAX20086-MAX20089 datasheet, the id for a MAX20086 is 0x30 and not 0x40. With the current code, the driver will fail on probe when the driver tries to identify the chip id from a MAX20086 device over I2C. Cc: stable@vger.kernel.org Fixes: bfff546aae50 ("regulator: Add MAX20086-MAX20089 driver") Signed-off-by: João Paulo Gonçalves Link: https://patch.msgid.link/20250420-fix-max20086-v1-1-8cc9ee0d5a08@gmail.com Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/regulator/max20086-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/max20086-regulator.c b/drivers/regulator/max20086-regulator.c index 1cf04d1efb33..deb1bae5a3e5 100644 --- a/drivers/regulator/max20086-regulator.c +++ b/drivers/regulator/max20086-regulator.c @@ -29,7 +29,7 @@ #define MAX20086_REG_ADC4 0x09 /* DEVICE IDs */ -#define MAX20086_DEVICE_ID_MAX20086 0x40 +#define MAX20086_DEVICE_ID_MAX20086 0x30 #define MAX20086_DEVICE_ID_MAX20087 0x20 #define MAX20086_DEVICE_ID_MAX20088 0x10 #define MAX20086_DEVICE_ID_MAX20089 0x00 From 278a92b8746309b7c6db4e9b57ef61e9724b7375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Paulo=20Gon=C3=A7alves?= Date: Sun, 20 Apr 2025 15:28:02 -0300 Subject: [PATCH 410/971] regulator: max20086: Change enable gpio to optional MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit e8ac7336dd62f0443a675ed80b17f0f0e6846e20 upstream. The enable pin can be configured as always enabled by the hardware. Make the enable gpio request optional so the driver doesn't fail to probe when `enable-gpios` property is not present in the device tree. Cc: stable@vger.kernel.org Fixes: bfff546aae50 ("regulator: Add MAX20086-MAX20089 driver") Signed-off-by: João Paulo Gonçalves Link: https://patch.msgid.link/20250420-fix-max20086-v1-2-8cc9ee0d5a08@gmail.com Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/regulator/max20086-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/max20086-regulator.c b/drivers/regulator/max20086-regulator.c index deb1bae5a3e5..8fcca52026bf 100644 --- a/drivers/regulator/max20086-regulator.c +++ b/drivers/regulator/max20086-regulator.c @@ -264,7 +264,7 @@ static int max20086_i2c_probe(struct i2c_client *i2c) * shutdown. */ flags = boot_on ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW; - chip->ena_gpiod = devm_gpiod_get(chip->dev, "enable", flags); + chip->ena_gpiod = devm_gpiod_get_optional(chip->dev, "enable", flags); if (IS_ERR(chip->ena_gpiod)) { ret = PTR_ERR(chip->ena_gpiod); dev_err(chip->dev, "Failed to get enable GPIO: %d\n", ret); From 477e4319c371c9a33630558c9db6a94c451b6b6d Mon Sep 17 00:00:00 2001 From: Wentao Liang Date: Wed, 21 May 2025 21:36:20 +0800 Subject: [PATCH 411/971] net/mlx5_core: Add error handling inmlx5_query_nic_vport_qkey_viol_cntr() commit f0b50730bdd8f2734e548de541e845c0d40dceb6 upstream. The function mlx5_query_nic_vport_qkey_viol_cntr() calls the function mlx5_query_nic_vport_context() but does not check its return value. This could lead to undefined behavior if the query fails. A proper implementation can be found in mlx5_nic_vport_query_local_lb(). Add error handling for mlx5_query_nic_vport_context(). If it fails, free the out buffer via kvfree() and return error code. Fixes: 9efa75254593 ("net/mlx5_core: Introduce access functions to query vport RoCE fields") Cc: stable@vger.kernel.org # v4.5 Signed-off-by: Wentao Liang Reviewed-by: Tariq Toukan Link: https://patch.msgid.link/20250521133620.912-1-vulab@iscas.ac.cn Signed-off-by: Paolo Abeni Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx5/core/vport.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vport.c b/drivers/net/ethernet/mellanox/mlx5/core/vport.c index 21753f327868..6587ba8bfccd 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/vport.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/vport.c @@ -498,19 +498,22 @@ int mlx5_query_nic_vport_qkey_viol_cntr(struct mlx5_core_dev *mdev, { u32 *out; int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out); + int err; out = kvzalloc(outlen, GFP_KERNEL); if (!out) return -ENOMEM; - mlx5_query_nic_vport_context(mdev, 0, out); + err = mlx5_query_nic_vport_context(mdev, 0, out); + if (err) + goto out; *qkey_viol_cntr = MLX5_GET(query_nic_vport_context_out, out, nic_vport_context.qkey_violation_counter); - +out: kvfree(out); - return 0; + return err; } EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_qkey_viol_cntr); From 782b3aff6763bc9d3854fcb64a602a5fdcfb6eb7 Mon Sep 17 00:00:00 2001 From: Wentao Liang Date: Sun, 25 May 2025 00:34:25 +0800 Subject: [PATCH 412/971] net/mlx5: Add error handling in mlx5_query_nic_vport_node_guid() commit c6bb8a21cdad8c975a3a646b9e5c8df01ad29783 upstream. The function mlx5_query_nic_vport_node_guid() calls the function mlx5_query_nic_vport_context() but does not check its return value. A proper implementation can be found in mlx5_nic_vport_query_local_lb(). Add error handling for mlx5_query_nic_vport_context(). If it fails, free the out buffer via kvfree() and return error code. Fixes: 9efa75254593 ("net/mlx5_core: Introduce access functions to query vport RoCE fields") Cc: stable@vger.kernel.org # v4.5 Signed-off-by: Wentao Liang Reviewed-by: Tariq Toukan Link: https://patch.msgid.link/20250524163425.1695-1-vulab@iscas.ac.cn Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx5/core/vport.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vport.c b/drivers/net/ethernet/mellanox/mlx5/core/vport.c index 6587ba8bfccd..06b5265b6e6d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/vport.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/vport.c @@ -444,19 +444,22 @@ int mlx5_query_nic_vport_node_guid(struct mlx5_core_dev *mdev, u64 *node_guid) { u32 *out; int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out); + int err; out = kvzalloc(outlen, GFP_KERNEL); if (!out) return -ENOMEM; - mlx5_query_nic_vport_context(mdev, 0, out); + err = mlx5_query_nic_vport_context(mdev, 0, out); + if (err) + goto out; *node_guid = MLX5_GET64(query_nic_vport_context_out, out, nic_vport_context.node_guid); - +out: kvfree(out); - return 0; + return err; } EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_node_guid); From 0e4dc150423b829c35cbcf399481ca11594fc036 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 16 May 2025 20:41:06 +0200 Subject: [PATCH 413/971] wifi: p54: prevent buffer-overflow in p54_rx_eeprom_readback() commit da1b9a55ff116cb040528ef664c70a4eec03ae99 upstream. Robert Morris reported: |If a malicious USB device pretends to be an Intersil p54 wifi |interface and generates an eeprom_readback message with a large |eeprom->v1.len, p54_rx_eeprom_readback() will copy data from the |message beyond the end of priv->eeprom. | |static void p54_rx_eeprom_readback(struct p54_common *priv, | struct sk_buff *skb) |{ | struct p54_hdr *hdr = (struct p54_hdr *) skb->data; | struct p54_eeprom_lm86 *eeprom = (struct p54_eeprom_lm86 *) hdr->data; | | if (priv->fw_var >= 0x509) { | memcpy(priv->eeprom, eeprom->v2.data, | le16_to_cpu(eeprom->v2.len)); | } else { | memcpy(priv->eeprom, eeprom->v1.data, | le16_to_cpu(eeprom->v1.len)); | } | [...] The eeprom->v{1,2}.len is set by the driver in p54_download_eeprom(). The device is supposed to provide the same length back to the driver. But yes, it's possible (like shown in the report) to alter the value to something that causes a crash/panic due to overrun. This patch addresses the issue by adding the size to the common device context, so p54_rx_eeprom_readback no longer relies on possibly tampered values... That said, it also checks if the "firmware" altered the value and no longer copies them. The one, small saving grace is: Before the driver tries to read the eeprom, it needs to upload >a< firmware. the vendor firmware has a proprietary license and as a reason, it is not present on most distributions by default. Cc: Reported-by: Robert Morris Closes: https://lore.kernel.org/linux-wireless/28782.1747258414@localhost/ Fixes: 7cb770729ba8 ("p54: move eeprom code into common library") Signed-off-by: Christian Lamparter Link: https://patch.msgid.link/20250516184107.47794-1-chunkeey@gmail.com Signed-off-by: Johannes Berg Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/intersil/p54/fwio.c | 2 ++ drivers/net/wireless/intersil/p54/p54.h | 1 + drivers/net/wireless/intersil/p54/txrx.c | 13 +++++++++---- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intersil/p54/fwio.c b/drivers/net/wireless/intersil/p54/fwio.c index b52cce38115d..06e5df90b43e 100644 --- a/drivers/net/wireless/intersil/p54/fwio.c +++ b/drivers/net/wireless/intersil/p54/fwio.c @@ -231,6 +231,7 @@ int p54_download_eeprom(struct p54_common *priv, void *buf, mutex_lock(&priv->eeprom_mutex); priv->eeprom = buf; + priv->eeprom_slice_size = len; eeprom_hdr = skb_put(skb, eeprom_hdr_size + len); if (priv->fw_var < 0x509) { @@ -253,6 +254,7 @@ int p54_download_eeprom(struct p54_common *priv, void *buf, ret = -EBUSY; } priv->eeprom = NULL; + priv->eeprom_slice_size = 0; mutex_unlock(&priv->eeprom_mutex); return ret; } diff --git a/drivers/net/wireless/intersil/p54/p54.h b/drivers/net/wireless/intersil/p54/p54.h index 3356ea708d81..97fc863fef81 100644 --- a/drivers/net/wireless/intersil/p54/p54.h +++ b/drivers/net/wireless/intersil/p54/p54.h @@ -258,6 +258,7 @@ struct p54_common { /* eeprom handling */ void *eeprom; + size_t eeprom_slice_size; struct completion eeprom_comp; struct mutex eeprom_mutex; }; diff --git a/drivers/net/wireless/intersil/p54/txrx.c b/drivers/net/wireless/intersil/p54/txrx.c index 8414aa208655..2deb1bb54f24 100644 --- a/drivers/net/wireless/intersil/p54/txrx.c +++ b/drivers/net/wireless/intersil/p54/txrx.c @@ -496,14 +496,19 @@ static void p54_rx_eeprom_readback(struct p54_common *priv, return ; if (priv->fw_var >= 0x509) { - memcpy(priv->eeprom, eeprom->v2.data, - le16_to_cpu(eeprom->v2.len)); + if (le16_to_cpu(eeprom->v2.len) != priv->eeprom_slice_size) + return; + + memcpy(priv->eeprom, eeprom->v2.data, priv->eeprom_slice_size); } else { - memcpy(priv->eeprom, eeprom->v1.data, - le16_to_cpu(eeprom->v1.len)); + if (le16_to_cpu(eeprom->v1.len) != priv->eeprom_slice_size) + return; + + memcpy(priv->eeprom, eeprom->v1.data, priv->eeprom_slice_size); } priv->eeprom = NULL; + priv->eeprom_slice_size = 0; tmp = p54_find_and_unlink_skb(priv, hdr->req_id); dev_kfree_skb_any(tmp); complete(&priv->eeprom_comp); From 68b29235778b2a88e54354cc4e75958e95992cf2 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 21 Mar 2025 15:53:02 +0100 Subject: [PATCH 414/971] wifi: ath11k: fix rx completion meta data corruption commit ab52e3e44fe9b666281752e2481d11e25b0e3fdd upstream. Add the missing memory barrier to make sure that the REO dest ring descriptor is read after the head pointer to avoid using stale data on weakly ordered architectures like aarch64. This may fix the ring-buffer corruption worked around by commit f9fff67d2d7c ("wifi: ath11k: Fix SKB corruption in REO destination ring") by silently discarding data, and may possibly also address user reported errors like: ath11k_pci 0006:01:00.0: msdu_done bit in attention is not set Tested-on: WCN6855 hw2.1 WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41 Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") Cc: stable@vger.kernel.org # 5.6 Link: https://bugzilla.kernel.org/show_bug.cgi?id=218005 Signed-off-by: Johan Hovold Tested-by: Clayton Craft Link: https://patch.msgid.link/20250321145302.4775-1-johan+linaro@kernel.org Signed-off-by: Jeff Johnson Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath11k/dp_rx.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index 4c70366ac56e..2b7bee666472 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -2649,7 +2649,7 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id, struct ath11k *ar; struct hal_reo_dest_ring *desc; enum hal_reo_dest_ring_push_reason push_reason; - u32 cookie; + u32 cookie, info0, rx_msdu_info0, rx_mpdu_info0; int i; for (i = 0; i < MAX_RADIOS; i++) @@ -2662,11 +2662,14 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id, try_again: ath11k_hal_srng_access_begin(ab, srng); + /* Make sure descriptor is read after the head pointer. */ + dma_rmb(); + while (likely(desc = (struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab, srng))) { cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, - desc->buf_addr_info.info1); + READ_ONCE(desc->buf_addr_info.info1)); buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID, cookie); mac_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_PDEV_ID, cookie); @@ -2695,8 +2698,9 @@ try_again: num_buffs_reaped[mac_id]++; + info0 = READ_ONCE(desc->info0); push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON, - desc->info0); + info0); if (unlikely(push_reason != HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION)) { dev_kfree_skb_any(msdu); @@ -2704,18 +2708,21 @@ try_again: continue; } - rxcb->is_first_msdu = !!(desc->rx_msdu_info.info0 & + rx_msdu_info0 = READ_ONCE(desc->rx_msdu_info.info0); + rx_mpdu_info0 = READ_ONCE(desc->rx_mpdu_info.info0); + + rxcb->is_first_msdu = !!(rx_msdu_info0 & RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU); - rxcb->is_last_msdu = !!(desc->rx_msdu_info.info0 & + rxcb->is_last_msdu = !!(rx_msdu_info0 & RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU); - rxcb->is_continuation = !!(desc->rx_msdu_info.info0 & + rxcb->is_continuation = !!(rx_msdu_info0 & RX_MSDU_DESC_INFO0_MSDU_CONTINUATION); rxcb->peer_id = FIELD_GET(RX_MPDU_DESC_META_DATA_PEER_ID, - desc->rx_mpdu_info.meta_data); + READ_ONCE(desc->rx_mpdu_info.meta_data)); rxcb->seq_no = FIELD_GET(RX_MPDU_DESC_INFO0_SEQ_NUM, - desc->rx_mpdu_info.info0); + rx_mpdu_info0); rxcb->tid = FIELD_GET(HAL_REO_DEST_RING_INFO0_RX_QUEUE_NUM, - desc->info0); + info0); rxcb->mac_id = mac_id; __skb_queue_tail(&msdu_list[mac_id], msdu); From f08689fe3153bf25891ea653d3e3ba267764a9dc Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 21 Mar 2025 10:49:16 +0100 Subject: [PATCH 415/971] wifi: ath11k: fix ring-buffer corruption commit 6d037a372f817e9fcb56482f37917545596bd776 upstream. Users of the Lenovo ThinkPad X13s have reported that Wi-Fi sometimes breaks and the log fills up with errors like: ath11k_pci 0006:01:00.0: HTC Rx: insufficient length, got 1484, expected 1492 ath11k_pci 0006:01:00.0: HTC Rx: insufficient length, got 1460, expected 1484 which based on a quick look at the driver seemed to indicate some kind of ring-buffer corruption. Miaoqing Pan tracked it down to the host seeing the updated destination ring head pointer before the updated descriptor, and the error handling for that in turn leaves the ring buffer in an inconsistent state. Add the missing memory barrier to make sure that the descriptor is read after the head pointer to address the root cause of the corruption while fixing up the error handling in case there are ever any (ordering) bugs on the device side. Note that the READ_ONCE() are only needed to avoid compiler mischief in case the ring-buffer helpers are ever inlined. Tested-on: WCN6855 hw2.1 WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41 Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218623 Link: https://lore.kernel.org/20250310010217.3845141-3-quic_miaoqing@quicinc.com Cc: Miaoqing Pan Cc: stable@vger.kernel.org # 5.6 Signed-off-by: Johan Hovold Reviewed-by: Miaoqing Pan Tested-by: Steev Klimaszewski Tested-by: Jens Glathe Tested-by: Clayton Craft Link: https://patch.msgid.link/20250321094916.19098-1-johan+linaro@kernel.org Signed-off-by: Jeff Johnson Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath11k/ce.c | 11 +++++------ drivers/net/wireless/ath/ath11k/hal.c | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/ce.c b/drivers/net/wireless/ath/ath11k/ce.c index e66e86bdec20..9d8efec46508 100644 --- a/drivers/net/wireless/ath/ath11k/ce.c +++ b/drivers/net/wireless/ath/ath11k/ce.c @@ -393,11 +393,10 @@ static int ath11k_ce_completed_recv_next(struct ath11k_ce_pipe *pipe, goto err; } + /* Make sure descriptor is read after the head pointer. */ + dma_rmb(); + *nbytes = ath11k_hal_ce_dst_status_get_length(desc); - if (*nbytes == 0) { - ret = -EIO; - goto err; - } *skb = pipe->dest_ring->skb[sw_index]; pipe->dest_ring->skb[sw_index] = NULL; @@ -430,8 +429,8 @@ static void ath11k_ce_recv_process_cb(struct ath11k_ce_pipe *pipe) dma_unmap_single(ab->dev, ATH11K_SKB_RXCB(skb)->paddr, max_nbytes, DMA_FROM_DEVICE); - if (unlikely(max_nbytes < nbytes)) { - ath11k_warn(ab, "rxed more than expected (nbytes %d, max %d)", + if (unlikely(max_nbytes < nbytes || nbytes == 0)) { + ath11k_warn(ab, "unexpected rx length (nbytes %d, max %d)", nbytes, max_nbytes); dev_kfree_skb_any(skb); continue; diff --git a/drivers/net/wireless/ath/ath11k/hal.c b/drivers/net/wireless/ath/ath11k/hal.c index ae5f7e401e21..f32fa104ded9 100644 --- a/drivers/net/wireless/ath/ath11k/hal.c +++ b/drivers/net/wireless/ath/ath11k/hal.c @@ -601,7 +601,7 @@ u32 ath11k_hal_ce_dst_status_get_length(void *buf) (struct hal_ce_srng_dst_status_desc *)buf; u32 len; - len = FIELD_GET(HAL_CE_DST_STATUS_DESC_FLAGS_LEN, desc->flags); + len = FIELD_GET(HAL_CE_DST_STATUS_DESC_FLAGS_LEN, READ_ONCE(desc->flags)); desc->flags &= ~HAL_CE_DST_STATUS_DESC_FLAGS_LEN; return len; @@ -802,7 +802,7 @@ void ath11k_hal_srng_access_begin(struct ath11k_base *ab, struct hal_srng *srng) srng->u.src_ring.cached_tp = *(volatile u32 *)srng->u.src_ring.tp_addr; } else { - srng->u.dst_ring.cached_hp = *srng->u.dst_ring.hp_addr; + srng->u.dst_ring.cached_hp = READ_ONCE(*srng->u.dst_ring.hp_addr); /* Try to prefetch the next descriptor in the ring */ if (srng->flags & HAL_SRNG_FLAGS_CACHED) From e7e943ddd1c6731812357a28e7954ade3a7d8517 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 28 Mar 2025 11:05:59 +1100 Subject: [PATCH 416/971] nfsd: nfsd4_spo_must_allow() must check this is a v4 compound request commit 1244f0b2c3cecd3f349a877006e67c9492b41807 upstream. If the request being processed is not a v4 compound request, then examining the cstate can have undefined results. This patch adds a check that the rpc procedure being executed (rq_procinfo) is the NFSPROC4_COMPOUND procedure. Reported-by: Olga Kornievskaia Cc: stable@vger.kernel.org Reviewed-by: Jeff Layton Signed-off-by: NeilBrown Signed-off-by: Chuck Lever Signed-off-by: Greg Kroah-Hartman --- fs/nfsd/nfs4proc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index b3eca08f15b1..b2bbf3d6d177 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -3580,7 +3580,8 @@ bool nfsd4_spo_must_allow(struct svc_rqst *rqstp) struct nfs4_op_map *allow = &cstate->clp->cl_spo_must_allow; u32 opiter; - if (!cstate->minorversion) + if (rqstp->rq_procinfo != &nfsd_version4.vs_proc[NFSPROC4_COMPOUND] || + cstate->minorversion == 0) return false; if (cstate->spo_must_allowed) From 5060e1a5fef184bd11d298e3f0ee920d96a23236 Mon Sep 17 00:00:00 2001 From: Li Lingfeng Date: Mon, 14 Apr 2025 22:38:52 +0800 Subject: [PATCH 417/971] nfsd: Initialize ssc before laundromat_work to prevent NULL dereference commit b31da62889e6d610114d81dc7a6edbcaa503fcf8 upstream. In nfs4_state_start_net(), laundromat_work may access nfsd_ssc through nfs4_laundromat -> nfsd4_ssc_expire_umount. If nfsd_ssc isn't initialized, this can cause NULL pointer dereference. Normally the delayed start of laundromat_work allows sufficient time for nfsd_ssc initialization to complete. However, when the kernel waits too long for userspace responses (e.g. in nfs4_state_start_net -> nfsd4_end_grace -> nfsd4_record_grace_done -> nfsd4_cld_grace_done -> cld_pipe_upcall -> __cld_pipe_upcall -> wait_for_completion path), the delayed work may start before nfsd_ssc initialization finishes. Fix this by moving nfsd_ssc initialization before starting laundromat_work. Fixes: f4e44b393389 ("NFSD: delay unmount source's export after inter-server copy completed.") Cc: stable@vger.kernel.org Reviewed-by: Jeff Layton Signed-off-by: Li Lingfeng Signed-off-by: Chuck Lever Signed-off-by: Greg Kroah-Hartman --- fs/nfsd/nfssvc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 710a54c7dffc..623f522b1565 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -432,13 +432,13 @@ static int nfsd_startup_net(struct net *net, const struct cred *cred) if (ret) goto out_filecache; +#ifdef CONFIG_NFSD_V4_2_INTER_SSC + nfsd4_ssc_init_umount_work(nn); +#endif ret = nfs4_state_start_net(net); if (ret) goto out_reply_cache; -#ifdef CONFIG_NFSD_V4_2_INTER_SSC - nfsd4_ssc_init_umount_work(nn); -#endif nn->nfsd_net_up = true; return 0; From 5ee9a07b456d62c672fb5b6109594f472aa4cee3 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 21 May 2025 16:34:13 -0400 Subject: [PATCH 418/971] SUNRPC: Prevent hang on NFS mount with xprtsec=[m]tls commit 0bd2f6b8996d4f1ca4573652454987826730a04a upstream. Engineers at Hammerspace noticed that sometimes mounting with "xprtsec=tls" hangs for a minute or so, and then times out, even when the NFS server is reachable and responsive. kTLS shuts off data_ready callbacks if strp->msg_ready is set to mitigate data_ready callbacks when a full TLS record is not yet ready to be read from the socket. Normally msg_ready is clear when the first TLS record arrives on a socket. However, I observed that sometimes tls_setsockopt() sets strp->msg_ready, and that prevents forward progress because tls_data_ready() becomes a no-op. Moreover, Jakub says: "If there's a full record queued at the time when [tlshd] passes the socket back to the kernel, it's up to the reader to read the already queued data out." So SunRPC cannot expect a data_ready call when ingress data is already waiting. Add an explicit poll after SunRPC's upper transport is set up to pick up any data that arrived after the TLS handshake but before transport set-up is complete. Reported-by: Steve Sears Suggested-by: Jakub Kacinski Fixes: 75eb6af7acdf ("SUNRPC: Add a TCP-with-TLS RPC transport class") Tested-by: Mike Snitzer Reviewed-by: Mike Snitzer Cc: stable@vger.kernel.org Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker Signed-off-by: Greg Kroah-Hartman --- net/sunrpc/xprtsock.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 29df05879c8e..f90d84492bbe 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -2724,6 +2724,11 @@ static void xs_tcp_tls_setup_socket(struct work_struct *work) } rpc_shutdown_client(lower_clnt); + /* Check for ingress data that arrived before the socket's + * ->data_ready callback was set up. + */ + xs_poll_check_readable(upper_transport); + out_unlock: current_restore_flags(pflags, PF_MEMALLOC); upper_transport->clnt = NULL; From 14f5549ad163be2c018abc1bb38370fff617a243 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 23 Apr 2025 15:22:50 +0200 Subject: [PATCH 419/971] fs/nfs/read: fix double-unlock bug in nfs_return_empty_folio() commit 4c10fa44bc5f700e2ea21de2fbae520ba21f19d9 upstream. Sometimes, when a file was read while it was being truncated by another NFS client, the kernel could deadlock because folio_unlock() was called twice, and the second call would XOR back the `PG_locked` flag. Most of the time (depending on the timing of the truncation), nobody notices the problem because folio_unlock() gets called three times, which flips `PG_locked` back off: 1. vfs_read, nfs_read_folio, ... nfs_read_add_folio, nfs_return_empty_folio 2. vfs_read, nfs_read_folio, ... netfs_read_collection, netfs_unlock_abandoned_read_pages 3. vfs_read, ... nfs_do_read_folio, nfs_read_add_folio, nfs_return_empty_folio The problem is that nfs_read_add_folio() is not supposed to unlock the folio if fscache is enabled, and a nfs_netfs_folio_unlock() check is missing in nfs_return_empty_folio(). Rarely this leads to a warning in netfs_read_collection(): ------------[ cut here ]------------ R=0000031c: folio 10 is not locked WARNING: CPU: 0 PID: 29 at fs/netfs/read_collect.c:133 netfs_read_collection+0x7c0/0xf00 [...] Workqueue: events_unbound netfs_read_collection_worker RIP: 0010:netfs_read_collection+0x7c0/0xf00 [...] Call Trace: netfs_read_collection_worker+0x67/0x80 process_one_work+0x12e/0x2c0 worker_thread+0x295/0x3a0 Most of the time, however, processes just get stuck forever in folio_wait_bit_common(), waiting for `PG_locked` to disappear, which never happens because nobody is really holding the folio lock. Fixes: 000dbe0bec05 ("NFS: Convert buffered read paths to use netfs when fscache is enabled") Cc: stable@vger.kernel.org Signed-off-by: Max Kellermann Reviewed-by: Dave Wysochanski Signed-off-by: Anna Schumaker Signed-off-by: Greg Kroah-Hartman --- fs/nfs/read.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/nfs/read.c b/fs/nfs/read.c index a142287d86f6..688a24e9bc8b 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c @@ -56,7 +56,8 @@ static int nfs_return_empty_folio(struct folio *folio) { folio_zero_segment(folio, 0, folio_size(folio)); folio_mark_uptodate(folio); - folio_unlock(folio); + if (nfs_netfs_folio_unlock(folio)) + folio_unlock(folio); return 0; } From 1eeecd9be9fe90a4c465ba156721b3cc11bdb5c9 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 21 Mar 2025 10:52:19 +0100 Subject: [PATCH 420/971] wifi: ath12k: fix ring-buffer corruption commit 6b67d2cf14ea997061f61e9c8afd4e1c0f22acb9 upstream. Users of the Lenovo ThinkPad X13s have reported that Wi-Fi sometimes breaks and the log fills up with errors like: ath11k_pci 0006:01:00.0: HTC Rx: insufficient length, got 1484, expected 1492 ath11k_pci 0006:01:00.0: HTC Rx: insufficient length, got 1460, expected 1484 which based on a quick look at the ath11k driver seemed to indicate some kind of ring-buffer corruption. Miaoqing Pan tracked it down to the host seeing the updated destination ring head pointer before the updated descriptor, and the error handling for that in turn leaves the ring buffer in an inconsistent state. While this has not yet been observed with ath12k, the ring-buffer implementation is very similar to the ath11k one and it suffers from the same bugs. Add the missing memory barrier to make sure that the descriptor is read after the head pointer to address the root cause of the corruption while fixing up the error handling in case there are ever any (ordering) bugs on the device side. Note that the READ_ONCE() are only needed to avoid compiler mischief in case the ring-buffer helpers are ever inlined. Tested-on: WCN7850 hw2.0 WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") Cc: stable@vger.kernel.org # 6.3 Link: https://bugzilla.kernel.org/show_bug.cgi?id=218623 Link: https://lore.kernel.org/20250310010217.3845141-3-quic_miaoqing@quicinc.com Cc: Miaoqing Pan Signed-off-by: Johan Hovold Reviewed-by: Miaoqing Pan Link: https://patch.msgid.link/20250321095219.19369-1-johan+linaro@kernel.org Signed-off-by: Jeff Johnson Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath12k/ce.c | 11 +++++------ drivers/net/wireless/ath/ath12k/hal.c | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ce.c b/drivers/net/wireless/ath/ath12k/ce.c index be0d669d31fc..740586fe49d1 100644 --- a/drivers/net/wireless/ath/ath12k/ce.c +++ b/drivers/net/wireless/ath/ath12k/ce.c @@ -343,11 +343,10 @@ static int ath12k_ce_completed_recv_next(struct ath12k_ce_pipe *pipe, goto err; } + /* Make sure descriptor is read after the head pointer. */ + dma_rmb(); + *nbytes = ath12k_hal_ce_dst_status_get_length(desc); - if (*nbytes == 0) { - ret = -EIO; - goto err; - } *skb = pipe->dest_ring->skb[sw_index]; pipe->dest_ring->skb[sw_index] = NULL; @@ -380,8 +379,8 @@ static void ath12k_ce_recv_process_cb(struct ath12k_ce_pipe *pipe) dma_unmap_single(ab->dev, ATH12K_SKB_RXCB(skb)->paddr, max_nbytes, DMA_FROM_DEVICE); - if (unlikely(max_nbytes < nbytes)) { - ath12k_warn(ab, "rxed more than expected (nbytes %d, max %d)", + if (unlikely(max_nbytes < nbytes || nbytes == 0)) { + ath12k_warn(ab, "unexpected rx length (nbytes %d, max %d)", nbytes, max_nbytes); dev_kfree_skb_any(skb); continue; diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 0b5a91ab0df4..169e16c6ed65 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -1565,7 +1565,7 @@ u32 ath12k_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc *desc { u32 len; - len = le32_get_bits(desc->flags, HAL_CE_DST_STATUS_DESC_FLAGS_LEN); + len = le32_get_bits(READ_ONCE(desc->flags), HAL_CE_DST_STATUS_DESC_FLAGS_LEN); desc->flags &= ~cpu_to_le32(HAL_CE_DST_STATUS_DESC_FLAGS_LEN); return len; @@ -1734,7 +1734,7 @@ void ath12k_hal_srng_access_begin(struct ath12k_base *ab, struct hal_srng *srng) srng->u.src_ring.cached_tp = *(volatile u32 *)srng->u.src_ring.tp_addr; else - srng->u.dst_ring.cached_hp = *srng->u.dst_ring.hp_addr; + srng->u.dst_ring.cached_hp = READ_ONCE(*srng->u.dst_ring.hp_addr); } /* Update cached ring head/tail pointers to HW. ath12k_hal_srng_access_begin() From 2e7c64d7a92c031d016f11c8e8cb05131ab7b75a Mon Sep 17 00:00:00 2001 From: Jeongjun Park Date: Wed, 14 May 2025 22:08:55 +0900 Subject: [PATCH 421/971] jbd2: fix data-race and null-ptr-deref in jbd2_journal_dirty_metadata() commit af98b0157adf6504fade79b3e6cb260c4ff68e37 upstream. Since handle->h_transaction may be a NULL pointer, so we should change it to call is_handle_aborted(handle) first before dereferencing it. And the following data-race was reported in my fuzzer: ================================================================== BUG: KCSAN: data-race in jbd2_journal_dirty_metadata / jbd2_journal_dirty_metadata write to 0xffff888011024104 of 4 bytes by task 10881 on cpu 1: jbd2_journal_dirty_metadata+0x2a5/0x770 fs/jbd2/transaction.c:1556 __ext4_handle_dirty_metadata+0xe7/0x4b0 fs/ext4/ext4_jbd2.c:358 ext4_do_update_inode fs/ext4/inode.c:5220 [inline] ext4_mark_iloc_dirty+0x32c/0xd50 fs/ext4/inode.c:5869 __ext4_mark_inode_dirty+0xe1/0x450 fs/ext4/inode.c:6074 ext4_dirty_inode+0x98/0xc0 fs/ext4/inode.c:6103 .... read to 0xffff888011024104 of 4 bytes by task 10880 on cpu 0: jbd2_journal_dirty_metadata+0xf2/0x770 fs/jbd2/transaction.c:1512 __ext4_handle_dirty_metadata+0xe7/0x4b0 fs/ext4/ext4_jbd2.c:358 ext4_do_update_inode fs/ext4/inode.c:5220 [inline] ext4_mark_iloc_dirty+0x32c/0xd50 fs/ext4/inode.c:5869 __ext4_mark_inode_dirty+0xe1/0x450 fs/ext4/inode.c:6074 ext4_dirty_inode+0x98/0xc0 fs/ext4/inode.c:6103 .... value changed: 0x00000000 -> 0x00000001 ================================================================== This issue is caused by missing data-race annotation for jh->b_modified. Therefore, the missing annotation needs to be added. Reported-by: syzbot+de24c3fe3c4091051710@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=de24c3fe3c4091051710 Fixes: 6e06ae88edae ("jbd2: speedup jbd2_journal_dirty_metadata()") Signed-off-by: Jeongjun Park Reviewed-by: Jan Kara Link: https://patch.msgid.link/20250514130855.99010-1-aha310510@gmail.com Signed-off-by: Theodore Ts'o Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman --- fs/jbd2/transaction.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 76adab83cac3..c2b8ad0b24c4 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -1499,7 +1499,7 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh) jh->b_next_transaction == transaction); spin_unlock(&jh->b_state_lock); } - if (jh->b_modified == 1) { + if (data_race(jh->b_modified == 1)) { /* If it's in our transaction it must be in BJ_Metadata list. */ if (data_race(jh->b_transaction == transaction && jh->b_jlist != BJ_Metadata)) { @@ -1518,7 +1518,6 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh) goto out; } - journal = transaction->t_journal; spin_lock(&jh->b_state_lock); if (is_handle_aborted(handle)) { @@ -1533,6 +1532,8 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh) goto out_unlock_bh; } + journal = transaction->t_journal; + if (jh->b_modified == 0) { /* * This buffer's got modified and becoming part From d4356ce8f82692ad218b466ccde1a26b3d883398 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sat, 10 May 2025 15:21:25 +0300 Subject: [PATCH 422/971] wifi: rtw88: usb: Reduce control message timeout to 500 ms commit 490340faddea461319652ce36dbc7c1b4482c35e upstream. RTL8811AU stops responding during the firmware download on some systems: [ 809.256440] rtw_8821au 5-2.1:1.0: Firmware version 42.4.0, H2C version 0 [ 812.759142] rtw_8821au 5-2.1:1.0 wlp48s0f4u2u1: renamed from wlan0 [ 837.315388] rtw_8821au 1-4:1.0: write register 0x1ef4 failed with -110 [ 867.524259] rtw_8821au 1-4:1.0: write register 0x1ef8 failed with -110 [ 868.930976] rtw_8821au 5-2.1:1.0 wlp48s0f4u2u1: entered promiscuous mode [ 897.730952] rtw_8821au 1-4:1.0: write register 0x1efc failed with -110 Each write takes 30 seconds to fail because that's the timeout currently used for control messages in rtw_usb_write(). In this scenario the firmware download takes at least 2000 seconds. Because this is done from the USB probe function, the long delay makes other things in the system hang. Reduce the timeout to 500 ms. This is the value used by the official USB wifi drivers from Realtek. Of course this only makes things hang for ~30 seconds instead of ~30 minutes. It doesn't fix the firmware download. Tested with RTL8822CU, RTL8812BU, RTL8811CU, RTL8814AU, RTL8811AU, RTL8812AU, RTL8821AU, RTL8723DU. Cc: stable@vger.kernel.org Fixes: a82dfd33d123 ("wifi: rtw88: Add common USB chip support") Link: https://github.com/lwfinger/rtw88/issues/344 Signed-off-by: Bitterblue Smith Acked-by: Ping-Ke Shih Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/1e35dd26-3f10-40b1-b2b4-f72184a26611@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/realtek/rtw88/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c index 8f1d653282b7..eba3a2ee747f 100644 --- a/drivers/net/wireless/realtek/rtw88/usb.c +++ b/drivers/net/wireless/realtek/rtw88/usb.c @@ -133,7 +133,7 @@ static void rtw_usb_write(struct rtw_dev *rtwdev, u32 addr, u32 val, int len) ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), RTW_USB_CMD_REQ, RTW_USB_CMD_WRITE, - addr, 0, data, len, 30000); + addr, 0, data, len, 500); if (ret < 0 && ret != -ENODEV && count++ < 4) rtw_err(rtwdev, "write register 0x%x failed with %d\n", addr, ret); From aaf516bb732c484ad534c7c42f51230940d806fe Mon Sep 17 00:00:00 2001 From: Mingcong Bai Date: Tue, 22 Apr 2025 14:17:54 +0800 Subject: [PATCH 423/971] wifi: rtlwifi: disable ASPM for RTL8723BE with subsystem ID 11ad:1723 commit 77a6407c6ab240527166fb19ee96e95f5be4d3cd upstream. RTL8723BE found on some ASUSTek laptops, such as F441U and X555UQ with subsystem ID 11ad:1723 are known to output large amounts of PCIe AER errors during and after boot up, causing heavy lags and at times lock-ups: pcieport 0000:00:1c.5: AER: Correctable error message received from 0000:00:1c.5 pcieport 0000:00:1c.5: PCIe Bus Error: severity=Correctable, type=Physical Layer, (Receiver ID) pcieport 0000:00:1c.5: device [8086:9d15] error status/mask=00000001/00002000 pcieport 0000:00:1c.5: [ 0] RxErr Disable ASPM on this combo as a quirk. This patch is a revision of a previous patch (linked below) which attempted to disable ASPM for RTL8723BE on all Intel Skylake and Kaby Lake PCIe bridges. I take a more conservative approach as all known reports point to ASUSTek laptops of these two generations with this particular wireless card. Please note, however, before the rtl8723be finishes probing, the AER errors remained. After the module finishes probing, all AER errors would indeed be eliminated, along with heavy lags, poor network throughput, and/or occasional lock-ups. Cc: Fixes: a619d1abe20c ("rtlwifi: rtl8723be: Add new driver") Reported-by: Liangliang Zou Link: https://bugzilla.kernel.org/show_bug.cgi?id=218127 Link: https://lore.kernel.org/lkml/05390e0b-27fd-4190-971e-e70a498c8221@lwfinger.net/T/ Tested-by: Liangliang Zou Signed-off-by: Mingcong Bai Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250422061755.356535-1-jeffbai@aosc.io Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/realtek/rtlwifi/pci.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c index 3abd0c4c954b..3645f212021f 100644 --- a/drivers/net/wireless/realtek/rtlwifi/pci.c +++ b/drivers/net/wireless/realtek/rtlwifi/pci.c @@ -155,6 +155,16 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw) if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8192SE && init_aspm == 0x43) ppsc->support_aspm = false; + + /* RTL8723BE found on some ASUSTek laptops, such as F441U and + * X555UQ with subsystem ID 11ad:1723 are known to output large + * amounts of PCIe AER errors during and after boot up, causing + * heavy lags, poor network throughput, and occasional lock-ups. + */ + if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8723BE && + (rtlpci->pdev->subsystem_vendor == 0x11ad && + rtlpci->pdev->subsystem_device == 0x1723)) + ppsc->support_aspm = false; } static bool _rtl_pci_platform_switch_device_pci_aspm( From ce4a5a34a2bf392dff11f63c95071ccebdd19e42 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 25 Apr 2025 14:52:38 +0200 Subject: [PATCH 424/971] media: ov8856: suppress probe deferral errors commit e3d86847fba58cf71f66e81b6a2515e07039ae17 upstream. Probe deferral should not be logged as an error: ov8856 24-0010: failed to get HW configuration: -517 Use dev_err_probe() for the clock lookup and drop the (mostly) redundant dev_err() from sensor probe() to suppress it. Note that errors during regulator lookup is already correctly logged using dev_err_probe(). Fixes: 0c2c7a1e0d69 ("media: ov8856: Add devicetree support") Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/i2c/ov8856.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/media/i2c/ov8856.c b/drivers/media/i2c/ov8856.c index f053c3a7676a..8c93fe6285f8 100644 --- a/drivers/media/i2c/ov8856.c +++ b/drivers/media/i2c/ov8856.c @@ -2323,8 +2323,8 @@ static int ov8856_get_hwcfg(struct ov8856 *ov8856, struct device *dev) if (!is_acpi_node(fwnode)) { ov8856->xvclk = devm_clk_get(dev, "xvclk"); if (IS_ERR(ov8856->xvclk)) { - dev_err(dev, "could not get xvclk clock (%pe)\n", - ov8856->xvclk); + dev_err_probe(dev, PTR_ERR(ov8856->xvclk), + "could not get xvclk clock\n"); return PTR_ERR(ov8856->xvclk); } @@ -2429,11 +2429,8 @@ static int ov8856_probe(struct i2c_client *client) return -ENOMEM; ret = ov8856_get_hwcfg(ov8856, &client->dev); - if (ret) { - dev_err(&client->dev, "failed to get HW configuration: %d", - ret); + if (ret) return ret; - } v4l2_i2c_subdev_init(&ov8856->sd, client, &ov8856_subdev_ops); From 585acb35497785642ec07523aaaf574f6eb6cbfb Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 25 Apr 2025 14:52:37 +0200 Subject: [PATCH 425/971] media: ov5675: suppress probe deferral errors commit 8268da3c474a43a79a6540fb06c5d3b730a0d5a5 upstream. Probe deferral should not be logged as an error: ov5675 24-0010: failed to get HW configuration: -517 Drop the (mostly) redundant dev_err() from sensor probe() to suppress it. Note that errors during clock and regulator lookup are already correctly logged using dev_err_probe(). Fixes: 49d9ad719e89 ("media: ov5675: add device-tree support and support runtime PM") Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/i2c/ov5675.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/media/i2c/ov5675.c b/drivers/media/i2c/ov5675.c index c499e7e93c54..92c3e7951ee7 100644 --- a/drivers/media/i2c/ov5675.c +++ b/drivers/media/i2c/ov5675.c @@ -1339,11 +1339,8 @@ static int ov5675_probe(struct i2c_client *client) return -ENOMEM; ret = ov5675_get_hwcfg(ov5675, &client->dev); - if (ret) { - dev_err(&client->dev, "failed to get HW configuration: %d", - ret); + if (ret) return ret; - } v4l2_i2c_subdev_init(&ov5675->sd, client, &ov5675_subdev_ops); From ecaf904a55c1ca96d26ef9a5a6e7fb939098b997 Mon Sep 17 00:00:00 2001 From: Laurentiu Palcu Date: Wed, 23 Oct 2024 11:56:43 +0300 Subject: [PATCH 426/971] media: nxp: imx8-isi: better handle the m2m usage_count commit 910efa649076be9c2e1326059830327cf4228cf6 upstream. Currently, if streamon/streamoff calls are imbalanced we can either end up with a negative ISI m2m usage_count (if streamoff() is called more times than streamon()) in which case we'll not be able to restart the ISI pipe next time, or the usage_count never gets to 0 and the pipe is never switched off. To avoid that, add a 'streaming' flag to mxc_isi_m2m_ctx_queue_data and use it in the streamon/streamoff to avoid incrementing/decrementing the usage_count uselessly, if called multiple times from the same context. Fixes: cf21f328fcafac ("media: nxp: Add i.MX8 ISI driver") Cc: stable@vger.kernel.org Suggested-by: Laurent Pinchart Signed-off-by: Laurentiu Palcu Reviewed-by: Laurent Pinchart Link: https://lore.kernel.org/r/20241023085643.978729-1-laurentiu.palcu@oss.nxp.com Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c index 9745d6219a16..cd6c52e9d158 100644 --- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c +++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c @@ -43,6 +43,7 @@ struct mxc_isi_m2m_ctx_queue_data { struct v4l2_pix_format_mplane format; const struct mxc_isi_format_info *info; u32 sequence; + bool streaming; }; struct mxc_isi_m2m_ctx { @@ -486,15 +487,18 @@ static int mxc_isi_m2m_streamon(struct file *file, void *fh, enum v4l2_buf_type type) { struct mxc_isi_m2m_ctx *ctx = to_isi_m2m_ctx(fh); + struct mxc_isi_m2m_ctx_queue_data *q = mxc_isi_m2m_ctx_qdata(ctx, type); const struct v4l2_pix_format_mplane *out_pix = &ctx->queues.out.format; const struct v4l2_pix_format_mplane *cap_pix = &ctx->queues.cap.format; const struct mxc_isi_format_info *cap_info = ctx->queues.cap.info; const struct mxc_isi_format_info *out_info = ctx->queues.out.info; struct mxc_isi_m2m *m2m = ctx->m2m; bool bypass; - int ret; + if (q->streaming) + return 0; + mutex_lock(&m2m->lock); if (m2m->usage_count == INT_MAX) { @@ -547,6 +551,8 @@ static int mxc_isi_m2m_streamon(struct file *file, void *fh, goto unchain; } + q->streaming = true; + return 0; unchain: @@ -569,10 +575,14 @@ static int mxc_isi_m2m_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) { struct mxc_isi_m2m_ctx *ctx = to_isi_m2m_ctx(fh); + struct mxc_isi_m2m_ctx_queue_data *q = mxc_isi_m2m_ctx_qdata(ctx, type); struct mxc_isi_m2m *m2m = ctx->m2m; v4l2_m2m_ioctl_streamoff(file, fh, type); + if (!q->streaming) + return 0; + mutex_lock(&m2m->lock); /* @@ -598,6 +608,8 @@ static int mxc_isi_m2m_streamoff(struct file *file, void *fh, mutex_unlock(&m2m->lock); + q->streaming = false; + return 0; } From eb7a4ea0a18ce2a67a7e26e344484291f35c9dd0 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 3 Mar 2025 21:32:05 +0530 Subject: [PATCH 427/971] media: i2c: ds90ub913: Fix returned fmt from .set_fmt() commit ef205273132bdc9bcfa1540eef8105475a453300 upstream. When setting the sink pad's stream format, set_fmt accidentally changes the returned format's code to 'outcode', while the purpose is to only use the 'outcode' for the propagated source stream format. Fixes: c158d0d4ff15 ("media: i2c: add DS90UB913 driver") Cc: stable@vger.kernel.org Signed-off-by: Tomi Valkeinen Signed-off-by: Jai Luthra Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/i2c/ds90ub913.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/ds90ub913.c b/drivers/media/i2c/ds90ub913.c index ae33d1ecf835..6ec960d7914e 100644 --- a/drivers/media/i2c/ds90ub913.c +++ b/drivers/media/i2c/ds90ub913.c @@ -453,10 +453,10 @@ static int ub913_set_fmt(struct v4l2_subdev *sd, if (!fmt) return -EINVAL; - format->format.code = finfo->outcode; - *fmt = format->format; + fmt->code = finfo->outcode; + return 0; } From ae2fe66065118c982e87c5b9bbfb3a647957fd28 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 18 Feb 2025 23:47:13 +0200 Subject: [PATCH 428/971] media: ccs-pll: Start VT pre-PLL multiplier search from correct value commit 06d2d478b09e6764fb6161d1621fc10d9f0f2860 upstream. The ccs_pll_calculate_vt_tree() function does a search over possible VT PLL configurations to find the "best" one. If the sensor does not support odd pre-PLL divisors and the minimum value (with constraints) isn't 1, other odd values could be errorneously searched (and selected) for the pre-PLL divisor. Fix this. Fixes: 415ddd993978 ("media: ccs-pll: Split limits and PLL configuration into front and back parts") Cc: stable@vger.kernel.org Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/i2c/ccs-pll.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/i2c/ccs-pll.c b/drivers/media/i2c/ccs-pll.c index cf8858cb13d4..7e5d87a7975f 100644 --- a/drivers/media/i2c/ccs-pll.c +++ b/drivers/media/i2c/ccs-pll.c @@ -397,6 +397,8 @@ static int ccs_pll_calculate_vt_tree(struct device *dev, min_pre_pll_clk_div = max_t(u16, min_pre_pll_clk_div, pll->ext_clk_freq_hz / lim_fr->max_pll_ip_clk_freq_hz); + if (!(pll->flags & CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER)) + min_pre_pll_clk_div = clk_div_even(min_pre_pll_clk_div); dev_dbg(dev, "vt min/max_pre_pll_clk_div: %u,%u\n", min_pre_pll_clk_div, max_pre_pll_clk_div); From b9e314231ffcd5fa000dc7460edb56e29b6e3670 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 18 Feb 2025 23:43:58 +0200 Subject: [PATCH 429/971] media: ccs-pll: Start OP pre-PLL multiplier search from correct value commit 660e613d05e449766784c549faf5927ffaf281f1 upstream. The ccs_pll_calculate() function does a search over possible PLL configurations to find the "best" one. If the sensor does not support odd pre-PLL divisors and the minimum value (with constraints) isn't 1, other odd values could be errorneously searched (and selected) for the pre-PLL divisor. Fix this. Fixes: 415ddd993978 ("media: ccs-pll: Split limits and PLL configuration into front and back parts") Cc: stable@vger.kernel.org Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/i2c/ccs-pll.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/i2c/ccs-pll.c b/drivers/media/i2c/ccs-pll.c index 7e5d87a7975f..98ffbdf565f3 100644 --- a/drivers/media/i2c/ccs-pll.c +++ b/drivers/media/i2c/ccs-pll.c @@ -817,6 +817,8 @@ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim, one_or_more( DIV_ROUND_UP(op_lim_fr->max_pll_op_clk_freq_hz, pll->ext_clk_freq_hz)))); + if (!(pll->flags & CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER)) + min_op_pre_pll_clk_div = clk_div_even(min_op_pre_pll_clk_div); dev_dbg(dev, "pll_op check: min / max op_pre_pll_clk_div: %u / %u\n", min_op_pre_pll_clk_div, max_op_pre_pll_clk_div); From 1e4b3f166795124fa1f6661f01c33684ec03e9fb Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 19 Feb 2025 15:06:11 +0200 Subject: [PATCH 430/971] media: ccs-pll: Correct the upper limit of maximum op_pre_pll_clk_div commit f639494db450770fa30d6845d9c84b9cb009758f upstream. The PLL calculator does a search of the PLL configuration space for all valid OP pre-PLL clock dividers. The maximum did not take into account the CCS PLL flag CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER in which case also odd PLL dividers (other than 1) are valid. Do that now. Fixes: 4e1e8d240dff ("media: ccs-pll: Add support for extended input PLL clock divider") Cc: stable@vger.kernel.org Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/i2c/ccs-pll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/ccs-pll.c b/drivers/media/i2c/ccs-pll.c index 98ffbdf565f3..fce3f0f18574 100644 --- a/drivers/media/i2c/ccs-pll.c +++ b/drivers/media/i2c/ccs-pll.c @@ -794,7 +794,7 @@ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim, op_lim_fr->min_pre_pll_clk_div, op_lim_fr->max_pre_pll_clk_div); max_op_pre_pll_clk_div = min_t(u16, op_lim_fr->max_pre_pll_clk_div, - clk_div_even(pll->ext_clk_freq_hz / + DIV_ROUND_UP(pll->ext_clk_freq_hz, op_lim_fr->min_pll_ip_clk_freq_hz)); min_op_pre_pll_clk_div = max_t(u16, op_lim_fr->min_pre_pll_clk_div, From 4425db511b9d4b8098b8d1cd13ca9a4493d44657 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 20 Feb 2025 10:54:44 +0200 Subject: [PATCH 431/971] media: ccs-pll: Check for too high VT PLL multiplier in dual PLL case commit 6868b955acd6e5d7405a2b730c2ffb692ad50d2c upstream. The check for VT PLL upper limit in dual PLL case was missing. Add it now. Fixes: 6c7469e46b60 ("media: ccs-pll: Add trivial dual PLL support") Cc: stable@vger.kernel.org Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/i2c/ccs-pll.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/media/i2c/ccs-pll.c b/drivers/media/i2c/ccs-pll.c index fce3f0f18574..611c9823be85 100644 --- a/drivers/media/i2c/ccs-pll.c +++ b/drivers/media/i2c/ccs-pll.c @@ -312,6 +312,11 @@ __ccs_pll_calculate_vt_tree(struct device *dev, dev_dbg(dev, "more_mul2: %u\n", more_mul); pll_fr->pll_multiplier = mul * more_mul; + if (pll_fr->pll_multiplier > lim_fr->max_pll_multiplier) { + dev_dbg(dev, "pll multiplier %u too high\n", + pll_fr->pll_multiplier); + return -EINVAL; + } if (pll_fr->pll_multiplier * pll_fr->pll_ip_clk_freq_hz > lim_fr->max_pll_op_clk_freq_hz) From 04354c529c8246a38ae28f713fd6bfdc028113bc Mon Sep 17 00:00:00 2001 From: Edward Adam Davis Date: Sat, 5 Apr 2025 19:56:41 +0800 Subject: [PATCH 432/971] media: cxusb: no longer judge rbuf when the write fails commit 73fb3b92da84637e3817580fa205d48065924e15 upstream. syzbot reported a uninit-value in cxusb_i2c_xfer. [1] Only when the write operation of usb_bulk_msg() in dvb_usb_generic_rw() succeeds and rlen is greater than 0, the read operation of usb_bulk_msg() will be executed to read rlen bytes of data from the dvb device into the rbuf. In this case, although rlen is 1, the write operation failed which resulted in the dvb read operation not being executed, and ultimately variable i was not initialized. [1] BUG: KMSAN: uninit-value in cxusb_gpio_tuner drivers/media/usb/dvb-usb/cxusb.c:124 [inline] BUG: KMSAN: uninit-value in cxusb_i2c_xfer+0x153a/0x1a60 drivers/media/usb/dvb-usb/cxusb.c:196 cxusb_gpio_tuner drivers/media/usb/dvb-usb/cxusb.c:124 [inline] cxusb_i2c_xfer+0x153a/0x1a60 drivers/media/usb/dvb-usb/cxusb.c:196 __i2c_transfer+0xe25/0x3150 drivers/i2c/i2c-core-base.c:-1 i2c_transfer+0x317/0x4a0 drivers/i2c/i2c-core-base.c:2315 i2c_transfer_buffer_flags+0x125/0x1e0 drivers/i2c/i2c-core-base.c:2343 i2c_master_send include/linux/i2c.h:109 [inline] i2cdev_write+0x210/0x280 drivers/i2c/i2c-dev.c:183 do_loop_readv_writev fs/read_write.c:848 [inline] vfs_writev+0x963/0x14e0 fs/read_write.c:1057 do_writev+0x247/0x5c0 fs/read_write.c:1101 __do_sys_writev fs/read_write.c:1169 [inline] __se_sys_writev fs/read_write.c:1166 [inline] __x64_sys_writev+0x98/0xe0 fs/read_write.c:1166 x64_sys_call+0x2229/0x3c80 arch/x86/include/generated/asm/syscalls_64.h:21 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcd/0x1e0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f Reported-by: syzbot+526bd95c0ec629993bf3@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=526bd95c0ec629993bf3 Tested-by: syzbot+526bd95c0ec629993bf3@syzkaller.appspotmail.com Fixes: 22c6d93a7310 ("[PATCH] dvb: usb: support Medion hybrid USB2.0 DVB-T/analogue box") Cc: stable@vger.kernel.org Signed-off-by: Edward Adam Davis Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/usb/dvb-usb/cxusb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index 1d98d3465e28..ce52c936cb93 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c @@ -119,9 +119,8 @@ static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff) o[0] = GPIO_TUNER; o[1] = onoff; - cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1); - if (i != 0x01) + if (!cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1) && i != 0x01) dev_info(&d->udev->dev, "gpio_write failed.\n"); st->gpio_write_state[GPIO_TUNER] = onoff; From ec5c328606baacb98b6c8117de1396191cdbeeec Mon Sep 17 00:00:00 2001 From: Dmitry Nikiforov Date: Wed, 16 Apr 2025 23:51:19 +0300 Subject: [PATCH 433/971] media: davinci: vpif: Fix memory leak in probe error path commit 024bf40edf1155e7a587f0ec46294049777d9b02 upstream. If an error occurs during the initialization of `pdev_display`, the allocated platform device `pdev_capture` is not released properly, leading to a memory leak. Adjust error path handling to fix the leak. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 43acb728bbc4 ("media: davinci: vpif: fix use-after-free on driver unbind") Cc: stable@vger.kernel.org Signed-off-by: Dmitry Nikiforov Reviewed-by: Johan Hovold Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/platform/ti/davinci/vpif.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/ti/davinci/vpif.c b/drivers/media/platform/ti/davinci/vpif.c index 63cdfed37bc9..fa9679abf7a4 100644 --- a/drivers/media/platform/ti/davinci/vpif.c +++ b/drivers/media/platform/ti/davinci/vpif.c @@ -505,7 +505,7 @@ static int vpif_probe(struct platform_device *pdev) pdev_display = kzalloc(sizeof(*pdev_display), GFP_KERNEL); if (!pdev_display) { ret = -ENOMEM; - goto err_put_pdev_capture; + goto err_del_pdev_capture; } pdev_display->name = "vpif_display"; @@ -528,6 +528,8 @@ static int vpif_probe(struct platform_device *pdev) err_put_pdev_display: platform_device_put(pdev_display); +err_del_pdev_capture: + platform_device_del(pdev_capture); err_put_pdev_capture: platform_device_put(pdev_capture); err_put_rpm: From 025a943c49c742a8b65383997331b9dd1faad73d Mon Sep 17 00:00:00 2001 From: Wentao Liang Date: Tue, 22 Apr 2025 11:07:39 +0800 Subject: [PATCH 434/971] media: gspca: Add error handling for stv06xx_read_sensor() commit 398a1b33f1479af35ca915c5efc9b00d6204f8fa upstream. In hdcs_init(), the return value of stv06xx_read_sensor() needs to be checked. A proper implementation can be found in vv6410_dump(). Add a check in loop condition and propergate error code to fix this issue. Fixes: 4c98834addfe ("V4L/DVB (10048): gspca - stv06xx: New subdriver.") Cc: stable@vger.kernel.org # v2.6+ Signed-off-by: Wentao Liang Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c index 5a47dcbf1c8e..303b055fefea 100644 --- a/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c +++ b/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c @@ -520,12 +520,13 @@ static int hdcs_init(struct sd *sd) static int hdcs_dump(struct sd *sd) { u16 reg, val; + int err = 0; pr_info("Dumping sensor registers:\n"); - for (reg = HDCS_IDENT; reg <= HDCS_ROWEXPH; reg++) { - stv06xx_read_sensor(sd, reg, &val); + for (reg = HDCS_IDENT; reg <= HDCS_ROWEXPH && !err; reg++) { + err = stv06xx_read_sensor(sd, reg, &val); pr_info("reg 0x%02x = 0x%02x\n", reg, val); } - return 0; + return (err < 0) ? err : 0; } From ac3a8e37cb8ea90834aa3807cc8b664da68577d1 Mon Sep 17 00:00:00 2001 From: Fei Shao Date: Fri, 14 Mar 2025 15:56:17 +0800 Subject: [PATCH 435/971] media: mediatek: vcodec: Correct vsi_core framebuffer size commit f19035b86382f635a0d13d177b601babaf263a12 upstream. The framebuffer size for decoder instances was being incorrectly set - inst->vsi_core->fb.y.size was assigned twice consecutively. Assign the second picinfo framebuffer size to the C framebuffer instead, which appears to be the intended target based on the surrounding code. Fixes: 2674486aac7d ("media: mediatek: vcodec: support stateless hevc decoder") Cc: stable@vger.kernel.org Signed-off-by: Fei Shao Reviewed-by: Nicolas Dufresne Signed-off-by: Nicolas Dufresne Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- .../mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c index 21836dd6ef85..bbf56016f70a 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c @@ -821,7 +821,7 @@ static int vdec_hevc_slice_setup_core_buffer(struct vdec_hevc_slice_inst *inst, inst->vsi_core->fb.y.dma_addr = y_fb_dma; inst->vsi_core->fb.y.size = ctx->picinfo.fb_sz[0]; inst->vsi_core->fb.c.dma_addr = c_fb_dma; - inst->vsi_core->fb.y.size = ctx->picinfo.fb_sz[1]; + inst->vsi_core->fb.c.size = ctx->picinfo.fb_sz[1]; inst->vsi_core->dec.vdec_fb_va = (unsigned long)fb; From dfb2add0baa7ef47cff60c2afca28b364098d79a Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 7 May 2025 18:09:13 +0200 Subject: [PATCH 436/971] media: omap3isp: use sgtable-based scatterlist wrappers commit 3de572fe2189a4a0bd80295e1f478401e739498e upstream. Use common wrappers operating directly on the struct sg_table objects to fix incorrect use of scatterlists sync calls. dma_sync_sg_for_*() functions have to be called with the number of elements originally passed to dma_map_sg_*() function, not the one returned in sgtable's nents. Fixes: d33186d0be18 ("[media] omap3isp: ccdc: Use the DMA API for LSC") Fixes: 0e24e90f2ca7 ("[media] omap3isp: stat: Use the DMA API") CC: stable@vger.kernel.org Signed-off-by: Marek Szyprowski Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/platform/ti/omap3isp/ispccdc.c | 8 ++++---- drivers/media/platform/ti/omap3isp/ispstat.c | 6 ++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/ti/omap3isp/ispccdc.c b/drivers/media/platform/ti/omap3isp/ispccdc.c index 2fe42aa91800..6eb387ea1dae 100644 --- a/drivers/media/platform/ti/omap3isp/ispccdc.c +++ b/drivers/media/platform/ti/omap3isp/ispccdc.c @@ -446,8 +446,8 @@ static int ccdc_lsc_config(struct isp_ccdc_device *ccdc, if (ret < 0) goto done; - dma_sync_sg_for_cpu(isp->dev, req->table.sgt.sgl, - req->table.sgt.nents, DMA_TO_DEVICE); + dma_sync_sgtable_for_cpu(isp->dev, &req->table.sgt, + DMA_TO_DEVICE); if (copy_from_user(req->table.addr, config->lsc, req->config.size)) { @@ -455,8 +455,8 @@ static int ccdc_lsc_config(struct isp_ccdc_device *ccdc, goto done; } - dma_sync_sg_for_device(isp->dev, req->table.sgt.sgl, - req->table.sgt.nents, DMA_TO_DEVICE); + dma_sync_sgtable_for_device(isp->dev, &req->table.sgt, + DMA_TO_DEVICE); } spin_lock_irqsave(&ccdc->lsc.req_lock, flags); diff --git a/drivers/media/platform/ti/omap3isp/ispstat.c b/drivers/media/platform/ti/omap3isp/ispstat.c index 68cf68dbcace..dc496ca9748a 100644 --- a/drivers/media/platform/ti/omap3isp/ispstat.c +++ b/drivers/media/platform/ti/omap3isp/ispstat.c @@ -161,8 +161,7 @@ static void isp_stat_buf_sync_for_device(struct ispstat *stat, if (ISP_STAT_USES_DMAENGINE(stat)) return; - dma_sync_sg_for_device(stat->isp->dev, buf->sgt.sgl, - buf->sgt.nents, DMA_FROM_DEVICE); + dma_sync_sgtable_for_device(stat->isp->dev, &buf->sgt, DMA_FROM_DEVICE); } static void isp_stat_buf_sync_for_cpu(struct ispstat *stat, @@ -171,8 +170,7 @@ static void isp_stat_buf_sync_for_cpu(struct ispstat *stat, if (ISP_STAT_USES_DMAENGINE(stat)) return; - dma_sync_sg_for_cpu(stat->isp->dev, buf->sgt.sgl, - buf->sgt.nents, DMA_FROM_DEVICE); + dma_sync_sgtable_for_cpu(stat->isp->dev, &buf->sgt, DMA_FROM_DEVICE); } static void isp_stat_buf_clear(struct ispstat *stat) From ae7b143e05b36fc69d6571751855946cc45064c6 Mon Sep 17 00:00:00 2001 From: Ma Ke Date: Wed, 19 Mar 2025 16:02:48 +0800 Subject: [PATCH 437/971] media: v4l2-dev: fix error handling in __video_register_device() commit 2a934fdb01db6458288fc9386d3d8ceba6dd551a upstream. Once device_register() failed, we should call put_device() to decrement reference count for cleanup. Or it could cause memory leak. And move callback function v4l2_device_release() and v4l2_device_get() before put_device(). As comment of device_register() says, 'NOTE: _Never_ directly free @dev after calling this function, even if it returned an error! Always use put_device() to give up the reference initialized in this function instead.' Found by code review. Cc: stable@vger.kernel.org Fixes: dc93a70cc7f9 ("V4L/DVB (9973): v4l2-dev: use the release callback from device instead of cdev") Signed-off-by: Ma Ke Reviewed-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/v4l2-core/v4l2-dev.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 77bbf276ae89..c4d3d110c500 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -1033,25 +1033,25 @@ int __video_register_device(struct video_device *vdev, vdev->dev.class = &video_class; vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor); vdev->dev.parent = vdev->dev_parent; + vdev->dev.release = v4l2_device_release; dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num); + + /* Increase v4l2_device refcount */ + v4l2_device_get(vdev->v4l2_dev); + mutex_lock(&videodev_lock); ret = device_register(&vdev->dev); if (ret < 0) { mutex_unlock(&videodev_lock); pr_err("%s: device_register failed\n", __func__); - goto cleanup; + put_device(&vdev->dev); + return ret; } - /* Register the release callback that will be called when the last - reference to the device goes away. */ - vdev->dev.release = v4l2_device_release; if (nr != -1 && nr != vdev->num && warn_if_nr_in_use) pr_warn("%s: requested %s%d, got %s\n", __func__, name_base, nr, video_device_node_name(vdev)); - /* Increase v4l2_device refcount */ - v4l2_device_get(vdev->v4l2_dev); - /* Part 5: Register the entity. */ ret = video_register_media_controller(vdev); From 36318ff3d6bf94ea01b2caa0967f2b366c7daea6 Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Thu, 27 Mar 2025 13:53:04 +0100 Subject: [PATCH 438/971] media: venus: Fix probe error handling commit 523cea3a19f0b3b020a4745344c136a636e6ffd7 upstream. Video device registering has been moved earlier in the probe function, but the new order has not been propagated to error handling. This means we can end with unreleased resources on error (e.g dangling video device on missing firmware probe aborting). Fixes: 08b1cf474b7f7 ("media: venus: core, venc, vdec: Fix probe dependency error") Cc: stable@vger.kernel.org Signed-off-by: Loic Poulain Reviewed-by: Dikshita Agarwal Reviewed-by: Bryan O'Donoghue Signed-off-by: Bryan O'Donoghue Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/platform/qcom/venus/core.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c index b570eb8c3756..47ce3365451d 100644 --- a/drivers/media/platform/qcom/venus/core.c +++ b/drivers/media/platform/qcom/venus/core.c @@ -348,7 +348,7 @@ static int venus_probe(struct platform_device *pdev) ret = v4l2_device_register(dev, &core->v4l2_dev); if (ret) - goto err_core_deinit; + goto err_hfi_destroy; platform_set_drvdata(pdev, core); @@ -380,24 +380,24 @@ static int venus_probe(struct platform_device *pdev) ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_DEC); if (ret) - goto err_venus_shutdown; + goto err_core_deinit; ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_ENC); if (ret) - goto err_venus_shutdown; + goto err_core_deinit; ret = pm_runtime_put_sync(dev); if (ret) { pm_runtime_get_noresume(dev); - goto err_dev_unregister; + goto err_core_deinit; } venus_dbgfs_init(core); return 0; -err_dev_unregister: - v4l2_device_unregister(&core->v4l2_dev); +err_core_deinit: + hfi_core_deinit(core, false); err_venus_shutdown: venus_shutdown(core); err_firmware_deinit: @@ -408,9 +408,9 @@ err_runtime_disable: pm_runtime_put_noidle(dev); pm_runtime_disable(dev); pm_runtime_set_suspended(dev); + v4l2_device_unregister(&core->v4l2_dev); +err_hfi_destroy: hfi_destroy(core); -err_core_deinit: - hfi_core_deinit(core, false); err_core_put: if (core->pm_ops->core_put) core->pm_ops->core_put(core); From 17cb043ea1334ebe57377ab138e155beec870c97 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 7 May 2025 18:09:11 +0200 Subject: [PATCH 439/971] media: videobuf2: use sgtable-based scatterlist wrappers commit a704a3c503ae1cfd9de8a2e2d16a0c9430e98162 upstream. Use common wrappers operating directly on the struct sg_table objects to fix incorrect use of scatterlists sync calls. dma_sync_sg_for_*() functions have to be called with the number of elements originally passed to dma_map_sg_*() function, not the one returned in sgt->nents. Fixes: d4db5eb57cab ("media: videobuf2: add begin/end cpu_access callbacks to dma-sg") CC: stable@vger.kernel.org Signed-off-by: Marek Szyprowski Reviewed-by: Sergey Senozhatsky Acked-by: Tomasz Figa Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/common/videobuf2/videobuf2-dma-sg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c index 6975a71d740f..a5aa6a2a028c 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c @@ -469,7 +469,7 @@ vb2_dma_sg_dmabuf_ops_begin_cpu_access(struct dma_buf *dbuf, struct vb2_dma_sg_buf *buf = dbuf->priv; struct sg_table *sgt = buf->dma_sgt; - dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); + dma_sync_sgtable_for_cpu(buf->dev, sgt, buf->dma_dir); return 0; } @@ -480,7 +480,7 @@ vb2_dma_sg_dmabuf_ops_end_cpu_access(struct dma_buf *dbuf, struct vb2_dma_sg_buf *buf = dbuf->priv; struct sg_table *sgt = buf->dma_sgt; - dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); + dma_sync_sgtable_for_device(buf->dev, sgt, buf->dma_dir); return 0; } From 9824e1732a163e005aa84e12ec439493ebd4f097 Mon Sep 17 00:00:00 2001 From: Edward Adam Davis Date: Tue, 11 Mar 2025 15:20:14 +0800 Subject: [PATCH 440/971] media: vidtv: Terminating the subsequent process of initialization failure commit 1d5f88f053480326873115092bc116b7d14916ba upstream. syzbot reported a slab-use-after-free Read in vidtv_mux_init. [1] After PSI initialization fails, the si member is accessed again, resulting in this uaf. After si initialization fails, the subsequent process needs to be exited. [1] BUG: KASAN: slab-use-after-free in vidtv_mux_pid_ctx_init drivers/media/test-drivers/vidtv/vidtv_mux.c:78 [inline] BUG: KASAN: slab-use-after-free in vidtv_mux_init+0xac2/0xbe0 drivers/media/test-drivers/vidtv/vidtv_mux.c:524 Read of size 8 at addr ffff88802fa42acc by task syz.2.37/6059 CPU: 0 UID: 0 PID: 6059 Comm: syz.2.37 Not tainted 6.14.0-rc5-syzkaller #0 Hardware name: Google Compute Engine, BIOS Google 02/12/2025 Call Trace: __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x116/0x1f0 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:408 [inline] print_report+0xc3/0x670 mm/kasan/report.c:521 kasan_report+0xd9/0x110 mm/kasan/report.c:634 vidtv_mux_pid_ctx_init drivers/media/test-drivers/vidtv/vidtv_mux.c:78 vidtv_mux_init+0xac2/0xbe0 drivers/media/test-drivers/vidtv/vidtv_mux.c:524 vidtv_start_streaming drivers/media/test-drivers/vidtv/vidtv_bridge.c:194 vidtv_start_feed drivers/media/test-drivers/vidtv/vidtv_bridge.c:239 dmx_section_feed_start_filtering drivers/media/dvb-core/dvb_demux.c:973 dvb_dmxdev_feed_start drivers/media/dvb-core/dmxdev.c:508 [inline] dvb_dmxdev_feed_restart.isra.0 drivers/media/dvb-core/dmxdev.c:537 dvb_dmxdev_filter_stop+0x2b4/0x3a0 drivers/media/dvb-core/dmxdev.c:564 dvb_dmxdev_filter_free drivers/media/dvb-core/dmxdev.c:840 [inline] dvb_demux_release+0x92/0x550 drivers/media/dvb-core/dmxdev.c:1246 __fput+0x3ff/0xb70 fs/file_table.c:464 task_work_run+0x14e/0x250 kernel/task_work.c:227 exit_task_work include/linux/task_work.h:40 [inline] do_exit+0xad8/0x2d70 kernel/exit.c:938 do_group_exit+0xd3/0x2a0 kernel/exit.c:1087 __do_sys_exit_group kernel/exit.c:1098 [inline] __se_sys_exit_group kernel/exit.c:1096 [inline] __x64_sys_exit_group+0x3e/0x50 kernel/exit.c:1096 x64_sys_call+0x151f/0x1720 arch/x86/include/generated/asm/syscalls_64.h:232 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcd/0x250 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f871d58d169 Code: Unable to access opcode bytes at 0x7f871d58d13f. RSP: 002b:00007fff4b19a788 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7 RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f871d58d169 RDX: 0000000000000064 RSI: 0000000000000000 RDI: 0000000000000000 RBP: 00007fff4b19a7ec R08: 0000000b4b19a87f R09: 00000000000927c0 R10: 0000000000000001 R11: 0000000000000246 R12: 0000000000000003 R13: 00000000000927c0 R14: 000000000001d553 R15: 00007fff4b19a840 Allocated by task 6059: kasan_save_stack+0x33/0x60 mm/kasan/common.c:47 kasan_save_track+0x14/0x30 mm/kasan/common.c:68 poison_kmalloc_redzone mm/kasan/common.c:377 [inline] __kasan_kmalloc+0xaa/0xb0 mm/kasan/common.c:394 kmalloc_noprof include/linux/slab.h:901 [inline] kzalloc_noprof include/linux/slab.h:1037 [inline] vidtv_psi_pat_table_init drivers/media/test-drivers/vidtv/vidtv_psi.c:970 vidtv_channel_si_init drivers/media/test-drivers/vidtv/vidtv_channel.c:423 vidtv_mux_init drivers/media/test-drivers/vidtv/vidtv_mux.c:519 vidtv_start_streaming drivers/media/test-drivers/vidtv/vidtv_bridge.c:194 vidtv_start_feed drivers/media/test-drivers/vidtv/vidtv_bridge.c:239 dmx_section_feed_start_filtering drivers/media/dvb-core/dvb_demux.c:973 dvb_dmxdev_feed_start drivers/media/dvb-core/dmxdev.c:508 [inline] dvb_dmxdev_feed_restart.isra.0 drivers/media/dvb-core/dmxdev.c:537 dvb_dmxdev_filter_stop+0x2b4/0x3a0 drivers/media/dvb-core/dmxdev.c:564 dvb_dmxdev_filter_free drivers/media/dvb-core/dmxdev.c:840 [inline] dvb_demux_release+0x92/0x550 drivers/media/dvb-core/dmxdev.c:1246 __fput+0x3ff/0xb70 fs/file_table.c:464 task_work_run+0x14e/0x250 kernel/task_work.c:227 exit_task_work include/linux/task_work.h:40 [inline] do_exit+0xad8/0x2d70 kernel/exit.c:938 do_group_exit+0xd3/0x2a0 kernel/exit.c:1087 __do_sys_exit_group kernel/exit.c:1098 [inline] __se_sys_exit_group kernel/exit.c:1096 [inline] __x64_sys_exit_group+0x3e/0x50 kernel/exit.c:1096 x64_sys_call arch/x86/include/generated/asm/syscalls_64.h:232 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcd/0x250 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 6059: kasan_save_stack+0x33/0x60 mm/kasan/common.c:47 kasan_save_track+0x14/0x30 mm/kasan/common.c:68 kasan_save_free_info+0x3b/0x60 mm/kasan/generic.c:576 poison_slab_object mm/kasan/common.c:247 [inline] __kasan_slab_free+0x51/0x70 mm/kasan/common.c:264 kasan_slab_free include/linux/kasan.h:233 [inline] slab_free_hook mm/slub.c:2353 [inline] slab_free mm/slub.c:4609 [inline] kfree+0x2c4/0x4d0 mm/slub.c:4757 vidtv_channel_si_init drivers/media/test-drivers/vidtv/vidtv_channel.c:499 vidtv_mux_init drivers/media/test-drivers/vidtv/vidtv_mux.c:519 vidtv_start_streaming drivers/media/test-drivers/vidtv/vidtv_bridge.c:194 vidtv_start_feed drivers/media/test-drivers/vidtv/vidtv_bridge.c:239 dmx_section_feed_start_filtering drivers/media/dvb-core/dvb_demux.c:973 dvb_dmxdev_feed_start drivers/media/dvb-core/dmxdev.c:508 [inline] dvb_dmxdev_feed_restart.isra.0 drivers/media/dvb-core/dmxdev.c:537 dvb_dmxdev_filter_stop+0x2b4/0x3a0 drivers/media/dvb-core/dmxdev.c:564 dvb_dmxdev_filter_free drivers/media/dvb-core/dmxdev.c:840 [inline] dvb_demux_release+0x92/0x550 drivers/media/dvb-core/dmxdev.c:1246 __fput+0x3ff/0xb70 fs/file_table.c:464 task_work_run+0x14e/0x250 kernel/task_work.c:227 exit_task_work include/linux/task_work.h:40 [inline] do_exit+0xad8/0x2d70 kernel/exit.c:938 do_group_exit+0xd3/0x2a0 kernel/exit.c:1087 __do_sys_exit_group kernel/exit.c:1098 [inline] __se_sys_exit_group kernel/exit.c:1096 [inline] __x64_sys_exit_group+0x3e/0x50 kernel/exit.c:1096 x64_sys_call arch/x86/include/generated/asm/syscalls_64.h:232 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcd/0x250 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f Fixes: 3be8037960bc ("media: vidtv: add error checks") Cc: stable@vger.kernel.org Reported-by: syzbot+0d33ab192bd50b6c91e6@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=0d33ab192bd50b6c91e6 Signed-off-by: Edward Adam Davis Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/test-drivers/vidtv/vidtv_channel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/test-drivers/vidtv/vidtv_channel.c b/drivers/media/test-drivers/vidtv/vidtv_channel.c index 7838e6272712..f3023e91b3eb 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_channel.c +++ b/drivers/media/test-drivers/vidtv/vidtv_channel.c @@ -497,7 +497,7 @@ free_sdt: vidtv_psi_sdt_table_destroy(m->si.sdt); free_pat: vidtv_psi_pat_table_destroy(m->si.pat); - return 0; + return -EINVAL; } void vidtv_channel_si_destroy(struct vidtv_mux *m) From f6b1b0f8ba0b61d8b511df5649d57235f230c135 Mon Sep 17 00:00:00 2001 From: Denis Arefev Date: Tue, 15 Apr 2025 11:27:21 +0300 Subject: [PATCH 441/971] media: vivid: Change the siize of the composing commit f83ac8d30c43fd902af7c84c480f216157b60ef0 upstream. syzkaller found a bug: BUG: KASAN: vmalloc-out-of-bounds in tpg_fill_plane_pattern drivers/media/common/v4l2-tpg/v4l2-tpg-core.c:2608 [inline] BUG: KASAN: vmalloc-out-of-bounds in tpg_fill_plane_buffer+0x1a9c/0x5af0 drivers/media/common/v4l2-tpg/v4l2-tpg-core.c:2705 Write of size 1440 at addr ffffc9000d0ffda0 by task vivid-000-vid-c/5304 CPU: 0 UID: 0 PID: 5304 Comm: vivid-000-vid-c Not tainted 6.14.0-rc2-syzkaller-00039-g09fbf3d50205 #0 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 Call Trace: __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:378 [inline] print_report+0x169/0x550 mm/kasan/report.c:489 kasan_report+0x143/0x180 mm/kasan/report.c:602 kasan_check_range+0x282/0x290 mm/kasan/generic.c:189 __asan_memcpy+0x40/0x70 mm/kasan/shadow.c:106 tpg_fill_plane_pattern drivers/media/common/v4l2-tpg/v4l2-tpg-core.c:2608 [inline] tpg_fill_plane_buffer+0x1a9c/0x5af0 drivers/media/common/v4l2-tpg/v4l2-tpg-core.c:2705 vivid_fillbuff drivers/media/test-drivers/vivid/vivid-kthread-cap.c:470 [inline] vivid_thread_vid_cap_tick+0xf8e/0x60d0 drivers/media/test-drivers/vivid/vivid-kthread-cap.c:629 vivid_thread_vid_cap+0x8aa/0xf30 drivers/media/test-drivers/vivid/vivid-kthread-cap.c:767 kthread+0x7a9/0x920 kernel/kthread.c:464 ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:148 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 The composition size cannot be larger than the size of fmt_cap_rect. So execute v4l2_rect_map_inside() even if has_compose_cap == 0. Fixes: 94a7ad928346 ("media: vivid: fix compose size exceed boundary") Cc: stable@vger.kernel.org Reported-by: syzbot+365005005522b70a36f2@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?id=8ed8e8cc30cbe0d86c9a25bd1d6a5775129b8ea3 Signed-off-by: Denis Arefev Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/test-drivers/vivid/vivid-vid-cap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c index 9443dbb04699..0ab47fb8696b 100644 --- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c +++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c @@ -954,8 +954,8 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection if (dev->has_compose_cap) { v4l2_rect_set_min_size(compose, &min_rect); v4l2_rect_set_max_size(compose, &max_rect); - v4l2_rect_map_inside(compose, &fmt); } + v4l2_rect_map_inside(compose, &fmt); dev->fmt_cap_rect = fmt; tpg_s_buf_height(&dev->tpg, fmt.height); } else if (dev->has_compose_cap) { From 350d4af0493a51fc153abe711f76160a004c15ab Mon Sep 17 00:00:00 2001 From: Ming Qian Date: Mon, 21 Apr 2025 15:06:12 +0800 Subject: [PATCH 442/971] media: imx-jpeg: Drop the first error frames commit d52b9b7e2f10d22a49468128540533e8d76910cd upstream. When an output buffer contains error frame header, v4l2_jpeg_parse_header() will return error, then driver will mark this buffer and a capture buffer done with error flag in device_run(). But if the error occurs in the first frames, before setup the capture queue, there is no chance to schedule device_run(), and there may be no capture to mark error. So we need to drop this buffer with error flag, and make the decoding can continue. Fixes: 2db16c6ed72c ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder") Cc: stable@vger.kernel.org Signed-off-by: Ming Qian Reviewed-by: Nicolas Dufresne Signed-off-by: Nicolas Dufresne Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c index 092d83b7e795..687f7cb8c4b9 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c @@ -1913,9 +1913,19 @@ static void mxc_jpeg_buf_queue(struct vb2_buffer *vb) jpeg_src_buf = vb2_to_mxc_buf(vb); jpeg_src_buf->jpeg_parse_error = false; ret = mxc_jpeg_parse(ctx, vb); - if (ret) + if (ret) { jpeg_src_buf->jpeg_parse_error = true; + /* + * if the capture queue is not setup, the device_run() won't be scheduled, + * need to drop the error buffer, so that the decoding can continue + */ + if (!vb2_is_streaming(v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx))) { + v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); + return; + } + } + end: v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); } From 683a1db6800e4e6ad466f1a8244796e984a7a4e6 Mon Sep 17 00:00:00 2001 From: Ming Qian Date: Mon, 21 Apr 2025 16:12:52 +0800 Subject: [PATCH 443/971] media: imx-jpeg: Move mxc_jpeg_free_slot_data() ahead commit 46e9c092f850bd7b4d06de92d3d21877f49a3fcb upstream. Move function mxc_jpeg_free_slot_data() above mxc_jpeg_alloc_slot_data() allowing to call that function during allocation failures. No functional changes are made. Fixes: 2db16c6ed72c ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder") Cc: stable@vger.kernel.org Signed-off-by: Ming Qian Reviewed-by: Nicolas Dufresne Reviewed-by: Frank Li Signed-off-by: Nicolas Dufresne Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- .../media/platform/nxp/imx-jpeg/mxc-jpeg.c | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c index 687f7cb8c4b9..f22ca3cc63fe 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c @@ -752,6 +752,26 @@ static int mxc_get_free_slot(struct mxc_jpeg_slot_data *slot_data) return -1; } +static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg) +{ + /* free descriptor for decoding/encoding phase */ + dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), + jpeg->slot_data.desc, + jpeg->slot_data.desc_handle); + + /* free descriptor for encoder configuration phase / decoder DHT */ + dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), + jpeg->slot_data.cfg_desc, + jpeg->slot_data.cfg_desc_handle); + + /* free configuration stream */ + dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM, + jpeg->slot_data.cfg_stream_vaddr, + jpeg->slot_data.cfg_stream_handle); + + jpeg->slot_data.used = false; +} + static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg) { struct mxc_jpeg_desc *desc; @@ -798,26 +818,6 @@ err: return false; } -static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg) -{ - /* free descriptor for decoding/encoding phase */ - dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), - jpeg->slot_data.desc, - jpeg->slot_data.desc_handle); - - /* free descriptor for encoder configuration phase / decoder DHT */ - dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), - jpeg->slot_data.cfg_desc, - jpeg->slot_data.cfg_desc_handle); - - /* free configuration stream */ - dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM, - jpeg->slot_data.cfg_stream_vaddr, - jpeg->slot_data.cfg_stream_handle); - - jpeg->slot_data.used = false; -} - static void mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx *ctx, struct vb2_v4l2_buffer *src_buf, struct vb2_v4l2_buffer *dst_buf) From 20a6db0ef356e4ede11dd6c0da1f1c37632ee454 Mon Sep 17 00:00:00 2001 From: Ming Qian Date: Mon, 21 Apr 2025 16:12:53 +0800 Subject: [PATCH 444/971] media: imx-jpeg: Reset slot data pointers when freed commit faa8051b128f4b34277ea8a026d02d83826f8122 upstream. Ensure that the slot data pointers are reset to NULL and handles are set to 0 after freeing the coherent memory. This makes he function mxc_jpeg_alloc_slot_data() and mxc_jpeg_free_slot_data() safe to be called multiple times. Fixes: 2db16c6ed72c ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder") Cc: stable@vger.kernel.org Signed-off-by: Ming Qian Reviewed-by: Nicolas Dufresne Reviewed-by: Frank Li Signed-off-by: Nicolas Dufresne Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c index f22ca3cc63fe..655d8dbe2c1a 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c @@ -758,16 +758,22 @@ static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg) dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), jpeg->slot_data.desc, jpeg->slot_data.desc_handle); + jpeg->slot_data.desc = NULL; + jpeg->slot_data.desc_handle = 0; /* free descriptor for encoder configuration phase / decoder DHT */ dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), jpeg->slot_data.cfg_desc, jpeg->slot_data.cfg_desc_handle); + jpeg->slot_data.cfg_desc_handle = 0; + jpeg->slot_data.cfg_desc = NULL; /* free configuration stream */ dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM, jpeg->slot_data.cfg_stream_vaddr, jpeg->slot_data.cfg_stream_handle); + jpeg->slot_data.cfg_stream_vaddr = NULL; + jpeg->slot_data.cfg_stream_handle = 0; jpeg->slot_data.used = false; } From ec26be7d6355a05552a0d0c1e73031f83aa4dc7f Mon Sep 17 00:00:00 2001 From: Ming Qian Date: Mon, 21 Apr 2025 16:12:54 +0800 Subject: [PATCH 445/971] media: imx-jpeg: Cleanup after an allocation error commit 7500bb9cf164edbb2c8117d57620227b1a4a8369 upstream. When allocation failures are not cleaned up by the driver, further allocation errors will be false-positives, which will cause buffers to remain uninitialized and cause NULL pointer dereferences. Ensure proper cleanup of failed allocations to prevent these issues. Fixes: 2db16c6ed72c ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder") Cc: stable@vger.kernel.org Signed-off-by: Ming Qian Reviewed-by: Frank Li Signed-off-by: Nicolas Dufresne Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c index 655d8dbe2c1a..dc3e0d292810 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c @@ -820,6 +820,7 @@ skip_alloc: return true; err: dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", jpeg->slot_data.slot); + mxc_jpeg_free_slot_data(jpeg); return false; } From d314f99b6f194697b7ed5c0907b19e39dac401f1 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Mon, 24 Feb 2025 10:34:53 +0000 Subject: [PATCH 446/971] media: uvcvideo: Return the number of processed controls commit ba4fafb02ad6a4eb2e00f861893b5db42ba54369 upstream. If we let know our callers that we have not done anything, they will be able to optimize their decisions. Cc: stable@kernel.org Fixes: b4012002f3a3 ("[media] uvcvideo: Add support for control events") Reviewed-by: Laurent Pinchart Signed-off-by: Ricardo Ribalda Message-ID: <20250224-uvc-data-backup-v2-1-de993ed9823b@chromium.org> Signed-off-by: Hans de Goede Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/usb/uvc/uvc_ctrl.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 5926a9dfb0b1..36acc7eeff08 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -1783,12 +1783,17 @@ int uvc_ctrl_begin(struct uvc_video_chain *chain) return mutex_lock_interruptible(&chain->ctrl_mutex) ? -ERESTARTSYS : 0; } +/* + * Returns the number of uvc controls that have been correctly set, or a + * negative number if there has been an error. + */ static int uvc_ctrl_commit_entity(struct uvc_device *dev, struct uvc_fh *handle, struct uvc_entity *entity, int rollback, struct uvc_control **err_ctrl) { + unsigned int processed_ctrls = 0; struct uvc_control *ctrl; unsigned int i; int ret; @@ -1823,6 +1828,9 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, else ret = 0; + if (!ret) + processed_ctrls++; + if (rollback || ret < 0) memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), @@ -1841,7 +1849,7 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, uvc_ctrl_set_handle(handle, ctrl, handle); } - return 0; + return processed_ctrls; } static int uvc_ctrl_find_ctrl_idx(struct uvc_entity *entity, @@ -1888,6 +1896,7 @@ int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback, if (!rollback) uvc_ctrl_send_events(handle, ctrls->controls, ctrls->count); + ret = 0; done: mutex_unlock(&chain->ctrl_mutex); return ret; From c51c0a0be23951f0e57a8fb6771010295390f224 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Mon, 24 Feb 2025 10:34:54 +0000 Subject: [PATCH 447/971] media: uvcvideo: Send control events for partial succeeds commit 5c791467aea6277430da5f089b9b6c2a9d8a4af7 upstream. Today, when we are applying a change to entities A, B. If A succeeds and B fails the events for A are not sent. This change changes the code so the events for A are send right after they happen. Cc: stable@kernel.org Fixes: b4012002f3a3 ("[media] uvcvideo: Add support for control events") Signed-off-by: Ricardo Ribalda Message-ID: <20250224-uvc-data-backup-v2-2-de993ed9823b@chromium.org> Signed-off-by: Hans de Goede Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/usb/uvc/uvc_ctrl.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 36acc7eeff08..59e21746f550 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -1642,7 +1642,9 @@ static bool uvc_ctrl_xctrls_has_control(const struct v4l2_ext_control *xctrls, } static void uvc_ctrl_send_events(struct uvc_fh *handle, - const struct v4l2_ext_control *xctrls, unsigned int xctrls_count) + struct uvc_entity *entity, + const struct v4l2_ext_control *xctrls, + unsigned int xctrls_count) { struct uvc_control_mapping *mapping; struct uvc_control *ctrl; @@ -1653,6 +1655,9 @@ static void uvc_ctrl_send_events(struct uvc_fh *handle, u32 changes = V4L2_EVENT_CTRL_CH_VALUE; ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping); + if (ctrl->entity != entity) + continue; + if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) /* Notification will be sent from an Interrupt event. */ continue; @@ -1891,11 +1896,12 @@ int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback, uvc_ctrl_find_ctrl_idx(entity, ctrls, err_ctrl); goto done; + } else if (ret > 0 && !rollback) { + uvc_ctrl_send_events(handle, entity, + ctrls->controls, ctrls->count); } } - if (!rollback) - uvc_ctrl_send_events(handle, ctrls->controls, ctrls->count); ret = 0; done: mutex_unlock(&chain->ctrl_mutex); From a31dce9b561d651d7bcc0e9fb2ccd326a90ee584 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Thu, 13 Mar 2025 12:20:39 +0000 Subject: [PATCH 448/971] media: uvcvideo: Fix deferred probing error commit 387e8939307192d5a852a2afeeb83427fa477151 upstream. uvc_gpio_parse() can return -EPROBE_DEFER when the GPIOs it depends on have not yet been probed. This return code should be propagated to the caller of uvc_probe() to ensure that probing is retried when the required GPIOs become available. Currently, this error code is incorrectly converted to -ENODEV, causing some internal cameras to be ignored. This commit fixes this issue by propagating the -EPROBE_DEFER error. Cc: stable@vger.kernel.org Fixes: 2886477ff987 ("media: uvcvideo: Implement UVC_EXT_GPIO_UNIT") Reviewed-by: Douglas Anderson Signed-off-by: Ricardo Ribalda Message-ID: <20250313-uvc-eprobedefer-v3-1-a1d312708eef@chromium.org> Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/usb/uvc/uvc_driver.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 02cfa12b9cb9..76f18557f37b 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -2217,13 +2217,16 @@ static int uvc_probe(struct usb_interface *intf, #endif /* Parse the Video Class control descriptor. */ - if (uvc_parse_control(dev) < 0) { + ret = uvc_parse_control(dev); + if (ret < 0) { + ret = -ENODEV; uvc_dbg(dev, PROBE, "Unable to parse UVC descriptors\n"); goto error; } /* Parse the associated GPIOs. */ - if (uvc_gpio_parse(dev) < 0) { + ret = uvc_gpio_parse(dev); + if (ret < 0) { uvc_dbg(dev, PROBE, "Unable to parse UVC GPIOs\n"); goto error; } @@ -2249,24 +2252,32 @@ static int uvc_probe(struct usb_interface *intf, } /* Register the V4L2 device. */ - if (v4l2_device_register(&intf->dev, &dev->vdev) < 0) + ret = v4l2_device_register(&intf->dev, &dev->vdev); + if (ret < 0) goto error; /* Scan the device for video chains. */ - if (uvc_scan_device(dev) < 0) + if (uvc_scan_device(dev) < 0) { + ret = -ENODEV; goto error; + } /* Initialize controls. */ - if (uvc_ctrl_init_device(dev) < 0) + if (uvc_ctrl_init_device(dev) < 0) { + ret = -ENODEV; goto error; + } /* Register video device nodes. */ - if (uvc_register_chains(dev) < 0) + if (uvc_register_chains(dev) < 0) { + ret = -ENODEV; goto error; + } #ifdef CONFIG_MEDIA_CONTROLLER /* Register the media device node */ - if (media_device_register(&dev->mdev) < 0) + ret = media_device_register(&dev->mdev); + if (ret < 0) goto error; #endif /* Save our data pointer in the interface data. */ @@ -2300,7 +2311,7 @@ static int uvc_probe(struct usb_interface *intf, error: uvc_unregister_video(dev); kref_put(&dev->ref, uvc_delete); - return -ENODEV; + return ret; } static void uvc_disconnect(struct usb_interface *intf) From 12cffd5bd1da63ff4188391357f0db9edbd2f52b Mon Sep 17 00:00:00 2001 From: Ryan Roberts Date: Fri, 30 May 2025 16:23:47 +0100 Subject: [PATCH 449/971] arm64/mm: Close theoretical race where stale TLB entry remains valid commit 4b634918384c0f84c33aeb4dd9fd4c38e7be5ccb upstream. Commit 3ea277194daa ("mm, mprotect: flush TLB if potentially racing with a parallel reclaim leaving stale TLB entries") describes a race that, prior to the commit, could occur between reclaim and operations such as mprotect() when using reclaim's tlbbatch mechanism. See that commit for details but the summary is: """ Nadav Amit identified a theoritical race between page reclaim and mprotect due to TLB flushes being batched outside of the PTL being held. He described the race as follows: CPU0 CPU1 ---- ---- user accesses memory using RW PTE [PTE now cached in TLB] try_to_unmap_one() ==> ptep_get_and_clear() ==> set_tlb_ubc_flush_pending() mprotect(addr, PROT_READ) ==> change_pte_range() ==> [ PTE non-present - no flush ] user writes using cached RW PTE ... try_to_unmap_flush() """ The solution was to insert flush_tlb_batched_pending() in mprotect() and friends to explcitly drain any pending reclaim TLB flushes. In the modern version of this solution, arch_flush_tlb_batched_pending() is called to do that synchronisation. arm64's tlbbatch implementation simply issues TLBIs at queue-time (arch_tlbbatch_add_pending()), eliding the trailing dsb(ish). The trailing dsb(ish) is finally issued in arch_tlbbatch_flush() at the end of the batch to wait for all the issued TLBIs to complete. Now, the Arm ARM states: """ The completion of the TLB maintenance instruction is guaranteed only by the execution of a DSB by the observer that performed the TLB maintenance instruction. The execution of a DSB by a different observer does not have this effect, even if the DSB is known to be executed after the TLB maintenance instruction is observed by that different observer. """ arch_tlbbatch_add_pending() and arch_tlbbatch_flush() conform to this requirement because they are called from the same task (either kswapd or caller of madvise(MADV_PAGEOUT)), so either they are on the same CPU or if the task was migrated, __switch_to() contains an extra dsb(ish). HOWEVER, arm64's arch_flush_tlb_batched_pending() is also implemented as a dsb(ish). But this may be running on a CPU remote from the one that issued the outstanding TLBIs. So there is no architectural gurantee of synchonization. Therefore we are still vulnerable to the theoretical race described in Commit 3ea277194daa ("mm, mprotect: flush TLB if potentially racing with a parallel reclaim leaving stale TLB entries"). Fix this by flushing the entire mm in arch_flush_tlb_batched_pending(). This aligns with what the other arches that implement the tlbbatch feature do. Cc: Fixes: 43b3dfdd0455 ("arm64: support batched/deferred tlb shootdown during page reclamation/migration") Signed-off-by: Ryan Roberts Link: https://lore.kernel.org/r/20250530152445.2430295-1-ryan.roberts@arm.com Signed-off-by: Will Deacon Signed-off-by: Greg Kroah-Hartman --- arch/arm64/include/asm/tlbflush.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h index d37db2f7a54c..6eeb56b6fac1 100644 --- a/arch/arm64/include/asm/tlbflush.h +++ b/arch/arm64/include/asm/tlbflush.h @@ -311,13 +311,14 @@ static inline void arch_tlbbatch_add_pending(struct arch_tlbflush_unmap_batch *b } /* - * If mprotect/munmap/etc occurs during TLB batched flushing, we need to - * synchronise all the TLBI issued with a DSB to avoid the race mentioned in - * flush_tlb_batched_pending(). + * If mprotect/munmap/etc occurs during TLB batched flushing, we need to ensure + * all the previously issued TLBIs targeting mm have completed. But since we + * can be executing on a remote CPU, a DSB cannot guarantee this like it can + * for arch_tlbbatch_flush(). Our only option is to flush the entire mm. */ static inline void arch_flush_tlb_batched_pending(struct mm_struct *mm) { - dsb(ish); + flush_tlb_mm(mm); } /* From c592d3ceca1aa5d5807e5ba6694d4cc222ed2a60 Mon Sep 17 00:00:00 2001 From: Ross Stutterheim Date: Wed, 16 Apr 2025 14:50:06 +0100 Subject: [PATCH 450/971] ARM: 9447/1: arm/memremap: fix arch_memremap_can_ram_remap() commit 96e0b355883006554a0bee3697da475971d6bba8 upstream. arm/memremap: fix arch_memremap_can_ram_remap() commit 260364d112bc ("arm[64]/memremap: don't abuse pfn_valid() to ensure presence of linear map") added the definition of arch_memremap_can_ram_remap() for arm[64] specific filtering of what pages can be used from the linear mapping. memblock_is_map_memory() was called with the pfn of the address given to arch_memremap_can_ram_remap(); however, memblock_is_map_memory() expects to be given an address for arm, not a pfn. This results in calls to memremap() returning a newly mapped area when it should return an address in the existing linear mapping. Fix this by removing the address to pfn translation and pass the address directly. Fixes: 260364d112bc ("arm[64]/memremap: don't abuse pfn_valid() to ensure presence of linear map") Signed-off-by: Ross Stutterheim Cc: Mike Rapoport Cc: stable@vger.kernel.org Reviewed-by: Catalin Marinas Reviewed-by: Linus Walleij Signed-off-by: Russell King (Oracle) Signed-off-by: Greg Kroah-Hartman --- arch/arm/mm/ioremap.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index 1c5aeba9bc27..7801c5bb775d 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c @@ -515,7 +515,5 @@ void __init early_ioremap_init(void) bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size, unsigned long flags) { - unsigned long pfn = PHYS_PFN(offset); - - return memblock_is_map_memory(pfn); + return memblock_is_map_memory(offset); } From 838d63de34a9defb22149b9606ca420e8772a66e Mon Sep 17 00:00:00 2001 From: Andreas Kemnade Date: Mon, 31 Mar 2025 16:44:39 +0200 Subject: [PATCH 451/971] ARM: omap: pmic-cpcap: do not mess around without CPCAP or OMAP4 commit 7397daf1029d5bfd3415ec8622f5179603d5702d upstream. The late init call just writes to omap4 registers as soon as CONFIG_MFD_CPCAP is enabled without checking whether the cpcap driver is actually there or the SoC is indeed an OMAP4. Rather do these things only with the right device combination. Fixes booting the BT200 with said configuration enabled and non-factory X-Loader and probably also some surprising behavior on other devices. Fixes: c145649bf262 ("ARM: OMAP2+: Configure voltage controller for cpcap to low-speed") CC: stable@vger.kernel.org Signed-off-by: Andreas Kemnade Reivewed-by: Tony Lindgren Link: https://lore.kernel.org/r/20250331144439.769697-1-andreas@kemnade.info Signed-off-by: Kevin Hilman Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-omap2/pmic-cpcap.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/pmic-cpcap.c b/arch/arm/mach-omap2/pmic-cpcap.c index 668dc84fd31e..527cf4b7e378 100644 --- a/arch/arm/mach-omap2/pmic-cpcap.c +++ b/arch/arm/mach-omap2/pmic-cpcap.c @@ -264,7 +264,11 @@ int __init omap4_cpcap_init(void) static int __init cpcap_late_init(void) { - omap4_vc_set_pmic_signaling(PWRDM_POWER_RET); + if (!of_find_compatible_node(NULL, NULL, "motorola,cpcap")) + return 0; + + if (soc_is_omap443x() || soc_is_omap446x() || soc_is_omap447x()) + omap4_vc_set_pmic_signaling(PWRDM_POWER_RET); return 0; } From 44b9620e82bbec2b9a6ac77f63913636d84f96dc Mon Sep 17 00:00:00 2001 From: Sumit Kumar Date: Wed, 9 Apr 2025 16:17:43 +0530 Subject: [PATCH 452/971] bus: mhi: ep: Update read pointer only after buffer is written commit 6f18d174b73d0ceeaa341f46c0986436b3aefc9a upstream. Inside mhi_ep_ring_add_element, the read pointer (rd_offset) is updated before the buffer is written, potentially causing race conditions where the host sees an updated read pointer before the buffer is actually written. Updating rd_offset prematurely can lead to the host accessing an uninitialized or incomplete element, resulting in data corruption. Invoke the buffer write before updating rd_offset to ensure the element is fully written before signaling its availability. Fixes: bbdcba57a1a2 ("bus: mhi: ep: Add support for ring management") cc: stable@vger.kernel.org Co-developed-by: Youssef Samir Signed-off-by: Youssef Samir Signed-off-by: Sumit Kumar Reviewed-by: Jeff Hugo Reviewed-by: Krishna Chaitanya Chundru Reviewed-by: Manivannan Sadhasivam Link: https://patch.msgid.link/20250409-rp_fix-v1-1-8cf1fa22ed28@quicinc.com Signed-off-by: Manivannan Sadhasivam Signed-off-by: Greg Kroah-Hartman --- drivers/bus/mhi/ep/ring.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/bus/mhi/ep/ring.c b/drivers/bus/mhi/ep/ring.c index ba9f696d1aa8..fedf26392e8d 100644 --- a/drivers/bus/mhi/ep/ring.c +++ b/drivers/bus/mhi/ep/ring.c @@ -131,19 +131,23 @@ int mhi_ep_ring_add_element(struct mhi_ep_ring *ring, struct mhi_ring_element *e } old_offset = ring->rd_offset; - mhi_ep_ring_inc_index(ring); dev_dbg(dev, "Adding an element to ring at offset (%zu)\n", ring->rd_offset); + buf_info.host_addr = ring->rbase + (old_offset * sizeof(*el)); + buf_info.dev_addr = el; + buf_info.size = sizeof(*el); + + ret = mhi_cntrl->write_sync(mhi_cntrl, &buf_info); + if (ret) + return ret; + + mhi_ep_ring_inc_index(ring); /* Update rp in ring context */ rp = cpu_to_le64(ring->rd_offset * sizeof(*el) + ring->rbase); memcpy_toio((void __iomem *) &ring->ring_ctx->generic.rp, &rp, sizeof(u64)); - buf_info.host_addr = ring->rbase + (old_offset * sizeof(*el)); - buf_info.dev_addr = el; - buf_info.size = sizeof(*el); - - return mhi_cntrl->write_sync(mhi_cntrl, &buf_info); + return ret; } void mhi_ep_ring_init(struct mhi_ep_ring *ring, enum mhi_ep_ring_type type, u32 id) From d5d4be47e06cc845697c9e2f8c1dea40120e0d64 Mon Sep 17 00:00:00 2001 From: Jeff Hugo Date: Fri, 28 Mar 2025 10:35:26 -0600 Subject: [PATCH 453/971] bus: mhi: host: Fix conflict between power_up and SYSERR commit 4d92e7c5ccadc79764674ffc2c88d329aabbb7e0 upstream. When mhi_async_power_up() enables IRQs, it is possible that we could receive a SYSERR notification from the device if the firmware has crashed for some reason. Then the SYSERR notification queues a work item that cannot execute until the pm_mutex is released by mhi_async_power_up(). So the SYSERR work item will be pending. If mhi_async_power_up() detects the SYSERR, it will handle it. If the device is in PBL, then the PBL state transition event will be queued, resulting in a work item after the pending SYSERR work item. Once mhi_async_power_up() releases the pm_mutex, the SYSERR work item can run. It will blindly attempt to reset the MHI state machine, which is the recovery action for SYSERR. PBL/SBL are not interrupt driven and will ignore the MHI Reset unless SYSERR is actively advertised. This will cause the SYSERR work item to timeout waiting for reset to be cleared, and will leave the host state in SYSERR processing. The PBL transition work item will then run, and immediately fail because SYSERR processing is not a valid state for PBL transition. This leaves the device uninitialized. This issue has a fairly unique signature in the kernel log: mhi mhi3: Requested to power ON Qualcomm Cloud AI 100 0000:36:00.0: Fatal error received from device. Attempting to recover mhi mhi3: Power on setup success mhi mhi3: Device failed to exit MHI Reset state mhi mhi3: Device MHI is not in valid state We cannot remove the SYSERR handling from mhi_async_power_up() because the device may be in the SYSERR state, but we missed the notification as the irq was fired before irqs were enabled. We also can't queue the SYSERR work item from mhi_async_power_up() if SYSERR is detected because that may result in a duplicate work item, and cause the same issue since the duplicate item will blindly issue MHI reset even if SYSERR is no longer active. Instead, add a check in the SYSERR work item to make sure that MHI reset is only issued if the device is in SYSERR state for PBL or SBL EEs. Fixes: a6e2e3522f29 ("bus: mhi: core: Add support for PM state transitions") Signed-off-by: Jeffrey Hugo Signed-off-by: Jeff Hugo Signed-off-by: Manivannan Sadhasivam Reviewed-by: Troy Hanson Reviewed-by: Manivannan Sadhasivam cc: stable@vger.kernel.org Link: https://patch.msgid.link/20250328163526.3365497-1-jeff.hugo@oss.qualcomm.com Signed-off-by: Greg Kroah-Hartman --- drivers/bus/mhi/host/pm.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index 27f8a40f288c..e48bf44c785c 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -586,6 +586,7 @@ static void mhi_pm_sys_error_transition(struct mhi_controller *mhi_cntrl) struct mhi_cmd *mhi_cmd; struct mhi_event_ctxt *er_ctxt; struct device *dev = &mhi_cntrl->mhi_dev->dev; + bool reset_device = false; int ret, i; dev_dbg(dev, "Transitioning from PM state: %s to: %s\n", @@ -614,8 +615,23 @@ static void mhi_pm_sys_error_transition(struct mhi_controller *mhi_cntrl) /* Wake up threads waiting for state transition */ wake_up_all(&mhi_cntrl->state_event); - /* Trigger MHI RESET so that the device will not access host memory */ if (MHI_REG_ACCESS_VALID(prev_state)) { + /* + * If the device is in PBL or SBL, it will only respond to + * RESET if the device is in SYSERR state. SYSERR might + * already be cleared at this point. + */ + enum mhi_state cur_state = mhi_get_mhi_state(mhi_cntrl); + enum mhi_ee_type cur_ee = mhi_get_exec_env(mhi_cntrl); + + if (cur_state == MHI_STATE_SYS_ERR) + reset_device = true; + else if (cur_ee != MHI_EE_PBL && cur_ee != MHI_EE_SBL) + reset_device = true; + } + + /* Trigger MHI RESET so that the device will not access host memory */ + if (reset_device) { u32 in_reset = -1; unsigned long timeout = msecs_to_jiffies(mhi_cntrl->timeout_ms); From 636391e8c98c1e26113cc1855ed4008213063c18 Mon Sep 17 00:00:00 2001 From: Brett Werling Date: Thu, 12 Jun 2025 14:18:25 -0500 Subject: [PATCH 454/971] can: tcan4x5x: fix power regulator retrieval during probe commit db22720545207f734aaa9d9f71637bfc8b0155e0 upstream. Fixes the power regulator retrieval in tcan4x5x_can_probe() by ensuring the regulator pointer is not set to NULL in the successful return from devm_regulator_get_optional(). Fixes: 3814ca3a10be ("can: tcan4x5x: tcan4x5x_can_probe(): turn on the power before parsing the config") Signed-off-by: Brett Werling Link: https://patch.msgid.link/20250612191825.3646364-1-brett.werling@garmin.com Cc: stable@vger.kernel.org Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/m_can/tcan4x5x-core.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/can/m_can/tcan4x5x-core.c b/drivers/net/can/m_can/tcan4x5x-core.c index ae8c42f5debd..4d440ecfc211 100644 --- a/drivers/net/can/m_can/tcan4x5x-core.c +++ b/drivers/net/can/m_can/tcan4x5x-core.c @@ -385,10 +385,11 @@ static int tcan4x5x_can_probe(struct spi_device *spi) priv = cdev_to_priv(mcan_class); priv->power = devm_regulator_get_optional(&spi->dev, "vsup"); - if (PTR_ERR(priv->power) == -EPROBE_DEFER) { - ret = -EPROBE_DEFER; - goto out_m_can_class_free_dev; - } else { + if (IS_ERR(priv->power)) { + if (PTR_ERR(priv->power) == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; + goto out_m_can_class_free_dev; + } priv->power = NULL; } From 96707ff5818f29926e4dd3626f56035bf7e45b2b Mon Sep 17 00:00:00 2001 From: Dennis Marttinen Date: Thu, 29 May 2025 17:45:12 +0000 Subject: [PATCH 455/971] ceph: set superblock s_magic for IMA fsmagic matching commit 72386d5245b249f5a0a8fabb881df7ad947b8ea4 upstream. The CephFS kernel driver forgets to set the filesystem magic signature in its superblock. As a result, IMA policy rules based on fsmagic matching do not apply as intended. This causes a major performance regression in Talos Linux [1] when mounting CephFS volumes, such as when deploying Rook Ceph [2]. Talos Linux ships a hardened kernel with the following IMA policy (irrelevant lines omitted): [...] dont_measure fsmagic=0xc36400 # CEPH_SUPER_MAGIC [...] measure func=FILE_CHECK mask=^MAY_READ euid=0 measure func=FILE_CHECK mask=^MAY_READ uid=0 [...] Currently, IMA compares 0xc36400 == 0x0 for CephFS files, resulting in all files opened with O_RDONLY or O_RDWR getting measured with SHA512 on every open(2): 10 69990c87e8af323d47e2d6ae4... ima-ng sha512: /data/cephfs/test-file Since O_WRONLY is rare, this results in an order of magnitude lower performance than expected for practically all file operations. Properly setting CEPH_SUPER_MAGIC in the CephFS superblock resolves the regression. Tests performed on a 3x replicated Ceph v19.3.0 cluster across three i5-7200U nodes each equipped with one Micron 7400 MAX M.2 disk (BlueStore) and Gigabit ethernet, on Talos Linux v1.10.2: FS-Mark 3.3 Test: 500 Files, Empty Files/s > Higher Is Better 6.12.27-talos . 16.6 |==== +twelho patch . 208.4 |==================================================== FS-Mark 3.3 Test: 500 Files, 1KB Size Files/s > Higher Is Better 6.12.27-talos . 15.6 |======= +twelho patch . 118.6 |==================================================== FS-Mark 3.3 Test: 500 Files, 32 Sub Dirs, 1MB Size Files/s > Higher Is Better 6.12.27-talos . 12.7 |=============== +twelho patch . 44.7 |===================================================== IO500 [3] 2fcd6d6 results (benchmarks within variance omitted): | IO500 benchmark | 6.12.27-talos | +twelho patch | Speedup | |-------------------|----------------|----------------|-----------| | mdtest-easy-write | 0.018524 kIOPS | 1.135027 kIOPS | 6027.33 % | | mdtest-hard-write | 0.018498 kIOPS | 0.973312 kIOPS | 5161.71 % | | ior-easy-read | 0.064727 GiB/s | 0.155324 GiB/s | 139.97 % | | mdtest-hard-read | 0.018246 kIOPS | 0.780800 kIOPS | 4179.29 % | This applies outside of synthetic benchmarks as well, for example, the time to rsync a 55 MiB directory with ~12k of mostly small files drops from an unusable 10m5s to a reasonable 26s (23x the throughput). [1]: https://www.talos.dev/ [2]: https://www.talos.dev/v1.10/kubernetes-guides/configuration/ceph-with-rook/ [3]: https://github.com/IO500/io500 Cc: stable@vger.kernel.org Signed-off-by: Dennis Marttinen Reviewed-by: Viacheslav Dubeyko Signed-off-by: Ilya Dryomov Signed-off-by: Greg Kroah-Hartman --- fs/ceph/super.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 29026ba4f022..84e855e8929b 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -1220,6 +1220,7 @@ static int ceph_set_super(struct super_block *s, struct fs_context *fc) s->s_time_min = 0; s->s_time_max = U32_MAX; s->s_flags |= SB_NODIRATIME | SB_NOATIME; + s->s_magic = CEPH_SUPER_MAGIC; ceph_fscrypt_set_ops(s); From 48f35a32947b7162cfac9c0027542157c471a655 Mon Sep 17 00:00:00 2001 From: Chen Ridong Date: Wed, 18 Jun 2025 07:32:17 +0000 Subject: [PATCH 456/971] cgroup,freezer: fix incomplete freezing when attaching tasks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 37fb58a7273726e59f9429c89ade5116083a213d upstream. An issue was found: # cd /sys/fs/cgroup/freezer/ # mkdir test # echo FROZEN > test/freezer.state # cat test/freezer.state FROZEN # sleep 1000 & [1] 863 # echo 863 > test/cgroup.procs # cat test/freezer.state FREEZING When tasks are migrated to a frozen cgroup, the freezer fails to immediately freeze the tasks, causing the cgroup to remain in the "FREEZING". The freeze_task() function is called before clearing the CGROUP_FROZEN flag. This causes the freezing() check to incorrectly return false, preventing __freeze_task() from being invoked for the migrated task. To fix this issue, clear the CGROUP_FROZEN state before calling freeze_task(). Fixes: f5d39b020809 ("freezer,sched: Rewrite core freezer logic") Cc: stable@vger.kernel.org # v6.1+ Reported-by: Zhong Jiawei Signed-off-by: Chen Ridong Acked-by: Michal Koutný Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- kernel/cgroup/legacy_freezer.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel/cgroup/legacy_freezer.c b/kernel/cgroup/legacy_freezer.c index 66d1708042a7..a3e13e6d5ee4 100644 --- a/kernel/cgroup/legacy_freezer.c +++ b/kernel/cgroup/legacy_freezer.c @@ -189,13 +189,12 @@ static void freezer_attach(struct cgroup_taskset *tset) if (!(freezer->state & CGROUP_FREEZING)) { __thaw_task(task); } else { - freeze_task(task); - /* clear FROZEN and propagate upwards */ while (freezer && (freezer->state & CGROUP_FROZEN)) { freezer->state &= ~CGROUP_FROZEN; freezer = parent_freezer(freezer); } + freeze_task(task); } } From 8edfed4439b107d62151ff6c075958d169da3e71 Mon Sep 17 00:00:00 2001 From: Tasos Sahanidis Date: Mon, 19 May 2025 11:49:45 +0300 Subject: [PATCH 457/971] ata: pata_via: Force PIO for ATAPI devices on VT6415/VT6330 commit d29fc02caad7f94b62d56ee1b01c954f9c961ba7 upstream. The controller has a hardware bug that can hard hang the system when doing ATAPI DMAs without any trace of what happened. Depending on the device attached, it can also prevent the system from booting. In this case, the system hangs when reading the ATIP from optical media with cdrecord -vvv -atip on an _NEC DVD_RW ND-4571A 1-01 and an Optiarc DVD RW AD-7200A 1.06 attached to an ASRock 990FX Extreme 4, running at UDMA/33. The issue can be reproduced by running the same command with a cygwin build of cdrecord on WinXP, although it requires more attempts to cause it. The hang in that case is also resolved by forcing PIO. It doesn't appear that VIA has produced any drivers for that OS, thus no known workaround exists. HDDs attached to the controller do not suffer from any DMA issues. Cc: stable@vger.kernel.org Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/916677 Signed-off-by: Tasos Sahanidis Link: https://lore.kernel.org/r/20250519085508.1398701-1-tasos@tasossah.com Signed-off-by: Niklas Cassel Signed-off-by: Greg Kroah-Hartman --- drivers/ata/pata_via.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 696b99720dcb..d82728a01832 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -368,7 +368,8 @@ static unsigned int via_mode_filter(struct ata_device *dev, unsigned int mask) } if (dev->class == ATA_DEV_ATAPI && - dmi_check_system(no_atapi_dma_dmi_table)) { + (dmi_check_system(no_atapi_dma_dmi_table) || + config->id == PCI_DEVICE_ID_VIA_6415)) { ata_dev_warn(dev, "controller locks up on ATAPI DMA, forcing PIO\n"); mask &= ATA_MASK_PIO; } From 1e474b5fab51ad731512128ccf81c813949d91ca Mon Sep 17 00:00:00 2001 From: Ioana Ciornei Date: Tue, 8 Apr 2025 13:58:10 +0300 Subject: [PATCH 458/971] bus: fsl-mc: do not add a device-link for the UAPI used DPMCP device commit dd7d8e012b23de158ca0188239c7a1f2a83b4484 upstream. The fsl-mc bus associated to the root DPRC in a DPAA2 system exports a device file for userspace access to the MC firmware. In case the DPRC's local MC portal (DPMCP) is currently in use, a new DPMCP device is allocated through the fsl_mc_portal_allocate() function. In this case, the call to fsl_mc_portal_allocate() will fail with -EINVAL when trying to add a device link between the root DPRC (consumer) and the newly allocated DPMCP device (supplier). This is because the DPMCP is a dependent of the DPRC device (the bus). Fix this by not adding a device link in case the DPMCP is allocated for the root DPRC's usage. Fixes: afb77422819f ("bus: fsl-mc: automatically add a device_link on fsl_mc_[portal,object]_allocate") Signed-off-by: Ioana Ciornei Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20250408105814.2837951-3-ioana.ciornei@nxp.com Signed-off-by: Christophe Leroy Signed-off-by: Greg Kroah-Hartman --- drivers/bus/fsl-mc/mc-io.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/bus/fsl-mc/mc-io.c b/drivers/bus/fsl-mc/mc-io.c index 95b10a6cf307..8b7a34f4db94 100644 --- a/drivers/bus/fsl-mc/mc-io.c +++ b/drivers/bus/fsl-mc/mc-io.c @@ -214,12 +214,19 @@ int __must_check fsl_mc_portal_allocate(struct fsl_mc_device *mc_dev, if (error < 0) goto error_cleanup_resource; - dpmcp_dev->consumer_link = device_link_add(&mc_dev->dev, - &dpmcp_dev->dev, - DL_FLAG_AUTOREMOVE_CONSUMER); - if (!dpmcp_dev->consumer_link) { - error = -EINVAL; - goto error_cleanup_mc_io; + /* If the DPRC device itself tries to allocate a portal (usually for + * UAPI interaction), don't add a device link between them since the + * DPMCP device is an actual child device of the DPRC and a reverse + * dependency is not allowed. + */ + if (mc_dev != mc_bus_dev) { + dpmcp_dev->consumer_link = device_link_add(&mc_dev->dev, + &dpmcp_dev->dev, + DL_FLAG_AUTOREMOVE_CONSUMER); + if (!dpmcp_dev->consumer_link) { + error = -EINVAL; + goto error_cleanup_mc_io; + } } *new_mc_io = mc_io; From 55995f1725980281420227ac8adc1ed7e9ea9d2c Mon Sep 17 00:00:00 2001 From: Wan Junjie Date: Tue, 8 Apr 2025 13:58:11 +0300 Subject: [PATCH 459/971] bus: fsl-mc: fix GET/SET_TAILDROP command ids commit c78230ad34f82c6c0e0e986865073aeeef1f5d30 upstream. Command ids for taildrop get/set can not pass the check when they are using from the restool user space utility. Correct them according to the user manual. Fixes: d67cc29e6d1f ("bus: fsl-mc: list more commands as accepted through the ioctl") Signed-off-by: Wan Junjie Signed-off-by: Ioana Ciornei Cc: stable@vger.kernel.org Reviewed-by: Ioana Ciornei Link: https://lore.kernel.org/r/20250408105814.2837951-4-ioana.ciornei@nxp.com Signed-off-by: Christophe Leroy Signed-off-by: Greg Kroah-Hartman --- drivers/bus/fsl-mc/fsl-mc-uapi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/bus/fsl-mc/fsl-mc-uapi.c b/drivers/bus/fsl-mc/fsl-mc-uapi.c index 9c4c1395fcdb..a376ec661653 100644 --- a/drivers/bus/fsl-mc/fsl-mc-uapi.c +++ b/drivers/bus/fsl-mc/fsl-mc-uapi.c @@ -275,13 +275,13 @@ static struct fsl_mc_cmd_desc fsl_mc_accepted_cmds[] = { .size = 8, }, [DPSW_GET_TAILDROP] = { - .cmdid_value = 0x0A80, + .cmdid_value = 0x0A90, .cmdid_mask = 0xFFF0, .token = true, .size = 14, }, [DPSW_SET_TAILDROP] = { - .cmdid_value = 0x0A90, + .cmdid_value = 0x0A80, .cmdid_mask = 0xFFF0, .token = true, .size = 24, From 26e09d18599da0adc543eabd300080daaeda6869 Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Tue, 15 Apr 2025 11:53:04 -0300 Subject: [PATCH 460/971] ext4: inline: fix len overflow in ext4_prepare_inline_data commit 227cb4ca5a6502164f850d22aec3104d7888b270 upstream. When running the following code on an ext4 filesystem with inline_data feature enabled, it will lead to the bug below. fd = open("file1", O_RDWR | O_CREAT | O_TRUNC, 0666); ftruncate(fd, 30); pwrite(fd, "a", 1, (1UL << 40) + 5UL); That happens because write_begin will succeed as when ext4_generic_write_inline_data calls ext4_prepare_inline_data, pos + len will be truncated, leading to ext4_prepare_inline_data parameter to be 6 instead of 0x10000000006. Then, later when write_end is called, we hit: BUG_ON(pos + len > EXT4_I(inode)->i_inline_size); at ext4_write_inline_data. Fix it by using a loff_t type for the len parameter in ext4_prepare_inline_data instead of an unsigned int. [ 44.545164] ------------[ cut here ]------------ [ 44.545530] kernel BUG at fs/ext4/inline.c:240! [ 44.545834] Oops: invalid opcode: 0000 [#1] SMP NOPTI [ 44.546172] CPU: 3 UID: 0 PID: 343 Comm: test Not tainted 6.15.0-rc2-00003-g9080916f4863 #45 PREEMPT(full) 112853fcebfdb93254270a7959841d2c6aa2c8bb [ 44.546523] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 [ 44.546523] RIP: 0010:ext4_write_inline_data+0xfe/0x100 [ 44.546523] Code: 3c 0e 48 83 c7 48 48 89 de 5b 41 5c 41 5d 41 5e 41 5f 5d e9 e4 fa 43 01 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc cc cc cc cc 0f 0b <0f> 0b 0f 1f 44 00 00 55 41 57 41 56 41 55 41 54 53 48 83 ec 20 49 [ 44.546523] RSP: 0018:ffffb342008b79a8 EFLAGS: 00010216 [ 44.546523] RAX: 0000000000000001 RBX: ffff9329c579c000 RCX: 0000010000000006 [ 44.546523] RDX: 000000000000003c RSI: ffffb342008b79f0 RDI: ffff9329c158e738 [ 44.546523] RBP: 0000000000000001 R08: 0000000000000001 R09: 0000000000000000 [ 44.546523] R10: 00007ffffffff000 R11: ffffffff9bd0d910 R12: 0000006210000000 [ 44.546523] R13: fffffc7e4015e700 R14: 0000010000000005 R15: ffff9329c158e738 [ 44.546523] FS: 00007f4299934740(0000) GS:ffff932a60179000(0000) knlGS:0000000000000000 [ 44.546523] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 44.546523] CR2: 00007f4299a1ec90 CR3: 0000000002886002 CR4: 0000000000770eb0 [ 44.546523] PKRU: 55555554 [ 44.546523] Call Trace: [ 44.546523] [ 44.546523] ext4_write_inline_data_end+0x126/0x2d0 [ 44.546523] generic_perform_write+0x17e/0x270 [ 44.546523] ext4_buffered_write_iter+0xc8/0x170 [ 44.546523] vfs_write+0x2be/0x3e0 [ 44.546523] __x64_sys_pwrite64+0x6d/0xc0 [ 44.546523] do_syscall_64+0x6a/0xf0 [ 44.546523] ? __wake_up+0x89/0xb0 [ 44.546523] ? xas_find+0x72/0x1c0 [ 44.546523] ? next_uptodate_folio+0x317/0x330 [ 44.546523] ? set_pte_range+0x1a6/0x270 [ 44.546523] ? filemap_map_pages+0x6ee/0x840 [ 44.546523] ? ext4_setattr+0x2fa/0x750 [ 44.546523] ? do_pte_missing+0x128/0xf70 [ 44.546523] ? security_inode_post_setattr+0x3e/0xd0 [ 44.546523] ? ___pte_offset_map+0x19/0x100 [ 44.546523] ? handle_mm_fault+0x721/0xa10 [ 44.546523] ? do_user_addr_fault+0x197/0x730 [ 44.546523] ? do_syscall_64+0x76/0xf0 [ 44.546523] ? arch_exit_to_user_mode_prepare+0x1e/0x60 [ 44.546523] ? irqentry_exit_to_user_mode+0x79/0x90 [ 44.546523] entry_SYSCALL_64_after_hwframe+0x55/0x5d [ 44.546523] RIP: 0033:0x7f42999c6687 [ 44.546523] Code: 48 89 fa 4c 89 df e8 58 b3 00 00 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> c3 0f 1f 80 00 00 00 00 83 e2 39 83 fa 08 75 de e8 23 ff ff ff [ 44.546523] RSP: 002b:00007ffeae4a7930 EFLAGS: 00000202 ORIG_RAX: 0000000000000012 [ 44.546523] RAX: ffffffffffffffda RBX: 00007f4299934740 RCX: 00007f42999c6687 [ 44.546523] RDX: 0000000000000001 RSI: 000055ea6149200f RDI: 0000000000000003 [ 44.546523] RBP: 00007ffeae4a79a0 R08: 0000000000000000 R09: 0000000000000000 [ 44.546523] R10: 0000010000000005 R11: 0000000000000202 R12: 0000000000000000 [ 44.546523] R13: 00007ffeae4a7ac8 R14: 00007f4299b86000 R15: 000055ea61493dd8 [ 44.546523] [ 44.546523] Modules linked in: [ 44.568501] ---[ end trace 0000000000000000 ]--- [ 44.568889] RIP: 0010:ext4_write_inline_data+0xfe/0x100 [ 44.569328] Code: 3c 0e 48 83 c7 48 48 89 de 5b 41 5c 41 5d 41 5e 41 5f 5d e9 e4 fa 43 01 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc cc cc cc cc 0f 0b <0f> 0b 0f 1f 44 00 00 55 41 57 41 56 41 55 41 54 53 48 83 ec 20 49 [ 44.570931] RSP: 0018:ffffb342008b79a8 EFLAGS: 00010216 [ 44.571356] RAX: 0000000000000001 RBX: ffff9329c579c000 RCX: 0000010000000006 [ 44.571959] RDX: 000000000000003c RSI: ffffb342008b79f0 RDI: ffff9329c158e738 [ 44.572571] RBP: 0000000000000001 R08: 0000000000000001 R09: 0000000000000000 [ 44.573148] R10: 00007ffffffff000 R11: ffffffff9bd0d910 R12: 0000006210000000 [ 44.573748] R13: fffffc7e4015e700 R14: 0000010000000005 R15: ffff9329c158e738 [ 44.574335] FS: 00007f4299934740(0000) GS:ffff932a60179000(0000) knlGS:0000000000000000 [ 44.575027] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 44.575520] CR2: 00007f4299a1ec90 CR3: 0000000002886002 CR4: 0000000000770eb0 [ 44.576112] PKRU: 55555554 [ 44.576338] Kernel panic - not syncing: Fatal exception [ 44.576517] Kernel Offset: 0x1a600000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) Reported-by: syzbot+fe2a25dae02a207717a0@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=fe2a25dae02a207717a0 Fixes: f19d5870cbf7 ("ext4: add normal write support for inline data") Signed-off-by: Thadeu Lima de Souza Cascardo Cc: stable@vger.kernel.org Reviewed-by: Jan Kara Reviewed-by: Andreas Dilger Link: https://patch.msgid.link/20250415-ext4-prepare-inline-overflow-v1-1-f4c13d900967@igalia.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/inline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 3f363276ddd3..c85647a0ba09 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -392,7 +392,7 @@ out: } static int ext4_prepare_inline_data(handle_t *handle, struct inode *inode, - unsigned int len) + loff_t len) { int ret, size, no_expand; struct ext4_inode_info *ei = EXT4_I(inode); From 223091c9897cf6d33bbb139b5bcabb80ba4df378 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 29 Apr 2025 19:55:36 +0200 Subject: [PATCH 461/971] ext4: fix calculation of credits for extent tree modification commit 32a93f5bc9b9812fc710f43a4d8a6830f91e4988 upstream. Luis and David are reporting that after running generic/750 test for 90+ hours on 2k ext4 filesystem, they are able to trigger a warning in jbd2_journal_dirty_metadata() complaining that there are not enough credits in the running transaction started in ext4_do_writepages(). Indeed the code in ext4_do_writepages() is racy and the extent tree can change between the time we compute credits necessary for extent tree computation and the time we actually modify the extent tree. Thus it may happen that the number of credits actually needed is higher. Modify ext4_ext_index_trans_blocks() to count with the worst case of maximum tree depth. This can reduce the possible number of writers that can operate in the system in parallel (because the credit estimates now won't fit in one transaction) but for reasonably sized journals this shouldn't really be an issue. So just go with a safe and simple fix. Link: https://lore.kernel.org/all/20250415013641.f2ppw6wov4kn4wq2@offworld Reported-by: Davidlohr Bueso Reported-by: Luis Chamberlain Tested-by: kdevops@lists.linux.dev Signed-off-by: Jan Kara Reviewed-by: Zhang Yi Link: https://patch.msgid.link/20250429175535.23125-2-jack@suse.cz Signed-off-by: Theodore Ts'o Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman --- fs/ext4/extents.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 39e3661a80c4..824d95c19564 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2374,18 +2374,19 @@ int ext4_ext_calc_credits_for_single_extent(struct inode *inode, int nrblocks, int ext4_ext_index_trans_blocks(struct inode *inode, int extents) { int index; - int depth; /* If we are converting the inline data, only one is needed here. */ if (ext4_has_inline_data(inode)) return 1; - depth = ext_depth(inode); - + /* + * Extent tree can change between the time we estimate credits and + * the time we actually modify the tree. Assume the worst case. + */ if (extents <= 1) - index = depth * 2; + index = EXT4_MAX_EXTENT_DEPTH * 2; else - index = depth * 3; + index = EXT4_MAX_EXTENT_DEPTH * 3; return index; } From 68cea04f1fb2ead5e10e1be8be98cb1cb24334ba Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Tue, 6 May 2025 09:20:08 +0800 Subject: [PATCH 462/971] ext4: factor out ext4_get_maxbytes() commit dbe27f06fa38b9bfc598f8864ae1c5d5831d9992 upstream. There are several locations that get the correct maxbytes value based on the inode's block type. It would be beneficial to extract a common helper function to make the code more clear. Signed-off-by: Zhang Yi Reviewed-by: Jan Kara Reviewed-by: Baokun Li Link: https://patch.msgid.link/20250506012009.3896990-3-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman --- fs/ext4/ext4.h | 7 +++++++ fs/ext4/extents.c | 7 +------ fs/ext4/file.c | 7 +------ 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 81fe87fcbfa0..b55d5e2abeb3 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -3351,6 +3351,13 @@ static inline unsigned int ext4_flex_bg_size(struct ext4_sb_info *sbi) return 1 << sbi->s_log_groups_per_flex; } +static inline loff_t ext4_get_maxbytes(struct inode *inode) +{ + if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) + return inode->i_sb->s_maxbytes; + return EXT4_SB(inode->i_sb)->s_bitmap_maxbytes; +} + #define ext4_std_error(sb, errno) \ do { \ if ((errno)) \ diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 824d95c19564..a3d3c9fc6426 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4970,12 +4970,7 @@ static const struct iomap_ops ext4_iomap_xattr_ops = { static int ext4_fiemap_check_ranges(struct inode *inode, u64 start, u64 *len) { - u64 maxbytes; - - if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) - maxbytes = inode->i_sb->s_maxbytes; - else - maxbytes = EXT4_SB(inode->i_sb)->s_bitmap_maxbytes; + u64 maxbytes = ext4_get_maxbytes(inode); if (*len == 0) return -EINVAL; diff --git a/fs/ext4/file.c b/fs/ext4/file.c index c71af675e310..b37e0e4a71bf 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -898,12 +898,7 @@ static int ext4_file_open(struct inode *inode, struct file *filp) loff_t ext4_llseek(struct file *file, loff_t offset, int whence) { struct inode *inode = file->f_mapping->host; - loff_t maxbytes; - - if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) - maxbytes = EXT4_SB(inode->i_sb)->s_bitmap_maxbytes; - else - maxbytes = inode->i_sb->s_maxbytes; + loff_t maxbytes = ext4_get_maxbytes(inode); switch (whence) { default: From 3e8a5163bcd3d92d4fc3a3116e6eeb67fcdded60 Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Tue, 6 May 2025 09:20:09 +0800 Subject: [PATCH 463/971] ext4: ensure i_size is smaller than maxbytes commit 1a77a028a392fab66dd637cdfac3f888450d00af upstream. The inode i_size cannot be larger than maxbytes, check it while loading inode from the disk. Signed-off-by: Zhang Yi Reviewed-by: Jan Kara Reviewed-by: Baokun Li Link: https://patch.msgid.link/20250506012009.3896990-4-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman --- fs/ext4/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 86245e27be18..aff82042e3f8 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4939,7 +4939,8 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, ei->i_file_acl |= ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32; inode->i_size = ext4_isize(sb, raw_inode); - if ((size = i_size_read(inode)) < 0) { + size = i_size_read(inode); + if (size < 0 || size > ext4_get_maxbytes(inode)) { ext4_error_inode(inode, function, line, 0, "iget: bad i_size value: %lld", size); ret = -EFSCORRUPTED; From cf6a4c4ac7b6e3214f25df594c9689a62f1bb456 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Fri, 16 May 2025 13:38:00 -0400 Subject: [PATCH 464/971] ext4: only dirty folios when data journaling regular files commit e26268ff1dcae5662c1b96c35f18cfa6ab73d9de upstream. fstest generic/388 occasionally reproduces a crash that looks as follows: BUG: kernel NULL pointer dereference, address: 0000000000000000 ... Call Trace: ext4_block_zero_page_range+0x30c/0x380 [ext4] ext4_truncate+0x436/0x440 [ext4] ext4_process_orphan+0x5d/0x110 [ext4] ext4_orphan_cleanup+0x124/0x4f0 [ext4] ext4_fill_super+0x262d/0x3110 [ext4] get_tree_bdev_flags+0x132/0x1d0 vfs_get_tree+0x26/0xd0 vfs_cmd_create+0x59/0xe0 __do_sys_fsconfig+0x4ed/0x6b0 do_syscall_64+0x82/0x170 ... This occurs when processing a symlink inode from the orphan list. The partial block zeroing code in the truncate path calls ext4_dirty_journalled_data() -> folio_mark_dirty(). The latter calls mapping->a_ops->dirty_folio(), but symlink inodes are not assigned an a_ops vector in ext4, hence the crash. To avoid this problem, update the ext4_dirty_journalled_data() helper to only mark the folio dirty on regular files (for which a_ops is assigned). This also matches the journaling logic in the ext4_symlink() creation path, where ext4_handle_dirty_metadata() is called directly. Fixes: d84c9ebdac1e ("ext4: Mark pages with journalled data dirty") Signed-off-by: Brian Foster Link: https://patch.msgid.link/20250516173800.175577-1-bfoster@redhat.com Signed-off-by: Theodore Ts'o Reviewed-by: Jan Kara Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman --- fs/ext4/inode.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index aff82042e3f8..9694ef6b996e 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1011,7 +1011,12 @@ int ext4_walk_page_buffers(handle_t *handle, struct inode *inode, */ static int ext4_dirty_journalled_data(handle_t *handle, struct buffer_head *bh) { - folio_mark_dirty(bh->b_folio); + struct folio *folio = bh->b_folio; + struct inode *inode = folio->mapping->host; + + /* only regular files have a_ops */ + if (S_ISREG(inode->i_mode)) + folio_mark_dirty(folio); return ext4_handle_dirty_metadata(handle, NULL, bh); } From 17474a56acf708bf6b2d174c06ed26abad0a9fd6 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 30 May 2025 16:13:32 -0700 Subject: [PATCH 465/971] Input: ims-pcu - check record size in ims_pcu_flash_firmware() commit a95ef0199e80f3384eb992889322957d26c00102 upstream. The "len" variable comes from the firmware and we generally do trust firmware, but it's always better to double check. If the "len" is too large it could result in memory corruption when we do "memcpy(fragment->data, rec->data, len);" Fixes: 628329d52474 ("Input: add IMS Passenger Control Unit driver") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/131fd1ae92c828ee9f4fa2de03d8c210ae1f3524.1748463049.git.dan.carpenter@linaro.org Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/misc/ims-pcu.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c index 180d90e46061..5cfe9b56978d 100644 --- a/drivers/input/misc/ims-pcu.c +++ b/drivers/input/misc/ims-pcu.c @@ -845,6 +845,12 @@ static int ims_pcu_flash_firmware(struct ims_pcu *pcu, addr = be32_to_cpu(rec->addr) / 2; len = be16_to_cpu(rec->len); + if (len > sizeof(pcu->cmd_buf) - 1 - sizeof(*fragment)) { + dev_err(pcu->dev, + "Invalid record length in firmware: %d\n", len); + return -EINVAL; + } + fragment = (void *)&pcu->cmd_buf[1]; put_unaligned_le32(addr, &fragment->addr); fragment->len = len; From 0f7100e8d9f0f0396a922f0f267cd60a8c4beecc Mon Sep 17 00:00:00 2001 From: Gatien Chevallier Date: Fri, 30 May 2025 16:09:23 -0700 Subject: [PATCH 466/971] Input: gpio-keys - fix possible concurrent access in gpio_keys_irq_timer() commit 8f38219fa139623c29db2cb0f17d0a197a86e344 upstream. gpio_keys_irq_isr() and gpio_keys_irq_timer() access the same resources. There could be a concurrent access if a GPIO interrupt occurs in parallel of a HR timer interrupt. Guard back those resources with a spinlock. Fixes: 019002f20cb5 ("Input: gpio-keys - use hrtimer for release timer") Signed-off-by: Gatien Chevallier Link: https://lore.kernel.org/r/20250528-gpio_keys_preempt_rt-v2-2-3fc55a9c3619@foss.st.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/keyboard/gpio_keys.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 2e7c2c046e67..c5f4207fddce 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -455,6 +455,8 @@ static enum hrtimer_restart gpio_keys_irq_timer(struct hrtimer *t) release_timer); struct input_dev *input = bdata->input; + guard(spinlock_irqsave)(&bdata->lock); + if (bdata->key_pressed) { input_report_key(input, *bdata->code, 0); input_sync(input); From aaddc6c696bd1bff20eaacfa88579d6eae64d541 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Mon, 24 Mar 2025 13:33:39 +0800 Subject: [PATCH 467/971] f2fs: fix to do sanity check on ino and xnid commit 061cf3a84bde038708eb0f1d065b31b7c2456533 upstream. syzbot reported a f2fs bug as below: INFO: task syz-executor140:5308 blocked for more than 143 seconds. Not tainted 6.14.0-rc7-syzkaller-00069-g81e4f8d68c66 #0 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. task:syz-executor140 state:D stack:24016 pid:5308 tgid:5308 ppid:5306 task_flags:0x400140 flags:0x00000006 Call Trace: context_switch kernel/sched/core.c:5378 [inline] __schedule+0x190e/0x4c90 kernel/sched/core.c:6765 __schedule_loop kernel/sched/core.c:6842 [inline] schedule+0x14b/0x320 kernel/sched/core.c:6857 io_schedule+0x8d/0x110 kernel/sched/core.c:7690 folio_wait_bit_common+0x839/0xee0 mm/filemap.c:1317 __folio_lock mm/filemap.c:1664 [inline] folio_lock include/linux/pagemap.h:1163 [inline] __filemap_get_folio+0x147/0xb40 mm/filemap.c:1917 pagecache_get_page+0x2c/0x130 mm/folio-compat.c:87 find_get_page_flags include/linux/pagemap.h:842 [inline] f2fs_grab_cache_page+0x2b/0x320 fs/f2fs/f2fs.h:2776 __get_node_page+0x131/0x11b0 fs/f2fs/node.c:1463 read_xattr_block+0xfb/0x190 fs/f2fs/xattr.c:306 lookup_all_xattrs fs/f2fs/xattr.c:355 [inline] f2fs_getxattr+0x676/0xf70 fs/f2fs/xattr.c:533 __f2fs_get_acl+0x52/0x870 fs/f2fs/acl.c:179 f2fs_acl_create fs/f2fs/acl.c:375 [inline] f2fs_init_acl+0xd7/0x9b0 fs/f2fs/acl.c:418 f2fs_init_inode_metadata+0xa0f/0x1050 fs/f2fs/dir.c:539 f2fs_add_inline_entry+0x448/0x860 fs/f2fs/inline.c:666 f2fs_add_dentry+0xba/0x1e0 fs/f2fs/dir.c:765 f2fs_do_add_link+0x28c/0x3a0 fs/f2fs/dir.c:808 f2fs_add_link fs/f2fs/f2fs.h:3616 [inline] f2fs_mknod+0x2e8/0x5b0 fs/f2fs/namei.c:766 vfs_mknod+0x36d/0x3b0 fs/namei.c:4191 unix_bind_bsd net/unix/af_unix.c:1286 [inline] unix_bind+0x563/0xe30 net/unix/af_unix.c:1379 __sys_bind_socket net/socket.c:1817 [inline] __sys_bind+0x1e4/0x290 net/socket.c:1848 __do_sys_bind net/socket.c:1853 [inline] __se_sys_bind net/socket.c:1851 [inline] __x64_sys_bind+0x7a/0x90 net/socket.c:1851 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 Let's dump and check metadata of corrupted inode, it shows its xattr_nid is the same to its i_ino. dump.f2fs -i 3 chaseyu.img.raw i_xattr_nid [0x 3 : 3] So that, during mknod in the corrupted directory, it tries to get and lock inode page twice, result in deadlock. - f2fs_mknod - f2fs_add_inline_entry - f2fs_get_inode_page --- lock dir's inode page - f2fs_init_acl - f2fs_acl_create(dir,..) - __f2fs_get_acl - f2fs_getxattr - lookup_all_xattrs - __get_node_page --- try to lock dir's inode page In order to fix this, let's add sanity check on ino and xnid. Cc: stable@vger.kernel.org Reported-by: syzbot+cc448dcdc7ae0b4e4ffa@syzkaller.appspotmail.com Closes: https://lore.kernel.org/linux-f2fs-devel/67e06150.050a0220.21942d.0005.GAE@google.com Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Greg Kroah-Hartman --- fs/f2fs/inode.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 06941705e893..21d3eabe95e0 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -285,6 +285,12 @@ static bool sanity_check_inode(struct inode *inode, struct page *node_page) return false; } + if (ino_of_node(node_page) == fi->i_xattr_nid) { + f2fs_warn(sbi, "%s: corrupted inode i_ino=%lx, xnid=%x, run fsck to fix.", + __func__, inode->i_ino, fi->i_xattr_nid); + return false; + } + if (f2fs_has_extra_attr(inode)) { if (!f2fs_sb_has_extra_attr(sbi)) { f2fs_warn(sbi, "%s: inode (ino=%lx) is with extra_attr, but extra_attr feature is off", From a87cbcc909ccfd394d4936a94663f586453d0961 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Sat, 12 Apr 2025 21:09:46 +0000 Subject: [PATCH 468/971] f2fs: prevent kernel warning due to negative i_nlink from corrupted image commit 42cb74a92adaf88061039601ddf7c874f58b554e upstream. WARNING: CPU: 1 PID: 9426 at fs/inode.c:417 drop_nlink+0xac/0xd0 home/cc/linux/fs/inode.c:417 Modules linked in: CPU: 1 UID: 0 PID: 9426 Comm: syz-executor568 Not tainted 6.14.0-12627-g94d471a4f428 #2 PREEMPT(full) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014 RIP: 0010:drop_nlink+0xac/0xd0 home/cc/linux/fs/inode.c:417 Code: 48 8b 5d 28 be 08 00 00 00 48 8d bb 70 07 00 00 e8 f9 67 e6 ff f0 48 ff 83 70 07 00 00 5b 5d e9 9a 12 82 ff e8 95 12 82 ff 90 <0f> 0b 90 c7 45 48 ff ff ff ff 5b 5d e9 83 12 82 ff e8 fe 5f e6 ff RSP: 0018:ffffc900026b7c28 EFLAGS: 00010293 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffff8239710f RDX: ffff888041345a00 RSI: ffffffff8239717b RDI: 0000000000000005 RBP: ffff888054509ad0 R08: 0000000000000005 R09: 0000000000000000 R10: 0000000000000000 R11: ffffffff9ab36f08 R12: ffff88804bb40000 R13: ffff8880545091e0 R14: 0000000000008000 R15: ffff8880545091e0 FS: 000055555d0c5880(0000) GS:ffff8880eb3e3000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f915c55b178 CR3: 0000000050d20000 CR4: 0000000000352ef0 Call Trace: f2fs_i_links_write home/cc/linux/fs/f2fs/f2fs.h:3194 [inline] f2fs_drop_nlink+0xd1/0x3c0 home/cc/linux/fs/f2fs/dir.c:845 f2fs_delete_entry+0x542/0x1450 home/cc/linux/fs/f2fs/dir.c:909 f2fs_unlink+0x45c/0x890 home/cc/linux/fs/f2fs/namei.c:581 vfs_unlink+0x2fb/0x9b0 home/cc/linux/fs/namei.c:4544 do_unlinkat+0x4c5/0x6a0 home/cc/linux/fs/namei.c:4608 __do_sys_unlink home/cc/linux/fs/namei.c:4654 [inline] __se_sys_unlink home/cc/linux/fs/namei.c:4652 [inline] __x64_sys_unlink+0xc5/0x110 home/cc/linux/fs/namei.c:4652 do_syscall_x64 home/cc/linux/arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xc7/0x250 home/cc/linux/arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7fb3d092324b Code: 73 01 c3 48 c7 c1 c0 ff ff ff f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 57 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 c0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007ffdc232d938 EFLAGS: 00000206 ORIG_RAX: 0000000000000057 RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fb3d092324b RDX: 00007ffdc232d960 RSI: 00007ffdc232d960 RDI: 00007ffdc232d9f0 RBP: 00007ffdc232d9f0 R08: 0000000000000001 R09: 00007ffdc232d7c0 R10: 00000000fffffffd R11: 0000000000000206 R12: 00007ffdc232eaf0 R13: 000055555d0cebb0 R14: 00007ffdc232d958 R15: 0000000000000001 Cc: stable@vger.kernel.org Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Greg Kroah-Hartman --- fs/f2fs/namei.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 4d6f0a6365fe..523009bc2732 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -560,6 +560,15 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry) goto fail; } + if (unlikely(inode->i_nlink == 0)) { + f2fs_warn(F2FS_I_SB(inode), "%s: inode (ino=%lx) has zero i_nlink", + __func__, inode->i_ino); + err = -EFSCORRUPTED; + set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK); + f2fs_put_page(page, 0); + goto fail; + } + f2fs_balance_fs(sbi, true); f2fs_lock_op(sbi); From 79ef8a6c4ec53d327580fd7d2b522cf4f1d05b0c Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Mon, 14 Apr 2025 18:55:20 +0800 Subject: [PATCH 469/971] f2fs: fix to do sanity check on sit_bitmap_size commit 5db0d252c64e91ba1929c70112352e85dc5751e7 upstream. w/ below testcase, resize will generate a corrupted image which contains inconsistent metadata, so when mounting such image, it will trigger kernel panic: touch img truncate -s $((512*1024*1024*1024)) img mkfs.f2fs -f img $((256*1024*1024)) resize.f2fs -s -i img -t $((1024*1024*1024)) mount img /mnt/f2fs ------------[ cut here ]------------ kernel BUG at fs/f2fs/segment.h:863! Oops: invalid opcode: 0000 [#1] SMP PTI CPU: 11 UID: 0 PID: 3922 Comm: mount Not tainted 6.15.0-rc1+ #191 PREEMPT(voluntary) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 RIP: 0010:f2fs_ra_meta_pages+0x47c/0x490 Call Trace: f2fs_build_segment_manager+0x11c3/0x2600 f2fs_fill_super+0xe97/0x2840 mount_bdev+0xf4/0x140 legacy_get_tree+0x2b/0x50 vfs_get_tree+0x29/0xd0 path_mount+0x487/0xaf0 __x64_sys_mount+0x116/0x150 do_syscall_64+0x82/0x190 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7fdbfde1bcfe The reaseon is: sit_i->bitmap_size is 192, so size of sit bitmap is 192*8=1536, at maximum there are 1536 sit blocks, however MAIN_SEGS is 261893, so that sit_blk_cnt is 4762, build_sit_entries() -> current_sit_addr() tries to access out-of-boundary in sit_bitmap at offset from [1536, 4762), once sit_bitmap and sit_bitmap_mirror is not the same, it will trigger f2fs_bug_on(). Let's add sanity check in f2fs_sanity_check_ckpt() to avoid panic. Cc: stable@vger.kernel.org Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Greg Kroah-Hartman --- fs/f2fs/super.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 6b3cafbe9867..50170e7cf3f9 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -3608,6 +3608,7 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi) block_t user_block_count, valid_user_blocks; block_t avail_node_count, valid_node_count; unsigned int nat_blocks, nat_bits_bytes, nat_bits_blocks; + unsigned int sit_blk_cnt; int i, j; total = le32_to_cpu(raw_super->segment_count); @@ -3719,6 +3720,13 @@ skip_cross: return 1; } + sit_blk_cnt = DIV_ROUND_UP(main_segs, SIT_ENTRY_PER_BLOCK); + if (sit_bitmap_size * 8 < sit_blk_cnt) { + f2fs_err(sbi, "Wrong bitmap size: sit: %u, sit_blk_cnt:%u", + sit_bitmap_size, sit_blk_cnt); + return 1; + } + cp_pack_start_sum = __start_sum_addr(sbi); cp_payload = __cp_payload(sbi); if (cp_pack_start_sum < cp_payload + 1 || From d95d87841d2a575bed3691884e8fedef57d7710d Mon Sep 17 00:00:00 2001 From: Gui-Dong Han Date: Fri, 6 Jun 2025 07:16:40 +0000 Subject: [PATCH 470/971] hwmon: (ftsteutates) Fix TOCTOU race in fts_read() commit 14c9ede9ca4cd078ad76a6ab9617b81074eb58bf upstream. In the fts_read() function, when handling hwmon_pwm_auto_channels_temp, the code accesses the shared variable data->fan_source[channel] twice without holding any locks. It is first checked against FTS_FAN_SOURCE_INVALID, and if the check passes, it is read again when used as an argument to the BIT() macro. This creates a Time-of-Check to Time-of-Use (TOCTOU) race condition. Another thread executing fts_update_device() can modify the value of data->fan_source[channel] between the check and its use. If the value is changed to FTS_FAN_SOURCE_INVALID (0xff) during this window, the BIT() macro will be called with a large shift value (BIT(255)). A bit shift by a value greater than or equal to the type width is undefined behavior and can lead to a crash or incorrect values being returned to userspace. Fix this by reading data->fan_source[channel] into a local variable once, eliminating the race condition. Additionally, add a bounds check to ensure the value is less than BITS_PER_LONG before passing it to the BIT() macro, making the code more robust against undefined behavior. This possible bug was found by an experimental static analysis tool developed by our team. Fixes: 1c5759d8ce05 ("hwmon: (ftsteutates) Replace fanX_source with pwmX_auto_channels_temp") Cc: stable@vger.kernel.org Signed-off-by: Gui-Dong Han Link: https://lore.kernel.org/r/20250606071640.501262-1-hanguidong02@gmail.com Signed-off-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/ftsteutates.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/ftsteutates.c b/drivers/hwmon/ftsteutates.c index b74a2665e733..27e5dd94b04f 100644 --- a/drivers/hwmon/ftsteutates.c +++ b/drivers/hwmon/ftsteutates.c @@ -423,13 +423,16 @@ static int fts_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, break; case hwmon_pwm: switch (attr) { - case hwmon_pwm_auto_channels_temp: - if (data->fan_source[channel] == FTS_FAN_SOURCE_INVALID) + case hwmon_pwm_auto_channels_temp: { + u8 fan_source = data->fan_source[channel]; + + if (fan_source == FTS_FAN_SOURCE_INVALID || fan_source >= BITS_PER_LONG) *val = 0; else - *val = BIT(data->fan_source[channel]); + *val = BIT(fan_source); return 0; + } default: break; } From a8acc7080ad55c5402a1b818b3008998247dda87 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 18 Jun 2025 09:36:50 +0200 Subject: [PATCH 471/971] NFC: nci: uart: Set tty->disc_data only in success path commit fc27ab48904ceb7e4792f0c400f1ef175edf16fe upstream. Setting tty->disc_data before opening the NCI device means we need to clean it up on error paths. This also opens some short window if device starts sending data, even before NCIUARTSETDRIVER IOCTL succeeded (broken hardware?). Close the window by exposing tty->disc_data only on the success path, when opening of the NCI device and try_module_get() succeeds. The code differs in error path in one aspect: tty->disc_data won't be ever assigned thus NULL-ified. This however should not be relevant difference, because of "tty->disc_data=NULL" in nci_uart_tty_open(). Cc: Linus Torvalds Fixes: 9961127d4bce ("NFC: nci: add generic uart support") Cc: Signed-off-by: Krzysztof Kozlowski Reviewed-by: Greg Kroah-Hartman Link: https://patch.msgid.link/20250618073649.25049-2-krzysztof.kozlowski@linaro.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/nfc/nci/uart.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/nfc/nci/uart.c b/net/nfc/nci/uart.c index ed1508a9e093..aab107727f18 100644 --- a/net/nfc/nci/uart.c +++ b/net/nfc/nci/uart.c @@ -119,22 +119,22 @@ static int nci_uart_set_driver(struct tty_struct *tty, unsigned int driver) memcpy(nu, nci_uart_drivers[driver], sizeof(struct nci_uart)); nu->tty = tty; - tty->disc_data = nu; skb_queue_head_init(&nu->tx_q); INIT_WORK(&nu->write_work, nci_uart_write_work); spin_lock_init(&nu->rx_lock); ret = nu->ops.open(nu); if (ret) { - tty->disc_data = NULL; kfree(nu); + return ret; } else if (!try_module_get(nu->owner)) { nu->ops.close(nu); - tty->disc_data = NULL; kfree(nu); return -ENOENT; } - return ret; + tty->disc_data = nu; + + return 0; } /* ------ LDISC part ------ */ From 8c5713ce1ced75f9e9ed5c642ea3d2ba06ead69c Mon Sep 17 00:00:00 2001 From: Hyunwoo Kim Date: Fri, 13 Jun 2025 20:54:57 -0400 Subject: [PATCH 472/971] net/sched: fix use-after-free in taprio_dev_notifier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit b160766e26d4e2e2d6fe2294e0b02f92baefcec5 upstream. Since taprio’s taprio_dev_notifier() isn’t protected by an RCU read-side critical section, a race with advance_sched() can lead to a use-after-free. Adding rcu_read_lock() inside taprio_dev_notifier() prevents this. Fixes: fed87cc6718a ("net/sched: taprio: automatically calculate queueMaxSDU based on TC gate durations") Cc: stable@vger.kernel.org Signed-off-by: Hyunwoo Kim Reviewed-by: Simon Horman Reviewed-by: Eric Dumazet Link: https://patch.msgid.link/aEzIYYxt0is9upYG@v4bel-B760M-AORUS-ELITE-AX Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/sched/sch_taprio.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index 951a87909c29..d162e2dd8602 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -1338,13 +1338,15 @@ static int taprio_dev_notifier(struct notifier_block *nb, unsigned long event, stab = rtnl_dereference(q->root->stab); - oper = rtnl_dereference(q->oper_sched); + rcu_read_lock(); + oper = rcu_dereference(q->oper_sched); if (oper) taprio_update_queue_max_sdu(q, oper, stab); - admin = rtnl_dereference(q->admin_sched); + admin = rcu_dereference(q->admin_sched); if (admin) taprio_update_queue_max_sdu(q, admin, stab); + rcu_read_unlock(); break; } From 061a5dd66608ccbccb9e046f046dbae95ee81084 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 17 Jun 2025 20:20:17 +0200 Subject: [PATCH 473/971] net: ftgmac100: select FIXED_PHY commit ae409629e022fbebbc6d31a1bfeccdbbeee20fd6 upstream. Depending on e.g. DT configuration this driver uses a fixed link. So we shouldn't rely on the user to enable FIXED_PHY, select it in Kconfig instead. We may end up with a non-functional driver otherwise. Fixes: 38561ded50d0 ("net: ftgmac100: support fixed link") Cc: stable@vger.kernel.org Signed-off-by: Heiner Kallweit Link: https://patch.msgid.link/476bb33b-5584-40f0-826a-7294980f2895@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/faraday/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/faraday/Kconfig b/drivers/net/ethernet/faraday/Kconfig index c699bd6bcbb9..474073c7f94d 100644 --- a/drivers/net/ethernet/faraday/Kconfig +++ b/drivers/net/ethernet/faraday/Kconfig @@ -31,6 +31,7 @@ config FTGMAC100 depends on ARM || COMPILE_TEST depends on !64BIT || BROKEN select PHYLIB + select FIXED_PHY select MDIO_ASPEED if MACH_ASPEED_G6 select CRC32 help From 0909b2b49c4546a7a08c80f53d93736b63270827 Mon Sep 17 00:00:00 2001 From: Murad Masimov Date: Mon, 28 Apr 2025 18:34:06 +0300 Subject: [PATCH 474/971] fbdev: Fix do_register_framebuffer to prevent null-ptr-deref in fb_videomode_to_var commit 17186f1f90d34fa701e4f14e6818305151637b9e upstream. If fb_add_videomode() in do_register_framebuffer() fails to allocate memory for fb_videomode, it will later lead to a null-ptr dereference in fb_videomode_to_var(), as the fb_info is registered while not having the mode in modelist that is expected to be there, i.e. the one that is described in fb_info->var. ================================================================ general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] PREEMPT SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f] CPU: 1 PID: 30371 Comm: syz-executor.1 Not tainted 5.10.226-syzkaller #0 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 RIP: 0010:fb_videomode_to_var+0x24/0x610 drivers/video/fbdev/core/modedb.c:901 Call Trace: display_to_var+0x3a/0x7c0 drivers/video/fbdev/core/fbcon.c:929 fbcon_resize+0x3e2/0x8f0 drivers/video/fbdev/core/fbcon.c:2071 resize_screen drivers/tty/vt/vt.c:1176 [inline] vc_do_resize+0x53a/0x1170 drivers/tty/vt/vt.c:1263 fbcon_modechanged+0x3ac/0x6e0 drivers/video/fbdev/core/fbcon.c:2720 fbcon_update_vcs+0x43/0x60 drivers/video/fbdev/core/fbcon.c:2776 do_fb_ioctl+0x6d2/0x740 drivers/video/fbdev/core/fbmem.c:1128 fb_ioctl+0xe7/0x150 drivers/video/fbdev/core/fbmem.c:1203 vfs_ioctl fs/ioctl.c:48 [inline] __do_sys_ioctl fs/ioctl.c:753 [inline] __se_sys_ioctl fs/ioctl.c:739 [inline] __x64_sys_ioctl+0x19a/0x210 fs/ioctl.c:739 do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46 entry_SYSCALL_64_after_hwframe+0x67/0xd1 ================================================================ Even though fbcon_init() checks beforehand if fb_match_mode() in var_to_display() fails, it can not prevent the panic because fbcon_init() does not return error code. Considering this and the comment in the code about fb_match_mode() returning NULL - "This should not happen" - it is better to prevent registering the fb_info if its mode was not set successfully. Also move fb_add_videomode() closer to the beginning of do_register_framebuffer() to avoid having to do the cleanup on fail. Found by Linux Verification Center (linuxtesting.org) with Syzkaller. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Murad Masimov Signed-off-by: Helge Deller Signed-off-by: Greg Kroah-Hartman --- drivers/video/fbdev/core/fbmem.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index ee44a46a66be..6a1f3910934d 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -928,7 +928,7 @@ static int fb_check_foreignness(struct fb_info *fi) static int do_register_framebuffer(struct fb_info *fb_info) { - int i; + int i, err = 0; struct fb_videomode mode; if (fb_check_foreignness(fb_info)) @@ -937,10 +937,18 @@ static int do_register_framebuffer(struct fb_info *fb_info) if (num_registered_fb == FB_MAX) return -ENXIO; - num_registered_fb++; for (i = 0 ; i < FB_MAX; i++) if (!registered_fb[i]) break; + + if (!fb_info->modelist.prev || !fb_info->modelist.next) + INIT_LIST_HEAD(&fb_info->modelist); + + fb_var_to_videomode(&mode, &fb_info->var); + err = fb_add_videomode(&mode, &fb_info->modelist); + if (err < 0) + return err; + fb_info->node = i; refcount_set(&fb_info->count, 1); mutex_init(&fb_info->lock); @@ -966,16 +974,12 @@ static int do_register_framebuffer(struct fb_info *fb_info) if (!fb_info->pixmap.blit_y) fb_info->pixmap.blit_y = ~(u32)0; - if (!fb_info->modelist.prev || !fb_info->modelist.next) - INIT_LIST_HEAD(&fb_info->modelist); - if (fb_info->skip_vt_switch) pm_vt_switch_required(fb_info->device, false); else pm_vt_switch_required(fb_info->device, true); - fb_var_to_videomode(&mode, &fb_info->var); - fb_add_videomode(&mode, &fb_info->modelist); + num_registered_fb++; registered_fb[i] = fb_info; #ifdef CONFIG_GUMSTIX_AM200EPD From e32a40db67960da2182f4a54d2b93f7eb87481f2 Mon Sep 17 00:00:00 2001 From: Niravkumar L Rabara Date: Tue, 27 May 2025 07:57:07 -0700 Subject: [PATCH 475/971] EDAC/altera: Use correct write width with the INTTEST register commit e5ef4cd2a47f27c0c9d8ff6c0f63a18937c071a3 upstream. On the SoCFPGA platform, the INTTEST register supports only 16-bit writes. A 32-bit write triggers an SError to the CPU so do 16-bit accesses only. [ bp: AI-massage the commit message. ] Fixes: c7b4be8db8bc ("EDAC, altera: Add Arria10 OCRAM ECC support") Signed-off-by: Niravkumar L Rabara Signed-off-by: Matthew Gerlach Signed-off-by: Borislav Petkov (AMD) Acked-by: Dinh Nguyen Cc: stable@kernel.org Link: https://lore.kernel.org/20250527145707.25458-1-matthew.gerlach@altera.com Signed-off-by: Greg Kroah-Hartman --- drivers/edac/altera_edac.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c index e04fd1a7e9aa..54ec89415093 100644 --- a/drivers/edac/altera_edac.c +++ b/drivers/edac/altera_edac.c @@ -1756,9 +1756,9 @@ altr_edac_a10_device_trig(struct file *file, const char __user *user_buf, local_irq_save(flags); if (trig_type == ALTR_UE_TRIGGER_CHAR) - writel(priv->ue_set_mask, set_addr); + writew(priv->ue_set_mask, set_addr); else - writel(priv->ce_set_mask, set_addr); + writew(priv->ce_set_mask, set_addr); /* Ensure the interrupt test bits are set */ wmb(); @@ -1788,7 +1788,7 @@ altr_edac_a10_device_trig2(struct file *file, const char __user *user_buf, local_irq_save(flags); if (trig_type == ALTR_UE_TRIGGER_CHAR) { - writel(priv->ue_set_mask, set_addr); + writew(priv->ue_set_mask, set_addr); } else { /* Setup read/write of 4 bytes */ writel(ECC_WORD_WRITE, drvdata->base + ECC_BLK_DBYTECTRL_OFST); From 3ca78032a388a0795201792b36e6fc9b6e6e8eed Mon Sep 17 00:00:00 2001 From: Murad Masimov Date: Mon, 28 Apr 2025 18:34:07 +0300 Subject: [PATCH 476/971] fbdev: Fix fb_set_var to prevent null-ptr-deref in fb_videomode_to_var commit 05f6e183879d9785a3cdf2f08a498bc31b7a20aa upstream. If fb_add_videomode() in fb_set_var() fails to allocate memory for fb_videomode, later it may lead to a null-ptr dereference in fb_videomode_to_var(), as the fb_info is registered while not having the mode in modelist that is expected to be there, i.e. the one that is described in fb_info->var. ================================================================ general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] PREEMPT SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f] CPU: 1 PID: 30371 Comm: syz-executor.1 Not tainted 5.10.226-syzkaller #0 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 RIP: 0010:fb_videomode_to_var+0x24/0x610 drivers/video/fbdev/core/modedb.c:901 Call Trace: display_to_var+0x3a/0x7c0 drivers/video/fbdev/core/fbcon.c:929 fbcon_resize+0x3e2/0x8f0 drivers/video/fbdev/core/fbcon.c:2071 resize_screen drivers/tty/vt/vt.c:1176 [inline] vc_do_resize+0x53a/0x1170 drivers/tty/vt/vt.c:1263 fbcon_modechanged+0x3ac/0x6e0 drivers/video/fbdev/core/fbcon.c:2720 fbcon_update_vcs+0x43/0x60 drivers/video/fbdev/core/fbcon.c:2776 do_fb_ioctl+0x6d2/0x740 drivers/video/fbdev/core/fbmem.c:1128 fb_ioctl+0xe7/0x150 drivers/video/fbdev/core/fbmem.c:1203 vfs_ioctl fs/ioctl.c:48 [inline] __do_sys_ioctl fs/ioctl.c:753 [inline] __se_sys_ioctl fs/ioctl.c:739 [inline] __x64_sys_ioctl+0x19a/0x210 fs/ioctl.c:739 do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46 entry_SYSCALL_64_after_hwframe+0x67/0xd1 ================================================================ The reason is that fb_info->var is being modified in fb_set_var(), and then fb_videomode_to_var() is called. If it fails to add the mode to fb_info->modelist, fb_set_var() returns error, but does not restore the old value of fb_info->var. Restore fb_info->var on failure the same way it is done earlier in the function. Found by Linux Verification Center (linuxtesting.org) with Syzkaller. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Murad Masimov Signed-off-by: Helge Deller Signed-off-by: Greg Kroah-Hartman --- drivers/video/fbdev/core/fbmem.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 6a1f3910934d..52bd3af54369 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -868,8 +868,10 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) !list_empty(&info->modelist)) ret = fb_add_videomode(&mode, &info->modelist); - if (ret) + if (ret) { + info->var = old_var; return ret; + } event.info = info; event.data = &mode; From 7f27859721ae878bb5051a90cd3575ec84501e3b Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sat, 31 May 2025 15:26:27 +0200 Subject: [PATCH 477/971] parisc/unaligned: Fix hex output to show 8 hex chars commit 213205889d5ffc19cb8df06aa6778b2d4724c887 upstream. Change back printk format to 0x%08lx instead of %#08lx, since the latter does not seem to reliably format the value to 8 hex chars. Signed-off-by: Helge Deller Cc: stable@vger.kernel.org # v5.18+ Fixes: e5e9e7f222e5b ("parisc/unaligned: Enhance user-space visible output") Signed-off-by: Greg Kroah-Hartman --- arch/parisc/kernel/unaligned.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c index a8e75e5b884a..e673c71e16d9 100644 --- a/arch/parisc/kernel/unaligned.c +++ b/arch/parisc/kernel/unaligned.c @@ -24,7 +24,7 @@ #define DPRINTF(fmt, args...) #endif -#define RFMT "%#08lx" +#define RFMT "0x%08lx" /* 1111 1100 0000 0000 0001 0011 1100 0000 */ #define OPCODE1(a,b,c) ((a)<<26|(b)<<12|(c)<<6) From 2f4040a5855a59e48296f1b5a7cc0fceea3195b1 Mon Sep 17 00:00:00 2001 From: GONG Ruiqi Date: Sun, 27 Apr 2025 10:53:03 +0800 Subject: [PATCH 478/971] vgacon: Add check for vc_origin address range in vgacon_scroll() commit 864f9963ec6b4b76d104d595ba28110b87158003 upstream. Our in-house Syzkaller reported the following BUG (twice), which we believed was the same issue with [1]: ================================================================== BUG: KASAN: slab-out-of-bounds in vcs_scr_readw+0xc2/0xd0 drivers/tty/vt/vt.c:4740 Read of size 2 at addr ffff88800f5bef60 by task syz.7.2620/12393 ... Call Trace: __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x72/0xa0 lib/dump_stack.c:106 print_address_description.constprop.0+0x6b/0x3d0 mm/kasan/report.c:364 print_report+0xba/0x280 mm/kasan/report.c:475 kasan_report+0xa9/0xe0 mm/kasan/report.c:588 vcs_scr_readw+0xc2/0xd0 drivers/tty/vt/vt.c:4740 vcs_write_buf_noattr drivers/tty/vt/vc_screen.c:493 [inline] vcs_write+0x586/0x840 drivers/tty/vt/vc_screen.c:690 vfs_write+0x219/0x960 fs/read_write.c:584 ksys_write+0x12e/0x260 fs/read_write.c:639 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x59/0x110 arch/x86/entry/common.c:81 entry_SYSCALL_64_after_hwframe+0x78/0xe2 ... Allocated by task 5614: kasan_save_stack+0x20/0x40 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 ____kasan_kmalloc mm/kasan/common.c:374 [inline] __kasan_kmalloc+0x8f/0xa0 mm/kasan/common.c:383 kasan_kmalloc include/linux/kasan.h:201 [inline] __do_kmalloc_node mm/slab_common.c:1007 [inline] __kmalloc+0x62/0x140 mm/slab_common.c:1020 kmalloc include/linux/slab.h:604 [inline] kzalloc include/linux/slab.h:721 [inline] vc_do_resize+0x235/0xf40 drivers/tty/vt/vt.c:1193 vgacon_adjust_height+0x2d4/0x350 drivers/video/console/vgacon.c:1007 vgacon_font_set+0x1f7/0x240 drivers/video/console/vgacon.c:1031 con_font_set drivers/tty/vt/vt.c:4628 [inline] con_font_op+0x4da/0xa20 drivers/tty/vt/vt.c:4675 vt_k_ioctl+0xa10/0xb30 drivers/tty/vt/vt_ioctl.c:474 vt_ioctl+0x14c/0x1870 drivers/tty/vt/vt_ioctl.c:752 tty_ioctl+0x655/0x1510 drivers/tty/tty_io.c:2779 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:871 [inline] __se_sys_ioctl+0x12d/0x190 fs/ioctl.c:857 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x59/0x110 arch/x86/entry/common.c:81 entry_SYSCALL_64_after_hwframe+0x78/0xe2 Last potentially related work creation: kasan_save_stack+0x20/0x40 mm/kasan/common.c:45 __kasan_record_aux_stack+0x94/0xa0 mm/kasan/generic.c:492 __call_rcu_common.constprop.0+0xc3/0xa10 kernel/rcu/tree.c:2713 netlink_release+0x620/0xc20 net/netlink/af_netlink.c:802 __sock_release+0xb5/0x270 net/socket.c:663 sock_close+0x1e/0x30 net/socket.c:1425 __fput+0x408/0xab0 fs/file_table.c:384 __fput_sync+0x4c/0x60 fs/file_table.c:465 __do_sys_close fs/open.c:1580 [inline] __se_sys_close+0x68/0xd0 fs/open.c:1565 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x59/0x110 arch/x86/entry/common.c:81 entry_SYSCALL_64_after_hwframe+0x78/0xe2 Second to last potentially related work creation: kasan_save_stack+0x20/0x40 mm/kasan/common.c:45 __kasan_record_aux_stack+0x94/0xa0 mm/kasan/generic.c:492 __call_rcu_common.constprop.0+0xc3/0xa10 kernel/rcu/tree.c:2713 netlink_release+0x620/0xc20 net/netlink/af_netlink.c:802 __sock_release+0xb5/0x270 net/socket.c:663 sock_close+0x1e/0x30 net/socket.c:1425 __fput+0x408/0xab0 fs/file_table.c:384 task_work_run+0x154/0x240 kernel/task_work.c:239 exit_task_work include/linux/task_work.h:45 [inline] do_exit+0x8e5/0x1320 kernel/exit.c:874 do_group_exit+0xcd/0x280 kernel/exit.c:1023 get_signal+0x1675/0x1850 kernel/signal.c:2905 arch_do_signal_or_restart+0x80/0x3b0 arch/x86/kernel/signal.c:310 exit_to_user_mode_loop kernel/entry/common.c:111 [inline] exit_to_user_mode_prepare include/linux/entry-common.h:328 [inline] __syscall_exit_to_user_mode_work kernel/entry/common.c:207 [inline] syscall_exit_to_user_mode+0x1b3/0x1e0 kernel/entry/common.c:218 do_syscall_64+0x66/0x110 arch/x86/entry/common.c:87 entry_SYSCALL_64_after_hwframe+0x78/0xe2 The buggy address belongs to the object at ffff88800f5be000 which belongs to the cache kmalloc-2k of size 2048 The buggy address is located 2656 bytes to the right of allocated 1280-byte region [ffff88800f5be000, ffff88800f5be500) ... Memory state around the buggy address: ffff88800f5bee00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff88800f5bee80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc >ffff88800f5bef00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ^ ffff88800f5bef80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff88800f5bf000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ================================================================== By analyzing the vmcore, we found that vc->vc_origin was somehow placed one line prior to vc->vc_screenbuf when vc was in KD_TEXT mode, and further writings to /dev/vcs caused out-of-bounds reads (and writes right after) in vcs_write_buf_noattr(). Our further experiments show that in most cases, vc->vc_origin equals to vga_vram_base when the console is in KD_TEXT mode, and it's around vc->vc_screenbuf for the KD_GRAPHICS mode. But via triggerring a TIOCL_SETVESABLANK ioctl beforehand, we can make vc->vc_origin be around vc->vc_screenbuf while the console is in KD_TEXT mode, and then by writing the special 'ESC M' control sequence to the tty certain times (depends on the value of `vc->state.y - vc->vc_top`), we can eventually move vc->vc_origin prior to vc->vc_screenbuf. Here's the PoC, tested on QEMU: ``` int main() { const int RI_NUM = 10; // should be greater than `vc->state.y - vc->vc_top` int tty_fd, vcs_fd; const char *tty_path = "/dev/tty0"; const char *vcs_path = "/dev/vcs"; const char escape_seq[] = "\x1bM"; // ESC + M const char trigger_seq[] = "Let's trigger an OOB write."; struct vt_sizes vt_size = { 70, 2 }; int blank = TIOCL_BLANKSCREEN; tty_fd = open(tty_path, O_RDWR); char vesa_mode[] = { TIOCL_SETVESABLANK, 1 }; ioctl(tty_fd, TIOCLINUX, vesa_mode); ioctl(tty_fd, TIOCLINUX, &blank); ioctl(tty_fd, VT_RESIZE, &vt_size); for (int i = 0; i < RI_NUM; ++i) write(tty_fd, escape_seq, sizeof(escape_seq) - 1); vcs_fd = open(vcs_path, O_RDWR); write(vcs_fd, trigger_seq, sizeof(trigger_seq)); close(vcs_fd); close(tty_fd); return 0; } ``` To solve this problem, add an address range validation check in vgacon_scroll(), ensuring vc->vc_origin never precedes vc_screenbuf. Reported-by: syzbot+9c09fda97a1a65ea859b@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=9c09fda97a1a65ea859b [1] Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Co-developed-by: Yi Yang Signed-off-by: Yi Yang Signed-off-by: GONG Ruiqi Signed-off-by: Helge Deller Signed-off-by: Greg Kroah-Hartman --- drivers/video/console/vgacon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 7ad047bcae17..c9ec89649b05 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -1139,7 +1139,7 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b, c->vc_screenbuf_size - delta); c->vc_origin = vga_vram_end - c->vc_screenbuf_size; vga_rolled_over = 0; - } else + } else if (oldo - delta >= (unsigned long)c->vc_screenbuf) c->vc_origin -= delta; c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size; scr_memsetw((u16 *) (c->vc_origin), c->vc_video_erase_char, From ebb8060561d552ab5acf23c65acec95f787929bf Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2025 11:00:46 +0200 Subject: [PATCH 479/971] parisc: fix building with gcc-15 commit 7cbb015e2d3d6f180256cde0c908eab21268e7b9 upstream. The decompressor is built with the default C dialect, which is now gnu23 on gcc-15, and this clashes with the kernel's bool type definition: In file included from include/uapi/linux/posix_types.h:5, from arch/parisc/boot/compressed/misc.c:7: include/linux/stddef.h:11:9: error: cannot use keyword 'false' as enumeration constant 11 | false = 0, Add the -std=gnu11 argument here, as we do for all other architectures. Cc: stable@vger.kernel.org Signed-off-by: Arnd Bergmann Signed-off-by: Helge Deller Signed-off-by: Greg Kroah-Hartman --- arch/parisc/boot/compressed/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/parisc/boot/compressed/Makefile b/arch/parisc/boot/compressed/Makefile index a294a1b58ee7..9fba12b70d1b 100644 --- a/arch/parisc/boot/compressed/Makefile +++ b/arch/parisc/boot/compressed/Makefile @@ -22,6 +22,7 @@ KBUILD_CFLAGS += -fno-PIE -mno-space-regs -mdisable-fpregs -Os ifndef CONFIG_64BIT KBUILD_CFLAGS += -mfast-indirect-calls endif +KBUILD_CFLAGS += -std=gnu11 LDFLAGS_vmlinux := -X -e startup --as-needed -T $(obj)/vmlinux: $(obj)/vmlinux.lds $(addprefix $(obj)/, $(OBJECTS)) $(LIBGCC) FORCE From f24d422452398e5d2b3461e081a2ac617d696701 Mon Sep 17 00:00:00 2001 From: Da Xue Date: Mon, 12 May 2025 10:26:16 -0400 Subject: [PATCH 480/971] clk: meson-g12a: add missing fclk_div2 to spicc commit daf004f87c3520c414992893e2eadd5db5f86a5a upstream. SPICC is missing fclk_div2, which means fclk_div5 and fclk_div7 indexes are wrong on this clock. This causes the spicc module to output sclk at 2.5x the expected rate when clock index 3 is picked. Adding the missing fclk_div2 resolves this. [jbrunet: amended commit description] Fixes: a18c8e0b7697 ("clk: meson: g12a: add support for the SPICC SCLK Source clocks") Cc: stable@vger.kernel.org # 6.1 Signed-off-by: Da Xue Reviewed-by: Martin Blumenstingl Link: https://lore.kernel.org/r/20250512142617.2175291-1-da@libre.computer Signed-off-by: Jerome Brunet Signed-off-by: Greg Kroah-Hartman --- drivers/clk/meson/g12a.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index 233ce4a4c1c2..69018efbf7f4 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -3971,6 +3971,7 @@ static const struct clk_parent_data spicc_sclk_parent_data[] = { { .hw = &g12a_clk81.hw }, { .hw = &g12a_fclk_div4.hw }, { .hw = &g12a_fclk_div3.hw }, + { .hw = &g12a_fclk_div2.hw }, { .hw = &g12a_fclk_div5.hw }, { .hw = &g12a_fclk_div7.hw }, }; From 5180561afff8e0f029073c8c8117c95c6512d1f9 Mon Sep 17 00:00:00 2001 From: Jeongjun Park Date: Thu, 24 Apr 2025 23:33:22 +0900 Subject: [PATCH 481/971] ipc: fix to protect IPCS lookups using RCU commit d66adabe91803ef34a8b90613c81267b5ded1472 upstream. syzbot reported that it discovered a use-after-free vulnerability, [0] [0]: https://lore.kernel.org/all/67af13f8.050a0220.21dd3.0038.GAE@google.com/ idr_for_each() is protected by rwsem, but this is not enough. If it is not protected by RCU read-critical region, when idr_for_each() calls radix_tree_node_free() through call_rcu() to free the radix_tree_node structure, the node will be freed immediately, and when reading the next node in radix_tree_for_each_slot(), the already freed memory may be read. Therefore, we need to add code to make sure that idr_for_each() is protected within the RCU read-critical region when we call it in shm_destroy_orphaned(). Link: https://lkml.kernel.org/r/20250424143322.18830-1-aha310510@gmail.com Fixes: b34a6b1da371 ("ipc: introduce shm_rmid_forced sysctl") Signed-off-by: Jeongjun Park Reported-by: syzbot+a2b84e569d06ca3a949c@syzkaller.appspotmail.com Cc: Jeongjun Park Cc: Liam Howlett Cc: Lorenzo Stoakes Cc: Matthew Wilcox (Oracle) Cc: Vasiliy Kulikov Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- ipc/shm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ipc/shm.c b/ipc/shm.c index 576a543b7cff..c4845689b7f6 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -430,8 +430,11 @@ static int shm_try_destroy_orphaned(int id, void *p, void *data) void shm_destroy_orphaned(struct ipc_namespace *ns) { down_write(&shm_ids(ns).rwsem); - if (shm_ids(ns).in_use) + if (shm_ids(ns).in_use) { + rcu_read_lock(); idr_for_each(&shm_ids(ns).ipcs_idr, &shm_try_destroy_orphaned, ns); + rcu_read_unlock(); + } up_write(&shm_ids(ns).rwsem); } From 442e80dcf6fe32f482bc890a0852f5192abf67b2 Mon Sep 17 00:00:00 2001 From: Luo Gengkun Date: Mon, 21 Apr 2025 03:50:21 +0000 Subject: [PATCH 482/971] watchdog: fix watchdog may detect false positive of softlockup commit 7123dbbef88cfd9f09e8a7899b0911834600cfa3 upstream. When updating `watchdog_thresh`, there is a race condition between writing the new `watchdog_thresh` value and stopping the old watchdog timer. If the old timer triggers during this window, it may falsely detect a softlockup due to the old interval and the new `watchdog_thresh` value being used. The problem can be described as follow: # We asuume previous watchdog_thresh is 60, so the watchdog timer is # coming every 24s. echo 10 > /proc/sys/kernel/watchdog_thresh (User space) | +------>+ update watchdog_thresh (We are in kernel now) | | # using old interval and new `watchdog_thresh` +------>+ watchdog hrtimer (irq context: detect softlockup) | | +-------+ | | + softlockup_stop_all To fix this problem, introduce a shadow variable for `watchdog_thresh`. The update to the actual `watchdog_thresh` is delayed until after the old timer is stopped, preventing false positives. The following testcase may help to understand this problem. --------------------------------------------- echo RT_RUNTIME_SHARE > /sys/kernel/debug/sched/features echo -1 > /proc/sys/kernel/sched_rt_runtime_us echo 0 > /sys/kernel/debug/sched/fair_server/cpu3/runtime echo 60 > /proc/sys/kernel/watchdog_thresh taskset -c 3 chrt -r 99 /bin/bash -c "while true;do true; done" & echo 10 > /proc/sys/kernel/watchdog_thresh & --------------------------------------------- The test case above first removes the throttling restrictions for real-time tasks. It then sets watchdog_thresh to 60 and executes a real-time task ,a simple while(1) loop, on cpu3. Consequently, the final command gets blocked because the presence of this real-time thread prevents kworker:3 from being selected by the scheduler. This eventually triggers a softlockup detection on cpu3 due to watchdog_timer_fn operating with inconsistent variable - using both the old interval and the updated watchdog_thresh simultaneously. [nysal@linux.ibm.com: fix the SOFTLOCKUP_DETECTOR=n case] Link: https://lkml.kernel.org/r/20250502111120.282690-1-nysal@linux.ibm.com Link: https://lkml.kernel.org/r/20250421035021.3507649-1-luogengkun@huaweicloud.com Signed-off-by: Luo Gengkun Signed-off-by: Nysal Jan K.A. Cc: Doug Anderson Cc: Joel Granados Cc: Song Liu Cc: Thomas Gleinxer Cc: "Nysal Jan K.A." Cc: Venkat Rao Bagalkote Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- kernel/watchdog.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/kernel/watchdog.c b/kernel/watchdog.c index 5cd6d4e26915..7abd69a776b2 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c @@ -40,6 +40,7 @@ int __read_mostly watchdog_user_enabled = 1; static int __read_mostly watchdog_hardlockup_user_enabled = WATCHDOG_HARDLOCKUP_DEFAULT; static int __read_mostly watchdog_softlockup_user_enabled = 1; int __read_mostly watchdog_thresh = 10; +static int __read_mostly watchdog_thresh_next; static int __read_mostly watchdog_hardlockup_available; struct cpumask watchdog_cpumask __read_mostly; @@ -627,12 +628,20 @@ int lockup_detector_offline_cpu(unsigned int cpu) return 0; } -static void __lockup_detector_reconfigure(void) +static void __lockup_detector_reconfigure(bool thresh_changed) { cpus_read_lock(); watchdog_hardlockup_stop(); softlockup_stop_all(); + /* + * To prevent watchdog_timer_fn from using the old interval and + * the new watchdog_thresh at the same time, which could lead to + * false softlockup reports, it is necessary to update the + * watchdog_thresh after the softlockup is completed. + */ + if (thresh_changed) + watchdog_thresh = READ_ONCE(watchdog_thresh_next); set_sample_period(); lockup_detector_update_enable(); if (watchdog_enabled && watchdog_thresh) @@ -650,7 +659,7 @@ static void __lockup_detector_reconfigure(void) void lockup_detector_reconfigure(void) { mutex_lock(&watchdog_mutex); - __lockup_detector_reconfigure(); + __lockup_detector_reconfigure(false); mutex_unlock(&watchdog_mutex); } @@ -670,27 +679,29 @@ static __init void lockup_detector_setup(void) return; mutex_lock(&watchdog_mutex); - __lockup_detector_reconfigure(); + __lockup_detector_reconfigure(false); softlockup_initialized = true; mutex_unlock(&watchdog_mutex); } #else /* CONFIG_SOFTLOCKUP_DETECTOR */ -static void __lockup_detector_reconfigure(void) +static void __lockup_detector_reconfigure(bool thresh_changed) { cpus_read_lock(); watchdog_hardlockup_stop(); + if (thresh_changed) + watchdog_thresh = READ_ONCE(watchdog_thresh_next); lockup_detector_update_enable(); watchdog_hardlockup_start(); cpus_read_unlock(); } void lockup_detector_reconfigure(void) { - __lockup_detector_reconfigure(); + __lockup_detector_reconfigure(false); } static inline void lockup_detector_setup(void) { - __lockup_detector_reconfigure(); + __lockup_detector_reconfigure(false); } #endif /* !CONFIG_SOFTLOCKUP_DETECTOR */ @@ -726,11 +737,11 @@ void lockup_detector_soft_poweroff(void) #ifdef CONFIG_SYSCTL /* Propagate any changes to the watchdog infrastructure */ -static void proc_watchdog_update(void) +static void proc_watchdog_update(bool thresh_changed) { /* Remove impossible cpus to keep sysctl output clean. */ cpumask_and(&watchdog_cpumask, &watchdog_cpumask, cpu_possible_mask); - __lockup_detector_reconfigure(); + __lockup_detector_reconfigure(thresh_changed); } /* @@ -763,7 +774,7 @@ static int proc_watchdog_common(int which, struct ctl_table *table, int write, old = READ_ONCE(*param); err = proc_dointvec_minmax(table, write, buffer, lenp, ppos); if (!err && old != READ_ONCE(*param)) - proc_watchdog_update(); + proc_watchdog_update(false); } mutex_unlock(&watchdog_mutex); return err; @@ -812,11 +823,13 @@ int proc_watchdog_thresh(struct ctl_table *table, int write, mutex_lock(&watchdog_mutex); - old = READ_ONCE(watchdog_thresh); + watchdog_thresh_next = READ_ONCE(watchdog_thresh); + + old = watchdog_thresh_next; err = proc_dointvec_minmax(table, write, buffer, lenp, ppos); - if (!err && write && old != READ_ONCE(watchdog_thresh)) - proc_watchdog_update(); + if (!err && write && old != READ_ONCE(watchdog_thresh_next)) + proc_watchdog_update(true); mutex_unlock(&watchdog_mutex); return err; @@ -837,7 +850,7 @@ int proc_watchdog_cpumask(struct ctl_table *table, int write, err = proc_do_large_bitmap(table, write, buffer, lenp, ppos); if (!err && write) - proc_watchdog_update(); + proc_watchdog_update(false); mutex_unlock(&watchdog_mutex); return err; @@ -857,7 +870,7 @@ static struct ctl_table watchdog_sysctls[] = { }, { .procname = "watchdog_thresh", - .data = &watchdog_thresh, + .data = &watchdog_thresh_next, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_watchdog_thresh, From 23a707bbcbea468eedb398832eeb7e8e0ceafd21 Mon Sep 17 00:00:00 2001 From: Shin'ichiro Kawasaki Date: Sat, 10 May 2025 19:10:36 +0900 Subject: [PATCH 483/971] RDMA/iwcm: Fix use-after-free of work objects after cm_id destruction commit 6883b680e703c6b2efddb4e7a8d891ce1803d06b upstream. The commit 59c68ac31e15 ("iw_cm: free cm_id resources on the last deref") simplified cm_id resource management by freeing cm_id once all references to the cm_id were removed. The references are removed either upon completion of iw_cm event handlers or when the application destroys the cm_id. This commit introduced the use-after-free condition where cm_id_private object could still be in use by event handler works during the destruction of cm_id. The commit aee2424246f9 ("RDMA/iwcm: Fix a use-after-free related to destroying CM IDs") addressed this use-after- free by flushing all pending works at the cm_id destruction. However, still another use-after-free possibility remained. It happens with the work objects allocated for each cm_id_priv within alloc_work_entries() during cm_id creation, and subsequently freed in dealloc_work_entries() once all references to the cm_id are removed. If the cm_id's last reference is decremented in the event handler work, the work object for the work itself gets removed, and causes the use- after-free BUG below: BUG: KASAN: slab-use-after-free in __pwq_activate_work+0x1ff/0x250 Read of size 8 at addr ffff88811f9cf800 by task kworker/u16:1/147091 CPU: 2 UID: 0 PID: 147091 Comm: kworker/u16:1 Not tainted 6.15.0-rc2+ #27 PREEMPT(voluntary) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-3.fc41 04/01/2014 Workqueue: 0x0 (iw_cm_wq) Call Trace: dump_stack_lvl+0x6a/0x90 print_report+0x174/0x554 ? __virt_addr_valid+0x208/0x430 ? __pwq_activate_work+0x1ff/0x250 kasan_report+0xae/0x170 ? __pwq_activate_work+0x1ff/0x250 __pwq_activate_work+0x1ff/0x250 pwq_dec_nr_in_flight+0x8c5/0xfb0 process_one_work+0xc11/0x1460 ? __pfx_process_one_work+0x10/0x10 ? assign_work+0x16c/0x240 worker_thread+0x5ef/0xfd0 ? __pfx_worker_thread+0x10/0x10 kthread+0x3b0/0x770 ? __pfx_kthread+0x10/0x10 ? rcu_is_watching+0x11/0xb0 ? _raw_spin_unlock_irq+0x24/0x50 ? rcu_is_watching+0x11/0xb0 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x30/0x70 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 Allocated by task 147416: kasan_save_stack+0x2c/0x50 kasan_save_track+0x10/0x30 __kasan_kmalloc+0xa6/0xb0 alloc_work_entries+0xa9/0x260 [iw_cm] iw_cm_connect+0x23/0x4a0 [iw_cm] rdma_connect_locked+0xbfd/0x1920 [rdma_cm] nvme_rdma_cm_handler+0x8e5/0x1b60 [nvme_rdma] cma_cm_event_handler+0xae/0x320 [rdma_cm] cma_work_handler+0x106/0x1b0 [rdma_cm] process_one_work+0x84f/0x1460 worker_thread+0x5ef/0xfd0 kthread+0x3b0/0x770 ret_from_fork+0x30/0x70 ret_from_fork_asm+0x1a/0x30 Freed by task 147091: kasan_save_stack+0x2c/0x50 kasan_save_track+0x10/0x30 kasan_save_free_info+0x37/0x60 __kasan_slab_free+0x4b/0x70 kfree+0x13a/0x4b0 dealloc_work_entries+0x125/0x1f0 [iw_cm] iwcm_deref_id+0x6f/0xa0 [iw_cm] cm_work_handler+0x136/0x1ba0 [iw_cm] process_one_work+0x84f/0x1460 worker_thread+0x5ef/0xfd0 kthread+0x3b0/0x770 ret_from_fork+0x30/0x70 ret_from_fork_asm+0x1a/0x30 Last potentially related work creation: kasan_save_stack+0x2c/0x50 kasan_record_aux_stack+0xa3/0xb0 __queue_work+0x2ff/0x1390 queue_work_on+0x67/0xc0 cm_event_handler+0x46a/0x820 [iw_cm] siw_cm_upcall+0x330/0x650 [siw] siw_cm_work_handler+0x6b9/0x2b20 [siw] process_one_work+0x84f/0x1460 worker_thread+0x5ef/0xfd0 kthread+0x3b0/0x770 ret_from_fork+0x30/0x70 ret_from_fork_asm+0x1a/0x30 This BUG is reproducible by repeating the blktests test case nvme/061 for the rdma transport and the siw driver. To avoid the use-after-free of cm_id_private work objects, ensure that the last reference to the cm_id is decremented not in the event handler works, but in the cm_id destruction context. For that purpose, move iwcm_deref_id() call from destroy_cm_id() to the callers of destroy_cm_id(). In iw_destroy_cm_id(), call iwcm_deref_id() after flushing the pending works. During the fix work, I noticed that iw_destroy_cm_id() is called from cm_work_handler() and process_event() context. However, the comment of iw_destroy_cm_id() notes that the function "cannot be called by the event thread". Drop the false comment. Closes: https://lore.kernel.org/linux-rdma/r5676e754sv35aq7cdsqrlnvyhiq5zktteaurl7vmfih35efko@z6lay7uypy3c/ Fixes: 59c68ac31e15 ("iw_cm: free cm_id resources on the last deref") Cc: stable@vger.kernel.org Signed-off-by: Shin'ichiro Kawasaki Link: https://patch.msgid.link/20250510101036.1756439-1-shinichiro.kawasaki@wdc.com Reviewed-by: Zhu Yanjun Signed-off-by: Leon Romanovsky Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/iwcm.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c index 3e4941754b48..ce41f235af25 100644 --- a/drivers/infiniband/core/iwcm.c +++ b/drivers/infiniband/core/iwcm.c @@ -367,12 +367,9 @@ EXPORT_SYMBOL(iw_cm_disconnect); /* * CM_ID <-- DESTROYING * - * Clean up all resources associated with the connection and release - * the initial reference taken by iw_create_cm_id. - * - * Returns true if and only if the last cm_id_priv reference has been dropped. + * Clean up all resources associated with the connection. */ -static bool destroy_cm_id(struct iw_cm_id *cm_id) +static void destroy_cm_id(struct iw_cm_id *cm_id) { struct iwcm_id_private *cm_id_priv; struct ib_qp *qp; @@ -441,20 +438,22 @@ static bool destroy_cm_id(struct iw_cm_id *cm_id) iwpm_remove_mapinfo(&cm_id->local_addr, &cm_id->m_local_addr); iwpm_remove_mapping(&cm_id->local_addr, RDMA_NL_IWCM); } - - return iwcm_deref_id(cm_id_priv); } /* - * This function is only called by the application thread and cannot - * be called by the event thread. The function will wait for all - * references to be released on the cm_id and then kfree the cm_id - * object. + * Destroy cm_id. If the cm_id still has other references, wait for all + * references to be released on the cm_id and then release the initial + * reference taken by iw_create_cm_id. */ void iw_destroy_cm_id(struct iw_cm_id *cm_id) { - if (!destroy_cm_id(cm_id)) + struct iwcm_id_private *cm_id_priv; + + cm_id_priv = container_of(cm_id, struct iwcm_id_private, id); + destroy_cm_id(cm_id); + if (refcount_read(&cm_id_priv->refcount) > 1) flush_workqueue(iwcm_wq); + iwcm_deref_id(cm_id_priv); } EXPORT_SYMBOL(iw_destroy_cm_id); @@ -1037,8 +1036,10 @@ static void cm_work_handler(struct work_struct *_work) if (!test_bit(IWCM_F_DROP_EVENTS, &cm_id_priv->flags)) { ret = process_event(cm_id_priv, &levent); - if (ret) - WARN_ON_ONCE(destroy_cm_id(&cm_id_priv->id)); + if (ret) { + destroy_cm_id(&cm_id_priv->id); + WARN_ON_ONCE(iwcm_deref_id(cm_id_priv)); + } } else pr_debug("dropping event %d\n", levent.event); if (iwcm_deref_id(cm_id_priv)) From d3abf0066b5ea558e7b30c02af8ff07a34442917 Mon Sep 17 00:00:00 2001 From: Jinliang Zheng Date: Tue, 15 Apr 2025 17:02:32 +0800 Subject: [PATCH 484/971] mm: fix ratelimit_pages update error in dirty_ratio_handler() commit f83f362d40ccceb647f7d80eb92206733d76a36b upstream. In dirty_ratio_handler(), vm_dirty_bytes must be set to zero before calling writeback_set_ratelimit(), as global_dirty_limits() always prioritizes the value of vm_dirty_bytes. It's domain_dirty_limits() that's relevant here, not node_dirty_ok: dirty_ratio_handler writeback_set_ratelimit global_dirty_limits(&dirty_thresh) <- ratelimit_pages based on dirty_thresh domain_dirty_limits if (bytes) <- bytes = vm_dirty_bytes <--------+ thresh = f1(bytes) <- prioritizes vm_dirty_bytes | else | thresh = f2(ratio) | ratelimit_pages = f3(dirty_thresh) | vm_dirty_bytes = 0 <- it's late! ---------------------+ This causes ratelimit_pages to still use the value calculated based on vm_dirty_bytes, which is wrong now. The impact visible to userspace is difficult to capture directly because there is no procfs/sysfs interface exported to user space. However, it will have a real impact on the balance of dirty pages. For example: 1. On default, we have vm_dirty_ratio=40, vm_dirty_bytes=0 2. echo 8192 > dirty_bytes, then vm_dirty_bytes=8192, vm_dirty_ratio=0, and ratelimit_pages is calculated based on vm_dirty_bytes now. 3. echo 20 > dirty_ratio, then since vm_dirty_bytes is not reset to zero when writeback_set_ratelimit() -> global_dirty_limits() -> domain_dirty_limits() is called, reallimit_pages is still calculated based on vm_dirty_bytes instead of vm_dirty_ratio. This does not conform to the actual intent of the user. Link: https://lkml.kernel.org/r/20250415090232.7544-1-alexjlzheng@tencent.com Fixes: 9d823e8f6b1b ("writeback: per task dirty rate limit") Signed-off-by: Jinliang Zheng Reviewed-by: MengEn Sun Cc: Andrea Righi Cc: Fenggaung Wu Cc: Jinliang Zheng Cc: Matthew Wilcox (Oracle) Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- mm/page-writeback.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/page-writeback.c b/mm/page-writeback.c index e632ec9b6421..9ceb841af819 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -541,8 +541,8 @@ static int dirty_ratio_handler(struct ctl_table *table, int write, void *buffer, ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); if (ret == 0 && write && vm_dirty_ratio != old_ratio) { - writeback_set_ratelimit(); vm_dirty_bytes = 0; + writeback_set_ratelimit(); } return ret; } From e06a1dadc481ed0b50d8818b0790ce671839d238 Mon Sep 17 00:00:00 2001 From: Wentao Liang Date: Mon, 26 May 2025 11:43:44 +0800 Subject: [PATCH 485/971] mtd: rawnand: sunxi: Add randomizer configuration in sunxi_nfc_hw_ecc_write_chunk commit 44ed1f5ff73e9e115b6f5411744d5a22ea1c855b upstream. The function sunxi_nfc_hw_ecc_write_chunk() calls the sunxi_nfc_hw_ecc_write_chunk(), but does not call the configuration function sunxi_nfc_randomizer_config(). Consequently, the randomization might not conduct correctly, which will affect the lifespan of NAND flash. A proper implementation can be found in sunxi_nfc_hw_ecc_write_page_dma(). Add the sunxi_nfc_randomizer_config() to config randomizer. Fixes: 4be4e03efc7f ("mtd: nand: sunxi: add randomizer support") Cc: stable@vger.kernel.org # v4.6 Signed-off-by: Wentao Liang Signed-off-by: Miquel Raynal Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/nand/raw/sunxi_nand.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 9abf38049d35..fe6a689f6d65 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1049,6 +1049,7 @@ static int sunxi_nfc_hw_ecc_write_chunk(struct nand_chip *nand, if (ret) return ret; + sunxi_nfc_randomizer_config(nand, page, false); sunxi_nfc_randomizer_enable(nand); sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, 0, bbm, page); From 7775ab2d53b3e2281f23622e4247deabdd007f69 Mon Sep 17 00:00:00 2001 From: Wentao Liang Date: Mon, 19 May 2025 23:42:24 +0800 Subject: [PATCH 486/971] mtd: nand: sunxi: Add randomizer configuration before randomizer enable commit 4a5a99bc79cdc4be63933653682b0261a67a0c9f upstream. In sunxi_nfc_hw_ecc_read_chunk(), the sunxi_nfc_randomizer_enable() is called without the config of randomizer. A proper implementation can be found in sunxi_nfc_hw_ecc_read_chunks_dma(). Add sunxi_nfc_randomizer_config() before the start of randomization. Fixes: 4be4e03efc7f ("mtd: nand: sunxi: add randomizer support") Cc: stable@vger.kernel.org # v4.6 Signed-off-by: Wentao Liang Signed-off-by: Miquel Raynal Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/nand/raw/sunxi_nand.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index fe6a689f6d65..4469618ee603 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -817,6 +817,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, if (ret) return ret; + sunxi_nfc_randomizer_config(nand, page, false); sunxi_nfc_randomizer_enable(nand); writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ECC_OP, nfc->regs + NFC_REG_CMD); From 0d7a2ea4351b12eda810c0902f45879dcd903160 Mon Sep 17 00:00:00 2001 From: Yosry Ahmed Date: Tue, 29 Apr 2025 08:32:15 -0700 Subject: [PATCH 487/971] KVM: SVM: Clear current_vmcb during vCPU free for all *possible* CPUs commit 1bee4838eb3a2c689f23c7170ea66ae87ea7d93a upstream. When freeing a vCPU and thus its VMCB, clear current_vmcb for all possible CPUs, not just online CPUs, as it's theoretically possible a CPU could go offline and come back online in conjunction with KVM reusing the page for a new VMCB. Link: https://lore.kernel.org/all/20250320013759.3965869-1-yosry.ahmed@linux.dev Fixes: fd65d3142f73 ("kvm: svm: Ensure an IBPB on all affected CPUs when freeing a vmcb") Cc: stable@vger.kernel.org Cc: Jim Mattson Signed-off-by: Yosry Ahmed [sean: split to separate patch, write changelog] Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/svm/svm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index c84a1451f194..86c50747e158 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1503,7 +1503,7 @@ static void svm_clear_current_vmcb(struct vmcb *vmcb) { int i; - for_each_online_cpu(i) + for_each_possible_cpu(i) cmpxchg(per_cpu_ptr(&svm_data.current_vmcb, i), vmcb, NULL); } From fe0ff7d801fb0d9e30b1421d7e27caf3bb9a14fe Mon Sep 17 00:00:00 2001 From: Chao Gao Date: Mon, 24 Mar 2025 22:08:48 +0800 Subject: [PATCH 488/971] KVM: VMX: Flush shadow VMCS on emergency reboot commit a0ee1d5faff135e28810f29e0f06328c66f89852 upstream. Ensure the shadow VMCS cache is evicted during an emergency reboot to prevent potential memory corruption if the cache is evicted after reboot. This issue was identified through code inspection, as __loaded_vmcs_clear() flushes both the normal VMCS and the shadow VMCS. Avoid checking the "launched" state during an emergency reboot, unlike the behavior in __loaded_vmcs_clear(). This is important because reboot NMIs can interfere with operations like copy_shadow_to_vmcs12(), where shadow VMCSes are loaded directly using VMPTRLD. In such cases, if NMIs occur right after the VMCS load, the shadow VMCSes will be active but the "launched" state may not be set. Fixes: 16f5b9034b69 ("KVM: nVMX: Copy processor-specific shadow-vmcs to VMCS12") Cc: stable@vger.kernel.org Signed-off-by: Chao Gao Reviewed-by: Kai Huang Link: https://lore.kernel.org/r/20250324140849.2099723-1-chao.gao@intel.com Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/vmx/vmx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index e5a2c230110e..e7f3b70f9114 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -787,8 +787,11 @@ static void vmx_emergency_disable(void) return; list_for_each_entry(v, &per_cpu(loaded_vmcss_on_cpu, cpu), - loaded_vmcss_on_cpu_link) + loaded_vmcss_on_cpu_link) { vmcs_clear(v->vmcs); + if (v->shadow_vmcs) + vmcs_clear(v->shadow_vmcs); + } kvm_cpu_vmxoff(); } From 61850a1b26735b601fe3c1dcfcd0dea704eca5de Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Tue, 3 Jun 2025 18:53:17 +0200 Subject: [PATCH 489/971] dm-mirror: fix a tiny race condition commit 829451beaed6165eb11d7a9fb4e28eb17f489980 upstream. There's a tiny race condition in dm-mirror. The functions queue_bio and write_callback grab a spinlock, add a bio to the list, drop the spinlock and wake up the mirrord thread that processes bios in the list. It may be possible that the mirrord thread processes the bio just after spin_unlock_irqrestore is called, before wakeup_mirrord. This spurious wake-up is normally harmless, however if the device mapper device is unloaded just after the bio was processed, it may be possible that wakeup_mirrord(ms) uses invalid "ms" pointer. Fix this bug by moving wakeup_mirrord inside the spinlock. Signed-off-by: Mikulas Patocka Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-raid1.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 9511dae5b556..94b6c43dfa5c 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -133,10 +133,9 @@ static void queue_bio(struct mirror_set *ms, struct bio *bio, int rw) spin_lock_irqsave(&ms->lock, flags); should_wake = !(bl->head); bio_list_add(bl, bio); - spin_unlock_irqrestore(&ms->lock, flags); - if (should_wake) wakeup_mirrord(ms); + spin_unlock_irqrestore(&ms->lock, flags); } static void dispatch_bios(void *context, struct bio_list *bio_list) @@ -646,9 +645,9 @@ static void write_callback(unsigned long error, void *context) if (!ms->failures.head) should_wake = 1; bio_list_add(&ms->failures, bio); - spin_unlock_irqrestore(&ms->lock, flags); if (should_wake) wakeup_mirrord(ms); + spin_unlock_irqrestore(&ms->lock, flags); } static void do_write(struct mirror_set *ms, struct bio *bio) From df4918c0bb494125bb90861d6513eea908a05f6e Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Tue, 3 Jun 2025 18:55:50 +0200 Subject: [PATCH 490/971] dm-verity: fix a memory leak if some arguments are specified multiple times commit 66be40a14e496689e1f0add50118408e22c96169 upstream. If some of the arguments "check_at_most_once", "ignore_zero_blocks", "use_fec_from_device", "root_hash_sig_key_desc" were specified more than once on the target line, a memory leak would happen. This commit fixes the memory leak. It also fixes error handling in verity_verify_sig_parse_opt_args. Signed-off-by: Mikulas Patocka Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-verity-fec.c | 4 ++++ drivers/md/dm-verity-target.c | 8 +++++++- drivers/md/dm-verity-verify-sig.c | 17 +++++++++++++---- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c index 6a7a17c489c9..8007e2e21972 100644 --- a/drivers/md/dm-verity-fec.c +++ b/drivers/md/dm-verity-fec.c @@ -624,6 +624,10 @@ int verity_fec_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v, (*argc)--; if (!strcasecmp(arg_name, DM_VERITY_OPT_FEC_DEV)) { + if (v->fec->dev) { + ti->error = "FEC device already specified"; + return -EINVAL; + } r = dm_get_device(ti, arg_value, BLK_OPEN_READ, &v->fec->dev); if (r) { ti->error = "FEC device lookup failed"; diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c index 6ae97da741bb..60e74c0e02f1 100644 --- a/drivers/md/dm-verity-target.c +++ b/drivers/md/dm-verity-target.c @@ -1043,6 +1043,9 @@ static int verity_alloc_most_once(struct dm_verity *v) { struct dm_target *ti = v->ti; + if (v->validated_blocks) + return 0; + /* the bitset can only handle INT_MAX blocks */ if (v->data_blocks > INT_MAX) { ti->error = "device too large to use check_at_most_once"; @@ -1066,6 +1069,9 @@ static int verity_alloc_zero_digest(struct dm_verity *v) struct ahash_request *req; u8 *zero_data; + if (v->zero_digest) + return 0; + v->zero_digest = kmalloc(v->digest_size, GFP_KERNEL); if (!v->zero_digest) @@ -1405,7 +1411,7 @@ static int verity_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto bad; } - /* Root hash signature is a optional parameter*/ + /* Root hash signature is an optional parameter */ r = verity_verify_root_hash(root_hash_digest_to_validate, strlen(root_hash_digest_to_validate), verify_args.sig, diff --git a/drivers/md/dm-verity-verify-sig.c b/drivers/md/dm-verity-verify-sig.c index 4836508ea50c..1ced2ef255f3 100644 --- a/drivers/md/dm-verity-verify-sig.c +++ b/drivers/md/dm-verity-verify-sig.c @@ -71,9 +71,14 @@ int verity_verify_sig_parse_opt_args(struct dm_arg_set *as, const char *arg_name) { struct dm_target *ti = v->ti; - int ret = 0; + int ret; const char *sig_key = NULL; + if (v->signature_key_desc) { + ti->error = DM_VERITY_VERIFY_ERR("root_hash_sig_key_desc already specified"); + return -EINVAL; + } + if (!*argc) { ti->error = DM_VERITY_VERIFY_ERR("Signature key not specified"); return -EINVAL; @@ -83,14 +88,18 @@ int verity_verify_sig_parse_opt_args(struct dm_arg_set *as, (*argc)--; ret = verity_verify_get_sig_from_key(sig_key, sig_opts); - if (ret < 0) + if (ret < 0) { ti->error = DM_VERITY_VERIFY_ERR("Invalid key specified"); + return ret; + } v->signature_key_desc = kstrdup(sig_key, GFP_KERNEL); - if (!v->signature_key_desc) + if (!v->signature_key_desc) { + ti->error = DM_VERITY_VERIFY_ERR("Could not allocate memory for signature key"); return -ENOMEM; + } - return ret; + return 0; } /* From 6737c4551d2be84d51b9c10beedae0ce1e5cdd39 Mon Sep 17 00:00:00 2001 From: Md Sadre Alam Date: Thu, 10 Apr 2025 15:30:19 +0530 Subject: [PATCH 491/971] mtd: rawnand: qcom: Fix read len for onfi param page commit e6031b11544b44966ba020c867fe438bccd3bdfa upstream. The minimum size to fetch the data from device to QPIC buffer is 512-bytes. If size is less than 512-bytes the data will not be protected by ECC as per QPIC standard. So while reading onfi parameter page from NAND device set nandc->buf_count = 512. Cc: stable@vger.kernel.org Fixes: 89550beb098e ("mtd: rawnand: qcom: Implement exec_op()") Reviewed-by: Manivannan Sadhasivam Tested-by: Lakshmi Sowjanya D Signed-off-by: Md Sadre Alam Signed-off-by: Miquel Raynal Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/nand/raw/qcom_nandc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c index b8cff9240b28..beafca6ba0df 100644 --- a/drivers/mtd/nand/raw/qcom_nandc.c +++ b/drivers/mtd/nand/raw/qcom_nandc.c @@ -2917,7 +2917,7 @@ static int qcom_param_page_type_exec(struct nand_chip *chip, const struct nand_ write_reg_dma(nandc, NAND_DEV_CMD1, 1, NAND_BAM_NEXT_SGL); } - nandc->buf_count = len; + nandc->buf_count = 512; memset(nandc->data_buffer, 0xff, nandc->buf_count); config_nand_single_cw_page_read(chip, false, 0); From 83a692a9792aa86249d68a8ac0b9d55ecdd255fa Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Thu, 29 May 2025 19:19:54 +0800 Subject: [PATCH 492/971] ftrace: Fix UAF when lookup kallsym after ftrace disabled commit f914b52c379c12288b7623bb814d0508dbe7481d upstream. The following issue happens with a buggy module: BUG: unable to handle page fault for address: ffffffffc05d0218 PGD 1bd66f067 P4D 1bd66f067 PUD 1bd671067 PMD 101808067 PTE 0 Oops: Oops: 0000 [#1] SMP KASAN PTI Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS RIP: 0010:sized_strscpy+0x81/0x2f0 RSP: 0018:ffff88812d76fa08 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffffffffc0601010 RCX: dffffc0000000000 RDX: 0000000000000038 RSI: dffffc0000000000 RDI: ffff88812608da2d RBP: 8080808080808080 R08: ffff88812608da2d R09: ffff88812608da68 R10: ffff88812608d82d R11: ffff88812608d810 R12: 0000000000000038 R13: ffff88812608da2d R14: ffffffffc05d0218 R15: fefefefefefefeff FS: 00007fef552de740(0000) GS:ffff8884251c7000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffffffc05d0218 CR3: 00000001146f0000 CR4: 00000000000006f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: ftrace_mod_get_kallsym+0x1ac/0x590 update_iter_mod+0x239/0x5b0 s_next+0x5b/0xa0 seq_read_iter+0x8c9/0x1070 seq_read+0x249/0x3b0 proc_reg_read+0x1b0/0x280 vfs_read+0x17f/0x920 ksys_read+0xf3/0x1c0 do_syscall_64+0x5f/0x2e0 entry_SYSCALL_64_after_hwframe+0x76/0x7e The above issue may happen as follows: (1) Add kprobe tracepoint; (2) insmod test.ko; (3) Module triggers ftrace disabled; (4) rmmod test.ko; (5) cat /proc/kallsyms; --> Will trigger UAF as test.ko already removed; ftrace_mod_get_kallsym() ... strscpy(module_name, mod_map->mod->name, MODULE_NAME_LEN); ... The problem is when a module triggers an issue with ftrace and sets ftrace_disable. The ftrace_disable is set when an anomaly is discovered and to prevent any more damage, ftrace stops all text modification. The issue that happened was that the ftrace_disable stops more than just the text modification. When a module is loaded, its init functions can also be traced. Because kallsyms deletes the init functions after a module has loaded, ftrace saves them when the module is loaded and function tracing is enabled. This allows the output of the function trace to show the init function names instead of just their raw memory addresses. When a module is removed, ftrace_release_mod() is called, and if ftrace_disable is set, it just returns without doing anything more. The problem here is that it leaves the mod_list still around and if kallsyms is called, it will call into this code and access the module memory that has already been freed as it will return: strscpy(module_name, mod_map->mod->name, MODULE_NAME_LEN); Where the "mod" no longer exists and triggers a UAF bug. Link: https://lore.kernel.org/all/20250523135452.626d8dcd@gandalf.local.home/ Cc: stable@vger.kernel.org Fixes: aba4b5c22cba ("ftrace: Save module init functions kallsyms symbols for tracing") Link: https://lore.kernel.org/20250529111955.2349189-2-yebin@huaweicloud.com Signed-off-by: Ye Bin Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/ftrace.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 650493ed76cd..4351b9069a91 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -6772,9 +6772,10 @@ void ftrace_release_mod(struct module *mod) mutex_lock(&ftrace_lock); - if (ftrace_disabled) - goto out_unlock; - + /* + * To avoid the UAF problem after the module is unloaded, the + * 'mod_map' resource needs to be released unconditionally. + */ list_for_each_entry_safe(mod_map, n, &ftrace_mod_maps, list) { if (mod_map->mod == mod) { list_del_rcu(&mod_map->list); @@ -6783,6 +6784,9 @@ void ftrace_release_mod(struct module *mod) } } + if (ftrace_disabled) + goto out_unlock; + /* * Each module has its own ftrace_pages, remove * them from the list. From b1bf167f46dd52836f058b5d0a4e06e3e1efa274 Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Wed, 30 Apr 2025 17:45:01 +0800 Subject: [PATCH 493/971] phy: fsl-imx8mq-usb: fix phy_tx_vboost_level_from_property() commit b15ee09ddb987a122e74fb0fdf1bd6e864959fd3 upstream. The description of TX_VBOOST_LVL is wrong in register PHY_CTRL3 bit[31:29]. The updated description as below: 011: Corresponds to a launch amplitude of 0.844 V. 100: Corresponds to a launch amplitude of 1.008 V. 101: Corresponds to a launch amplitude of 1.156 V. This will fix the parsing function phy_tx_vboost_level_from_property() to return correct value. Fixes: 63c85ad0cd81 ("phy: fsl-imx8mp-usb: add support for phy tuning") Cc: stable@vger.kernel.org Reviewed-by: Jun Li Signed-off-by: Xu Yang Link: https://lore.kernel.org/r/20250430094502.2723983-3-xu.yang_2@nxp.com Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman --- drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c index adc6394626ce..f914f016b3d2 100644 --- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c +++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c @@ -95,12 +95,12 @@ static u32 phy_tx_preemp_amp_tune_from_property(u32 microamp) static u32 phy_tx_vboost_level_from_property(u32 microvolt) { switch (microvolt) { - case 0 ... 960: - return 0; - case 961 ... 1160: - return 2; - default: + case 1156: + return 5; + case 844: return 3; + default: + return 4; } } From 6bd2569d0b2f918e9581f744df0263caf73ee76c Mon Sep 17 00:00:00 2001 From: Qasim Ijaz Date: Mon, 26 May 2025 19:36:07 +0100 Subject: [PATCH 494/971] net: ch9200: fix uninitialised access during mii_nway_restart commit 9ad0452c0277b816a435433cca601304cfac7c21 upstream. In mii_nway_restart() the code attempts to call mii->mdio_read which is ch9200_mdio_read(). ch9200_mdio_read() utilises a local buffer called "buff", which is initialised with control_read(). However "buff" is conditionally initialised inside control_read(): if (err == size) { memcpy(data, buf, size); } If the condition of "err == size" is not met, then "buff" remains uninitialised. Once this happens the uninitialised "buff" is accessed and returned during ch9200_mdio_read(): return (buff[0] | buff[1] << 8); The problem stems from the fact that ch9200_mdio_read() ignores the return value of control_read(), leading to uinit-access of "buff". To fix this we should check the return value of control_read() and return early on error. Reported-by: syzbot Closes: https://syzkaller.appspot.com/bug?extid=3361c2d6f78a3e0892f9 Tested-by: syzbot Fixes: 4a476bd6d1d9 ("usbnet: New driver for QinHeng CH9200 devices") Cc: stable@vger.kernel.org Signed-off-by: Qasim Ijaz Link: https://patch.msgid.link/20250526183607.66527-1-qasdev00@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/ch9200.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/ch9200.c b/drivers/net/usb/ch9200.c index f69d9b902da0..a206ffa76f1b 100644 --- a/drivers/net/usb/ch9200.c +++ b/drivers/net/usb/ch9200.c @@ -178,6 +178,7 @@ static int ch9200_mdio_read(struct net_device *netdev, int phy_id, int loc) { struct usbnet *dev = netdev_priv(netdev); unsigned char buff[2]; + int ret; netdev_dbg(netdev, "%s phy_id:%02x loc:%02x\n", __func__, phy_id, loc); @@ -185,8 +186,10 @@ static int ch9200_mdio_read(struct net_device *netdev, int phy_id, int loc) if (phy_id != 0) return -ENODEV; - control_read(dev, REQUEST_READ, 0, loc * 2, buff, 0x02, - CONTROL_TIMEOUT_MS); + ret = control_read(dev, REQUEST_READ, 0, loc * 2, buff, 0x02, + CONTROL_TIMEOUT_MS); + if (ret < 0) + return ret; return (buff[0] | buff[1] << 8); } From fa2118e9e2339732adbc3acaa3da1b56c506b332 Mon Sep 17 00:00:00 2001 From: Lorenzo Stoakes Date: Mon, 19 May 2025 15:56:57 +0100 Subject: [PATCH 495/971] KVM: s390: rename PROT_NONE to PROT_TYPE_DUMMY commit 15ac613f124e51a6623975efad9657b1f3ee47e7 upstream. The enum type prot_type declared in arch/s390/kvm/gaccess.c declares an unfortunate identifier within it - PROT_NONE. This clashes with the protection bit define from the uapi for mmap() declared in include/uapi/asm-generic/mman-common.h, which is indeed what those casually reading this code would assume this to refer to. This means that any changes which subsequently alter headers in any way which results in the uapi header being imported here will cause build errors. Resolve the issue by renaming PROT_NONE to PROT_TYPE_DUMMY. Link: https://lkml.kernel.org/r/20250519145657.178365-1-lorenzo.stoakes@oracle.com Fixes: b3cefd6bf16e ("KVM: s390: Pass initialized arg even if unused") Signed-off-by: Lorenzo Stoakes Suggested-by: Ignacio Moreno Gonzalez Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202505140943.IgHDa9s7-lkp@intel.com/ Acked-by: Christian Borntraeger Acked-by: Ignacio Moreno Gonzalez Acked-by: Yang Shi Reviewed-by: David Hildenbrand Acked-by: Liam R. Howlett Reviewed-by: Oscar Salvador Reviewed-by: Claudio Imbrenda Cc: Cc: Alexander Gordeev Cc: Heiko Carstens Cc: James Houghton Cc: Janosch Frank Cc: Matthew Wilcox (Oracle) Cc: Paolo Bonzini Cc: Sven Schnelle Cc: Vasily Gorbik Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/s390/kvm/gaccess.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c index 090dc3833433..969a5e156919 100644 --- a/arch/s390/kvm/gaccess.c +++ b/arch/s390/kvm/gaccess.c @@ -490,7 +490,7 @@ enum prot_type { PROT_TYPE_DAT = 3, PROT_TYPE_IEP = 4, /* Dummy value for passing an initialized value when code != PGM_PROTECTION */ - PROT_NONE, + PROT_TYPE_DUMMY, }; static int trans_exc_ending(struct kvm_vcpu *vcpu, int code, unsigned long gva, u8 ar, @@ -506,7 +506,7 @@ static int trans_exc_ending(struct kvm_vcpu *vcpu, int code, unsigned long gva, switch (code) { case PGM_PROTECTION: switch (prot) { - case PROT_NONE: + case PROT_TYPE_DUMMY: /* We should never get here, acts like termination */ WARN_ON_ONCE(1); break; @@ -976,7 +976,7 @@ static int guest_range_to_gpas(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, gpa = kvm_s390_real_to_abs(vcpu, ga); if (kvm_is_error_gpa(vcpu->kvm, gpa)) { rc = PGM_ADDRESSING; - prot = PROT_NONE; + prot = PROT_TYPE_DUMMY; } } if (rc) @@ -1134,7 +1134,7 @@ int access_guest_with_key(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, if (rc == PGM_PROTECTION) prot = PROT_TYPE_KEYC; else - prot = PROT_NONE; + prot = PROT_TYPE_DUMMY; rc = trans_exc_ending(vcpu, rc, ga, ar, mode, prot, terminate); } out_unlock: From cc3cc41ed67054a03134bea42408c720eec0fa04 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 28 May 2025 10:02:08 +0200 Subject: [PATCH 496/971] video: screen_info: Relocate framebuffers behind PCI bridges commit 2f29b5c231011b94007d2c8a6d793992f2275db1 upstream. Apply PCI host-bridge window offsets to screen_info framebuffers. Fixes invalid access to I/O memory. Resources behind a PCI host bridge can be relocated by a certain offset in the kernel's CPU address range used for I/O. The framebuffer memory range stored in screen_info refers to the CPU addresses as seen during boot (where the offset is 0). During boot up, firmware may assign a different memory offset to the PCI host bridge and thereby relocating the framebuffer address of the PCI graphics device as seen by the kernel. The information in screen_info must be updated as well. The helper pcibios_bus_to_resource() performs the relocation of the screen_info's framebuffer resource (given in PCI bus addresses). The result matches the I/O-memory resource of the PCI graphics device (given in CPU addresses). As before, we store away the information necessary to later update the information in screen_info itself. Commit 78aa89d1dfba ("firmware/sysfb: Update screen_info for relocated EFI framebuffers") added the code for updating screen_info. It is based on similar functionality that pre-existed in efifb. Efifb uses a pointer to the PCI resource, while the newer code does a memcpy of the region. Hence efifb sees any updates to the PCI resource and avoids the issue. v3: - Only use struct pci_bus_region for PCI bus addresses (Bjorn) - Clarify address semantics in commit messages and comments (Bjorn) v2: - Fixed tags (Takashi, Ivan) - Updated information on efifb Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas Reported-by: "Ivan T. Ivanov" Closes: https://bugzilla.suse.com/show_bug.cgi?id=1240696 Tested-by: "Ivan T. Ivanov" Fixes: 78aa89d1dfba ("firmware/sysfb: Update screen_info for relocated EFI framebuffers") Cc: dri-devel@lists.freedesktop.org Cc: # v6.9+ Link: https://lore.kernel.org/r/20250528080234.7380-1-tzimmermann@suse.de Signed-off-by: Greg Kroah-Hartman --- drivers/video/screen_info_pci.c | 75 +++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/drivers/video/screen_info_pci.c b/drivers/video/screen_info_pci.c index 6c5833517141..66bfc1d0a6dc 100644 --- a/drivers/video/screen_info_pci.c +++ b/drivers/video/screen_info_pci.c @@ -7,8 +7,8 @@ static struct pci_dev *screen_info_lfb_pdev; static size_t screen_info_lfb_bar; -static resource_size_t screen_info_lfb_offset; -static struct resource screen_info_lfb_res = DEFINE_RES_MEM(0, 0); +static resource_size_t screen_info_lfb_res_start; // original start of resource +static resource_size_t screen_info_lfb_offset; // framebuffer offset within resource static bool __screen_info_relocation_is_valid(const struct screen_info *si, struct resource *pr) { @@ -31,7 +31,7 @@ void screen_info_apply_fixups(void) if (screen_info_lfb_pdev) { struct resource *pr = &screen_info_lfb_pdev->resource[screen_info_lfb_bar]; - if (pr->start != screen_info_lfb_res.start) { + if (pr->start != screen_info_lfb_res_start) { if (__screen_info_relocation_is_valid(si, pr)) { /* * Only update base if we have an actual @@ -47,46 +47,67 @@ void screen_info_apply_fixups(void) } } +static int __screen_info_lfb_pci_bus_region(const struct screen_info *si, unsigned int type, + struct pci_bus_region *r) +{ + u64 base, size; + + base = __screen_info_lfb_base(si); + if (!base) + return -EINVAL; + + size = __screen_info_lfb_size(si, type); + if (!size) + return -EINVAL; + + r->start = base; + r->end = base + size - 1; + + return 0; +} + static void screen_info_fixup_lfb(struct pci_dev *pdev) { unsigned int type; - struct resource res[SCREEN_INFO_MAX_RESOURCES]; - size_t i, numres; + struct pci_bus_region bus_region; int ret; + struct resource r = { + .flags = IORESOURCE_MEM, + }; + const struct resource *pr; const struct screen_info *si = &screen_info; if (screen_info_lfb_pdev) return; // already found type = screen_info_video_type(si); - if (type != VIDEO_TYPE_EFI) - return; // only applies to EFI + if (!__screen_info_has_lfb(type)) + return; // only applies to EFI; maybe VESA - ret = screen_info_resources(si, res, ARRAY_SIZE(res)); + ret = __screen_info_lfb_pci_bus_region(si, type, &bus_region); if (ret < 0) return; - numres = ret; - for (i = 0; i < numres; ++i) { - struct resource *r = &res[i]; - const struct resource *pr; + /* + * Translate the PCI bus address to resource. Account + * for an offset if the framebuffer is behind a PCI host + * bridge. + */ + pcibios_bus_to_resource(pdev->bus, &r, &bus_region); - if (!(r->flags & IORESOURCE_MEM)) - continue; - pr = pci_find_resource(pdev, r); - if (!pr) - continue; + pr = pci_find_resource(pdev, &r); + if (!pr) + return; - /* - * We've found a PCI device with the framebuffer - * resource. Store away the parameters to track - * relocation of the framebuffer aperture. - */ - screen_info_lfb_pdev = pdev; - screen_info_lfb_bar = pr - pdev->resource; - screen_info_lfb_offset = r->start - pr->start; - memcpy(&screen_info_lfb_res, r, sizeof(screen_info_lfb_res)); - } + /* + * We've found a PCI device with the framebuffer + * resource. Store away the parameters to track + * relocation of the framebuffer aperture. + */ + screen_info_lfb_pdev = pdev; + screen_info_lfb_bar = pr - pdev->resource; + screen_info_lfb_offset = r.start - pr->start; + screen_info_lfb_res_start = bus_region.start; } DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY, 16, screen_info_fixup_lfb); From dfa9ef978d9c795b40244665c155ff2537b32d8a Mon Sep 17 00:00:00 2001 From: Gabriel Shahrouzi Date: Sat, 19 Apr 2025 21:30:09 -0400 Subject: [PATCH 497/971] staging: iio: ad5933: Correct settling cycles encoding per datasheet commit 60638e2a2d4bc03798f00d5ab65ce9b83cb8b03b upstream. The AD5933 datasheet (Table 13) lists the maximum cycles to be 0x7FC (2044). Clamp the user input to the maximum effective value of 0x7FC cycles. Fixes: f94aa354d676 ("iio: impedance-analyzer: New driver for AD5933/4 Impedance Converter, Network Analyzer") Cc: stable@vger.kernel.org Signed-off-by: Gabriel Shahrouzi Reviewed-by: Marcelo Schmitt Link: https://patch.msgid.link/20250420013009.847851-1-gshahrouzi@gmail.com Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/impedance-analyzer/ad5933.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 2d0883a64082..31d82a042dad 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -412,7 +412,7 @@ static ssize_t ad5933_store(struct device *dev, ret = ad5933_cmd(st, 0); break; case AD5933_OUT_SETTLING_CYCLES: - val = clamp(val, (u16)0, (u16)0x7FF); + val = clamp(val, (u16)0, (u16)0x7FC); st->settling_cycles = val; /* 2x, 4x handling, see datasheet */ From 231f6a1de15b3f62eb8d6163a8b1bc5935025c69 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Sat, 29 Mar 2025 08:39:03 -0700 Subject: [PATCH 498/971] mips: Add -std= flag specified in KBUILD_CFLAGS to vdso CFLAGS commit 0f4ae7c6ecb89bfda026d210dcf8216fb67d2333 upstream. GCC 15 changed the default C standard dialect from gnu17 to gnu23, which should not have impacted the kernel because it explicitly requests the gnu11 standard in the main Makefile. However, mips/vdso code uses its own CFLAGS without a '-std=' value, which break with this dialect change because of the kernel's own definitions of bool, false, and true conflicting with the C23 reserved keywords. include/linux/stddef.h:11:9: error: cannot use keyword 'false' as enumeration constant 11 | false = 0, | ^~~~~ include/linux/stddef.h:11:9: note: 'false' is a keyword with '-std=c23' onwards include/linux/types.h:35:33: error: 'bool' cannot be defined via 'typedef' 35 | typedef _Bool bool; | ^~~~ include/linux/types.h:35:33: note: 'bool' is a keyword with '-std=c23' onwards Add -std as specified in KBUILD_CFLAGS to the decompressor and purgatory CFLAGS to eliminate these errors and make the C standard version of these areas match the rest of the kernel. Signed-off-by: Khem Raj Cc: stable@vger.kernel.org Signed-off-by: Thomas Bogendoerfer Signed-off-by: Greg Kroah-Hartman --- arch/mips/vdso/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile index eb56581f6d73..0a3249647401 100644 --- a/arch/mips/vdso/Makefile +++ b/arch/mips/vdso/Makefile @@ -30,6 +30,7 @@ endif # offsets. cflags-vdso := $(ccflags-vdso) \ $(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \ + $(filter -std=%,$(KBUILD_CFLAGS)) \ -O3 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \ -mrelax-pic-calls $(call cc-option, -mexplicit-relocs) \ -fno-stack-protector -fno-jump-tables -DDISABLE_BRANCH_PROFILING \ From a4df96e2e81cf3b052adb2312a8269e089c23ea5 Mon Sep 17 00:00:00 2001 From: Wentao Liang Date: Mon, 26 May 2025 10:56:27 +0800 Subject: [PATCH 499/971] regulator: max14577: Add error check for max14577_read_reg() commit 65271f868cb1dca709ff69e45939bbef8d6d0b70 upstream. The function max14577_reg_get_current_limit() calls the function max14577_read_reg(), but does not check its return value. A proper implementation can be found in max14577_get_online(). Add a error check for the max14577_read_reg() and return error code if the function fails. Fixes: b0902bbeb768 ("regulator: max14577: Add regulator driver for Maxim 14577") Cc: stable@vger.kernel.org # v3.14 Signed-off-by: Wentao Liang Link: https://patch.msgid.link/20250526025627.407-1-vulab@iscas.ac.cn Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/regulator/max14577-regulator.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/max14577-regulator.c b/drivers/regulator/max14577-regulator.c index 5e7171b9065a..41fd15adfd1f 100644 --- a/drivers/regulator/max14577-regulator.c +++ b/drivers/regulator/max14577-regulator.c @@ -40,11 +40,14 @@ static int max14577_reg_get_current_limit(struct regulator_dev *rdev) struct max14577 *max14577 = rdev_get_drvdata(rdev); const struct maxim_charger_current *limits = &maxim_charger_currents[max14577->dev_type]; + int ret; if (rdev_get_id(rdev) != MAX14577_CHARGER) return -EINVAL; - max14577_read_reg(rmap, MAX14577_CHG_REG_CHG_CTRL4, ®_data); + ret = max14577_read_reg(rmap, MAX14577_CHG_REG_CHG_CTRL4, ®_data); + if (ret < 0) + return ret; if ((reg_data & CHGCTRL4_MBCICHWRCL_MASK) == 0) return limits->min; From 9515d74c9d1ae7308a02e8bd4f894eb8137cf8df Mon Sep 17 00:00:00 2001 From: Xiaolei Wang Date: Wed, 30 Apr 2025 17:20:42 +0800 Subject: [PATCH 500/971] remoteproc: core: Cleanup acquired resources when rproc_handle_resources() fails in rproc_attach() commit 7692c9fbedd9087dc9050903f58095915458d9b1 upstream. When rproc->state = RPROC_DETACHED and rproc_attach() is used to attach to the remote processor, if rproc_handle_resources() returns a failure, the resources allocated by imx_rproc_prepare() should be released, otherwise the following memory leak will occur. Since almost the same thing is done in imx_rproc_prepare() and rproc_resource_cleanup(), Function rproc_resource_cleanup() is able to deal with empty lists so it is better to fix the "goto" statements in rproc_attach(). replace the "unprepare_device" goto statement with "clean_up_resources" and get rid of the "unprepare_device" label. unreferenced object 0xffff0000861c5d00 (size 128): comm "kworker/u12:3", pid 59, jiffies 4294893509 (age 149.220s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 02 88 00 00 00 00 00 00 10 00 00 00 00 00 ............ backtrace: [<00000000f949fe18>] slab_post_alloc_hook+0x98/0x37c [<00000000adbfb3e7>] __kmem_cache_alloc_node+0x138/0x2e0 [<00000000521c0345>] kmalloc_trace+0x40/0x158 [<000000004e330a49>] rproc_mem_entry_init+0x60/0xf8 [<000000002815755e>] imx_rproc_prepare+0xe0/0x180 [<0000000003f61b4e>] rproc_boot+0x2ec/0x528 [<00000000e7e994ac>] rproc_add+0x124/0x17c [<0000000048594076>] imx_rproc_probe+0x4ec/0x5d4 [<00000000efc298a1>] platform_probe+0x68/0xd8 [<00000000110be6fe>] really_probe+0x110/0x27c [<00000000e245c0ae>] __driver_probe_device+0x78/0x12c [<00000000f61f6f5e>] driver_probe_device+0x3c/0x118 [<00000000a7874938>] __device_attach_driver+0xb8/0xf8 [<0000000065319e69>] bus_for_each_drv+0x84/0xe4 [<00000000db3eb243>] __device_attach+0xfc/0x18c [<0000000072e4e1a4>] device_initial_probe+0x14/0x20 Fixes: 10a3d4079eae ("remoteproc: imx_rproc: move memory parsing to rproc_ops") Suggested-by: Mathieu Poirier Signed-off-by: Xiaolei Wang Reviewed-by: Peng Fan Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20250430092043.1819308-2-xiaolei.wang@windriver.com Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/remoteproc/remoteproc_core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 0c363ca566ff..7b9f6bc4cb1f 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -1616,7 +1616,7 @@ static int rproc_attach(struct rproc *rproc) ret = rproc_set_rsc_table(rproc); if (ret) { dev_err(dev, "can't load resource table: %d\n", ret); - goto unprepare_device; + goto clean_up_resources; } /* reset max_notifyid */ @@ -1633,7 +1633,7 @@ static int rproc_attach(struct rproc *rproc) ret = rproc_handle_resources(rproc, rproc_loading_handlers); if (ret) { dev_err(dev, "Failed to process resources: %d\n", ret); - goto unprepare_device; + goto clean_up_resources; } /* Allocate carveout resources associated to rproc */ @@ -1652,7 +1652,6 @@ static int rproc_attach(struct rproc *rproc) clean_up_resources: rproc_resource_cleanup(rproc); -unprepare_device: /* release HW resources if needed */ rproc_unprepare_device(rproc); disable_iommu: From 3ee979709e16a83b257bc9a544a7ff71fd445ea9 Mon Sep 17 00:00:00 2001 From: Xiaolei Wang Date: Wed, 30 Apr 2025 17:20:43 +0800 Subject: [PATCH 501/971] remoteproc: core: Release rproc->clean_table after rproc_attach() fails commit bcd241230fdbc6005230f80a4f8646ff5a84f15b upstream. When rproc->state = RPROC_DETACHED is attached to remote processor through rproc_attach(), if rproc_handle_resources() returns failure, then the clean table should be released, otherwise the following memory leak will occur. unreferenced object 0xffff000086a99800 (size 1024): comm "kworker/u12:3", pid 59, jiffies 4294893670 (age 121.140s) hex dump (first 32 bytes): 00 00 00 00 00 80 00 00 00 00 00 00 00 00 10 00 ............ 00 00 00 00 00 00 08 00 00 00 00 00 00 00 00 00 ............ backtrace: [<000000008bbe4ca8>] slab_post_alloc_hook+0x98/0x3fc [<000000003b8a272b>] __kmem_cache_alloc_node+0x13c/0x230 [<000000007a507c51>] __kmalloc_node_track_caller+0x5c/0x260 [<0000000037818dae>] kmemdup+0x34/0x60 [<00000000610f7f57>] rproc_boot+0x35c/0x56c [<0000000065f8871a>] rproc_add+0x124/0x17c [<00000000497416ee>] imx_rproc_probe+0x4ec/0x5d4 [<000000003bcaa37d>] platform_probe+0x68/0xd8 [<00000000771577f9>] really_probe+0x110/0x27c [<00000000531fea59>] __driver_probe_device+0x78/0x12c [<0000000080036a04>] driver_probe_device+0x3c/0x118 [<000000007e0bddcb>] __device_attach_driver+0xb8/0xf8 [<000000000cf1fa33>] bus_for_each_drv+0x84/0xe4 [<000000001a53b53e>] __device_attach+0xfc/0x18c [<00000000d1a2a32c>] device_initial_probe+0x14/0x20 [<00000000d8f8b7ae>] bus_probe_device+0xb0/0xb4 unreferenced object 0xffff0000864c9690 (size 16): Fixes: 9dc9507f1880 ("remoteproc: Properly deal with the resource table when detaching") Signed-off-by: Xiaolei Wang Reviewed-by: Peng Fan Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20250430092043.1819308-3-xiaolei.wang@windriver.com Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/remoteproc/remoteproc_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 7b9f6bc4cb1f..2d4ae3b5af86 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -1654,6 +1654,7 @@ clean_up_resources: rproc_resource_cleanup(rproc); /* release HW resources if needed */ rproc_unprepare_device(rproc); + kfree(rproc->clean_table); disable_iommu: rproc_disable_iommu(rproc); return ret; From 9d80e1d37e85d8c75d5aedc747a3daf2033fc61b Mon Sep 17 00:00:00 2001 From: Shyam Prasad N Date: Mon, 2 Jun 2025 22:37:13 +0530 Subject: [PATCH 502/971] cifs: reset connections for all channels when reconnect requested commit 1f396b9bfe39aaf55ea74a7005806164b236653d upstream. cifs_reconnect can be called with a flag to mark the session as needing reconnect too. When this is done, we expect the connections of all channels to be reconnected too, which is not happening today. Without doing this, we have seen bad things happen when primary and secondary channels are connected to different servers (in case of cloud services like Azure Files SMB). This change would force all connections to reconnect as well, not just the sessions and tcons. Cc: Signed-off-by: Shyam Prasad N Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/smb/client/connect.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c index 3faaee33ad45..b03ea877602c 100644 --- a/fs/smb/client/connect.c +++ b/fs/smb/client/connect.c @@ -393,6 +393,13 @@ static int __cifs_reconnect(struct TCP_Server_Info *server, if (!cifs_tcp_ses_needs_reconnect(server, 1)) return 0; + /* + * if smb session has been marked for reconnect, also reconnect all + * connections. This way, the other connections do not end up bad. + */ + if (mark_smb_session) + cifs_signal_cifsd_for_reconnect(server, mark_smb_session); + cifs_mark_tcp_ses_conns_for_reconnect(server, mark_smb_session); cifs_abort_connection(server); From 5713127da8552f69e0311f9b7ba1ade04f4328c3 Mon Sep 17 00:00:00 2001 From: Shyam Prasad N Date: Mon, 2 Jun 2025 22:37:14 +0530 Subject: [PATCH 503/971] cifs: update dstaddr whenever channel iface is updated commit c1846893991f3b4ec8a0cc12219ada153f0814d6 upstream. When the server interface info changes (more common in clustered servers like Azure Files), the per-channel iface gets updated. However, this did not update the corresponding dstaddr. As a result these channels will still connect (or try connecting) to older addresses. Fixes: b54034a73baf ("cifs: during reconnect, update interface if necessary") Cc: Signed-off-by: Shyam Prasad N Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/smb/client/sess.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c index f04922eb45d4..c9e6de42eedb 100644 --- a/fs/smb/client/sess.c +++ b/fs/smb/client/sess.c @@ -485,6 +485,10 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server) ses->chans[chan_index].iface = iface; spin_unlock(&ses->chan_lock); + + spin_lock(&server->srv_lock); + memcpy(&server->dstaddr, &iface->sockaddr, sizeof(server->dstaddr)); + spin_unlock(&server->srv_lock); } /* From 39ff3774693f5ff410b44afa96dbfd4ac5d0b984 Mon Sep 17 00:00:00 2001 From: Shyam Prasad N Date: Mon, 2 Jun 2025 22:37:16 +0530 Subject: [PATCH 504/971] cifs: dns resolution is needed only for primary channel commit b4f60a053a2534c3e510ba0c1f8727566adf8317 upstream. When calling cifs_reconnect, before the connection to the server is reestablished, the code today does a DNS resolution and updates server->dstaddr. However, this is not necessary for secondary channels. Secondary channels use the interface list returned by the server to decide which address to connect to. And that happens after tcon is reconnected and server interfaces are requested. Signed-off-by: Shyam Prasad N Cc: stable@vger.kernel.org Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/smb/client/connect.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c index b03ea877602c..ccf0a2c67479 100644 --- a/fs/smb/client/connect.c +++ b/fs/smb/client/connect.c @@ -408,7 +408,8 @@ static int __cifs_reconnect(struct TCP_Server_Info *server, try_to_freeze(); cifs_server_lock(server); - if (!cifs_swn_set_server_dstaddr(server)) { + if (!cifs_swn_set_server_dstaddr(server) && + !SERVER_IS_CHAN(server)) { /* resolve the hostname again to make sure that IP address is up-to-date */ rc = reconn_set_ipaddr_from_hostname(server); cifs_dbg(FYI, "%s: reconn_set_ipaddr_from_hostname: rc=%d\n", __func__, rc); From 37166d63e42c34846a16001950ecec96229a8d17 Mon Sep 17 00:00:00 2001 From: Ruben Devos Date: Sun, 1 Jun 2025 19:18:55 +0200 Subject: [PATCH 505/971] smb: client: add NULL check in automount_fullpath commit f1e7a277a1736e12cc4bd6d93b8a5c439b8ca20c upstream. page is checked for null in __build_path_from_dentry_optional_prefix when tcon->origin_fullpath is not set. However, the check is missing when it is set. Add a check to prevent a potential NULL pointer dereference. Signed-off-by: Ruben Devos Cc: stable@vger.kernel.org Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/smb/client/namespace.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/smb/client/namespace.c b/fs/smb/client/namespace.c index 830f2a292bb0..ec58c0e50724 100644 --- a/fs/smb/client/namespace.c +++ b/fs/smb/client/namespace.c @@ -146,6 +146,9 @@ static char *automount_fullpath(struct dentry *dentry, void *page) } spin_unlock(&tcon->tc_lock); + if (unlikely(!page)) + return ERR_PTR(-ENOMEM); + s = dentry_path_raw(dentry, page, PATH_MAX); if (IS_ERR(s)) return s; From 6f824cdd8209cddca06d1667c1ff467f2bf5a759 Mon Sep 17 00:00:00 2001 From: Long Li Date: Mon, 5 May 2025 17:56:33 -0700 Subject: [PATCH 506/971] Drivers: hv: Allocate interrupt and monitor pages aligned to system page boundary commit 09eea7ad0b8e973dcf5ed49902838e5d68177f8e upstream. There are use cases that interrupt and monitor pages are mapped to user-mode through UIO, so they need to be system page aligned. Some Hyper-V allocation APIs introduced earlier broke those requirements. Fix this by using page allocation functions directly for interrupt and monitor pages. Cc: stable@vger.kernel.org Fixes: ca48739e59df ("Drivers: hv: vmbus: Move Hyper-V page allocator to arch neutral code") Signed-off-by: Long Li Reviewed-by: Michael Kelley Link: https://lore.kernel.org/r/1746492997-4599-2-git-send-email-longli@linuxonhyperv.com Signed-off-by: Wei Liu Message-ID: <1746492997-4599-2-git-send-email-longli@linuxonhyperv.com> Signed-off-by: Greg Kroah-Hartman --- drivers/hv/connection.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c index f001ae880e1d..27306c17b0c4 100644 --- a/drivers/hv/connection.c +++ b/drivers/hv/connection.c @@ -206,11 +206,20 @@ int vmbus_connect(void) INIT_LIST_HEAD(&vmbus_connection.chn_list); mutex_init(&vmbus_connection.channel_mutex); + /* + * The following Hyper-V interrupt and monitor pages can be used by + * UIO for mapping to user-space, so they should always be allocated on + * system page boundaries. The system page size must be >= the Hyper-V + * page size. + */ + BUILD_BUG_ON(PAGE_SIZE < HV_HYP_PAGE_SIZE); + /* * Setup the vmbus event connection for channel interrupt * abstraction stuff */ - vmbus_connection.int_page = hv_alloc_hyperv_zeroed_page(); + vmbus_connection.int_page = + (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO); if (vmbus_connection.int_page == NULL) { ret = -ENOMEM; goto cleanup; @@ -225,8 +234,8 @@ int vmbus_connect(void) * Setup the monitor notification facility. The 1st page for * parent->child and the 2nd page for child->parent */ - vmbus_connection.monitor_pages[0] = hv_alloc_hyperv_page(); - vmbus_connection.monitor_pages[1] = hv_alloc_hyperv_page(); + vmbus_connection.monitor_pages[0] = (void *)__get_free_page(GFP_KERNEL); + vmbus_connection.monitor_pages[1] = (void *)__get_free_page(GFP_KERNEL); if ((vmbus_connection.monitor_pages[0] == NULL) || (vmbus_connection.monitor_pages[1] == NULL)) { ret = -ENOMEM; @@ -342,21 +351,23 @@ void vmbus_disconnect(void) destroy_workqueue(vmbus_connection.work_queue); if (vmbus_connection.int_page) { - hv_free_hyperv_page(vmbus_connection.int_page); + free_page((unsigned long)vmbus_connection.int_page); vmbus_connection.int_page = NULL; } if (vmbus_connection.monitor_pages[0]) { if (!set_memory_encrypted( (unsigned long)vmbus_connection.monitor_pages[0], 1)) - hv_free_hyperv_page(vmbus_connection.monitor_pages[0]); + free_page((unsigned long) + vmbus_connection.monitor_pages[0]); vmbus_connection.monitor_pages[0] = NULL; } if (vmbus_connection.monitor_pages[1]) { if (!set_memory_encrypted( (unsigned long)vmbus_connection.monitor_pages[1], 1)) - hv_free_hyperv_page(vmbus_connection.monitor_pages[1]); + free_page((unsigned long) + vmbus_connection.monitor_pages[1]); vmbus_connection.monitor_pages[1] = NULL; } } From 7ca06d696a2f00fa9f8fd90f71354aa552525525 Mon Sep 17 00:00:00 2001 From: Long Li Date: Mon, 5 May 2025 17:56:34 -0700 Subject: [PATCH 507/971] uio_hv_generic: Use correct size for interrupt and monitor pages commit c951ab8fd3589cf6991ed4111d2130816f2e3ac2 upstream. Interrupt and monitor pages should be in Hyper-V page size (4k bytes). This can be different from the system page size. This size is read and used by the user-mode program to determine the mapped data region. An example of such user-mode program is the VMBus driver in DPDK. Cc: stable@vger.kernel.org Fixes: 95096f2fbd10 ("uio-hv-generic: new userspace i/o driver for VMBus") Signed-off-by: Long Li Reviewed-by: Michael Kelley Link: https://lore.kernel.org/r/1746492997-4599-3-git-send-email-longli@linuxonhyperv.com Signed-off-by: Wei Liu Message-ID: <1746492997-4599-3-git-send-email-longli@linuxonhyperv.com> Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio_hv_generic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c index a2c7abf8c289..2804a4f74975 100644 --- a/drivers/uio/uio_hv_generic.c +++ b/drivers/uio/uio_hv_generic.c @@ -288,13 +288,13 @@ hv_uio_probe(struct hv_device *dev, pdata->info.mem[INT_PAGE_MAP].name = "int_page"; pdata->info.mem[INT_PAGE_MAP].addr = (uintptr_t)vmbus_connection.int_page; - pdata->info.mem[INT_PAGE_MAP].size = PAGE_SIZE; + pdata->info.mem[INT_PAGE_MAP].size = HV_HYP_PAGE_SIZE; pdata->info.mem[INT_PAGE_MAP].memtype = UIO_MEM_LOGICAL; pdata->info.mem[MON_PAGE_MAP].name = "monitor_page"; pdata->info.mem[MON_PAGE_MAP].addr = (uintptr_t)vmbus_connection.monitor_pages[1]; - pdata->info.mem[MON_PAGE_MAP].size = PAGE_SIZE; + pdata->info.mem[MON_PAGE_MAP].size = HV_HYP_PAGE_SIZE; pdata->info.mem[MON_PAGE_MAP].memtype = UIO_MEM_LOGICAL; pdata->recv_buf = vzalloc(RECV_BUFFER_SIZE); From 9895f9d9b515b6dc7a46cbf66fd511971f01c75a Mon Sep 17 00:00:00 2001 From: Niklas Cassel Date: Wed, 14 May 2025 09:43:15 +0200 Subject: [PATCH 508/971] PCI: cadence-ep: Correct PBA offset in .set_msix() callback commit c8bcb01352a86bc5592403904109c22b66bd916e upstream. While cdns_pcie_ep_set_msix() writes the Table Size field correctly (N-1), the calculation of the PBA offset is wrong because it calculates space for (N-1) entries instead of N. This results in the following QEMU error when using PCI passthrough on a device which relies on the PCI endpoint subsystem: failed to add PCI capability 0x11[0x50]@0xb0: table & pba overlap, or they don't fit in BARs, or don't align Fix the calculation of PBA offset in the MSI-X capability. [bhelgaas: more specific subject and commit log] Fixes: 3ef5d16f50f8 ("PCI: cadence: Add MSI-X support to Endpoint driver") Signed-off-by: Niklas Cassel Signed-off-by: Manivannan Sadhasivam Signed-off-by: Bjorn Helgaas Reviewed-by: Wilfred Mallawa Reviewed-by: Damien Le Moal Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20250514074313.283156-10-cassel@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/pci/controller/cadence/pcie-cadence-ep.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c index a87dab9abba2..08fb16918043 100644 --- a/drivers/pci/controller/cadence/pcie-cadence-ep.c +++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c @@ -294,13 +294,14 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn, struct cdns_pcie *pcie = &ep->pcie; u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET; u32 val, reg; + u16 actual_interrupts = interrupts + 1; fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn); reg = cap + PCI_MSIX_FLAGS; val = cdns_pcie_ep_fn_readw(pcie, fn, reg); val &= ~PCI_MSIX_FLAGS_QSIZE; - val |= interrupts; + val |= interrupts; /* 0's based value */ cdns_pcie_ep_fn_writew(pcie, fn, reg, val); /* Set MSIX BAR and offset */ @@ -310,7 +311,7 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn, /* Set PBA BAR and offset. BAR must match MSIX BAR */ reg = cap + PCI_MSIX_PBA; - val = (offset + (interrupts * PCI_MSIX_ENTRY_SIZE)) | bir; + val = (offset + (actual_interrupts * PCI_MSIX_ENTRY_SIZE)) | bir; cdns_pcie_ep_fn_writel(pcie, fn, reg, val); return 0; From 7f6a2d3784259226b004998a2da75c206ff7c945 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Thu, 3 Apr 2025 12:07:56 +0800 Subject: [PATCH 509/971] PCI: Add ACS quirk for Loongson PCIe commit 1f3303aa92e15fa273779acac2d0023609de30f1 upstream. Loongson PCIe Root Ports don't advertise an ACS capability, but they do not allow peer-to-peer transactions between Root Ports. Add an ACS quirk so each Root Port can be in a separate IOMMU group. Signed-off-by: Xianglai Li Signed-off-by: Huacai Chen Signed-off-by: Bjorn Helgaas Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20250403040756.720409-1-chenhuacai@loongson.cn Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 70f484b811de..d67ea16e69e6 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -4988,6 +4988,18 @@ static int pci_quirk_brcm_acs(struct pci_dev *dev, u16 acs_flags) PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF); } +static int pci_quirk_loongson_acs(struct pci_dev *dev, u16 acs_flags) +{ + /* + * Loongson PCIe Root Ports don't advertise an ACS capability, but + * they do not allow peer-to-peer transactions between Root Ports. + * Allow each Root Port to be in a separate IOMMU group by masking + * SV/RR/CR/UF bits. + */ + return pci_acs_ctrl_enabled(acs_flags, + PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF); +} + /* * Wangxun 40G/25G/10G/1G NICs have no ACS capability, but on * multi-function devices, the hardware isolates the functions by @@ -5121,6 +5133,17 @@ static const struct pci_dev_acs_enabled { { PCI_VENDOR_ID_BROADCOM, 0x1762, pci_quirk_mf_endpoint_acs }, { PCI_VENDOR_ID_BROADCOM, 0x1763, pci_quirk_mf_endpoint_acs }, { PCI_VENDOR_ID_BROADCOM, 0xD714, pci_quirk_brcm_acs }, + /* Loongson PCIe Root Ports */ + { PCI_VENDOR_ID_LOONGSON, 0x3C09, pci_quirk_loongson_acs }, + { PCI_VENDOR_ID_LOONGSON, 0x3C19, pci_quirk_loongson_acs }, + { PCI_VENDOR_ID_LOONGSON, 0x3C29, pci_quirk_loongson_acs }, + { PCI_VENDOR_ID_LOONGSON, 0x7A09, pci_quirk_loongson_acs }, + { PCI_VENDOR_ID_LOONGSON, 0x7A19, pci_quirk_loongson_acs }, + { PCI_VENDOR_ID_LOONGSON, 0x7A29, pci_quirk_loongson_acs }, + { PCI_VENDOR_ID_LOONGSON, 0x7A39, pci_quirk_loongson_acs }, + { PCI_VENDOR_ID_LOONGSON, 0x7A49, pci_quirk_loongson_acs }, + { PCI_VENDOR_ID_LOONGSON, 0x7A59, pci_quirk_loongson_acs }, + { PCI_VENDOR_ID_LOONGSON, 0x7A69, pci_quirk_loongson_acs }, /* Amazon Annapurna Labs */ { PCI_VENDOR_ID_AMAZON_ANNAPURNA_LABS, 0x0031, pci_quirk_al_acs }, /* Zhaoxin multi-function devices */ From 0b522796a80faf3bb81ec2ed6deb4c1d22efb9f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Mon, 5 May 2025 14:54:12 +0300 Subject: [PATCH 510/971] PCI: Fix lock symmetry in pci_slot_unlock() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit f3efb9569b4a21354ef2caf7ab0608a3e14cc6e4 upstream. The commit a4e772898f8b ("PCI: Add missing bridge lock to pci_bus_lock()") made the lock function to call depend on dev->subordinate but left pci_slot_unlock() unmodified creating locking asymmetry compared with pci_slot_lock(). Because of the asymmetric lock handling, the same bridge device is unlocked twice. First pci_bus_unlock() unlocks bus->self and then pci_slot_unlock() will unconditionally unlock the same bridge device. Move pci_dev_unlock() inside an else branch to match the logic in pci_slot_lock(). Fixes: a4e772898f8b ("PCI: Add missing bridge lock to pci_bus_lock()") Signed-off-by: Ilpo Järvinen Signed-off-by: Bjorn Helgaas Reviewed-by: Lukas Wunner Reviewed-by: Dave Jiang Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20250505115412.37628-1-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 503304aba9ea..4541dfbf0e1b 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -5823,7 +5823,8 @@ static void pci_slot_unlock(struct pci_slot *slot) continue; if (dev->subordinate) pci_bus_unlock(dev->subordinate); - pci_dev_unlock(dev); + else + pci_dev_unlock(dev); } } From a9f6c1ad6c93f5ad695d1fcea133bc670781d79c Mon Sep 17 00:00:00 2001 From: Diederik de Haas Date: Thu, 17 Apr 2025 16:21:18 +0200 Subject: [PATCH 511/971] PCI: dw-rockchip: Fix PHY function call sequence in rockchip_pcie_phy_deinit() commit 286ed198b899739862456f451eda884558526a9d upstream. The documentation for the phy_power_off() function explicitly says that it must be called before phy_exit(). Hence, follow the same rule in rockchip_pcie_phy_deinit(). Fixes: 0e898eb8df4e ("PCI: rockchip-dwc: Add Rockchip RK356X host controller driver") Signed-off-by: Diederik de Haas [mani: commit message change] Signed-off-by: Manivannan Sadhasivam Reviewed-by: Niklas Cassel Reviewed-by: Dragan Simic Acked-by: Shawn Lin Cc: stable@vger.kernel.org # v5.15+ Link: https://patch.msgid.link/20250417142138.1377451-1-didi.debian@cknow.org Signed-off-by: Greg Kroah-Hartman --- drivers/pci/controller/dwc/pcie-dw-rockchip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c index 9b1256da096c..8af7a837a061 100644 --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c @@ -275,8 +275,8 @@ static int rockchip_pcie_phy_init(struct rockchip_pcie *rockchip) static void rockchip_pcie_phy_deinit(struct rockchip_pcie *rockchip) { - phy_exit(rockchip->phy); phy_power_off(rockchip->phy); + phy_exit(rockchip->phy); } static const struct dw_pcie_ops dw_pcie_ops = { From 6a860536306e6ec176c2268b822dbd3af769a008 Mon Sep 17 00:00:00 2001 From: Sean Nyekjaer Date: Mon, 5 May 2025 21:20:08 +0200 Subject: [PATCH 512/971] iio: accel: fxls8962af: Fix temperature scan element sign commit 9c78317b42e7c32523c91099859bc4721e9f75dd upstream. Mark the temperature element signed, data read from the TEMP_OUT register is in two's complement format. This will avoid the temperature being mishandled and miss displayed. Fixes: a3e0b51884ee ("iio: accel: add support for FXLS8962AF/FXLS8964AF accelerometers") Suggested-by: Marcelo Schmitt Cc: stable@vger.kernel.org Reviewed-by: Marcelo Schmitt Signed-off-by: Sean Nyekjaer Link: https://patch.msgid.link/20250505-fxls-v4-2-a38652e21738@geanix.com Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/accel/fxls8962af-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iio/accel/fxls8962af-core.c b/drivers/iio/accel/fxls8962af-core.c index be8a15cb945f..9dc8b4530e86 100644 --- a/drivers/iio/accel/fxls8962af-core.c +++ b/drivers/iio/accel/fxls8962af-core.c @@ -737,6 +737,7 @@ static const struct iio_event_spec fxls8962af_event[] = { BIT(IIO_CHAN_INFO_OFFSET),\ .scan_index = -1, \ .scan_type = { \ + .sign = 's', \ .realbits = 8, \ .storagebits = 8, \ }, \ From fe684290418ef9ef76630072086ee530b92f02b8 Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Tue, 27 May 2025 23:23:54 +0200 Subject: [PATCH 513/971] mm/hugetlb: fix huge_pmd_unshare() vs GUP-fast race commit 1013af4f585fccc4d3e5c5824d174de2257f7d6d upstream. huge_pmd_unshare() drops a reference on a page table that may have previously been shared across processes, potentially turning it into a normal page table used in another process in which unrelated VMAs can afterwards be installed. If this happens in the middle of a concurrent gup_fast(), gup_fast() could end up walking the page tables of another process. While I don't see any way in which that immediately leads to kernel memory corruption, it is really weird and unexpected. Fix it with an explicit broadcast IPI through tlb_remove_table_sync_one(), just like we do in khugepaged when removing page tables for a THP collapse. Link: https://lkml.kernel.org/r/20250528-hugetlb-fixes-splitrace-v2-2-1329349bad1a@google.com Link: https://lkml.kernel.org/r/20250527-hugetlb-fixes-splitrace-v1-2-f4136f5ec58a@google.com Fixes: 39dde65c9940 ("[PATCH] shared page table for hugetlb page") Signed-off-by: Jann Horn Reviewed-by: Lorenzo Stoakes Cc: Liam Howlett Cc: Muchun Song Cc: Oscar Salvador Cc: Vlastimil Babka Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- mm/hugetlb.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 7c196b754071..b731f8e0e9d8 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -7062,6 +7062,13 @@ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, return 0; pud_clear(pud); + /* + * Once our caller drops the rmap lock, some other process might be + * using this page table as a normal, non-hugetlb page table. + * Wait for pending gup_fast() in other threads to finish before letting + * that happen. + */ + tlb_remove_table_sync_one(); ptdesc_pmd_pts_dec(virt_to_ptdesc(ptep)); mm_dec_nr_pmds(mm); return 1; From f6a5b84f450b7a34f49a6f956dcd544261715c3c Mon Sep 17 00:00:00 2001 From: Sean Nyekjaer Date: Fri, 2 May 2025 11:37:26 +0200 Subject: [PATCH 514/971] iio: imu: inv_icm42600: Fix temperature calculation commit e2f820014239df9360064079ae93f838ff3b7f8c upstream. >From the documentation: "offset to be added to [Y]_raw prior toscaling by [Y]_scale" Offset should be applied before multiplying scale, so divide offset by scale to make this correct. Fixes: bc3eb0207fb5 ("iio: imu: inv_icm42600: add temperature sensor support") Signed-off-by: Sean Nyekjaer Acked-by: Jean-Baptiste Maneyrol Link: https://patch.msgid.link/20250502-imu-v1-1-129b8391a4e3@geanix.com Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c index 213cce1c3111..91f0f381082b 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c @@ -67,16 +67,18 @@ int inv_icm42600_temp_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT; /* * T°C = (temp / 132.48) + 25 - * Tm°C = 1000 * ((temp * 100 / 13248) + 25) + * Tm°C = 1000 * ((temp / 132.48) + 25) + * Tm°C = 7.548309 * temp + 25000 + * Tm°C = (temp + 3312) * 7.548309 * scale: 100000 / 13248 ~= 7.548309 - * offset: 25000 + * offset: 3312 */ case IIO_CHAN_INFO_SCALE: *val = 7; *val2 = 548309; return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_OFFSET: - *val = 25000; + *val = 3312; return IIO_VAL_INT; default: return -EINVAL; From 3175377e8ee120e21f167e5dacc4b6e05f942503 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Mon, 28 Apr 2025 20:55:34 -0500 Subject: [PATCH 515/971] iio: adc: ad7606_spi: fix reg write value mask commit 89944d88f8795c6c89b9514cb365998145511cd4 upstream. Fix incorrect value mask for register write. Register values are 8-bit, not 9. If this function was called with a value > 0xFF and an even addr, it would cause writing to the next register. Fixes: f2a22e1e172f ("iio: adc: ad7606: Add support for software mode for ad7616") Signed-off-by: David Lechner Reviewed-by: Angelo Dureghello Link: https://patch.msgid.link/20250428-iio-adc-ad7606_spi-fix-write-value-mask-v1-1-a2d5e85a809f@baylibre.com Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/adc/ad7606_spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/ad7606_spi.c b/drivers/iio/adc/ad7606_spi.c index 67c96572cecc..df48464a115d 100644 --- a/drivers/iio/adc/ad7606_spi.c +++ b/drivers/iio/adc/ad7606_spi.c @@ -151,7 +151,7 @@ static int ad7606_spi_reg_write(struct ad7606_state *st, struct spi_device *spi = to_spi_device(st->dev); st->d16[0] = cpu_to_be16((st->bops->rd_wr_cmd(addr, 1) << 8) | - (val & 0x1FF)); + (val & 0xFF)); return spi_write(spi, &st->d16[0], sizeof(st->d16[0])); } From 755a8006b76792922ff7b1c9674d8897a476b5d7 Mon Sep 17 00:00:00 2001 From: Seunghun Han Date: Wed, 26 Mar 2025 21:05:24 +0100 Subject: [PATCH 516/971] ACPICA: fix acpi operand cache leak in dswstate.c [ Upstream commit 156fd20a41e776bbf334bd5e45c4f78dfc90ce1c ] ACPICA commit 987a3b5cf7175916e2a4b6ea5b8e70f830dfe732 I found an ACPI cache leak in ACPI early termination and boot continuing case. When early termination occurs due to malicious ACPI table, Linux kernel terminates ACPI function and continues to boot process. While kernel terminates ACPI function, kmem_cache_destroy() reports Acpi-Operand cache leak. Boot log of ACPI operand cache leak is as follows: >[ 0.585957] ACPI: Added _OSI(Module Device) >[ 0.587218] ACPI: Added _OSI(Processor Device) >[ 0.588530] ACPI: Added _OSI(3.0 _SCP Extensions) >[ 0.589790] ACPI: Added _OSI(Processor Aggregator Device) >[ 0.591534] ACPI Error: Illegal I/O port address/length above 64K: C806E00000004002/0x2 (20170303/hwvalid-155) >[ 0.594351] ACPI Exception: AE_LIMIT, Unable to initialize fixed events (20170303/evevent-88) >[ 0.597858] ACPI: Unable to start the ACPI Interpreter >[ 0.599162] ACPI Error: Could not remove SCI handler (20170303/evmisc-281) >[ 0.601836] kmem_cache_destroy Acpi-Operand: Slab cache still has objects >[ 0.603556] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.12.0-rc5 #26 >[ 0.605159] Hardware name: innotek gmb_h virtual_box/virtual_box, BIOS virtual_box 12/01/2006 >[ 0.609177] Call Trace: >[ 0.610063] ? dump_stack+0x5c/0x81 >[ 0.611118] ? kmem_cache_destroy+0x1aa/0x1c0 >[ 0.612632] ? acpi_sleep_proc_init+0x27/0x27 >[ 0.613906] ? acpi_os_delete_cache+0xa/0x10 >[ 0.617986] ? acpi_ut_delete_caches+0x3f/0x7b >[ 0.619293] ? acpi_terminate+0xa/0x14 >[ 0.620394] ? acpi_init+0x2af/0x34f >[ 0.621616] ? __class_create+0x4c/0x80 >[ 0.623412] ? video_setup+0x7f/0x7f >[ 0.624585] ? acpi_sleep_proc_init+0x27/0x27 >[ 0.625861] ? do_one_initcall+0x4e/0x1a0 >[ 0.627513] ? kernel_init_freeable+0x19e/0x21f >[ 0.628972] ? rest_init+0x80/0x80 >[ 0.630043] ? kernel_init+0xa/0x100 >[ 0.631084] ? ret_from_fork+0x25/0x30 >[ 0.633343] vgaarb: loaded >[ 0.635036] EDAC MC: Ver: 3.0.0 >[ 0.638601] PCI: Probing PCI hardware >[ 0.639833] PCI host bridge to bus 0000:00 >[ 0.641031] pci_bus 0000:00: root bus resource [io 0x0000-0xffff] > ... Continue to boot and log is omitted ... I analyzed this memory leak in detail and found acpi_ds_obj_stack_pop_and_ delete() function miscalculated the top of the stack. acpi_ds_obj_stack_push() function uses walk_state->operand_index for start position of the top, but acpi_ds_obj_stack_pop_and_delete() function considers index 0 for it. Therefore, this causes acpi operand memory leak. This cache leak causes a security threat because an old kernel (<= 4.9) shows memory locations of kernel functions in stack dump. Some malicious users could use this information to neutralize kernel ASLR. I made a patch to fix ACPI operand cache leak. Link: https://github.com/acpica/acpica/commit/987a3b5c Signed-off-by: Seunghun Han Signed-off-by: Rafael J. Wysocki Link: https://patch.msgid.link/4999480.31r3eYUQgx@rjwysocki.net Signed-off-by: Sasha Levin --- drivers/acpi/acpica/dsutils.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c index fb9ed5e1da89..2bdae8a25e08 100644 --- a/drivers/acpi/acpica/dsutils.c +++ b/drivers/acpi/acpica/dsutils.c @@ -668,6 +668,8 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, union acpi_parse_object *arguments[ACPI_OBJ_NUM_OPERANDS]; u32 arg_count = 0; u32 index = walk_state->num_operands; + u32 prev_num_operands = walk_state->num_operands; + u32 new_num_operands; u32 i; ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg); @@ -696,6 +698,7 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, /* Create the interpreter arguments, in reverse order */ + new_num_operands = index; index--; for (i = 0; i < arg_count; i++) { arg = arguments[index]; @@ -720,7 +723,11 @@ cleanup: * pop everything off of the operand stack and delete those * objects */ - acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state); + walk_state->num_operands = i; + acpi_ds_obj_stack_pop_and_delete(new_num_operands, walk_state); + + /* Restore operand count */ + walk_state->num_operands = prev_num_operands; ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %u", index)); return_ACPI_STATUS(status); From 28ecaebbed55e22cfd4bb4747d7778bf1f0b04fc Mon Sep 17 00:00:00 2001 From: Talhah Peerbhai Date: Fri, 16 May 2025 01:27:41 +0300 Subject: [PATCH 517/971] ASoC: amd: yc: Add quirk for Lenovo Yoga Pro 7 14ASP9 [ Upstream commit a28206060dc5848a1a2a15b7f6ac6223d869084d ] Similar to many other Lenovo models with AMD chips, the Lenovo Yoga Pro 7 14ASP9 (product name 83HN) requires a specific quirk to ensure internal mic detection. This patch adds a quirk fixing this. Signed-off-by: Talhah Peerbhai Link: https://patch.msgid.link/20250515222741.144616-1-talhah.peerbhai@gmail.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/amd/yc/acp6x-mach.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index 622df58a9694..9fdee74c28df 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -311,6 +311,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "83AS"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83HN"), + } + }, { .driver_data = &acp6x_card, .matches = { @@ -360,7 +367,7 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "M5402RA"), } }, - { + { .driver_data = &acp6x_card, .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), From 1c24a738971cb012ff7f450ca5656a52aeba6de3 Mon Sep 17 00:00:00 2001 From: "Guilherme G. Piccoli" Date: Sun, 23 Mar 2025 14:36:24 -0300 Subject: [PATCH 518/971] clocksource: Fix the CPUs' choice in the watchdog per CPU verification [ Upstream commit 08d7becc1a6b8c936e25d827becabfe3bff72a36 ] Right now, if the clocksource watchdog detects a clocksource skew, it might perform a per CPU check, for example in the TSC case on x86. In other words: supposing TSC is detected as unstable by the clocksource watchdog running at CPU1, as part of marking TSC unstable the kernel will also run a check of TSC readings on some CPUs to be sure it is synced between them all. But that check happens only on some CPUs, not all of them; this choice is based on the parameter "verify_n_cpus" and in some random cpumask calculation. So, the watchdog runs such per CPU checks on up to "verify_n_cpus" random CPUs among all online CPUs, with the risk of repeating CPUs (that aren't double checked) in the cpumask random calculation. But if "verify_n_cpus" > num_online_cpus(), it should skip the random calculation and just go ahead and check the clocksource sync between all online CPUs, without the risk of skipping some CPUs due to duplicity in the random cpumask calculation. Tests in a 4 CPU laptop with TSC skew detected led to some cases of the per CPU verification skipping some CPU even with verify_n_cpus=8, due to the duplicity on random cpumask generation. Skipping the randomization when the number of online CPUs is smaller than verify_n_cpus, solves that. Suggested-by: Thadeu Lima de Souza Cascardo Signed-off-by: Guilherme G. Piccoli Signed-off-by: Thomas Gleixner Reviewed-by: Paul E. McKenney Link: https://lore.kernel.org/all/20250323173857.372390-1-gpiccoli@igalia.com Signed-off-by: Sasha Levin --- kernel/time/clocksource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 3130f24daf59..353829883e66 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c @@ -288,7 +288,7 @@ static void clocksource_verify_choose_cpus(void) { int cpu, i, n = verify_n_cpus; - if (n < 0) { + if (n < 0 || n >= num_online_cpus()) { /* Check all of the CPUs. */ cpumask_copy(&cpus_chosen, cpu_online_mask); cpumask_clear_cpu(smp_processor_id(), &cpus_chosen); From 74f765e85d4bd419f41897824a5600aa0dd04947 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 6 Apr 2025 22:27:29 +0200 Subject: [PATCH 519/971] power: supply: collie: Fix wakeup source leaks on device unbind [ Upstream commit c73d19f89cb03c43abbbfa3b9caa1b8fc719764c ] Device can be unbound, so driver must also release memory for the wakeup source. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250406202730.55096-1-krzysztof.kozlowski@linaro.org Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin --- drivers/power/supply/collie_battery.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/power/supply/collie_battery.c b/drivers/power/supply/collie_battery.c index 68390bd1004f..3daf7befc0bf 100644 --- a/drivers/power/supply/collie_battery.c +++ b/drivers/power/supply/collie_battery.c @@ -440,6 +440,7 @@ err_put_gpio_full: static void collie_bat_remove(struct ucb1x00_dev *dev) { + device_init_wakeup(&ucb->dev, 0); free_irq(gpiod_to_irq(collie_bat_main.gpio_full), &collie_bat_main); power_supply_unregister(collie_bat_bu.psy); power_supply_unregister(collie_bat_main.psy); From 58cf7ba36b94d09f5d68ae25d4b5456ed214eaf5 Mon Sep 17 00:00:00 2001 From: Erick Shepherd Date: Mon, 31 Mar 2025 17:13:37 -0500 Subject: [PATCH 520/971] mmc: Add quirk to disable DDR50 tuning [ Upstream commit 9510b38dc0ba358c93cbf5ee7c28820afb85937b ] Adds the MMC_QUIRK_NO_UHS_DDR50_TUNING quirk and updates mmc_execute_tuning() to return 0 if that quirk is set. This fixes an issue on certain Swissbit SD cards that do not support DDR50 tuning where tuning requests caused I/O errors to be thrown. Signed-off-by: Erick Shepherd Acked-by: Adrian Hunter Link: https://lore.kernel.org/r/20250331221337.1414534-1-erick.shepherd@ni.com Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin --- drivers/mmc/core/card.h | 6 ++++++ drivers/mmc/core/quirks.h | 10 ++++++++++ drivers/mmc/core/sd.c | 32 ++++++++++++++++++++++++-------- include/linux/mmc/card.h | 1 + 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h index 8476754b1b17..fe0b2fa3bb89 100644 --- a/drivers/mmc/core/card.h +++ b/drivers/mmc/core/card.h @@ -86,6 +86,7 @@ struct mmc_fixup { #define CID_MANFID_MICRON 0x13 #define CID_MANFID_SAMSUNG 0x15 #define CID_MANFID_APACER 0x27 +#define CID_MANFID_SWISSBIT 0x5D #define CID_MANFID_KINGSTON 0x70 #define CID_MANFID_HYNIX 0x90 #define CID_MANFID_KINGSTON_SD 0x9F @@ -291,4 +292,9 @@ static inline int mmc_card_broken_sd_poweroff_notify(const struct mmc_card *c) return c->quirks & MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY; } +static inline int mmc_card_no_uhs_ddr50_tuning(const struct mmc_card *c) +{ + return c->quirks & MMC_QUIRK_NO_UHS_DDR50_TUNING; +} + #endif diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h index 89b512905be1..7f893bafaa60 100644 --- a/drivers/mmc/core/quirks.h +++ b/drivers/mmc/core/quirks.h @@ -34,6 +34,16 @@ static const struct mmc_fixup __maybe_unused mmc_sd_fixups[] = { MMC_QUIRK_BROKEN_SD_CACHE | MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY, EXT_CSD_REV_ANY), + /* + * Swissbit series S46-u cards throw I/O errors during tuning requests + * after the initial tuning request expectedly times out. This has + * only been observed on cards manufactured on 01/2019 that are using + * Bay Trail host controllers. + */ + _FIXUP_EXT("0016G", CID_MANFID_SWISSBIT, 0x5342, 2019, 1, + 0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd, + MMC_QUIRK_NO_UHS_DDR50_TUNING, EXT_CSD_REV_ANY), + END_FIXUP }; diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index f02c3e5eb5c8..a06f3011e2b5 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -618,6 +618,29 @@ static int sd_set_current_limit(struct mmc_card *card, u8 *status) return 0; } +/* + * Determine if the card should tune or not. + */ +static bool mmc_sd_use_tuning(struct mmc_card *card) +{ + /* + * SPI mode doesn't define CMD19 and tuning is only valid for SDR50 and + * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104. + */ + if (mmc_host_is_spi(card->host)) + return false; + + switch (card->host->ios.timing) { + case MMC_TIMING_UHS_SDR50: + case MMC_TIMING_UHS_SDR104: + return true; + case MMC_TIMING_UHS_DDR50: + return !mmc_card_no_uhs_ddr50_tuning(card); + } + + return false; +} + /* * UHS-I specific initialization procedure */ @@ -661,14 +684,7 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card) if (err) goto out; - /* - * SPI mode doesn't define CMD19 and tuning is only valid for SDR50 and - * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104. - */ - if (!mmc_host_is_spi(card->host) && - (card->host->ios.timing == MMC_TIMING_UHS_SDR50 || - card->host->ios.timing == MMC_TIMING_UHS_DDR50 || - card->host->ios.timing == MMC_TIMING_UHS_SDR104)) { + if (mmc_sd_use_tuning(card)) { err = mmc_execute_tuning(card); /* diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index afa575e362a4..7c6da19fff9f 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -297,6 +297,7 @@ struct mmc_card { #define MMC_QUIRK_BROKEN_SD_CACHE (1<<15) /* Disable broken SD cache support */ #define MMC_QUIRK_BROKEN_CACHE_FLUSH (1<<16) /* Don't flush cache until the write has occurred */ #define MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY (1<<17) /* Disable broken SD poweroff notify support */ +#define MMC_QUIRK_NO_UHS_DDR50_TUNING (1<<18) /* Disable DDR50 tuning */ bool written_flag; /* Indicates eMMC has been written since power on */ bool reenable_cmdq; /* Re-enable Command Queue */ From 30e11a8cff732e50a5c2faef0f1f9498604aebff Mon Sep 17 00:00:00 2001 From: Ahmed Salem Date: Fri, 25 Apr 2025 21:30:27 +0200 Subject: [PATCH 521/971] ACPICA: Avoid sequence overread in call to strncmp() [ Upstream commit 64b9dfd0776e9c38d733094859a09f13282ce6f8 ] ACPICA commit 8b83a8d88dfec59ea147fad35fc6deea8859c58c ap_get_table_length() checks if tables are valid by calling ap_is_valid_header(). The latter then calls ACPI_VALIDATE_RSDP_SIG(Table->Signature). ap_is_valid_header() accepts struct acpi_table_header as an argument, so the signature size is always fixed to 4 bytes. The problem is when the string comparison is between ACPI-defined table signature and ACPI_SIG_RSDP. Common ACPI table header specifies the Signature field to be 4 bytes long[1], with the exception of the RSDP structure whose signature is 8 bytes long "RSD PTR " (including the trailing blank character)[2]. Calling strncmp(sig, rsdp_sig, 8) would then result in a sequence overread[3] as sig would be smaller (4 bytes) than the specified bound (8 bytes). As a workaround, pass the bound conditionally based on the size of the signature being passed. Link: https://uefi.org/specs/ACPI/6.5_A/05_ACPI_Software_Programming_Model.html#system-description-table-header [1] Link: https://uefi.org/specs/ACPI/6.5_A/05_ACPI_Software_Programming_Model.html#root-system-description-pointer-rsdp-structure [2] Link: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wstringop-overread [3] Link: https://github.com/acpica/acpica/commit/8b83a8d8 Signed-off-by: Ahmed Salem Signed-off-by: Rafael J. Wysocki Link: https://patch.msgid.link/2248233.Mh6RI2rZIc@rjwysocki.net Signed-off-by: Sasha Levin --- include/acpi/actypes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 85c2dcf2b704..0a2420085241 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -527,7 +527,7 @@ typedef u64 acpi_integer; /* Support for the special RSDP signature (8 characters) */ -#define ACPI_VALIDATE_RSDP_SIG(a) (!strncmp (ACPI_CAST_PTR (char, (a)), ACPI_SIG_RSDP, 8)) +#define ACPI_VALIDATE_RSDP_SIG(a) (!strncmp (ACPI_CAST_PTR (char, (a)), ACPI_SIG_RSDP, (sizeof(a) < 8) ? ACPI_NAMESEG_SIZE : 8)) #define ACPI_MAKE_RSDP_SIG(dest) (memcpy (ACPI_CAST_PTR (char, (dest)), ACPI_SIG_RSDP, 8)) /* Support for OEMx signature (x can be any character) */ From 7d346ca11a6e2faa2d0e6292613928f5ff67c7d7 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sun, 6 Apr 2025 09:15:05 +1000 Subject: [PATCH 522/971] ASoC: tas2770: Power cycle amp on ISENSE/VSENSE change [ Upstream commit f529c91be8a34ac12e7599bf87c65b6f4a2c9f5c ] The ISENSE/VSENSE blocks are only powered up when the amplifier transitions from shutdown to active. This means that if those controls are flipped on while the amplifier is already playing back audio, they will have no effect. Fix this by forcing a power cycle around transitions in those controls. Reviewed-by: Neal Gompa Signed-off-by: Hector Martin Signed-off-by: James Calligeros Link: https://patch.msgid.link/20250406-apple-codec-changes-v5-1-50a00ec850a3@gmail.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/tas2770.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/tas2770.c b/sound/soc/codecs/tas2770.c index 5c6b825c757b..181b16530e5b 100644 --- a/sound/soc/codecs/tas2770.c +++ b/sound/soc/codecs/tas2770.c @@ -158,11 +158,37 @@ static const struct snd_kcontrol_new isense_switch = static const struct snd_kcontrol_new vsense_switch = SOC_DAPM_SINGLE("Switch", TAS2770_PWR_CTRL, 2, 1, 1); +static int sense_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct tas2770_priv *tas2770 = snd_soc_component_get_drvdata(component); + + /* + * Powering up ISENSE/VSENSE requires a trip through the shutdown state. + * Do that here to ensure that our changes are applied properly, otherwise + * we might end up with non-functional IVSENSE if playback started earlier, + * which would break software speaker protection. + */ + switch (event) { + case SND_SOC_DAPM_PRE_REG: + return snd_soc_component_update_bits(component, TAS2770_PWR_CTRL, + TAS2770_PWR_CTRL_MASK, + TAS2770_PWR_CTRL_SHUTDOWN); + case SND_SOC_DAPM_POST_REG: + return tas2770_update_pwr_ctrl(tas2770); + default: + return 0; + } +} + static const struct snd_soc_dapm_widget tas2770_dapm_widgets[] = { SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0, &tas2770_asi1_mux), - SND_SOC_DAPM_SWITCH("ISENSE", TAS2770_PWR_CTRL, 3, 1, &isense_switch), - SND_SOC_DAPM_SWITCH("VSENSE", TAS2770_PWR_CTRL, 2, 1, &vsense_switch), + SND_SOC_DAPM_SWITCH_E("ISENSE", TAS2770_PWR_CTRL, 3, 1, &isense_switch, + sense_event, SND_SOC_DAPM_PRE_REG | SND_SOC_DAPM_POST_REG), + SND_SOC_DAPM_SWITCH_E("VSENSE", TAS2770_PWR_CTRL, 2, 1, &vsense_switch, + sense_event, SND_SOC_DAPM_PRE_REG | SND_SOC_DAPM_POST_REG), SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2770_dac_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_OUTPUT("OUT"), From 0ab90839bf6c0e5608f14ad21d71cc1971c8d7de Mon Sep 17 00:00:00 2001 From: Armin Wolf Date: Sun, 18 May 2025 20:51:11 +0200 Subject: [PATCH 523/971] ACPI: bus: Bail out if acpi_kobj registration fails [ Upstream commit 94a370fc8def6038dbc02199db9584b0b3690f1a ] The ACPI sysfs code will fail to initialize if acpi_kobj is NULL, together with some ACPI drivers. Follow the other firmware subsystems and bail out if the kobject cannot be registered. Signed-off-by: Armin Wolf Link: https://patch.msgid.link/20250518185111.3560-2-W_Armin@gmx.de Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/bus.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index a4aa53b7e2bb..645464f02363 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1396,8 +1396,10 @@ static int __init acpi_init(void) } acpi_kobj = kobject_create_and_add("acpi", firmware_kobj); - if (!acpi_kobj) - pr_debug("%s: kset create error\n", __func__); + if (!acpi_kobj) { + pr_err("Failed to register kobject\n"); + return -ENOMEM; + } init_prmt(); acpi_init_pcc(); From 8621fbeb4db9929723b75618541792892732e216 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 7 Apr 2025 13:36:55 -0500 Subject: [PATCH 524/971] ACPI: Add missing prototype for non CONFIG_SUSPEND/CONFIG_X86 case [ Upstream commit e1bdbbc98279164d910d2de82a745f090a8b249f ] acpi_register_lps0_dev() and acpi_unregister_lps0_dev() may be used in drivers that don't require CONFIG_SUSPEND or compile on !X86. Add prototypes for those cases. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202502191627.fRgoBwcZ-lkp@intel.com/ Signed-off-by: Mario Limonciello Link: https://patch.msgid.link/20250407183656.1503446-1-superm1@kernel.org Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- include/linux/acpi.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 1b76d2f83eac..7c6f4006389d 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -1098,13 +1098,13 @@ void acpi_os_set_prepare_extended_sleep(int (*func)(u8 sleep_state, acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state, u32 val_a, u32 val_b); -#if defined(CONFIG_SUSPEND) && defined(CONFIG_X86) struct acpi_s2idle_dev_ops { struct list_head list_node; void (*prepare)(void); void (*check)(void); void (*restore)(void); }; +#if defined(CONFIG_SUSPEND) && defined(CONFIG_X86) int acpi_register_lps0_dev(struct acpi_s2idle_dev_ops *arg); void acpi_unregister_lps0_dev(struct acpi_s2idle_dev_ops *arg); int acpi_get_lps0_constraint(struct acpi_device *adev); @@ -1113,6 +1113,13 @@ static inline int acpi_get_lps0_constraint(struct device *dev) { return ACPI_STATE_UNKNOWN; } +static inline int acpi_register_lps0_dev(struct acpi_s2idle_dev_ops *arg) +{ + return -ENODEV; +} +static inline void acpi_unregister_lps0_dev(struct acpi_s2idle_dev_ops *arg) +{ +} #endif /* CONFIG_SUSPEND && CONFIG_X86 */ #ifndef CONFIG_IA64 void arch_reserve_mem_area(acpi_physical_address addr, size_t size); From 1fee4324b5660de080cefc3fc91c371543bdb8f6 Mon Sep 17 00:00:00 2001 From: Seunghun Han Date: Wed, 26 Mar 2025 21:06:21 +0100 Subject: [PATCH 525/971] ACPICA: fix acpi parse and parseext cache leaks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit bed18f0bdcd6737a938264a59d67923688696fc4 ] ACPICA commit 8829e70e1360c81e7a5a901b5d4f48330e021ea5 I'm Seunghun Han, and I work for National Security Research Institute of South Korea. I have been doing a research on ACPI and found an ACPI cache leak in ACPI early abort cases. Boot log of ACPI cache leak is as follows: [ 0.352414] ACPI: Added _OSI(Module Device) [ 0.353182] ACPI: Added _OSI(Processor Device) [ 0.353182] ACPI: Added _OSI(3.0 _SCP Extensions) [ 0.353182] ACPI: Added _OSI(Processor Aggregator Device) [ 0.356028] ACPI: Unable to start the ACPI Interpreter [ 0.356799] ACPI Error: Could not remove SCI handler (20170303/evmisc-281) [ 0.360215] kmem_cache_destroy Acpi-State: Slab cache still has objects [ 0.360648] CPU: 0 PID: 1 Comm: swapper/0 Tainted: G W 4.12.0-rc4-next-20170608+ #10 [ 0.361273] Hardware name: innotek gmb_h virtual_box/virtual_box, BIOS virtual_box 12/01/2006 [ 0.361873] Call Trace: [ 0.362243] ? dump_stack+0x5c/0x81 [ 0.362591] ? kmem_cache_destroy+0x1aa/0x1c0 [ 0.362944] ? acpi_sleep_proc_init+0x27/0x27 [ 0.363296] ? acpi_os_delete_cache+0xa/0x10 [ 0.363646] ? acpi_ut_delete_caches+0x6d/0x7b [ 0.364000] ? acpi_terminate+0xa/0x14 [ 0.364000] ? acpi_init+0x2af/0x34f [ 0.364000] ? __class_create+0x4c/0x80 [ 0.364000] ? video_setup+0x7f/0x7f [ 0.364000] ? acpi_sleep_proc_init+0x27/0x27 [ 0.364000] ? do_one_initcall+0x4e/0x1a0 [ 0.364000] ? kernel_init_freeable+0x189/0x20a [ 0.364000] ? rest_init+0xc0/0xc0 [ 0.364000] ? kernel_init+0xa/0x100 [ 0.364000] ? ret_from_fork+0x25/0x30 I analyzed this memory leak in detail. I found that “Acpi-State” cache and “Acpi-Parse” cache were merged because the size of cache objects was same slab cache size. I finally found “Acpi-Parse” cache and “Acpi-parse_ext” cache were leaked using SLAB_NEVER_MERGE flag in kmem_cache_create() function. Real ACPI cache leak point is as follows: [ 0.360101] ACPI: Added _OSI(Module Device) [ 0.360101] ACPI: Added _OSI(Processor Device) [ 0.360101] ACPI: Added _OSI(3.0 _SCP Extensions) [ 0.361043] ACPI: Added _OSI(Processor Aggregator Device) [ 0.364016] ACPI: Unable to start the ACPI Interpreter [ 0.365061] ACPI Error: Could not remove SCI handler (20170303/evmisc-281) [ 0.368174] kmem_cache_destroy Acpi-Parse: Slab cache still has objects [ 0.369332] CPU: 1 PID: 1 Comm: swapper/0 Tainted: G W 4.12.0-rc4-next-20170608+ #8 [ 0.371256] Hardware name: innotek gmb_h virtual_box/virtual_box, BIOS virtual_box 12/01/2006 [ 0.372000] Call Trace: [ 0.372000] ? dump_stack+0x5c/0x81 [ 0.372000] ? kmem_cache_destroy+0x1aa/0x1c0 [ 0.372000] ? acpi_sleep_proc_init+0x27/0x27 [ 0.372000] ? acpi_os_delete_cache+0xa/0x10 [ 0.372000] ? acpi_ut_delete_caches+0x56/0x7b [ 0.372000] ? acpi_terminate+0xa/0x14 [ 0.372000] ? acpi_init+0x2af/0x34f [ 0.372000] ? __class_create+0x4c/0x80 [ 0.372000] ? video_setup+0x7f/0x7f [ 0.372000] ? acpi_sleep_proc_init+0x27/0x27 [ 0.372000] ? do_one_initcall+0x4e/0x1a0 [ 0.372000] ? kernel_init_freeable+0x189/0x20a [ 0.372000] ? rest_init+0xc0/0xc0 [ 0.372000] ? kernel_init+0xa/0x100 [ 0.372000] ? ret_from_fork+0x25/0x30 [ 0.388039] kmem_cache_destroy Acpi-parse_ext: Slab cache still has objects [ 0.389063] CPU: 1 PID: 1 Comm: swapper/0 Tainted: G W 4.12.0-rc4-next-20170608+ #8 [ 0.390557] Hardware name: innotek gmb_h virtual_box/virtual_box, BIOS virtual_box 12/01/2006 [ 0.392000] Call Trace: [ 0.392000] ? dump_stack+0x5c/0x81 [ 0.392000] ? kmem_cache_destroy+0x1aa/0x1c0 [ 0.392000] ? acpi_sleep_proc_init+0x27/0x27 [ 0.392000] ? acpi_os_delete_cache+0xa/0x10 [ 0.392000] ? acpi_ut_delete_caches+0x6d/0x7b [ 0.392000] ? acpi_terminate+0xa/0x14 [ 0.392000] ? acpi_init+0x2af/0x34f [ 0.392000] ? __class_create+0x4c/0x80 [ 0.392000] ? video_setup+0x7f/0x7f [ 0.392000] ? acpi_sleep_proc_init+0x27/0x27 [ 0.392000] ? do_one_initcall+0x4e/0x1a0 [ 0.392000] ? kernel_init_freeable+0x189/0x20a [ 0.392000] ? rest_init+0xc0/0xc0 [ 0.392000] ? kernel_init+0xa/0x100 [ 0.392000] ? ret_from_fork+0x25/0x30 When early abort is occurred due to invalid ACPI information, Linux kernel terminates ACPI by calling acpi_terminate() function. The function calls acpi_ut_delete_caches() function to delete local caches (acpi_gbl_namespace_ cache, state_cache, operand_cache, ps_node_cache, ps_node_ext_cache). But the deletion codes in acpi_ut_delete_caches() function only delete slab caches using kmem_cache_destroy() function, therefore the cache objects should be flushed before acpi_ut_delete_caches() function. "Acpi-Parse" cache and "Acpi-ParseExt" cache are used in an AML parse function, acpi_ps_parse_loop(). The function should complete all ops using acpi_ps_complete_final_op() when an error occurs due to invalid AML codes. However, the current implementation of acpi_ps_complete_final_op() does not complete all ops when it meets some errors and this cause cache leak. This cache leak has a security threat because an old kernel (<= 4.9) shows memory locations of kernel functions in stack dump. Some malicious users could use this information to neutralize kernel ASLR. To fix ACPI cache leak for enhancing security, I made a patch to complete all ops unconditionally for acpi_ps_complete_final_op() function. I hope that this patch improves the security of Linux kernel. Thank you. Link: https://github.com/acpica/acpica/commit/8829e70e Signed-off-by: Seunghun Han Signed-off-by: Rafael J. Wysocki Link: https://patch.msgid.link/2363774.ElGaqSPkdT@rjwysocki.net Signed-off-by: Sasha Levin --- drivers/acpi/acpica/psobject.c | 52 ++++++++++------------------------ 1 file changed, 15 insertions(+), 37 deletions(-) diff --git a/drivers/acpi/acpica/psobject.c b/drivers/acpi/acpica/psobject.c index 54471083ba54..0bce1baaa62b 100644 --- a/drivers/acpi/acpica/psobject.c +++ b/drivers/acpi/acpica/psobject.c @@ -636,7 +636,8 @@ acpi_status acpi_ps_complete_final_op(struct acpi_walk_state *walk_state, union acpi_parse_object *op, acpi_status status) { - acpi_status status2; + acpi_status return_status = status; + u8 ascending = TRUE; ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state); @@ -650,7 +651,7 @@ acpi_ps_complete_final_op(struct acpi_walk_state *walk_state, op)); do { if (op) { - if (walk_state->ascending_callback != NULL) { + if (ascending && walk_state->ascending_callback != NULL) { walk_state->op = op; walk_state->op_info = acpi_ps_get_opcode_info(op->common. @@ -672,49 +673,26 @@ acpi_ps_complete_final_op(struct acpi_walk_state *walk_state, } if (status == AE_CTRL_TERMINATE) { - status = AE_OK; - - /* Clean up */ - do { - if (op) { - status2 = - acpi_ps_complete_this_op - (walk_state, op); - if (ACPI_FAILURE - (status2)) { - return_ACPI_STATUS - (status2); - } - } - - acpi_ps_pop_scope(& - (walk_state-> - parser_state), - &op, - &walk_state-> - arg_types, - &walk_state-> - arg_count); - - } while (op); - - return_ACPI_STATUS(status); + ascending = FALSE; + return_status = AE_CTRL_TERMINATE; } else if (ACPI_FAILURE(status)) { /* First error is most important */ - (void) - acpi_ps_complete_this_op(walk_state, - op); - return_ACPI_STATUS(status); + ascending = FALSE; + return_status = status; } } - status2 = acpi_ps_complete_this_op(walk_state, op); - if (ACPI_FAILURE(status2)) { - return_ACPI_STATUS(status2); + status = acpi_ps_complete_this_op(walk_state, op); + if (ACPI_FAILURE(status)) { + ascending = FALSE; + if (ACPI_SUCCESS(return_status) || + return_status == AE_CTRL_TERMINATE) { + return_status = status; + } } } @@ -724,5 +702,5 @@ acpi_ps_complete_final_op(struct acpi_walk_state *walk_state, } while (op); - return_ACPI_STATUS(status); + return_ACPI_STATUS(return_status); } From 558ba4afdfe5bbf0173d632c58e294b2ced899fa Mon Sep 17 00:00:00 2001 From: Jerry Lv Date: Tue, 15 Apr 2025 11:40:47 +0800 Subject: [PATCH 526/971] power: supply: bq27xxx: Retrieve again when busy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit f16d9fb6cf03fdbdefa41a8b32ba1e57afb7ae3d ] Multiple applications may access the battery gauge at the same time, so the gauge may be busy and EBUSY will be returned. The driver will set a flag to record the EBUSY state, and this flag will be kept until the next periodic update. When this flag is set, bq27xxx_battery_get_property() will just return ENODEV until the flag is updated. Even if the gauge was busy during the last accessing attempt, returning ENODEV is not ideal, and can cause confusion in the applications layer. Instead, retry accessing the I2C to update the flag is as expected, for the gauge typically recovers from busy state within a few milliseconds. If still failed to access the gauge, the real error code would be returned instead of ENODEV (as suggested by Pali Rohár). Reviewed-by: Pali Rohár Signed-off-by: Jerry Lv Link: https://lore.kernel.org/r/20250415-foo-fix-v2-1-5b45a395e4cc@axis.com Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin --- drivers/power/supply/bq27xxx_battery.c | 2 +- drivers/power/supply/bq27xxx_battery_i2c.c | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c index 23c873656757..e51fa2c694bc 100644 --- a/drivers/power/supply/bq27xxx_battery.c +++ b/drivers/power/supply/bq27xxx_battery.c @@ -2044,7 +2044,7 @@ static int bq27xxx_battery_get_property(struct power_supply *psy, mutex_unlock(&di->lock); if (psp != POWER_SUPPLY_PROP_PRESENT && di->cache.flags < 0) - return -ENODEV; + return di->cache.flags; switch (psp) { case POWER_SUPPLY_PROP_STATUS: diff --git a/drivers/power/supply/bq27xxx_battery_i2c.c b/drivers/power/supply/bq27xxx_battery_i2c.c index 886e0a8e2abd..8877fa333cd0 100644 --- a/drivers/power/supply/bq27xxx_battery_i2c.c +++ b/drivers/power/supply/bq27xxx_battery_i2c.c @@ -6,6 +6,7 @@ * Andrew F. Davis */ +#include #include #include #include @@ -32,6 +33,7 @@ static int bq27xxx_battery_i2c_read(struct bq27xxx_device_info *di, u8 reg, struct i2c_msg msg[2]; u8 data[2]; int ret; + int retry = 0; if (!client->adapter) return -ENODEV; @@ -48,7 +50,16 @@ static int bq27xxx_battery_i2c_read(struct bq27xxx_device_info *di, u8 reg, else msg[1].len = 2; - ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); + do { + ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); + if (ret == -EBUSY && ++retry < 3) { + /* sleep 10 milliseconds when busy */ + usleep_range(10000, 11000); + continue; + } + break; + } while (1); + if (ret < 0) return ret; From cf961a38e4500ef77186d5c9db1668000a3ea941 Mon Sep 17 00:00:00 2001 From: gldrk Date: Fri, 25 Apr 2025 21:21:52 +0200 Subject: [PATCH 527/971] ACPICA: utilities: Fix overflow check in vsnprintf() [ Upstream commit 12b660251007e00a3e4d47ec62dbe3a7ace7023e ] ACPICA commit d9d59b7918514ae55063b93f3ec041b1a569bf49 The old version breaks sprintf on 64-bit systems for buffers outside [0..UINT32_MAX]. Link: https://github.com/acpica/acpica/commit/d9d59b79 Signed-off-by: Rafael J. Wysocki Link: https://patch.msgid.link/4994935.GXAFRqVoOG@rjwysocki.net Signed-off-by: gldrk [ rjw: Added the tag from gldrk ] Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/acpica/utprint.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/acpica/utprint.c b/drivers/acpi/acpica/utprint.c index 42b30b9f9312..7fad03c5252c 100644 --- a/drivers/acpi/acpica/utprint.c +++ b/drivers/acpi/acpica/utprint.c @@ -333,11 +333,8 @@ int vsnprintf(char *string, acpi_size size, const char *format, va_list args) pos = string; - if (size != ACPI_UINT32_MAX) { - end = string + size; - } else { - end = ACPI_CAST_PTR(char, ACPI_UINT32_MAX); - } + size = ACPI_MIN(size, ACPI_PTR_DIFF(ACPI_MAX_PTR, string)); + end = string + size; for (; *format; ++format) { if (*format != '%') { From 5505ec191f77b0adce151b8a7526bfc26e910e92 Mon Sep 17 00:00:00 2001 From: Yuanjun Gong Date: Tue, 13 May 2025 20:37:44 +0800 Subject: [PATCH 528/971] ASoC: tegra210_ahub: Add check to of_device_get_match_data() [ Upstream commit 04cb269c204398763a620d426cbee43064854000 ] In tegra_ahub_probe(), check the result of function of_device_get_match_data(), return an error code in case it fails. Signed-off-by: Yuanjun Gong Link: https://patch.msgid.link/20250513123744.3041724-1-ruc_gongyuanjun@163.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/tegra/tegra210_ahub.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/tegra/tegra210_ahub.c b/sound/soc/tegra/tegra210_ahub.c index ab3c6b2544d2..140cb27f7328 100644 --- a/sound/soc/tegra/tegra210_ahub.c +++ b/sound/soc/tegra/tegra210_ahub.c @@ -1359,6 +1359,8 @@ static int tegra_ahub_probe(struct platform_device *pdev) return -ENOMEM; ahub->soc_data = of_device_get_match_data(&pdev->dev); + if (!ahub->soc_data) + return -ENODEV; platform_set_drvdata(pdev, ahub); From 6a7c583f56b991235bafa5d015403e4ebdce810a Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Thu, 27 Mar 2025 08:49:44 +0800 Subject: [PATCH 529/971] gpiolib: of: Add polarity quirk for s5m8767 [ Upstream commit 4e310626eb4df52a31a142c1360fead0fcbd3793 ] This is prepare patch for switching s5m8767 regulator driver to use GPIO descriptor. DTS for exynos5250 spring incorrectly specifies "active low" polarity for the DVS and DS line. But per datasheet, they are actually active high. So add polarity quirk for it. Signed-off-by: Peng Fan Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20250327004945.563765-1-peng.fan@oss.nxp.com Signed-off-by: Bartosz Golaszewski Signed-off-by: Sasha Levin --- drivers/gpio/gpiolib-of.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index a0a2a0f75bba..c1e83b2926ae 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -203,6 +203,15 @@ static void of_gpio_try_fixup_polarity(const struct device_node *np, */ { "lantiq,pci-xway", "gpio-reset", false }, #endif +#if IS_ENABLED(CONFIG_REGULATOR_S5M8767) + /* + * According to S5M8767, the DVS and DS pin are + * active-high signals. However, exynos5250-spring.dts use + * active-low setting. + */ + { "samsung,s5m8767-pmic", "s5m8767,pmic-buck-dvs-gpios", true }, + { "samsung,s5m8767-pmic", "s5m8767,pmic-buck-ds-gpios", true }, +#endif #if IS_ENABLED(CONFIG_TOUCHSCREEN_TSC2005) /* * DTS for Nokia N900 incorrectly specified "active high" From 6635356483b860b55347cdb1770f01d3df4528f9 Mon Sep 17 00:00:00 2001 From: Charan Teja Kalla Date: Thu, 15 May 2025 12:11:25 +0530 Subject: [PATCH 530/971] PM: runtime: fix denying of auto suspend in pm_suspend_timer_fn() [ Upstream commit 40d3b40dce375d6f1c1dbf08d79eed3aed6c691d ] pm_runtime_put_autosuspend() schedules a hrtimer to expire at "dev->power.timer_expires". If the hrtimer's callback, pm_suspend_timer_fn(), observes that the current time equals "dev->power.timer_expires", it unexpectedly bails out instead of proceeding with runtime suspend. pm_suspend_timer_fn(): if (expires > 0 && expires < ktime_get_mono_fast_ns()) { dev->power.timer_expires = 0; rpm_suspend(..) } Additionally, as ->timer_expires is not cleared, all the future auto suspend requests will not schedule hrtimer to perform auto suspend. rpm_suspend(): if ((rpmflags & RPM_AUTO) &&...) { if (!(dev->power.timer_expires && ...) { <-- this will fail. hrtimer_start_range_ns(&dev->power.suspend_timer,...); } } Fix this by as well checking if current time reaches the set expiration. Co-developed-by: Patrick Daly Signed-off-by: Patrick Daly Signed-off-by: Charan Teja Kalla Link: https://patch.msgid.link/20250515064125.1211561-1-quic_charante@quicinc.com Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/base/power/runtime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 0af26cf8c005..0d43bf5b6cec 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -1001,7 +1001,7 @@ static enum hrtimer_restart pm_suspend_timer_fn(struct hrtimer *timer) * If 'expires' is after the current time, we've been called * too early. */ - if (expires > 0 && expires < ktime_get_mono_fast_ns()) { + if (expires > 0 && expires <= ktime_get_mono_fast_ns()) { dev->power.timer_expires = 0; rpm_suspend(dev, dev->power.timer_autosuspends ? (RPM_ASYNC | RPM_AUTO) : RPM_ASYNC); From c148af1f398bae41f7362e83b242b78d38f35923 Mon Sep 17 00:00:00 2001 From: Peter Marheine Date: Thu, 8 May 2025 12:41:45 +1000 Subject: [PATCH 531/971] ACPI: battery: negate current when discharging [ Upstream commit 234f71555019d308c6bc6f98c78c5551cb8cd56a ] The ACPI specification requires that battery rate is always positive, but the kernel ABI for POWER_SUPPLY_PROP_CURRENT_NOW (Documentation/ABI/testing/sysfs-class-power) specifies that it should be negative when a battery is discharging. When reporting CURRENT_NOW, massage the value to match the documented ABI. This only changes the sign of `current_now` and not `power_now` because documentation doesn't describe any particular meaning for `power_now` so leaving `power_now` unchanged is less likely to confuse userspace unnecessarily, whereas becoming consistent with the documented ABI is worth potentially confusing clients that read `current_now`. Signed-off-by: Peter Marheine Link: https://patch.msgid.link/20250508024146.1436129-1-pmarheine@chromium.org Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/battery.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index e3cbaf3c3bbc..cd3cbb7a36f8 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -243,10 +243,23 @@ static int acpi_battery_get_property(struct power_supply *psy, break; case POWER_SUPPLY_PROP_CURRENT_NOW: case POWER_SUPPLY_PROP_POWER_NOW: - if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN) + if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN) { ret = -ENODEV; - else - val->intval = battery->rate_now * 1000; + break; + } + + val->intval = battery->rate_now * 1000; + /* + * When discharging, the current should be reported as a + * negative number as per the power supply class interface + * definition. + */ + if (psp == POWER_SUPPLY_PROP_CURRENT_NOW && + (battery->state & ACPI_BATTERY_STATE_DISCHARGING) && + acpi_battery_handle_discharging(battery) + == POWER_SUPPLY_STATUS_DISCHARGING) + val->intval = -val->intval; + break; case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: From d2a25ca4134c8939f3ab3a1337bc7da5d5c9aaaa Mon Sep 17 00:00:00 2001 From: Sergio Perez Gonzalez Date: Sun, 25 May 2025 21:20:31 -0600 Subject: [PATCH 532/971] net: macb: Check return value of dma_set_mask_and_coherent() [ Upstream commit 3920a758800762917177a6b5ab39707d8e376fe6 ] Issue flagged by coverity. Add a safety check for the return value of dma_set_mask_and_coherent, go to a safe exit if it returns error. Link: https://scan7.scan.coverity.com/#/project-view/53936/11354?selectedIssue=1643754 Signed-off-by: Sergio Perez Gonzalez Reviewed-by: Claudiu Beznea Link: https://patch.msgid.link/20250526032034.84900-1-sperezglz@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/cadence/macb_main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 6f45f4d9fba7..534e7f7bca4c 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -5070,7 +5070,11 @@ static int macb_probe(struct platform_device *pdev) #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT if (GEM_BFEXT(DAW64, gem_readl(bp, DCFG6))) { - dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(44)); + err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(44)); + if (err) { + dev_err(&pdev->dev, "failed to set DMA mask\n"); + goto err_out_free_netdev; + } bp->hw_dma_cap |= HW_DMA_CAP_64B; } #endif From 088279ff18cdc437d6fac5890e0c52c624f78a5b Mon Sep 17 00:00:00 2001 From: Rengarajan S Date: Fri, 23 May 2025 23:03:26 +0530 Subject: [PATCH 533/971] net: lan743x: Modify the EEPROM and OTP size for PCI1xxxx devices [ Upstream commit 3b9935586a9b54d2da27901b830d3cf46ad66a1e ] Maximum OTP and EEPROM size for hearthstone PCI1xxxx devices are 8 Kb and 64 Kb respectively. Adjust max size definitions and return correct EEPROM length based on device. Also prevent out-of-bound read/write. Signed-off-by: Rengarajan S Link: https://patch.msgid.link/20250523173326.18509-1-rengarajan.s@microchip.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- .../net/ethernet/microchip/lan743x_ethtool.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/microchip/lan743x_ethtool.c b/drivers/net/ethernet/microchip/lan743x_ethtool.c index 72b3092d35f7..39a58c3578a0 100644 --- a/drivers/net/ethernet/microchip/lan743x_ethtool.c +++ b/drivers/net/ethernet/microchip/lan743x_ethtool.c @@ -18,6 +18,8 @@ #define EEPROM_MAC_OFFSET (0x01) #define MAX_EEPROM_SIZE (512) #define MAX_OTP_SIZE (1024) +#define MAX_HS_OTP_SIZE (8 * 1024) +#define MAX_HS_EEPROM_SIZE (64 * 1024) #define OTP_INDICATOR_1 (0xF3) #define OTP_INDICATOR_2 (0xF7) @@ -272,6 +274,9 @@ static int lan743x_hs_otp_read(struct lan743x_adapter *adapter, u32 offset, int ret; int i; + if (offset + length > MAX_HS_OTP_SIZE) + return -EINVAL; + ret = lan743x_hs_syslock_acquire(adapter, LOCK_TIMEOUT_MAX_CNT); if (ret < 0) return ret; @@ -320,6 +325,9 @@ static int lan743x_hs_otp_write(struct lan743x_adapter *adapter, u32 offset, int ret; int i; + if (offset + length > MAX_HS_OTP_SIZE) + return -EINVAL; + ret = lan743x_hs_syslock_acquire(adapter, LOCK_TIMEOUT_MAX_CNT); if (ret < 0) return ret; @@ -497,6 +505,9 @@ static int lan743x_hs_eeprom_read(struct lan743x_adapter *adapter, u32 val; int i; + if (offset + length > MAX_HS_EEPROM_SIZE) + return -EINVAL; + retval = lan743x_hs_syslock_acquire(adapter, LOCK_TIMEOUT_MAX_CNT); if (retval < 0) return retval; @@ -539,6 +550,9 @@ static int lan743x_hs_eeprom_write(struct lan743x_adapter *adapter, u32 val; int i; + if (offset + length > MAX_HS_EEPROM_SIZE) + return -EINVAL; + retval = lan743x_hs_syslock_acquire(adapter, LOCK_TIMEOUT_MAX_CNT); if (retval < 0) return retval; @@ -604,9 +618,9 @@ static int lan743x_ethtool_get_eeprom_len(struct net_device *netdev) struct lan743x_adapter *adapter = netdev_priv(netdev); if (adapter->flags & LAN743X_ADAPTER_FLAG_OTP) - return MAX_OTP_SIZE; + return adapter->is_pci11x1x ? MAX_HS_OTP_SIZE : MAX_OTP_SIZE; - return MAX_EEPROM_SIZE; + return adapter->is_pci11x1x ? MAX_HS_EEPROM_SIZE : MAX_EEPROM_SIZE; } static int lan743x_ethtool_get_eeprom(struct net_device *netdev, From 92dbc2a2e2ec2808e638a3cdf6e8514014940449 Mon Sep 17 00:00:00 2001 From: Zilin Guan Date: Fri, 23 May 2025 11:47:17 +0000 Subject: [PATCH 534/971] tipc: use kfree_sensitive() for aead cleanup [ Upstream commit c8ef20fe7274c5766a317f9193b70bed717b6b3d ] The tipc_aead_free() function currently uses kfree() to release the aead structure. However, this structure contains sensitive information, such as key's SALT value, which should be securely erased from memory to prevent potential leakage. To enhance security, replace kfree() with kfree_sensitive() when freeing the aead structure. This change ensures that sensitive data is explicitly cleared before memory deallocation, aligning with the approach used in tipc_aead_init() and adhering to best practices for handling confidential information. Signed-off-by: Zilin Guan Reviewed-by: Tung Nguyen Link: https://patch.msgid.link/20250523114717.4021518-1-zilin@seu.edu.cn Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/tipc/crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c index 79f91b6ca8c8..ea5bb131ebd0 100644 --- a/net/tipc/crypto.c +++ b/net/tipc/crypto.c @@ -425,7 +425,7 @@ static void tipc_aead_free(struct rcu_head *rp) } free_percpu(aead->tfm_entry); kfree_sensitive(aead->key); - kfree(aead); + kfree_sensitive(aead); } static int tipc_aead_users(struct tipc_aead __rcu *aead) From 61fc32485d6419f7cd8149bd11876ad1294cb585 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 13 May 2025 13:57:20 +0800 Subject: [PATCH 535/971] f2fs: use vmalloc instead of kvmalloc in .init_{,de}compress_ctx [ Upstream commit 70dd07c888451503c3e93b6821e10d1ea1ec9930 ] .init_{,de}compress_ctx uses kvmalloc() to alloc memory, it will try to allocate physically continuous page first, it may cause more memory allocation pressure, let's use vmalloc instead to mitigate it. [Test] cd /data/local/tmp touch file f2fs_io setflags compression file f2fs_io getflags file for i in $(seq 1 10); do sync; echo 3 > /proc/sys/vm/drop_caches;\ time f2fs_io write 512 0 4096 zero osync file; truncate -s 0 file;\ done [Result] Before After Delta 21.243 21.694 -2.12% For compression, we recommend to use ioctl to compress file data in background for workaround. For decompression, only zstd will be affected. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- fs/f2fs/compress.c | 23 ++++++++++------------- fs/f2fs/f2fs.h | 5 +++++ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index f7ef69f44f3d..e962de4ecaa2 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -176,8 +176,7 @@ void f2fs_compress_ctx_add_page(struct compress_ctx *cc, struct page *page) #ifdef CONFIG_F2FS_FS_LZO static int lzo_init_compress_ctx(struct compress_ctx *cc) { - cc->private = f2fs_kvmalloc(F2FS_I_SB(cc->inode), - LZO1X_MEM_COMPRESS, GFP_NOFS); + cc->private = f2fs_vmalloc(LZO1X_MEM_COMPRESS); if (!cc->private) return -ENOMEM; @@ -187,7 +186,7 @@ static int lzo_init_compress_ctx(struct compress_ctx *cc) static void lzo_destroy_compress_ctx(struct compress_ctx *cc) { - kvfree(cc->private); + vfree(cc->private); cc->private = NULL; } @@ -244,7 +243,7 @@ static int lz4_init_compress_ctx(struct compress_ctx *cc) size = LZ4HC_MEM_COMPRESS; #endif - cc->private = f2fs_kvmalloc(F2FS_I_SB(cc->inode), size, GFP_NOFS); + cc->private = f2fs_vmalloc(size); if (!cc->private) return -ENOMEM; @@ -259,7 +258,7 @@ static int lz4_init_compress_ctx(struct compress_ctx *cc) static void lz4_destroy_compress_ctx(struct compress_ctx *cc) { - kvfree(cc->private); + vfree(cc->private); cc->private = NULL; } @@ -340,8 +339,7 @@ static int zstd_init_compress_ctx(struct compress_ctx *cc) params = zstd_get_params(level, cc->rlen); workspace_size = zstd_cstream_workspace_bound(¶ms.cParams); - workspace = f2fs_kvmalloc(F2FS_I_SB(cc->inode), - workspace_size, GFP_NOFS); + workspace = f2fs_vmalloc(workspace_size); if (!workspace) return -ENOMEM; @@ -349,7 +347,7 @@ static int zstd_init_compress_ctx(struct compress_ctx *cc) if (!stream) { f2fs_err_ratelimited(F2FS_I_SB(cc->inode), "%s zstd_init_cstream failed", __func__); - kvfree(workspace); + vfree(workspace); return -EIO; } @@ -362,7 +360,7 @@ static int zstd_init_compress_ctx(struct compress_ctx *cc) static void zstd_destroy_compress_ctx(struct compress_ctx *cc) { - kvfree(cc->private); + vfree(cc->private); cc->private = NULL; cc->private2 = NULL; } @@ -421,8 +419,7 @@ static int zstd_init_decompress_ctx(struct decompress_io_ctx *dic) workspace_size = zstd_dstream_workspace_bound(max_window_size); - workspace = f2fs_kvmalloc(F2FS_I_SB(dic->inode), - workspace_size, GFP_NOFS); + workspace = f2fs_vmalloc(workspace_size); if (!workspace) return -ENOMEM; @@ -430,7 +427,7 @@ static int zstd_init_decompress_ctx(struct decompress_io_ctx *dic) if (!stream) { f2fs_err_ratelimited(F2FS_I_SB(dic->inode), "%s zstd_init_dstream failed", __func__); - kvfree(workspace); + vfree(workspace); return -EIO; } @@ -442,7 +439,7 @@ static int zstd_init_decompress_ctx(struct decompress_io_ctx *dic) static void zstd_destroy_decompress_ctx(struct decompress_io_ctx *dic) { - kvfree(dic->private); + vfree(dic->private); dic->private = NULL; dic->private2 = NULL; } diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 911c4c64d729..2d9a86129bd8 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -3449,6 +3449,11 @@ static inline void *f2fs_kvzalloc(struct f2fs_sb_info *sbi, return f2fs_kvmalloc(sbi, size, flags | __GFP_ZERO); } +static inline void *f2fs_vmalloc(size_t size) +{ + return vmalloc(size); +} + static inline int get_extra_isize(struct inode *inode) { return F2FS_I(inode)->i_extra_isize / sizeof(__le32); From 7bf4461f1c97207fda757014690d55a447ce859f Mon Sep 17 00:00:00 2001 From: Hou Tao Date: Mon, 26 May 2025 14:25:34 +0800 Subject: [PATCH 536/971] bpf: Check rcu_read_lock_trace_held() in bpf_map_lookup_percpu_elem() [ Upstream commit d4965578267e2e81f67c86e2608481e77e9c8569 ] bpf_map_lookup_percpu_elem() helper is also available for sleepable bpf program. When BPF JIT is disabled or under 32-bit host, bpf_map_lookup_percpu_elem() will not be inlined. Using it in a sleepable bpf program will trigger the warning in bpf_map_lookup_percpu_elem(), because the bpf program only holds rcu_read_lock_trace lock. Therefore, add the missed check. Reported-by: syzbot+dce5aae19ae4d6399986@syzkaller.appspotmail.com Closes: https://lore.kernel.org/bpf/000000000000176a130617420310@google.com/ Signed-off-by: Hou Tao Link: https://lore.kernel.org/r/20250526062534.1105938-1-houtao@huaweicloud.com Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin --- kernel/bpf/helpers.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 41d62405c852..8f0b62b04dee 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -128,7 +128,8 @@ const struct bpf_func_proto bpf_map_peek_elem_proto = { BPF_CALL_3(bpf_map_lookup_percpu_elem, struct bpf_map *, map, void *, key, u32, cpu) { - WARN_ON_ONCE(!rcu_read_lock_held() && !rcu_read_lock_bh_held()); + WARN_ON_ONCE(!rcu_read_lock_held() && !rcu_read_lock_trace_held() && + !rcu_read_lock_bh_held()); return (unsigned long) map->ops->map_lookup_percpu_elem(map, key, cpu); } From 775fdb4042b29097d60d9cef88dcf7aa30e5229a Mon Sep 17 00:00:00 2001 From: Tan En De Date: Sat, 12 Apr 2025 10:33:03 +0800 Subject: [PATCH 537/971] i2c: designware: Invoke runtime suspend on quick slave re-registration [ Upstream commit 2fe2b969d911a09abcd6a47401a3c66c38a310e6 ] Replaced pm_runtime_put() with pm_runtime_put_sync_suspend() to ensure the runtime suspend is invoked immediately when unregistering a slave. This prevents a race condition where suspend was skipped when unregistering and registering slave in quick succession. For example, consider the rapid sequence of `delete_device -> new_device -> delete_device -> new_device`. In this sequence, it is observed that the dw_i2c_plat_runtime_suspend() might not be invoked after `delete_device` operation. This is because after `delete_device` operation, when the pm_runtime_put() is about to trigger suspend, the following `new_device` operation might race and cancel the suspend. If that happens, during the `new_device` operation, dw_i2c_plat_runtime_resume() is skipped (since there was no suspend), which means `i_dev->init()`, i.e. i2c_dw_init_slave(), is skipped. Since i2c_dw_init_slave() is skipped, i2c_dw_configure_fifo_slave() is skipped too, which leaves `DW_IC_INTR_MASK` unconfigured. If we inspect the interrupt mask register using devmem, it will show as zero. Example shell script to reproduce the issue: ``` #!/bin/sh SLAVE_LADDR=0x1010 SLAVE_BUS=13 NEW_DEVICE=/sys/bus/i2c/devices/i2c-$SLAVE_BUS/new_device DELETE_DEVICE=/sys/bus/i2c/devices/i2c-$SLAVE_BUS/delete_device # Create initial device echo slave-24c02 $SLAVE_LADDR > $NEW_DEVICE sleep 2 # Rapid sequence of # delete_device -> new_device -> delete_device -> new_device echo $SLAVE_LADDR > $DELETE_DEVICE echo slave-24c02 $SLAVE_LADDR > $NEW_DEVICE echo $SLAVE_LADDR > $DELETE_DEVICE echo slave-24c02 $SLAVE_LADDR > $NEW_DEVICE # Using devmem to inspect IC_INTR_MASK will show as zero ``` Signed-off-by: Tan En De Acked-by: Jarkko Nikula Link: https://lore.kernel.org/r/20250412023303.378600-1-ende.tan@starfivetech.com Signed-off-by: Andi Shyti Signed-off-by: Sasha Levin --- drivers/i2c/busses/i2c-designware-slave.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-designware-slave.c b/drivers/i2c/busses/i2c-designware-slave.c index 345b532a2b45..ea4c4955fe26 100644 --- a/drivers/i2c/busses/i2c-designware-slave.c +++ b/drivers/i2c/busses/i2c-designware-slave.c @@ -91,7 +91,7 @@ static int i2c_dw_unreg_slave(struct i2c_client *slave) i2c_dw_disable(dev); synchronize_irq(dev->irq); dev->slave = NULL; - pm_runtime_put(dev->dev); + pm_runtime_put_sync_suspend(dev->dev); return 0; } From 24900688ee47071aa6a61e78473999b5b80f0423 Mon Sep 17 00:00:00 2001 From: Benjamin Lin Date: Thu, 15 May 2025 11:29:47 +0800 Subject: [PATCH 538/971] wifi: mt76: mt7996: drop fragments with multicast or broadcast RA [ Upstream commit 80fda1cd7b0a1edd0849dc71403a070d0922118d ] IEEE 802.11 fragmentation can only be applied to unicast frames. Therefore, drop fragments with multicast or broadcast RA. This patch addresses vulnerabilities such as CVE-2020-26145. Signed-off-by: Benjamin Lin Signed-off-by: Shayne Chen Link: https://patch.msgid.link/20250515032952.1653494-4-shayne.chen@mediatek.com Signed-off-by: Felix Fietkau Signed-off-by: Sasha Levin --- drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c index 35d9673ec0d8..8fa16f95e6a7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c @@ -650,6 +650,14 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb) status->last_amsdu = amsdu_info == MT_RXD4_LAST_AMSDU_FRAME; } + /* IEEE 802.11 fragmentation can only be applied to unicast frames. + * Hence, drop fragments with multicast/broadcast RA. + * This check fixes vulnerabilities, like CVE-2020-26145. + */ + if ((ieee80211_has_morefrags(fc) || seq_ctrl & IEEE80211_SCTL_FRAG) && + FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, rxd3) != MT_RXD3_NORMAL_U2M) + return -EINVAL; + hdr_gap = (u8 *)rxd - skb->data + 2 * remove_pad; if (hdr_trans && ieee80211_has_morefrags(fc)) { if (mt7996_reverse_frag0_hdr_trans(skb, hdr_gap)) From 2c1a2d863b24c0607a43339a600274687d7059eb Mon Sep 17 00:00:00 2001 From: Alok Tiwari Date: Mon, 19 May 2025 07:17:19 -0700 Subject: [PATCH 539/971] emulex/benet: correct command version selection in be_cmd_get_stats() [ Upstream commit edb888d29748cee674006a52e544925dacc7728e ] Logic here always sets hdr->version to 2 if it is not a BE3 or Lancer chip, even if it is BE2. Use 'else if' to prevent multiple assignments, setting version 0 for BE2, version 1 for BE3 and Lancer, and version 2 for others. Fixes potential incorrect version setting when BE2_chip and BE3_chip/lancer_chip checks could both be true. Signed-off-by: Alok Tiwari Link: https://patch.msgid.link/20250519141731.691136-1-alok.a.tiwari@oracle.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/emulex/benet/be_cmds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 51b8377edd1d..a89aa4ac0a06 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -1609,7 +1609,7 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd) /* version 1 of the cmd is not supported only by BE2 */ if (BE2_chip(adapter)) hdr->version = 0; - if (BE3_chip(adapter) || lancer_chip(adapter)) + else if (BE3_chip(adapter) || lancer_chip(adapter)) hdr->version = 1; else hdr->version = 2; From bf3dcb53ba32b097795c378822ff602365a1563e Mon Sep 17 00:00:00 2001 From: Henk Vergonet Date: Fri, 18 Apr 2025 16:39:14 +0200 Subject: [PATCH 540/971] wifi: mt76: mt76x2: Add support for LiteOn WN4516R,WN4519R [ Upstream commit 3c0e4f606d8693795a2c965d6f4987b1bfc31097 ] Adds support for: - LiteOn WN4516R - LiteOn WN4519R Both use: - A nonstandard USB connector - Mediatek chipset MT7600U - ASIC revision: 76320044 Disabled VHT support on ASIC revision 76320044: This fixes the 5G connectibity issue on LiteOn WN4519R module see https://github.com/openwrt/mt76/issues/971 And may also fix the 5G issues on the XBox One Wireless Adapter see https://github.com/openwrt/mt76/issues/200 I have looked at the FCC info related to the MT7632U chip as mentioned in here: https://github.com/openwrt/mt76/issues/459 These confirm the chipset does not support 'ac' mode and hence VHT should be turned of. Signed-off-by: Henk Vergonet Acked-by: Lorenzo Bianconi Link: https://patch.msgid.link/20250418143914.31384-1-henk.vergonet@gmail.com Signed-off-by: Felix Fietkau Signed-off-by: Sasha Levin --- drivers/net/wireless/mediatek/mt76/mt76x2/usb.c | 2 ++ .../net/wireless/mediatek/mt76/mt76x2/usb_init.c | 13 ++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c index 70d3895762b4..00248e2b21ea 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c @@ -17,6 +17,8 @@ static const struct usb_device_id mt76x2u_device_table[] = { { USB_DEVICE(0x057c, 0x8503) }, /* Avm FRITZ!WLAN AC860 */ { USB_DEVICE(0x7392, 0xb711) }, /* Edimax EW 7722 UAC */ { USB_DEVICE(0x0e8d, 0x7632) }, /* HC-M7662BU1 */ + { USB_DEVICE(0x0471, 0x2126) }, /* LiteOn WN4516R module, nonstandard USB connector */ + { USB_DEVICE(0x0471, 0x7600) }, /* LiteOn WN4519R module, nonstandard USB connector */ { USB_DEVICE(0x2c4e, 0x0103) }, /* Mercury UD13 */ { USB_DEVICE(0x0846, 0x9053) }, /* Netgear A6210 */ { USB_DEVICE(0x045e, 0x02e6) }, /* XBox One Wireless Adapter */ diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c index 33a14365ec9b..3b5562811511 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c @@ -191,6 +191,7 @@ int mt76x2u_register_device(struct mt76x02_dev *dev) { struct ieee80211_hw *hw = mt76_hw(dev); struct mt76_usb *usb = &dev->mt76.usb; + bool vht; int err; INIT_DELAYED_WORK(&dev->cal_work, mt76x2u_phy_calibrate); @@ -217,7 +218,17 @@ int mt76x2u_register_device(struct mt76x02_dev *dev) /* check hw sg support in order to enable AMSDU */ hw->max_tx_fragments = dev->mt76.usb.sg_en ? MT_TX_SG_MAX_SIZE : 1; - err = mt76_register_device(&dev->mt76, true, mt76x02_rates, + switch (dev->mt76.rev) { + case 0x76320044: + /* these ASIC revisions do not support VHT */ + vht = false; + break; + default: + vht = true; + break; + } + + err = mt76_register_device(&dev->mt76, vht, mt76x02_rates, ARRAY_SIZE(mt76x02_rates)); if (err) goto fail; From a0b91fa813d4c1798344c13812403111969faca1 Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Sat, 10 May 2025 19:53:09 -0500 Subject: [PATCH 541/971] wifi: mt76: mt7921: add 160 MHz AP for mt7922 device [ Upstream commit 7011faebe543f8f094fdb3281d0ec9e1eab81309 ] This allows mt7922 in hostapd mode to transmit up to 1.4 Gbps. Signed-off-by: Samuel Williams Link: https://patch.msgid.link/20250511005316.1118961-1-sam8641@gmail.com Signed-off-by: Felix Fietkau Signed-off-by: Sasha Levin --- drivers/net/wireless/mediatek/mt76/mt7921/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c index 31ef58e2a3d2..8e2ec3956331 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c @@ -83,6 +83,11 @@ mt7921_init_he_caps(struct mt792x_phy *phy, enum nl80211_band band, he_cap_elem->phy_cap_info[9] |= IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU | IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU; + + if (is_mt7922(phy->mt76->dev)) { + he_cap_elem->phy_cap_info[0] |= + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; + } break; case NL80211_IFTYPE_STATION: he_cap_elem->mac_cap_info[1] |= From a620f66675e56ed43ef2eb8bc975a754e02c91a6 Mon Sep 17 00:00:00 2001 From: Petr Malat Date: Fri, 16 May 2025 10:17:28 +0200 Subject: [PATCH 542/971] sctp: Do not wake readers in __sctp_write_space() [ Upstream commit af295892a7abbf05a3c2ba7abc4d81bb448623d6 ] Function __sctp_write_space() doesn't set poll key, which leads to ep_poll_callback() waking up all waiters, not only these waiting for the socket being writable. Set the key properly using wake_up_interruptible_poll(), which is preferred over the sync variant, as writers are not woken up before at least half of the queue is available. Also, TCP does the same. Signed-off-by: Petr Malat Acked-by: Xin Long Link: https://patch.msgid.link/20250516081727.1361451-1-oss@malat.biz Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/sctp/socket.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index b84c5e0a76f5..adc04e88f349 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -9094,7 +9094,8 @@ static void __sctp_write_space(struct sctp_association *asoc) wq = rcu_dereference(sk->sk_wq); if (wq) { if (waitqueue_active(&wq->wait)) - wake_up_interruptible(&wq->wait); + wake_up_interruptible_poll(&wq->wait, EPOLLOUT | + EPOLLWRNORM | EPOLLWRBAND); /* Note that we try to include the Async I/O support * here by modeling from the current TCP/UDP code. From 762325441e3a51c0602c056fecd3f81abb1556f3 Mon Sep 17 00:00:00 2001 From: Mike Tipton Date: Wed, 14 May 2025 20:53:12 -0700 Subject: [PATCH 543/971] cpufreq: scmi: Skip SCMI devices that aren't used by the CPUs [ Upstream commit 6c9bb86922728c7a4cceb99f131e00dd87514f20 ] Currently, all SCMI devices with performance domains attempt to register a cpufreq driver, even if their performance domains aren't used to control the CPUs. The cpufreq framework only supports registering a single driver, so only the first device will succeed. And if that device isn't used for the CPUs, then cpufreq will scale the wrong domains. To avoid this, return early from scmi_cpufreq_probe() if the probing SCMI device isn't referenced by the CPU device phandles. This keeps the existing assumption that all CPUs are controlled by a single SCMI device. Signed-off-by: Mike Tipton Reviewed-by: Peng Fan Reviewed-by: Cristian Marussi Reviewed-by: Sudeep Holla Tested-by: Cristian Marussi Signed-off-by: Viresh Kumar Signed-off-by: Sasha Levin --- drivers/cpufreq/scmi-cpufreq.c | 36 +++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c index e4989764efe2..6ff77003a96e 100644 --- a/drivers/cpufreq/scmi-cpufreq.c +++ b/drivers/cpufreq/scmi-cpufreq.c @@ -299,6 +299,40 @@ static struct cpufreq_driver scmi_cpufreq_driver = { .register_em = scmi_cpufreq_register_em, }; +static bool scmi_dev_used_by_cpus(struct device *scmi_dev) +{ + struct device_node *scmi_np = dev_of_node(scmi_dev); + struct device_node *cpu_np, *np; + struct device *cpu_dev; + int cpu, idx; + + if (!scmi_np) + return false; + + for_each_possible_cpu(cpu) { + cpu_dev = get_cpu_device(cpu); + if (!cpu_dev) + continue; + + cpu_np = dev_of_node(cpu_dev); + + np = of_parse_phandle(cpu_np, "clocks", 0); + of_node_put(np); + + if (np == scmi_np) + return true; + + idx = of_property_match_string(cpu_np, "power-domain-names", "perf"); + np = of_parse_phandle(cpu_np, "power-domains", idx); + of_node_put(np); + + if (np == scmi_np) + return true; + } + + return false; +} + static int scmi_cpufreq_probe(struct scmi_device *sdev) { int ret; @@ -307,7 +341,7 @@ static int scmi_cpufreq_probe(struct scmi_device *sdev) handle = sdev->handle; - if (!handle) + if (!handle || !scmi_dev_used_by_cpus(dev)) return -ENODEV; perf_ops = handle->devm_protocol_get(sdev, SCMI_PROTOCOL_PERF, &ph); From be5f6a65509cd5675362f15eb0440fb28b0f9d64 Mon Sep 17 00:00:00 2001 From: Akhil R Date: Thu, 24 Apr 2025 11:03:20 +0530 Subject: [PATCH 544/971] i2c: tegra: check msg length in SMBUS block read [ Upstream commit a6e04f05ce0b070ab39d5775580e65c7d943da0b ] For SMBUS block read, do not continue to read if the message length passed from the device is '0' or greater than the maximum allowed bytes. Signed-off-by: Akhil R Acked-by: Thierry Reding Link: https://lore.kernel.org/r/20250424053320.19211-1-akhilrajeev@nvidia.com Signed-off-by: Andi Shyti Signed-off-by: Sasha Levin --- drivers/i2c/busses/i2c-tegra.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 91be04b534fe..08a81daedc11 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -1397,6 +1397,11 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], MSG_END_CONTINUE); if (ret) break; + + /* Validate message length before proceeding */ + if (msgs[i].buf[0] == 0 || msgs[i].buf[0] > I2C_SMBUS_BLOCK_MAX) + break; + /* Set the msg length from first byte */ msgs[i].len += msgs[i].buf[0]; dev_dbg(i2c_dev->dev, "reading %d bytes\n", msgs[i].len); From 04fa1bef29d59e596c8cfa9efba541743a1aaa08 Mon Sep 17 00:00:00 2001 From: Tali Perry Date: Fri, 28 Mar 2025 19:32:50 +0000 Subject: [PATCH 545/971] i2c: npcm: Add clock toggle recovery [ Upstream commit 38010591a0fc3203f1cee45b01ab358b72dd9ab2 ] During init of the bus, the module checks that the bus is idle. If one of the lines are stuck try to recover them first before failing. Sometimes SDA and SCL are low if improper reset occurs (e.g., reboot). Signed-off-by: Tali Perry Signed-off-by: Mohammed Elbadry Reviewed-by: Mukesh Kumar Savaliya Link: https://lore.kernel.org/r/20250328193252.1570811-1-mohammed.0.elbadry@gmail.com Signed-off-by: Andi Shyti Signed-off-by: Sasha Levin --- drivers/i2c/busses/i2c-npcm7xx.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c index 91f508d50e7a..5b3987460976 100644 --- a/drivers/i2c/busses/i2c-npcm7xx.c +++ b/drivers/i2c/busses/i2c-npcm7xx.c @@ -1971,10 +1971,14 @@ static int npcm_i2c_init_module(struct npcm_i2c *bus, enum i2c_mode mode, /* Check HW is OK: SDA and SCL should be high at this point. */ if ((npcm_i2c_get_SDA(&bus->adap) == 0) || (npcm_i2c_get_SCL(&bus->adap) == 0)) { - dev_err(bus->dev, "I2C%d init fail: lines are low\n", bus->num); - dev_err(bus->dev, "SDA=%d SCL=%d\n", npcm_i2c_get_SDA(&bus->adap), - npcm_i2c_get_SCL(&bus->adap)); - return -ENXIO; + dev_warn(bus->dev, " I2C%d SDA=%d SCL=%d, attempting to recover\n", bus->num, + npcm_i2c_get_SDA(&bus->adap), npcm_i2c_get_SCL(&bus->adap)); + if (npcm_i2c_recovery_tgclk(&bus->adap)) { + dev_err(bus->dev, "I2C%d init fail: SDA=%d SCL=%d\n", + bus->num, npcm_i2c_get_SDA(&bus->adap), + npcm_i2c_get_SCL(&bus->adap)); + return -ENXIO; + } } npcm_i2c_int_enable(bus, true); From 6f79eb2e681678c054137935d86009b2e2b6fc2f Mon Sep 17 00:00:00 2001 From: Moon Yeounsu Date: Thu, 15 May 2025 16:53:31 +0900 Subject: [PATCH 546/971] net: dlink: add synchronization for stats update [ Upstream commit 12889ce926e9a9baf6b83d809ba316af539b89e2 ] This patch synchronizes code that accesses from both user-space and IRQ contexts. The `get_stats()` function can be called from both context. `dev->stats.tx_errors` and `dev->stats.collisions` are also updated in the `tx_errors()` function. Therefore, these fields must also be protected by synchronized. There is no code that accessses `dev->stats.tx_errors` between the previous and updated lines, so the updating point can be moved. Signed-off-by: Moon Yeounsu Link: https://patch.msgid.link/20250515075333.48290-1-yyyynoom@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/dlink/dl2k.c | 14 +++++++++++++- drivers/net/ethernet/dlink/dl2k.h | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c index ce46f3ac3b5a..fad5a72d3b16 100644 --- a/drivers/net/ethernet/dlink/dl2k.c +++ b/drivers/net/ethernet/dlink/dl2k.c @@ -146,6 +146,8 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent) np->ioaddr = ioaddr; np->chip_id = chip_idx; np->pdev = pdev; + + spin_lock_init(&np->stats_lock); spin_lock_init (&np->tx_lock); spin_lock_init (&np->rx_lock); @@ -866,7 +868,6 @@ tx_error (struct net_device *dev, int tx_status) frame_id = (tx_status & 0xffff0000); printk (KERN_ERR "%s: Transmit error, TxStatus %4.4x, FrameId %d.\n", dev->name, tx_status, frame_id); - dev->stats.tx_errors++; /* Ttransmit Underrun */ if (tx_status & 0x10) { dev->stats.tx_fifo_errors++; @@ -903,9 +904,15 @@ tx_error (struct net_device *dev, int tx_status) rio_set_led_mode(dev); /* Let TxStartThresh stay default value */ } + + spin_lock(&np->stats_lock); /* Maximum Collisions */ if (tx_status & 0x08) dev->stats.collisions++; + + dev->stats.tx_errors++; + spin_unlock(&np->stats_lock); + /* Restart the Tx */ dw32(MACCtrl, dr16(MACCtrl) | TxEnable); } @@ -1074,7 +1081,9 @@ get_stats (struct net_device *dev) int i; #endif unsigned int stat_reg; + unsigned long flags; + spin_lock_irqsave(&np->stats_lock, flags); /* All statistics registers need to be acknowledged, else statistic overflow could cause problems */ @@ -1124,6 +1133,9 @@ get_stats (struct net_device *dev) dr16(TCPCheckSumErrors); dr16(UDPCheckSumErrors); dr16(IPCheckSumErrors); + + spin_unlock_irqrestore(&np->stats_lock, flags); + return &dev->stats; } diff --git a/drivers/net/ethernet/dlink/dl2k.h b/drivers/net/ethernet/dlink/dl2k.h index 0e33e2eaae96..56aff2f0bdbf 100644 --- a/drivers/net/ethernet/dlink/dl2k.h +++ b/drivers/net/ethernet/dlink/dl2k.h @@ -372,6 +372,8 @@ struct netdev_private { struct pci_dev *pdev; void __iomem *ioaddr; void __iomem *eeprom_addr; + // To ensure synchronization when stats are updated. + spinlock_t stats_lock; spinlock_t tx_lock; spinlock_t rx_lock; unsigned int rx_buf_sz; /* Based on MTU+slack. */ From 7c4b6d8bd72ddfd8f127cbf3ffdbfa6d88a1691a Mon Sep 17 00:00:00 2001 From: Kang Yang Date: Mon, 21 Apr 2025 10:34:39 +0800 Subject: [PATCH 547/971] wifi: ath12k: fix macro definition HAL_RX_MSDU_PKT_LENGTH_GET [ Upstream commit a69bbf89d751ba2d6da21d773c4e29c91c5e53c4 ] Currently, HAL_RX_MSDU_PKT_LENGTH_GET uses u32_get_bits to obtain the MSDU length from the MSDU description. This is not right. Because all halphy descriptions are little endian. So use le32_get_bits for HAL_RX_MSDU_PKT_LENGTH_GET. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Signed-off-by: Kang Yang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20250421023444.1778-9-kang.yang@oss.qualcomm.com Signed-off-by: Jeff Johnson Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath12k/hal_desc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/hal_desc.h b/drivers/net/wireless/ath/ath12k/hal_desc.h index 1bb840c2bef5..5fd9232ad101 100644 --- a/drivers/net/wireless/ath/ath12k/hal_desc.h +++ b/drivers/net/wireless/ath/ath12k/hal_desc.h @@ -683,7 +683,7 @@ enum hal_rx_msdu_desc_reo_dest_ind { #define RX_MSDU_DESC_INFO0_DECAP_FORMAT GENMASK(30, 29) #define HAL_RX_MSDU_PKT_LENGTH_GET(val) \ - (u32_get_bits((val), RX_MSDU_DESC_INFO0_MSDU_LENGTH)) + (le32_get_bits((val), RX_MSDU_DESC_INFO0_MSDU_LENGTH)) struct rx_msdu_desc { __le32 info0; From dcf7bb4397dec9ca80c35cb313ff3f1a152394c2 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Fri, 18 Apr 2025 10:55:34 +0800 Subject: [PATCH 548/971] wifi: ath12k: fix a possible dead lock caused by ab->base_lock [ Upstream commit ef115c265a21e3c11deee7f73bd1061775a7bf20 ] spin_lock/spin_unlock are used in ath12k_reg_chan_list_event to acquire/release ab->base_lock. For now this is safe because that function is only called in soft IRQ context. But ath12k_reg_chan_list_event() will be called from process context in an upcoming patch, and this can result in a deadlock if ab->base_lock is acquired in process context and then soft IRQ occurs on the same CPU and tries to acquire that lock. Fix it by using spin_lock_bh and spin_unlock_bh instead. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20250418-ath12k-6g-lp-vlp-v1-1-c869c86cad60@quicinc.com Signed-off-by: Jeff Johnson Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath12k/wmi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index a0ac2f350934..31af940bc572 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -5503,7 +5503,7 @@ static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *sk goto fallback; } - spin_lock(&ab->base_lock); + spin_lock_bh(&ab->base_lock); if (test_bit(ATH12K_FLAG_REGISTERED, &ab->dev_flags)) { /* Once mac is registered, ar is valid and all CC events from * fw is considered to be received due to user requests @@ -5527,7 +5527,7 @@ static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *sk ab->default_regd[pdev_idx] = regd; } ab->dfs_region = reg_info->dfs_region; - spin_unlock(&ab->base_lock); + spin_unlock_bh(&ab->base_lock); goto mem_free; From f11520c6174cc99b04d2ee81ed393fc348416dc9 Mon Sep 17 00:00:00 2001 From: Muhammad Usama Anjum Date: Mon, 28 Apr 2025 13:02:41 +0500 Subject: [PATCH 549/971] wifi: ath11k: Fix QMI memory reuse logic [ Upstream commit cd2e7bae92bd7e65063ab8d04721d2b711ba4cbe ] Firmware requests 2 segments at first. The first segment is of 6799360 whose allocation fails due to dma remapping not available. The success is returned to firmware. Then firmware asks for 22 smaller segments instead of 2 big ones. Those get allocated successfully. At suspend/ hibernation time, these segments aren't freed as they will be reused by firmware after resuming. After resuming, the firmware asks for the 2 segments again with the first segment of 6799360 size. Since chunk->vaddr is not NULL, the type and size are compared with the previous type and size to know if it can be reused or not. Unfortunately, it is detected that it cannot be reused and this first smaller segment is freed. Then we continue to allocate 6799360 size memory which fails and ath11k_qmi_free_target_mem_chunk() is called which frees the second smaller segment as well. Later success is returned to firmware which asks for 22 smaller segments again. But as we had freed 2 segments already, we'll allocate the first 2 new smaller segments again and reuse the remaining 20. Hence 20 small segments are being reused instead of 22. Add skip logic when vaddr is set, but size/type don't match. Use the same skip and success logic as used when dma_alloc_coherent() fails. By skipping, the possibility of resume failure due to kernel failing to allocate memory for QMI can be avoided. kernel: ath11k_pci 0000:03:00.0: failed to allocate dma memory for qmi (524288 B type 1) ath11k_pci 0000:03:00.0: failed to allocate qmi target memory: -22 Tested-on: WCN6855 WLAN.HSP.1.1-03926.13-QCAHSPSWPL_V2_SILICONZ_CE-2.52297.6 Signed-off-by: Muhammad Usama Anjum Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250428080242.466901-1-usama.anjum@collabora.com Signed-off-by: Jeff Johnson Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath11k/qmi.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index fa46e645009c..91e31f30d2c8 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -1989,6 +1989,15 @@ static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab) chunk->prev_size == chunk->size) continue; + if (ab->qmi.mem_seg_count <= ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT) { + ath11k_dbg(ab, ATH11K_DBG_QMI, + "size/type mismatch (current %d %u) (prev %d %u), try later with small size\n", + chunk->size, chunk->type, + chunk->prev_size, chunk->prev_type); + ab->qmi.target_mem_delayed = true; + return 0; + } + /* cannot reuse the existing chunk */ dma_free_coherent(ab->dev, chunk->prev_size, chunk->vaddr, chunk->paddr); From 969d61aa168c08d8c5cfc56a9318d1692ca2a341 Mon Sep 17 00:00:00 2001 From: Dian-Syuan Yang Date: Wed, 7 May 2025 11:12:03 +0800 Subject: [PATCH 550/971] wifi: rtw89: leave idle mode when setting WEP encryption for AP mode [ Upstream commit d105652b33245162867ac769bea336976e67efb8 ] Due to mac80211 triggering the hardware to enter idle mode, it fails to install WEP key causing connected station can't ping successfully. Currently, it forces the hardware to leave idle mode before driver adding WEP keys. Signed-off-by: Dian-Syuan Yang Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250507031203.8256-1-pkshih@realtek.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtw89/cam.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c index f5301c2bbf13..9a0ffaddb836 100644 --- a/drivers/net/wireless/realtek/rtw89/cam.c +++ b/drivers/net/wireless/realtek/rtw89/cam.c @@ -6,6 +6,7 @@ #include "debug.h" #include "fw.h" #include "mac.h" +#include "ps.h" static struct sk_buff * rtw89_cam_get_sec_key_cmd(struct rtw89_dev *rtwdev, @@ -333,9 +334,11 @@ int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev, switch (key->cipher) { case WLAN_CIPHER_SUITE_WEP40: + rtw89_leave_ips_by_hwflags(rtwdev); hw_key_type = RTW89_SEC_KEY_TYPE_WEP40; break; case WLAN_CIPHER_SUITE_WEP104: + rtw89_leave_ips_by_hwflags(rtwdev); hw_key_type = RTW89_SEC_KEY_TYPE_WEP104; break; case WLAN_CIPHER_SUITE_CCMP: From 156b6bac76450f61b1a409eaaa4c2ac3a3369eea Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 13 May 2025 19:39:15 +0000 Subject: [PATCH 551/971] tcp: always seek for minimal rtt in tcp_rcv_rtt_update() [ Upstream commit b879dcb1aeeca278eacaac0b1e2425b1c7599f9f ] tcp_rcv_rtt_update() goal is to maintain an estimation of the RTT in tp->rcv_rtt_est.rtt_us, used by tcp_rcv_space_adjust() When TCP TS are enabled, tcp_rcv_rtt_update() is using EWMA to smooth the samples. Change this to immediately latch the incoming value if it is lower than tp->rcv_rtt_est.rtt_us, so that tcp_rcv_space_adjust() does not overshoot tp->rcvq_space.space and sk->sk_rcvbuf. Signed-off-by: Eric Dumazet Link: https://patch.msgid.link/20250513193919.1089692-8-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/ipv4/tcp_input.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index a172248b6678..994c563b35f3 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -671,10 +671,12 @@ EXPORT_SYMBOL(tcp_initialize_rcv_mss); */ static void tcp_rcv_rtt_update(struct tcp_sock *tp, u32 sample, int win_dep) { - u32 new_sample = tp->rcv_rtt_est.rtt_us; - long m = sample; + u32 new_sample, old_sample = tp->rcv_rtt_est.rtt_us; + long m = sample << 3; - if (new_sample != 0) { + if (old_sample == 0 || m < old_sample) { + new_sample = m; + } else { /* If we sample in larger samples in the non-timestamp * case, we could grossly overestimate the RTT especially * with chatty applications or bulk transfer apps which @@ -685,17 +687,9 @@ static void tcp_rcv_rtt_update(struct tcp_sock *tp, u32 sample, int win_dep) * else with timestamps disabled convergence takes too * long. */ - if (!win_dep) { - m -= (new_sample >> 3); - new_sample += m; - } else { - m <<= 3; - if (m < new_sample) - new_sample = m; - } - } else { - /* No previous measure. */ - new_sample = m << 3; + if (win_dep) + return; + new_sample = old_sample - (old_sample >> 3) + sample; } tp->rcv_rtt_est.rtt_us = new_sample; From c1025a54289bf9de1a587e2a258fe33c507965e9 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 13 May 2025 19:39:14 +0000 Subject: [PATCH 552/971] tcp: fix initial tp->rcvq_space.space value for passive TS enabled flows [ Upstream commit cd171461b90a2d2cf230943df60d580174633718 ] tcp_rcv_state_process() must tweak tp->advmss for TS enabled flows before the call to tcp_init_transfer() / tcp_init_buffer_space(). Otherwise tp->rcvq_space.space is off by 120 bytes (TCP_INIT_CWND * TCPOLEN_TSTAMP_ALIGNED). Signed-off-by: Eric Dumazet Reviewed-by: Wei Wang Link: https://patch.msgid.link/20250513193919.1089692-7-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/ipv4/tcp_input.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 994c563b35f3..66d6ad6d633c 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -6699,6 +6699,9 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) if (!tp->srtt_us) tcp_synack_rtt_meas(sk, req); + if (tp->rx_opt.tstamp_ok) + tp->advmss -= TCPOLEN_TSTAMP_ALIGNED; + if (req) { tcp_rcv_synrecv_state_fastopen(sk); } else { @@ -6723,9 +6726,6 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) tp->snd_wnd = ntohs(th->window) << tp->rx_opt.snd_wscale; tcp_init_wl(tp, TCP_SKB_CB(skb)->seq); - if (tp->rx_opt.tstamp_ok) - tp->advmss -= TCPOLEN_TSTAMP_ALIGNED; - if (!inet_csk(sk)->icsk_ca_ops->cong_control) tcp_update_pacing_rate(sk); From 62b62a2a6dc51ed6e8e334861f04220c9cf8106a Mon Sep 17 00:00:00 2001 From: Andrew Zaborowski Date: Fri, 9 May 2025 01:04:29 +0200 Subject: [PATCH 553/971] x86/sgx: Prevent attempts to reclaim poisoned pages [ Upstream commit ed16618c380c32c68c06186d0ccbb0d5e0586e59 ] TL;DR: SGX page reclaim touches the page to copy its contents to secondary storage. SGX instructions do not gracefully handle machine checks. Despite this, the existing SGX code will try to reclaim pages that it _knows_ are poisoned. Avoid even trying to reclaim poisoned pages. The longer story: Pages used by an enclave only get epc_page->poison set in arch_memory_failure() but they currently stay on sgx_active_page_list until sgx_encl_release(), with the SGX_EPC_PAGE_RECLAIMER_TRACKED flag untouched. epc_page->poison is not checked in the reclaimer logic meaning that, if other conditions are met, an attempt will be made to reclaim an EPC page that was poisoned. This is bad because 1. we don't want that page to end up added to another enclave and 2. it is likely to cause one core to shut down and the kernel to panic. Specifically, reclaiming uses microcode operations including "EWB" which accesses the EPC page contents to encrypt and write them out to non-SGX memory. Those operations cannot handle MCEs in their accesses other than by putting the executing core into a special shutdown state (affecting both threads with HT.) The kernel will subsequently panic on the remaining cores seeing the core didn't enter MCE handler(s) in time. Call sgx_unmark_page_reclaimable() to remove the affected EPC page from sgx_active_page_list on memory error to stop it being considered for reclaiming. Testing epc_page->poison in sgx_reclaim_pages() would also work but I assume it's better to add code in the less likely paths. The affected EPC page is not added to &node->sgx_poison_page_list until later in sgx_encl_release()->sgx_free_epc_page() when it is EREMOVEd. Membership on other lists doesn't change to avoid changing any of the lists' semantics except for sgx_active_page_list. There's a "TBD" comment in arch_memory_failure() about pre-emptive actions, the goal here is not to address everything that it may imply. This also doesn't completely close the time window when a memory error notification will be fatal (for a not previously poisoned EPC page) -- the MCE can happen after sgx_reclaim_pages() has selected its candidates or even *inside* a microcode operation (actually easy to trigger due to the amount of time spent in them.) The spinlock in sgx_unmark_page_reclaimable() is safe because memory_failure() runs in process context and no spinlocks are held, explicitly noted in a mm/memory-failure.c comment. Signed-off-by: Andrew Zaborowski Signed-off-by: Ingo Molnar Acked-by: Dave Hansen Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Tony Luck Cc: balrogg@gmail.com Cc: linux-sgx@vger.kernel.org Link: https://lore.kernel.org/r/20250508230429.456271-1-andrew.zaborowski@intel.com Signed-off-by: Sasha Levin --- arch/x86/kernel/cpu/sgx/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c index c7f8c3200e8d..0db6eeeeb672 100644 --- a/arch/x86/kernel/cpu/sgx/main.c +++ b/arch/x86/kernel/cpu/sgx/main.c @@ -718,6 +718,8 @@ int arch_memory_failure(unsigned long pfn, int flags) goto out; } + sgx_unmark_page_reclaimable(page); + /* * TBD: Add additional plumbing to enable pre-emptive * action for asynchronous poison notification. Until From 9121c2ddd177a165dc36f79d6b197351c6ebd52b Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 12 May 2025 11:27:24 +0200 Subject: [PATCH 554/971] ipv4/route: Use this_cpu_inc() for stats on PREEMPT_RT [ Upstream commit 1c0829788a6e6e165846b9bedd0b908ef16260b6 ] The statistics are incremented with raw_cpu_inc() assuming it always happens with bottom half disabled. Without per-CPU locking in local_bh_disable() on PREEMPT_RT this is no longer true. Use this_cpu_inc() on PREEMPT_RT for the increment to not worry about preemption. Cc: David Ahern Signed-off-by: Sebastian Andrzej Siewior Link: https://patch.msgid.link/20250512092736.229935-4-bigeasy@linutronix.de Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- net/ipv4/route.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 97dc30a03dbf..8ee1ad2d8c13 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -192,7 +192,11 @@ const __u8 ip_tos2prio[16] = { EXPORT_SYMBOL(ip_tos2prio); static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat); +#ifndef CONFIG_PREEMPT_RT #define RT_CACHE_STAT_INC(field) raw_cpu_inc(rt_cache_stat.field) +#else +#define RT_CACHE_STAT_INC(field) this_cpu_inc(rt_cache_stat.field) +#endif #ifdef CONFIG_PROC_FS static void *rt_cache_seq_start(struct seq_file *seq, loff_t *pos) From 79f3e44df6e6efe453a9ad37acdd3097544ad880 Mon Sep 17 00:00:00 2001 From: Jason Xing Date: Sat, 10 May 2025 21:48:10 +0800 Subject: [PATCH 555/971] net: atlantic: generate software timestamp just before the doorbell [ Upstream commit 285ad7477559b6b5ceed10ba7ecfed9d17c0e7c6 ] Make sure the call of skb_tx_timestamp is as close as possible to the doorbell. Signed-off-by: Jason Xing Link: https://patch.msgid.link/20250510134812.48199-2-kerneljasonxing@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/aquantia/atlantic/aq_main.c | 1 - drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c b/drivers/net/ethernet/aquantia/atlantic/aq_main.c index 0b2a52199914..75d436c90696 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c @@ -123,7 +123,6 @@ static netdev_tx_t aq_ndev_start_xmit(struct sk_buff *skb, struct net_device *nd } #endif - skb_tx_timestamp(skb); return aq_nic_xmit(aq_nic, skb); } diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index c9b0d57696a4..07392174f643 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c @@ -898,6 +898,8 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb) frags = aq_nic_map_skb(self, skb, ring); + skb_tx_timestamp(skb); + if (likely(frags)) { err = self->aq_hw_ops->hw_ring_tx_xmit(self->aq_hw, ring, frags); From 14a26f6692062a529b612420adb6c0b9290b25d3 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Wed, 14 May 2025 21:18:38 +0200 Subject: [PATCH 556/971] pinctrl: armada-37xx: propagate error from armada_37xx_pmx_set_by_name() [ Upstream commit 4229c28323db141eda69cb99427be75d3edba071 ] The regmap_update_bits() function can fail, so propagate its error up to the stack instead of silently ignoring that. Signed-off-by: Imre Kaloz Reviewed-by: Andrew Lunn Signed-off-by: Gabor Juhos Link: https://lore.kernel.org/20250514-pinctrl-a37xx-fixes-v2-7-07e9ac1ab737@gmail.com Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin --- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index 1a39fd97a900..1d9aa4e76a23 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -358,9 +358,7 @@ static int armada_37xx_pmx_set_by_name(struct pinctrl_dev *pctldev, val = grp->val[func]; - regmap_update_bits(info->regmap, reg, mask, val); - - return 0; + return regmap_update_bits(info->regmap, reg, mask, val); } static int armada_37xx_pmx_set(struct pinctrl_dev *pctldev, From 02c966a8869becb29282403540c88ba33e19c347 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Wed, 14 May 2025 21:18:37 +0200 Subject: [PATCH 557/971] pinctrl: armada-37xx: propagate error from armada_37xx_gpio_get_direction() [ Upstream commit 6481c0a83367b0672951ccc876fbae7ee37b594b ] The regmap_read() function can fail, so propagate its error up to the stack instead of silently ignoring that. Signed-off-by: Imre Kaloz Reviewed-by: Andrew Lunn Signed-off-by: Gabor Juhos Link: https://lore.kernel.org/20250514-pinctrl-a37xx-fixes-v2-6-07e9ac1ab737@gmail.com Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin --- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index 1d9aa4e76a23..8008bad481b7 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -400,10 +400,13 @@ static int armada_37xx_gpio_get_direction(struct gpio_chip *chip, struct armada_37xx_pinctrl *info = gpiochip_get_data(chip); unsigned int reg = OUTPUT_EN; unsigned int val, mask; + int ret; armada_37xx_update_reg(®, &offset); mask = BIT(offset); - regmap_read(info->regmap, reg, &val); + ret = regmap_read(info->regmap, reg, &val); + if (ret) + return ret; if (val & mask) return GPIO_LINE_DIRECTION_OUT; From 8a15a5438c5816a1003b88ce20f25ccc92909ee7 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Wed, 14 May 2025 21:18:36 +0200 Subject: [PATCH 558/971] pinctrl: armada-37xx: propagate error from armada_37xx_pmx_gpio_set_direction() [ Upstream commit bfa0ff804ffa8b1246ade8be08de98c9eb19d16f ] The armada_37xx_gpio_direction_{in,out}put() functions can fail, so propagate their error values back to the stack instead of silently ignoring those. Signed-off-by: Imre Kaloz Reviewed-by: Andrew Lunn Signed-off-by: Gabor Juhos Link: https://lore.kernel.org/20250514-pinctrl-a37xx-fixes-v2-5-07e9ac1ab737@gmail.com Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin --- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index 8008bad481b7..a9e665ea0f61 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -472,16 +472,17 @@ static int armada_37xx_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, { struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); struct gpio_chip *chip = range->gc; + int ret; dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n", offset, range->name, offset, input ? "input" : "output"); if (input) - armada_37xx_gpio_direction_input(chip, offset); + ret = armada_37xx_gpio_direction_input(chip, offset); else - armada_37xx_gpio_direction_output(chip, offset, 0); + ret = armada_37xx_gpio_direction_output(chip, offset, 0); - return 0; + return ret; } static int armada_37xx_gpio_request_enable(struct pinctrl_dev *pctldev, From ae48bc0b8be8786fd0ceab4b5a95c09b5aa93816 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Wed, 14 May 2025 21:18:35 +0200 Subject: [PATCH 559/971] pinctrl: armada-37xx: propagate error from armada_37xx_gpio_get() [ Upstream commit 57273ff8bb16f3842c2597b5bbcd49e7fa12edf7 ] The regmap_read() function can fail, so propagate its error up to the stack instead of silently ignoring that. Signed-off-by: Imre Kaloz Reviewed-by: Andrew Lunn Signed-off-by: Gabor Juhos Link: https://lore.kernel.org/20250514-pinctrl-a37xx-fixes-v2-4-07e9ac1ab737@gmail.com Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin --- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index a9e665ea0f61..ef87a6045e07 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -443,11 +443,14 @@ static int armada_37xx_gpio_get(struct gpio_chip *chip, unsigned int offset) struct armada_37xx_pinctrl *info = gpiochip_get_data(chip); unsigned int reg = INPUT_VAL; unsigned int val, mask; + int ret; armada_37xx_update_reg(®, &offset); mask = BIT(offset); - regmap_read(info->regmap, reg, &val); + ret = regmap_read(info->regmap, reg, &val); + if (ret) + return ret; return (val & mask) != 0; } From 84d34bd55d6a98d8e2766ed7ecf6f547d7cbd62e Mon Sep 17 00:00:00 2001 From: Jason Xing Date: Sat, 10 May 2025 17:34:42 +0800 Subject: [PATCH 560/971] net: mlx4: add SOF_TIMESTAMPING_TX_SOFTWARE flag when getting ts info [ Upstream commit b86bcfee30576b752302c55693fff97242b35dfd ] As mlx4 has implemented skb_tx_timestamp() in mlx4_en_xmit(), the SOFTWARE flag is surely needed when users are trying to get timestamp information. Signed-off-by: Jason Xing Reviewed-by: Tariq Toukan Link: https://patch.msgid.link/20250510093442.79711-1-kerneljasonxing@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index 164a13272faa..07dced3c2b1c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -1916,6 +1916,7 @@ static int mlx4_en_get_ts_info(struct net_device *dev, if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS) { info->so_timestamping |= SOF_TIMESTAMPING_TX_HARDWARE | + SOF_TIMESTAMPING_TX_SOFTWARE | SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_RAW_HARDWARE; From 187829fb0c3577b235a90e88736701cc48c24d72 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Fri, 9 May 2025 14:04:34 +0200 Subject: [PATCH 561/971] net: vertexcom: mse102x: Return code for mse102x_rx_pkt_spi [ Upstream commit 4ecf56f4b66011b583644bf9a62188d05dfcd78c ] The MSE102x doesn't provide any interrupt register, so the only way to handle the level interrupt is to fetch the whole packet from the MSE102x internal buffer via SPI. So in cases the interrupt handler fails to do this, it should return IRQ_NONE. This allows the core to disable the interrupt in case the issue persists and prevent an interrupt storm. Signed-off-by: Stefan Wahren Link: https://patch.msgid.link/20250509120435.43646-6-wahrenst@gmx.net Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/vertexcom/mse102x.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/vertexcom/mse102x.c b/drivers/net/ethernet/vertexcom/mse102x.c index 060a566bc6aa..c902f8761d5d 100644 --- a/drivers/net/ethernet/vertexcom/mse102x.c +++ b/drivers/net/ethernet/vertexcom/mse102x.c @@ -306,7 +306,7 @@ static void mse102x_dump_packet(const char *msg, int len, const char *data) data, len, true); } -static void mse102x_rx_pkt_spi(struct mse102x_net *mse) +static irqreturn_t mse102x_rx_pkt_spi(struct mse102x_net *mse) { struct sk_buff *skb; unsigned int rxalign; @@ -327,7 +327,7 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse) mse102x_tx_cmd_spi(mse, CMD_CTR); ret = mse102x_rx_cmd_spi(mse, (u8 *)&rx); if (ret) - return; + return IRQ_NONE; cmd_resp = be16_to_cpu(rx); if ((cmd_resp & CMD_MASK) != CMD_RTS) { @@ -360,7 +360,7 @@ drop: rxalign = ALIGN(rxlen + DET_SOF_LEN + DET_DFT_LEN, 4); skb = netdev_alloc_skb_ip_align(mse->ndev, rxalign); if (!skb) - return; + return IRQ_NONE; /* 2 bytes Start of frame (before ethernet header) * 2 bytes Data frame tail (after ethernet frame) @@ -370,7 +370,7 @@ drop: if (mse102x_rx_frame_spi(mse, rxpkt, rxlen, drop)) { mse->ndev->stats.rx_errors++; dev_kfree_skb(skb); - return; + return IRQ_HANDLED; } if (netif_msg_pktdata(mse)) @@ -381,6 +381,8 @@ drop: mse->ndev->stats.rx_packets++; mse->ndev->stats.rx_bytes += rxlen; + + return IRQ_HANDLED; } static int mse102x_tx_pkt_spi(struct mse102x_net *mse, struct sk_buff *txb, @@ -512,12 +514,13 @@ static irqreturn_t mse102x_irq(int irq, void *_mse) { struct mse102x_net *mse = _mse; struct mse102x_net_spi *mses = to_mse102x_spi(mse); + irqreturn_t ret; mutex_lock(&mses->lock); - mse102x_rx_pkt_spi(mse); + ret = mse102x_rx_pkt_spi(mse); mutex_unlock(&mses->lock); - return IRQ_HANDLED; + return ret; } static int mse102x_net_open(struct net_device *ndev) From efa7997ce846b9aff4121dba53e4e2429e8cafa0 Mon Sep 17 00:00:00 2001 From: Salah Triki Date: Sun, 27 Apr 2025 10:57:45 +0100 Subject: [PATCH 562/971] wireless: purelifi: plfxlc: fix memory leak in plfxlc_usb_wreq_asyn() [ Upstream commit 63a9a727d373fa5b8ce509eef50dbc45e0f745b9 ] Add usb_free_urb() in the error path to prevent memory leak. Signed-off-by: Salah Triki Link: https://patch.msgid.link/aA3_maPlEJzO7wrL@pc [fix subject] Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- drivers/net/wireless/purelifi/plfxlc/usb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/purelifi/plfxlc/usb.c b/drivers/net/wireless/purelifi/plfxlc/usb.c index 311676c1ece0..8151bc5e00cc 100644 --- a/drivers/net/wireless/purelifi/plfxlc/usb.c +++ b/drivers/net/wireless/purelifi/plfxlc/usb.c @@ -503,8 +503,10 @@ int plfxlc_usb_wreq_async(struct plfxlc_usb *usb, const u8 *buffer, (void *)buffer, buffer_len, complete_fn, context); r = usb_submit_urb(urb, GFP_ATOMIC); - if (r) + if (r) { + usb_free_urb(urb); dev_err(&udev->dev, "Async write submit failed (%d)\n", r); + } return r; } From dfec43c50376743e4ddaa0a6e81c2df8a63a439e Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Wed, 30 Apr 2025 21:10:42 +0200 Subject: [PATCH 563/971] wifi: mac80211: do not offer a mesh path if forwarding is disabled [ Upstream commit cf1b684a06170d253b47d6a5287821de976435bd ] When processing a PREQ the code would always check whether we have a mesh path locally and reply accordingly. However, when forwarding is disabled then we should not reply with this information as we will not forward data packets down that path. Move the check for dot11MeshForwarding up in the function and skip the mesh path lookup in that case. In the else block, set forward to false so that the rest of the function becomes a no-op and the dot11MeshForwarding check does not need to be duplicated. This explains an effect observed in the Freifunk community where mesh forwarding is disabled. In that case a mesh with three STAs and only bad links in between them, individual STAs would occionally have indirect mpath entries. This should not have happened. Signed-off-by: Benjamin Berg Reviewed-by: Rouven Czerwinski Link: https://patch.msgid.link/20250430191042.3287004-1-benjamin@sipsolutions.net Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- net/mac80211/mesh_hwmp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index c6395551f5df..54930b06c3a4 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -634,7 +634,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, mesh_path_add_gate(mpath); } rcu_read_unlock(); - } else { + } else if (ifmsh->mshcfg.dot11MeshForwarding) { rcu_read_lock(); mpath = mesh_path_lookup(sdata, target_addr); if (mpath) { @@ -652,6 +652,8 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, } } rcu_read_unlock(); + } else { + forward = false; } if (reply) { @@ -669,7 +671,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, } } - if (forward && ifmsh->mshcfg.dot11MeshForwarding) { + if (forward) { u32 preq_id; u8 hopcount; From f11cfb48f2d2c4c136fa866a3b23390eb092e7b5 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Sat, 3 May 2025 22:25:31 +0200 Subject: [PATCH 564/971] clk: rockchip: rk3036: mark ddrphy as critical [ Upstream commit 596a977b34a722c00245801a5774aa79cec4e81d ] The ddrphy is supplied by the dpll, but due to the limited number of PLLs on the rk3036, the dpll also is used for other periperhals, like the GPU. So it happened, when the Lima driver turned off the gpu clock, this in turn also disabled the dpll and thus the ram. Signed-off-by: Heiko Stuebner Link: https://lore.kernel.org/r/20250503202532.992033-4-heiko@sntech.de Signed-off-by: Sasha Levin --- drivers/clk/rockchip/clk-rk3036.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c index d644bc155ec6..f5f27535087a 100644 --- a/drivers/clk/rockchip/clk-rk3036.c +++ b/drivers/clk/rockchip/clk-rk3036.c @@ -431,6 +431,7 @@ static const char *const rk3036_critical_clocks[] __initconst = { "hclk_peri", "pclk_peri", "pclk_ddrupctl", + "ddrphy", }; static void __init rk3036_clk_init(struct device_node *np) From c697dac969375570d07a2353fe1207813017eb2a Mon Sep 17 00:00:00 2001 From: Alan Maguire Date: Tue, 29 Apr 2025 17:10:42 +0100 Subject: [PATCH 565/971] libbpf: Add identical pointer detection to btf_dedup_is_equiv() [ Upstream commit 8e64c387c942229c551d0f23de4d9993d3a2acb6 ] Recently as a side-effect of commit ac053946f5c4 ("compiler.h: introduce TYPEOF_UNQUAL() macro") issues were observed in deduplication between modules and kernel BTF such that a large number of kernel types were not deduplicated so were found in module BTF (task_struct, bpf_prog etc). The root cause appeared to be a failure to dedup struct types, specifically those with members that were pointers with __percpu annotations. The issue in dedup is at the point that we are deduplicating structures, we have not yet deduplicated reference types like pointers. If multiple copies of a pointer point at the same (deduplicated) integer as in this case, we do not see them as identical. Special handling already exists to deal with structures and arrays, so add pointer handling here too. Reported-by: Alexei Starovoitov Signed-off-by: Alan Maguire Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20250429161042.2069678-1-alan.maguire@oracle.com Signed-off-by: Sasha Levin --- tools/lib/bpf/btf.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index 8484b563b53d..2e9f28cece3f 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -3922,6 +3922,19 @@ static bool btf_dedup_identical_structs(struct btf_dedup *d, __u32 id1, __u32 id return true; } +static bool btf_dedup_identical_ptrs(struct btf_dedup *d, __u32 id1, __u32 id2) +{ + struct btf_type *t1, *t2; + + t1 = btf_type_by_id(d->btf, id1); + t2 = btf_type_by_id(d->btf, id2); + + if (!btf_is_ptr(t1) || !btf_is_ptr(t2)) + return false; + + return t1->type == t2->type; +} + /* * Check equivalence of BTF type graph formed by candidate struct/union (we'll * call it "candidate graph" in this description for brevity) to a type graph @@ -4054,6 +4067,9 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id, */ if (btf_dedup_identical_structs(d, hypot_type_id, cand_id)) return 1; + /* A similar case is again observed for PTRs. */ + if (btf_dedup_identical_ptrs(d, hypot_type_id, cand_id)) + return 1; return 0; } From 32f25633f3667000296656ea3bc41f38a9587e5d Mon Sep 17 00:00:00 2001 From: Justin Tee Date: Fri, 25 Apr 2025 12:47:59 -0700 Subject: [PATCH 566/971] scsi: lpfc: Fix lpfc_check_sli_ndlp() handling for GEN_REQUEST64 commands [ Upstream commit 05ae6c9c7315d844fbc15afe393f5ba5e5771126 ] In lpfc_check_sli_ndlp(), the get_job_els_rsp64_did remote_id assignment does not apply for GEN_REQUEST64 commands as it only has meaning for a ELS_REQUEST64 command. So, if (iocb->ndlp == ndlp) is false, we could erroneously return the wrong value. Fix by replacing the fallthrough statement with a break statement before the remote_id check. Signed-off-by: Justin Tee Link: https://lore.kernel.org/r/20250425194806.3585-2-justintee8345@gmail.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/lpfc/lpfc_hbadisc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 5c9bc8af3c2d..ff4428333877 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -5101,7 +5101,7 @@ lpfc_check_sli_ndlp(struct lpfc_hba *phba, case CMD_GEN_REQUEST64_CR: if (iocb->ndlp == ndlp) return 1; - fallthrough; + break; case CMD_ELS_REQUEST64_CR: if (remote_id == ndlp->nlp_DID) return 1; From 920fcc7adc73891a417857c7d6f026f854ec3b0f Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Fri, 14 Mar 2025 20:10:48 -0700 Subject: [PATCH 567/971] iommu/amd: Ensure GA log notifier callbacks finish running before module unload [ Upstream commit 94c721ea03c7078163f41dbaa101ac721ddac329 ] Synchronize RCU when unregistering KVM's GA log notifier to ensure all in-flight interrupt handlers complete before KVM-the module is unloaded. Signed-off-by: Sean Christopherson Link: https://lore.kernel.org/r/20250315031048.2374109-1-seanjc@google.com Signed-off-by: Joerg Roedel Signed-off-by: Sasha Levin --- drivers/iommu/amd/iommu.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index 83c5d786686d..a5d6d786dba5 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -780,6 +780,14 @@ int amd_iommu_register_ga_log_notifier(int (*notifier)(u32)) { iommu_ga_log_notifier = notifier; + /* + * Ensure all in-flight IRQ handlers run to completion before returning + * to the caller, e.g. to ensure module code isn't unloaded while it's + * being executed in the IRQ handler. + */ + if (!notifier) + synchronize_rcu(); + return 0; } EXPORT_SYMBOL(amd_iommu_register_ga_log_notifier); From 2077cef44d3312a13d546bab5e45aac8213b7917 Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Thu, 24 Apr 2025 15:38:30 +0300 Subject: [PATCH 568/971] wifi: iwlwifi: pcie: make sure to lock rxq->read [ Upstream commit 1cc2c48c4af81bed5ddbe9f2c9d6e20fa163acf9 ] rxq->read is accessed without the rxq->lock in a few places, Make sure to have the lock there. Signed-off-by: Miri Korenblit Reviewed-by: Emmanuel Grumbach Tested-by: Emmanuel Grumbach Link: https://patch.msgid.link/20250424153620.73725f207aaa.I1a3e4b6c5fd370e029fdacfcdc9ee335788afa98@changeid Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index e9807fcca6ad..5c2e8d288397 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -2701,6 +2701,8 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file, for (i = 0; i < trans->num_rx_queues && pos < bufsz; i++) { struct iwl_rxq *rxq = &trans_pcie->rxq[i]; + spin_lock_bh(&rxq->lock); + pos += scnprintf(buf + pos, bufsz - pos, "queue#: %2d\n", i); pos += scnprintf(buf + pos, bufsz - pos, "\tread: %u\n", @@ -2721,6 +2723,7 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file, pos += scnprintf(buf + pos, bufsz - pos, "\tclosed_rb_num: Not Allocated\n"); } + spin_unlock_bh(&rxq->lock); } ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); @@ -3385,8 +3388,11 @@ iwl_trans_pcie_dump_data(struct iwl_trans *trans, /* Dump RBs is supported only for pre-9000 devices (1 queue) */ struct iwl_rxq *rxq = &trans_pcie->rxq[0]; /* RBs */ + spin_lock_bh(&rxq->lock); num_rbs = iwl_get_closed_rb_stts(trans, rxq); num_rbs = (num_rbs - rxq->read) & RX_QUEUE_MASK; + spin_unlock_bh(&rxq->lock); + len += num_rbs * (sizeof(*data) + sizeof(struct iwl_fw_error_dump_rb) + (PAGE_SIZE << trans_pcie->rx_page_order)); From 4fc2b3c0657bd51c43d220f44413215590b05bd7 Mon Sep 17 00:00:00 2001 From: Edward Adam Davis Date: Wed, 23 Apr 2025 22:15:53 +0800 Subject: [PATCH 569/971] wifi: mac80211_hwsim: Prevent tsf from setting if beacon is disabled [ Upstream commit c575f5374be7a5c4be4acb9fe6be3a4669d94674 ] Setting tsf is meaningless if beacon is disabled, so check that beacon is enabled before setting tsf. Reported-by: syzbot+064815c6cd721082a52a@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=064815c6cd721082a52a Tested-by: syzbot+064815c6cd721082a52a@syzkaller.appspotmail.com Signed-off-by: Edward Adam Davis Link: https://patch.msgid.link/tencent_3609AC2EFAAED68CA5A7E3C6D212D1C67806@qq.com Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- drivers/net/wireless/virtual/mac80211_hwsim.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c index d86a1bd7aab0..f5f48f7e6d26 100644 --- a/drivers/net/wireless/virtual/mac80211_hwsim.c +++ b/drivers/net/wireless/virtual/mac80211_hwsim.c @@ -1201,6 +1201,11 @@ static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw, /* MLD not supported here */ u32 bcn_int = data->link_data[0].beacon_int; u64 delta = abs(tsf - now); + struct ieee80211_bss_conf *conf; + + conf = link_conf_dereference_protected(vif, data->link_data[0].link_id); + if (conf && !conf->enable_beacon) + return; /* adjust after beaconing with new timestamp at old TBTT */ if (tsf > now) { From 172d1e4a68041dfae4fb0f1d1de4ffbd412eaa07 Mon Sep 17 00:00:00 2001 From: Muna Sinada Date: Tue, 25 Mar 2025 14:31:25 -0700 Subject: [PATCH 570/971] wifi: mac80211: VLAN traffic in multicast path [ Upstream commit 1a4a6a22552ca9d723f28a1fe35eab1b9b3d8b33 ] Currently for MLO, sending out multicast frames on each link is handled by mac80211 only when IEEE80211_HW_MLO_MCAST_MULTI_LINK_TX flag is not set. Dynamic VLAN multicast traffic utilizes software encryption. Due to this, mac80211 should handle transmitting multicast frames on all links for multicast VLAN traffic. Signed-off-by: Muna Sinada Link: https://patch.msgid.link/20250325213125.1509362-4-muna.sinada@oss.qualcomm.com [remove unnecessary parentheses] Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- net/mac80211/tx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 45a093d3f1fa..ec5469add68a 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -4507,8 +4507,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, IEEE80211_TX_CTRL_MLO_LINK_UNSPEC, NULL); } else if (ieee80211_vif_is_mld(&sdata->vif) && - sdata->vif.type == NL80211_IFTYPE_AP && - !ieee80211_hw_check(&sdata->local->hw, MLO_MCAST_MULTI_LINK_TX)) { + ((sdata->vif.type == NL80211_IFTYPE_AP && + !ieee80211_hw_check(&sdata->local->hw, MLO_MCAST_MULTI_LINK_TX)) || + (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && + !sdata->wdev.use_4addr))) { ieee80211_mlo_multicast_tx(dev, skb); } else { normal: From a0ab9e9148ddf93583623def7b96adfb281c4081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Gonzalo?= Date: Wed, 13 Mar 2024 20:02:27 +0200 Subject: [PATCH 571/971] wifi: iwlwifi: Add missing MODULE_FIRMWARE for Qu-c0-jf-b0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 2b801487ac3be7bec561ae62d1a6c4d6f5283f8c ] The module metadata for the firmware file iwlwifi-Qu-c0-jf-b0-* is missing. Signed-off-by: Víctor Gonzalo Link: https://patch.msgid.link/20240313180227.2224780-1-victor.gonzalo@anddroptable.net Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index d594694206b3..906f2790f561 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -44,6 +44,8 @@ IWL_QU_C_HR_B_FW_PRE "-" __stringify(api) ".ucode" #define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \ IWL_QU_B_JF_B_FW_PRE "-" __stringify(api) ".ucode" +#define IWL_QU_C_JF_B_MODULE_FIRMWARE(api) \ + IWL_QU_C_JF_B_FW_PRE "-" __stringify(api) ".ucode" #define IWL_CC_A_MODULE_FIRMWARE(api) \ IWL_CC_A_FW_PRE "-" __stringify(api) ".ucode" @@ -423,6 +425,7 @@ const struct iwl_cfg iwl_cfg_quz_a0_hr_b0 = { MODULE_FIRMWARE(IWL_QU_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_QU_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL_QU_C_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_QUZ_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_QUZ_A_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_CC_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); From cd97899361bc57aa596761799875ddac7b41ebb4 Mon Sep 17 00:00:00 2001 From: Yong Wang Date: Thu, 17 Apr 2025 15:43:13 +0200 Subject: [PATCH 572/971] net: bridge: mcast: update multicast contex when vlan state is changed [ Upstream commit 6c131043eaf1be2a6cc2d228f92ceb626fbcc0f3 ] When the vlan STP state is changed, which could be manipulated by "bridge vlan" commands, similar to port STP state, this also impacts multicast behaviors such as igmp query. In the scenario of per-VLAN snooping, there's a need to update the corresponding multicast context to re-arm the port query timer when vlan state becomes "forwarding" etc. Update br_vlan_set_state() function to enable vlan multicast context in such scenario. Before the patch, the IGMP query does not happen in the last step of the following test sequence, i.e. no growth for tx counter: # ip link add name br1 up type bridge vlan_filtering 1 mcast_snooping 1 mcast_vlan_snooping 1 mcast_querier 1 mcast_stats_enabled 1 # bridge vlan global set vid 1 dev br1 mcast_snooping 1 mcast_querier 1 mcast_query_interval 100 mcast_startup_query_count 0 # ip link add name swp1 up master br1 type dummy # sleep 1 # bridge vlan set vid 1 dev swp1 state 4 # ip -j -p stats show dev swp1 group xstats_slave subgroup bridge suite mcast | jq '.[]["multicast"]["igmp_queries"]["tx_v2"]' 1 # sleep 1 # ip -j -p stats show dev swp1 group xstats_slave subgroup bridge suite mcast | jq '.[]["multicast"]["igmp_queries"]["tx_v2"]' 1 # bridge vlan set vid 1 dev swp1 state 3 # sleep 2 # ip -j -p stats show dev swp1 group xstats_slave subgroup bridge suite mcast | jq '.[]["multicast"]["igmp_queries"]["tx_v2"]' 1 After the patch, the IGMP query happens in the last step of the test: # ip link add name br1 up type bridge vlan_filtering 1 mcast_snooping 1 mcast_vlan_snooping 1 mcast_querier 1 mcast_stats_enabled 1 # bridge vlan global set vid 1 dev br1 mcast_snooping 1 mcast_querier 1 mcast_query_interval 100 mcast_startup_query_count 0 # ip link add name swp1 up master br1 type dummy # sleep 1 # bridge vlan set vid 1 dev swp1 state 4 # ip -j -p stats show dev swp1 group xstats_slave subgroup bridge suite mcast | jq '.[]["multicast"]["igmp_queries"]["tx_v2"]' 1 # sleep 1 # ip -j -p stats show dev swp1 group xstats_slave subgroup bridge suite mcast | jq '.[]["multicast"]["igmp_queries"]["tx_v2"]' 1 # bridge vlan set vid 1 dev swp1 state 3 # sleep 2 # ip -j -p stats show dev swp1 group xstats_slave subgroup bridge suite mcast | jq '.[]["multicast"]["igmp_queries"]["tx_v2"]' 3 Signed-off-by: Yong Wang Reviewed-by: Andy Roulin Reviewed-by: Ido Schimmel Signed-off-by: Petr Machata Acked-by: Nikolay Aleksandrov Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/bridge/br_mst.c | 4 ++-- net/bridge/br_multicast.c | 26 ++++++++++++++++++++++++++ net/bridge/br_private.h | 11 ++++++++++- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/net/bridge/br_mst.c b/net/bridge/br_mst.c index 1820f09ff59c..3f24b4ee49c2 100644 --- a/net/bridge/br_mst.c +++ b/net/bridge/br_mst.c @@ -80,10 +80,10 @@ static void br_mst_vlan_set_state(struct net_bridge_vlan_group *vg, if (br_vlan_get_state(v) == state) return; - br_vlan_set_state(v, state); - if (v->vid == vg->pvid) br_vlan_set_pvid_state(vg, state); + + br_vlan_set_state(v, state); } int br_mst_set_state(struct net_bridge_port *p, u16 msti, u8 state, diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index c38244d60ff8..ea71a64f915f 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -4210,6 +4210,32 @@ static void __br_multicast_stop(struct net_bridge_mcast *brmctx) #endif } +void br_multicast_update_vlan_mcast_ctx(struct net_bridge_vlan *v, u8 state) +{ +#if IS_ENABLED(CONFIG_BRIDGE_VLAN_FILTERING) + struct net_bridge *br; + + if (!br_vlan_should_use(v)) + return; + + if (br_vlan_is_master(v)) + return; + + br = v->port->br; + + if (!br_opt_get(br, BROPT_MCAST_VLAN_SNOOPING_ENABLED)) + return; + + if (br_vlan_state_allowed(state, true)) + br_multicast_enable_port_ctx(&v->port_mcast_ctx); + + /* Multicast is not disabled for the vlan when it goes in + * blocking state because the timers will expire and stop by + * themselves without sending more queries. + */ +#endif +} + void br_multicast_toggle_one_vlan(struct net_bridge_vlan *vlan, bool on) { struct net_bridge *br; diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 9197b511e459..067d47b8eb8f 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -1043,6 +1043,7 @@ void br_multicast_port_ctx_init(struct net_bridge_port *port, struct net_bridge_vlan *vlan, struct net_bridge_mcast_port *pmctx); void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx); +void br_multicast_update_vlan_mcast_ctx(struct net_bridge_vlan *v, u8 state); void br_multicast_toggle_one_vlan(struct net_bridge_vlan *vlan, bool on); int br_multicast_toggle_vlan_snooping(struct net_bridge *br, bool on, struct netlink_ext_ack *extack); @@ -1479,6 +1480,11 @@ static inline void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pm { } +static inline void br_multicast_update_vlan_mcast_ctx(struct net_bridge_vlan *v, + u8 state) +{ +} + static inline void br_multicast_toggle_one_vlan(struct net_bridge_vlan *vlan, bool on) { @@ -1830,7 +1836,9 @@ bool br_vlan_global_opts_can_enter_range(const struct net_bridge_vlan *v_curr, bool br_vlan_global_opts_fill(struct sk_buff *skb, u16 vid, u16 vid_range, const struct net_bridge_vlan *v_opts); -/* vlan state manipulation helpers using *_ONCE to annotate lock-free access */ +/* vlan state manipulation helpers using *_ONCE to annotate lock-free access, + * while br_vlan_set_state() may access data protected by multicast_lock. + */ static inline u8 br_vlan_get_state(const struct net_bridge_vlan *v) { return READ_ONCE(v->state); @@ -1839,6 +1847,7 @@ static inline u8 br_vlan_get_state(const struct net_bridge_vlan *v) static inline void br_vlan_set_state(struct net_bridge_vlan *v, u8 state) { WRITE_ONCE(v->state, state); + br_multicast_update_vlan_mcast_ctx(v, state); } static inline u8 br_vlan_get_pvid_state(const struct net_bridge_vlan_group *vg) From b4c83b37490d61cfdd62a2b29e98a9b89004b5c0 Mon Sep 17 00:00:00 2001 From: Yong Wang Date: Thu, 17 Apr 2025 15:43:12 +0200 Subject: [PATCH 573/971] net: bridge: mcast: re-implement br_multicast_{enable, disable}_port functions [ Upstream commit 4b30ae9adb047dd0a7982975ec3933c529537026 ] When a bridge port STP state is changed from BLOCKING/DISABLED to FORWARDING, the port's igmp query timer will NOT re-arm itself if the bridge has been configured as per-VLAN multicast snooping. Solve this by choosing the correct multicast context(s) to enable/disable port multicast based on whether per-VLAN multicast snooping is enabled or not, i.e. using per-{port, VLAN} context in case of per-VLAN multicast snooping by re-implementing br_multicast_enable_port() and br_multicast_disable_port() functions. Before the patch, the IGMP query does not happen in the last step of the following test sequence, i.e. no growth for tx counter: # ip link add name br1 up type bridge vlan_filtering 1 mcast_snooping 1 mcast_vlan_snooping 1 mcast_querier 1 mcast_stats_enabled 1 # bridge vlan global set vid 1 dev br1 mcast_snooping 1 mcast_querier 1 mcast_query_interval 100 mcast_startup_query_count 0 # ip link add name swp1 up master br1 type dummy # bridge link set dev swp1 state 0 # ip -j -p stats show dev swp1 group xstats_slave subgroup bridge suite mcast | jq '.[]["multicast"]["igmp_queries"]["tx_v2"]' 1 # sleep 1 # ip -j -p stats show dev swp1 group xstats_slave subgroup bridge suite mcast | jq '.[]["multicast"]["igmp_queries"]["tx_v2"]' 1 # bridge link set dev swp1 state 3 # sleep 2 # ip -j -p stats show dev swp1 group xstats_slave subgroup bridge suite mcast | jq '.[]["multicast"]["igmp_queries"]["tx_v2"]' 1 After the patch, the IGMP query happens in the last step of the test: # ip link add name br1 up type bridge vlan_filtering 1 mcast_snooping 1 mcast_vlan_snooping 1 mcast_querier 1 mcast_stats_enabled 1 # bridge vlan global set vid 1 dev br1 mcast_snooping 1 mcast_querier 1 mcast_query_interval 100 mcast_startup_query_count 0 # ip link add name swp1 up master br1 type dummy # bridge link set dev swp1 state 0 # ip -j -p stats show dev swp1 group xstats_slave subgroup bridge suite mcast | jq '.[]["multicast"]["igmp_queries"]["tx_v2"]' 1 # sleep 1 # ip -j -p stats show dev swp1 group xstats_slave subgroup bridge suite mcast | jq '.[]["multicast"]["igmp_queries"]["tx_v2"]' 1 # bridge link set dev swp1 state 3 # sleep 2 # ip -j -p stats show dev swp1 group xstats_slave subgroup bridge suite mcast | jq '.[]["multicast"]["igmp_queries"]["tx_v2"]' 3 Signed-off-by: Yong Wang Reviewed-by: Andy Roulin Reviewed-by: Ido Schimmel Signed-off-by: Petr Machata Acked-by: Nikolay Aleksandrov Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/bridge/br_multicast.c | 77 +++++++++++++++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 8 deletions(-) diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index ea71a64f915f..fa16ee88ec39 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -2104,12 +2104,17 @@ static void __br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx) } } -void br_multicast_enable_port(struct net_bridge_port *port) +static void br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx) { - struct net_bridge *br = port->br; + struct net_bridge *br = pmctx->port->br; spin_lock_bh(&br->multicast_lock); - __br_multicast_enable_port_ctx(&port->multicast_ctx); + if (br_multicast_port_ctx_is_vlan(pmctx) && + !(pmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED)) { + spin_unlock_bh(&br->multicast_lock); + return; + } + __br_multicast_enable_port_ctx(pmctx); spin_unlock_bh(&br->multicast_lock); } @@ -2136,11 +2141,67 @@ static void __br_multicast_disable_port_ctx(struct net_bridge_mcast_port *pmctx) br_multicast_rport_del_notify(pmctx, del); } +static void br_multicast_disable_port_ctx(struct net_bridge_mcast_port *pmctx) +{ + struct net_bridge *br = pmctx->port->br; + + spin_lock_bh(&br->multicast_lock); + if (br_multicast_port_ctx_is_vlan(pmctx) && + !(pmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED)) { + spin_unlock_bh(&br->multicast_lock); + return; + } + + __br_multicast_disable_port_ctx(pmctx); + spin_unlock_bh(&br->multicast_lock); +} + +static void br_multicast_toggle_port(struct net_bridge_port *port, bool on) +{ +#if IS_ENABLED(CONFIG_BRIDGE_VLAN_FILTERING) + if (br_opt_get(port->br, BROPT_MCAST_VLAN_SNOOPING_ENABLED)) { + struct net_bridge_vlan_group *vg; + struct net_bridge_vlan *vlan; + + rcu_read_lock(); + vg = nbp_vlan_group_rcu(port); + if (!vg) { + rcu_read_unlock(); + return; + } + + /* iterate each vlan, toggle vlan multicast context */ + list_for_each_entry_rcu(vlan, &vg->vlan_list, vlist) { + struct net_bridge_mcast_port *pmctx = + &vlan->port_mcast_ctx; + u8 state = br_vlan_get_state(vlan); + /* enable vlan multicast context when state is + * LEARNING or FORWARDING + */ + if (on && br_vlan_state_allowed(state, true)) + br_multicast_enable_port_ctx(pmctx); + else + br_multicast_disable_port_ctx(pmctx); + } + rcu_read_unlock(); + return; + } +#endif + /* toggle port multicast context when vlan snooping is disabled */ + if (on) + br_multicast_enable_port_ctx(&port->multicast_ctx); + else + br_multicast_disable_port_ctx(&port->multicast_ctx); +} + +void br_multicast_enable_port(struct net_bridge_port *port) +{ + br_multicast_toggle_port(port, true); +} + void br_multicast_disable_port(struct net_bridge_port *port) { - spin_lock_bh(&port->br->multicast_lock); - __br_multicast_disable_port_ctx(&port->multicast_ctx); - spin_unlock_bh(&port->br->multicast_lock); + br_multicast_toggle_port(port, false); } static int __grp_src_delete_marked(struct net_bridge_port_group *pg) @@ -4329,9 +4390,9 @@ int br_multicast_toggle_vlan_snooping(struct net_bridge *br, bool on, __br_multicast_open(&br->multicast_ctx); list_for_each_entry(p, &br->port_list, list) { if (on) - br_multicast_disable_port(p); + br_multicast_disable_port_ctx(&p->multicast_ctx); else - br_multicast_enable_port(p); + br_multicast_enable_port_ctx(&p->multicast_ctx); } list_for_each_entry(vlan, &vg->vlan_list, vlist) From c0d8c14d9bf28ebbedf8efacb0724949f0468fce Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Tue, 15 Apr 2025 15:11:41 +0300 Subject: [PATCH 574/971] vxlan: Do not treat dst cache initialization errors as fatal [ Upstream commit 20c76dadc783759fd3819d289c72be590660cc8b ] FDB entries are allocated in an atomic context as they can be added from the data path when learning is enabled. After converting the FDB hash table to rhashtable, the insertion rate will be much higher (*) which will entail a much higher rate of per-CPU allocations via dst_cache_init(). When adding a large number of entries (e.g., 256k) in a batch, a small percentage (< 0.02%) of these per-CPU allocations will fail [1]. This does not happen with the current code since the insertion rate is low enough to give the per-CPU allocator a chance to asynchronously create new chunks of per-CPU memory. Given that: a. Only a small percentage of these per-CPU allocations fail. b. The scenario where this happens might not be the most realistic one. c. The driver can work correctly without dst caches. The dst_cache_*() APIs first check that the dst cache was properly initialized. d. The dst caches are not always used (e.g., 'tos inherit'). It seems reasonable to not treat these allocation failures as fatal. Therefore, do not bail when dst_cache_init() fails and suppress warnings by specifying '__GFP_NOWARN'. [1] percpu: allocation failed, size=40 align=8 atomic=1, atomic alloc failed, no space left (*) 97% reduction in average latency of vxlan_fdb_update() when adding 256k entries in a batch. Reviewed-by: Petr Machata Signed-off-by: Ido Schimmel Link: https://patch.msgid.link/20250415121143.345227-14-idosch@nvidia.com Reviewed-by: Nikolay Aleksandrov Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- drivers/net/vxlan/vxlan_core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c index 2ed879a0abc6..1b6b6acd3489 100644 --- a/drivers/net/vxlan/vxlan_core.c +++ b/drivers/net/vxlan/vxlan_core.c @@ -606,10 +606,10 @@ static int vxlan_fdb_append(struct vxlan_fdb *f, if (rd == NULL) return -ENOMEM; - if (dst_cache_init(&rd->dst_cache, GFP_ATOMIC)) { - kfree(rd); - return -ENOMEM; - } + /* The driver can work correctly without a dst cache, so do not treat + * dst cache initialization errors as fatal. + */ + dst_cache_init(&rd->dst_cache, GFP_ATOMIC | __GFP_NOWARN); rd->remote_ip = *ip; rd->remote_port = port; From 03545901ec096bb95d0d4d59ab66349624b8311a Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Mon, 14 Apr 2025 10:43:36 +0200 Subject: [PATCH 575/971] net: ethernet: ti: am65-cpsw: handle -EPROBE_DEFER [ Upstream commit 09737cb80b8686ffca4ed1805fee745d5c85604d ] of_get_mac_address() might fetch the MAC address from NVMEM and that driver might not have been loaded. In that case, -EPROBE_DEFER is returned. Right now, this will trigger an immediate fallback to am65_cpsw_am654_get_efuse_macid() possibly resulting in a random MAC address although the MAC address is stored in the referenced NVMEM. Fix it by handling the -EPROBE_DEFER return code correctly. This also means that the creation of the MDIO device has to be moved to a later stage as -EPROBE_DEFER must not be returned after child devices are created. Signed-off-by: Michael Walle Reviewed-by: Andrew Lunn Link: https://patch.msgid.link/20250414084336.4017237-3-mwalle@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/ti/am65-cpsw-nuss.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c index c379a958380c..28cc23736a69 100644 --- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c +++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c @@ -2089,7 +2089,9 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common) goto of_node_put; ret = of_get_mac_address(port_np, port->slave.mac_addr); - if (ret) { + if (ret == -EPROBE_DEFER) { + goto of_node_put; + } else if (ret) { am65_cpsw_am654_get_efuse_macid(port_np, port->port_id, port->slave.mac_addr); @@ -2949,6 +2951,16 @@ static int am65_cpsw_nuss_probe(struct platform_device *pdev) return ret; } + am65_cpsw_nuss_get_ver(common); + + ret = am65_cpsw_nuss_init_host_p(common); + if (ret) + goto err_pm_clear; + + ret = am65_cpsw_nuss_init_slave_ports(common); + if (ret) + goto err_pm_clear; + node = of_get_child_by_name(dev->of_node, "mdio"); if (!node) { dev_warn(dev, "MDIO node not found\n"); @@ -2965,16 +2977,6 @@ static int am65_cpsw_nuss_probe(struct platform_device *pdev) } of_node_put(node); - am65_cpsw_nuss_get_ver(common); - - ret = am65_cpsw_nuss_init_host_p(common); - if (ret) - goto err_of_clear; - - ret = am65_cpsw_nuss_init_slave_ports(common); - if (ret) - goto err_of_clear; - /* init common data */ ale_params.dev = dev; ale_params.ale_ageout = AM65_CPSW_ALE_AGEOUT_DEFAULT; From f9397cf7bfb680799fb8c7f717c8f756384c3280 Mon Sep 17 00:00:00 2001 From: Zijun Hu Date: Mon, 14 Apr 2025 19:36:52 +0800 Subject: [PATCH 576/971] software node: Correct a OOB check in software_node_get_reference_args() [ Upstream commit 31e4e12e0e9609850cefd4b2e1adf782f56337d6 ] software_node_get_reference_args() wants to get @index-th element, so the property value requires at least '(index + 1) * sizeof(*ref)' bytes but that can not be guaranteed by current OOB check, and may cause OOB for malformed property. Fix by using as OOB check '((index + 1) * sizeof(*ref) > prop->length)'. Reviewed-by: Sakari Ailus Signed-off-by: Zijun Hu Link: https://lore.kernel.org/r/20250414-fix_swnode-v2-1-9c9e6ae11eab@quicinc.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/base/swnode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c index 079bd14bdedc..a7a3e3b66bb5 100644 --- a/drivers/base/swnode.c +++ b/drivers/base/swnode.c @@ -518,7 +518,7 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode, if (prop->is_inline) return -EINVAL; - if (index * sizeof(*ref) >= prop->length) + if ((index + 1) * sizeof(*ref) > prop->length) return -ENOENT; ref_array = prop->pointer; From 5cf32cef3a38cf26e0f86fcfa64afa6cc399c4cd Mon Sep 17 00:00:00 2001 From: Mike Looijmans Date: Fri, 14 Mar 2025 16:17:45 +0100 Subject: [PATCH 577/971] pinctrl: mcp23s08: Reset all pins to input at probe [ Upstream commit 3ede3f8b4b4b399b0ca41e44959f80d5cf84fc98 ] At startup, the driver just assumes that all registers have their default values. But after a soft reset, the chip will just be in the state it was, and some pins may have been configured as outputs. Any modification of the output register will cause these pins to be driven low, which leads to unexpected/unwanted effects. To prevent this from happening, set the chip's IO configuration register to a known safe mode (all inputs) before toggling any other bits. Signed-off-by: Mike Looijmans Link: https://lore.kernel.org/20250314151803.28903-1-mike.looijmans@topic.nl Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin --- drivers/pinctrl/pinctrl-mcp23s08.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/pinctrl/pinctrl-mcp23s08.c b/drivers/pinctrl/pinctrl-mcp23s08.c index fd97b6ee2a8d..ca45c1f36a89 100644 --- a/drivers/pinctrl/pinctrl-mcp23s08.c +++ b/drivers/pinctrl/pinctrl-mcp23s08.c @@ -612,6 +612,14 @@ int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, mcp->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); + /* + * Reset the chip - we don't really know what state it's in, so reset + * all pins to input first to prevent surprises. + */ + ret = mcp_write(mcp, MCP_IODIR, mcp->chip.ngpio == 16 ? 0xFFFF : 0xFF); + if (ret < 0) + return ret; + /* verify MCP_IOCON.SEQOP = 0, so sequential reads work, * and MCP_IOCON.HAEN = 1, so we work with all chips. */ From 79dc5e78d13d0f6a18a9e52357a9286a6d397073 Mon Sep 17 00:00:00 2001 From: Aditya Kumar Singh Date: Tue, 8 Apr 2025 11:36:31 +0530 Subject: [PATCH 578/971] wifi: ath12k: fix failed to set mhi state error during reboot with hardware grouping [ Upstream commit dce7aec6b1f74b0a46b901ab8de1f7bd0515f733 ] With hardware grouping, during reboot, whenever a device is removed, it powers down itself and all its partner devices in the same group. Now this is done by all devices and hence there is multiple power down for devices and hence the following error messages can be seen: ath12k_pci 0002:01:00.0: failed to set mhi state POWER_OFF(3) in current mhi state (0x0) ath12k_pci 0002:01:00.0: failed to set mhi state: POWER_OFF(3) ath12k_pci 0002:01:00.0: failed to set mhi state DEINIT(1) in current mhi state (0x0) ath12k_pci 0002:01:00.0: failed to set mhi state: DEINIT(1) ath12k_pci 0003:01:00.0: failed to set mhi state POWER_OFF(3) in current mhi state (0x0) ath12k_pci 0003:01:00.0: failed to set mhi state: POWER_OFF(3) ath12k_pci 0003:01:00.0: failed to set mhi state DEINIT(1) in current mhi state (0x0) ath12k_pci 0003:01:00.0: failed to set mhi state: DEINIT(1) ath12k_pci 0004:01:00.0: failed to set mhi state POWER_OFF(3) in current mhi state (0x0) ath12k_pci 0004:01:00.0: failed to set mhi state: POWER_OFF(3) To prevent this, check if the ATH12K_PCI_FLAG_INIT_DONE flag is already set before powering down. If it is set, it indicates that another partner device has already performed the power down, and this device can skip this step. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Aditya Kumar Singh Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20250408-fix_reboot_issues_with_hw_grouping-v4-3-95e7bf048595@oss.qualcomm.com Signed-off-by: Jeff Johnson Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath12k/pci.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index 5fd80f90ecaf..7dfbabf0637d 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -1153,6 +1153,9 @@ void ath12k_pci_power_down(struct ath12k_base *ab) { struct ath12k_pci *ab_pci = ath12k_pci_priv(ab); + if (!test_bit(ATH12K_PCI_FLAG_INIT_DONE, &ab_pci->flags)) + return; + /* restore aspm in case firmware bootup fails */ ath12k_pci_aspm_restore(ab_pci); From 34c0a670556b24d36c9f8934227edb819ca5609e Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Wed, 9 Apr 2025 13:34:22 +0200 Subject: [PATCH 579/971] scsi: lpfc: Use memcpy() for BIOS version [ Upstream commit ae82eaf4aeea060bb736c3e20c0568b67c701d7d ] The strlcat() with FORTIFY support is triggering a panic because it thinks the target buffer will overflow although the correct target buffer size is passed in. Anyway, instead of memset() with 0 followed by a strlcat(), just use memcpy() and ensure that the resulting buffer is NULL terminated. BIOSVersion is only used for the lpfc_printf_log() which expects a properly terminated string. Signed-off-by: Daniel Wagner Link: https://lore.kernel.org/r/20250409-fix-lpfc-bios-str-v1-1-05dac9e51e13@kernel.org Reviewed-by: Justin Tee Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/lpfc/lpfc_sli.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 4a9fa00eeb79..4cf935b7223a 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -6014,9 +6014,9 @@ lpfc_sli4_get_ctl_attr(struct lpfc_hba *phba) phba->sli4_hba.flash_id = bf_get(lpfc_cntl_attr_flash_id, cntl_attr); phba->sli4_hba.asic_rev = bf_get(lpfc_cntl_attr_asic_rev, cntl_attr); - memset(phba->BIOSVersion, 0, sizeof(phba->BIOSVersion)); - strlcat(phba->BIOSVersion, (char *)cntl_attr->bios_ver_str, + memcpy(phba->BIOSVersion, cntl_attr->bios_ver_str, sizeof(phba->BIOSVersion)); + phba->BIOSVersion[sizeof(phba->BIOSVersion) - 1] = '\0'; lpfc_printf_log(phba, KERN_INFO, LOG_SLI, "3086 lnk_type:%d, lnk_numb:%d, bios_ver:%s, " From 52a16bafda0ef1f077e411a88a7fa1a2178050ee Mon Sep 17 00:00:00 2001 From: Zijun Hu Date: Thu, 10 Apr 2025 09:01:27 +0800 Subject: [PATCH 580/971] sock: Correct error checking condition for (assign|release)_proto_idx() [ Upstream commit faeefc173be40512341b102cf1568aa0b6571acd ] (assign|release)_proto_idx() wrongly check find_first_zero_bit() failure by condition '(prot->inuse_idx == PROTO_INUSE_NR - 1)' obviously. Fix by correcting the condition to '(prot->inuse_idx == PROTO_INUSE_NR)' Signed-off-by: Zijun Hu Reviewed-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20250410-fix_net-v2-1-d69e7c5739a4@quicinc.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/core/sock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/core/sock.c b/net/core/sock.c index 84ba3f67bca9..ec48690b5174 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -3817,7 +3817,7 @@ static int assign_proto_idx(struct proto *prot) { prot->inuse_idx = find_first_zero_bit(proto_inuse_idx, PROTO_INUSE_NR); - if (unlikely(prot->inuse_idx == PROTO_INUSE_NR - 1)) { + if (unlikely(prot->inuse_idx == PROTO_INUSE_NR)) { pr_err("PROTO_INUSE_NR exhausted\n"); return -ENOSPC; } @@ -3828,7 +3828,7 @@ static int assign_proto_idx(struct proto *prot) static void release_proto_idx(struct proto *prot) { - if (prot->inuse_idx != PROTO_INUSE_NR - 1) + if (prot->inuse_idx != PROTO_INUSE_NR) clear_bit(prot->inuse_idx, proto_inuse_idx); } #else From 8cde755f56163281ec2c46b4ae8b61f532758a6f Mon Sep 17 00:00:00 2001 From: Kyungwook Boo Date: Tue, 11 Mar 2025 14:16:02 +0900 Subject: [PATCH 581/971] i40e: fix MMIO write access to an invalid page in i40e_clear_hw [ Upstream commit 015bac5daca978448f2671478c553ce1f300c21e ] When the device sends a specific input, an integer underflow can occur, leading to MMIO write access to an invalid page. Prevent the integer underflow by changing the type of related variables. Signed-off-by: Kyungwook Boo Link: https://lore.kernel.org/lkml/ffc91764-1142-4ba2-91b6-8c773f6f7095@gmail.com/T/ Reviewed-by: Przemek Kitszel Reviewed-by: Simon Horman Reviewed-by: Aleksandr Loktionov Tested-by: Rinitha S (A Contingent worker at Intel) Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/i40e/i40e_common.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index 4d7caa119971..5d46a8e5376d 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -1067,10 +1067,11 @@ int i40e_pf_reset(struct i40e_hw *hw) void i40e_clear_hw(struct i40e_hw *hw) { u32 num_queues, base_queue; - u32 num_pf_int; - u32 num_vf_int; + s32 num_pf_int; + s32 num_vf_int; u32 num_vfs; - u32 i, j; + s32 i; + u32 j; u32 val; u32 eol = 0x7ff; From e036d648773c27c3378eb273742a8094497dac94 Mon Sep 17 00:00:00 2001 From: Mateusz Pacuszka Date: Fri, 14 Feb 2025 09:50:35 +0100 Subject: [PATCH 582/971] ice: fix check for existing switch rule [ Upstream commit a808691df39b52cd9db861b118e88e18b63e2299 ] In case the rule already exists and another VSI wants to subscribe to it new VSI list is being created and both VSIs are moved to it. Currently, the check for already existing VSI with the same rule is done based on fdw_id.hw_vsi_id, which applies only to LOOKUP_RX flag. Change it to vsi_handle. This is software VSI ID, but it can be applied here, because vsi_map itself is also based on it. Additionally change return status in case the VSI already exists in the VSI map to "Already exists". Such case should be handled by the caller. Signed-off-by: Mateusz Pacuszka Reviewed-by: Przemek Kitszel Reviewed-by: Michal Swiatkowski Signed-off-by: Larysa Zaremba Reviewed-by: Simon Horman Tested-by: Rafal Romanowski Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/ice/ice_switch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c index 19f730a68fa2..ac004ef1d724 100644 --- a/drivers/net/ethernet/intel/ice/ice_switch.c +++ b/drivers/net/ethernet/intel/ice/ice_switch.c @@ -3024,7 +3024,7 @@ ice_add_update_vsi_list(struct ice_hw *hw, u16 vsi_handle_arr[2]; /* A rule already exists with the new VSI being added */ - if (cur_fltr->fwd_id.hw_vsi_id == new_fltr->fwd_id.hw_vsi_id) + if (cur_fltr->vsi_handle == new_fltr->vsi_handle) return -EEXIST; vsi_handle_arr[0] = cur_fltr->vsi_handle; @@ -5991,7 +5991,7 @@ ice_adv_add_update_vsi_list(struct ice_hw *hw, /* A rule already exists with the new VSI being added */ if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map)) - return 0; + return -EEXIST; /* Update the previously created VSI list set with * the new VSI ID passed in From a3c32f17acbf75a7aef9e319f02d18e688247ede Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Ha=C5=82asa?= Date: Tue, 8 Apr 2025 13:59:41 +0200 Subject: [PATCH 583/971] usbnet: asix AX88772: leave the carrier control to phylink MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 4145f00227ee80f21ab274e9cd9c09758e9bcf3d ] ASIX AX88772B based USB 10/100 Ethernet adapter doesn't come up ("carrier off"), despite the built-in 100BASE-FX PHY positive link indication. The internal PHY is configured (using EEPROM) in fixed 100 Mbps full duplex mode. The primary problem appears to be using carrier_netif_{on,off}() while, at the same time, delegating carrier management to phylink. Use only the latter and remove "manual control" in the asix driver. I don't have any other AX88772 board here, but the problem doesn't seem specific to a particular board or settings - it's probably timing-dependent. Remove unused asix_adjust_link() as well. Signed-off-by: Krzysztof Hałasa Tested-by: Oleksij Rempel Link: https://patch.msgid.link/m3plhmdfte.fsf_-_@t19.piap.pl Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/usb/asix.h | 1 - drivers/net/usb/asix_common.c | 22 ---------------------- drivers/net/usb/asix_devices.c | 17 ++++------------- 3 files changed, 4 insertions(+), 36 deletions(-) diff --git a/drivers/net/usb/asix.h b/drivers/net/usb/asix.h index 74162190bccc..8531b804021a 100644 --- a/drivers/net/usb/asix.h +++ b/drivers/net/usb/asix.h @@ -224,7 +224,6 @@ int asix_write_rx_ctl(struct usbnet *dev, u16 mode, int in_pm); u16 asix_read_medium_status(struct usbnet *dev, int in_pm); int asix_write_medium_mode(struct usbnet *dev, u16 mode, int in_pm); -void asix_adjust_link(struct net_device *netdev); int asix_write_gpio(struct usbnet *dev, u16 value, int sleep, int in_pm); diff --git a/drivers/net/usb/asix_common.c b/drivers/net/usb/asix_common.c index 72ffc89b477a..7fd763917ae2 100644 --- a/drivers/net/usb/asix_common.c +++ b/drivers/net/usb/asix_common.c @@ -414,28 +414,6 @@ int asix_write_medium_mode(struct usbnet *dev, u16 mode, int in_pm) return ret; } -/* set MAC link settings according to information from phylib */ -void asix_adjust_link(struct net_device *netdev) -{ - struct phy_device *phydev = netdev->phydev; - struct usbnet *dev = netdev_priv(netdev); - u16 mode = 0; - - if (phydev->link) { - mode = AX88772_MEDIUM_DEFAULT; - - if (phydev->duplex == DUPLEX_HALF) - mode &= ~AX_MEDIUM_FD; - - if (phydev->speed != SPEED_100) - mode &= ~AX_MEDIUM_PS; - } - - asix_write_medium_mode(dev, mode, 0); - phy_print_status(phydev); - usbnet_link_change(dev, phydev->link, 0); -} - int asix_write_gpio(struct usbnet *dev, u16 value, int sleep, int in_pm) { int ret; diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c index ec4dcf89cbed..119295f5f3b3 100644 --- a/drivers/net/usb/asix_devices.c +++ b/drivers/net/usb/asix_devices.c @@ -752,7 +752,6 @@ static void ax88772_mac_link_down(struct phylink_config *config, struct usbnet *dev = netdev_priv(to_net_dev(config->dev)); asix_write_medium_mode(dev, 0, 0); - usbnet_link_change(dev, false, false); } static void ax88772_mac_link_up(struct phylink_config *config, @@ -783,7 +782,6 @@ static void ax88772_mac_link_up(struct phylink_config *config, m |= AX_MEDIUM_RFC; asix_write_medium_mode(dev, m, 0); - usbnet_link_change(dev, true, false); } static const struct phylink_mac_ops ax88772_phylink_mac_ops = { @@ -1350,10 +1348,9 @@ static const struct driver_info ax88772_info = { .description = "ASIX AX88772 USB 2.0 Ethernet", .bind = ax88772_bind, .unbind = ax88772_unbind, - .status = asix_status, .reset = ax88772_reset, .stop = ax88772_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | FLAG_MULTI_PACKET, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_MULTI_PACKET, .rx_fixup = asix_rx_fixup_common, .tx_fixup = asix_tx_fixup, }; @@ -1362,11 +1359,9 @@ static const struct driver_info ax88772b_info = { .description = "ASIX AX88772B USB 2.0 Ethernet", .bind = ax88772_bind, .unbind = ax88772_unbind, - .status = asix_status, .reset = ax88772_reset, .stop = ax88772_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | - FLAG_MULTI_PACKET, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_MULTI_PACKET, .rx_fixup = asix_rx_fixup_common, .tx_fixup = asix_tx_fixup, .data = FLAG_EEPROM_MAC, @@ -1376,11 +1371,9 @@ static const struct driver_info lxausb_t1l_info = { .description = "Linux Automation GmbH USB 10Base-T1L", .bind = ax88772_bind, .unbind = ax88772_unbind, - .status = asix_status, .reset = ax88772_reset, .stop = ax88772_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | - FLAG_MULTI_PACKET, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_MULTI_PACKET, .rx_fixup = asix_rx_fixup_common, .tx_fixup = asix_tx_fixup, .data = FLAG_EEPROM_MAC, @@ -1412,10 +1405,8 @@ static const struct driver_info hg20f9_info = { .description = "HG20F9 USB 2.0 Ethernet", .bind = ax88772_bind, .unbind = ax88772_unbind, - .status = asix_status, .reset = ax88772_reset, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | - FLAG_MULTI_PACKET, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_MULTI_PACKET, .rx_fixup = asix_rx_fixup_common, .tx_fixup = asix_tx_fixup, .data = FLAG_EEPROM_MAC, From bdb4da9e1921c2284e149b6c420ee40a0192383e Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Thu, 27 Mar 2025 13:56:06 +0800 Subject: [PATCH 584/971] f2fs: fix to set atomic write status more clear [ Upstream commit db03c20c0850dc8d2bcabfa54b9438f7d666c863 ] 1. After we start atomic write in a database file, before committing all data, we'd better not set inode w/ vfs dirty status to avoid redundant updates, instead, we only set inode w/ atomic dirty status. 2. After we commit all data, before committing metadata, we need to clear atomic dirty status, and set vfs dirty status to allow vfs flush dirty inode. Cc: Daeho Jeong Reported-by: Zhiguo Niu Signed-off-by: Chao Yu Reviewed-by: Daeho Jeong Reviewed-by: Zhiguo Niu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- fs/f2fs/inode.c | 4 +++- fs/f2fs/segment.c | 6 ++++++ fs/f2fs/super.c | 4 +++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 21d3eabe95e0..66721c2093c0 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -35,7 +35,9 @@ void f2fs_mark_inode_dirty_sync(struct inode *inode, bool sync) if (f2fs_inode_dirtied(inode, sync)) return; - if (f2fs_is_atomic_file(inode)) + /* only atomic file w/ FI_ATOMIC_COMMITTED can be set vfs dirty */ + if (f2fs_is_atomic_file(inode) && + !is_inode_flag_set(inode, FI_ATOMIC_COMMITTED)) return; mark_inode_dirty_sync(inode); diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 156d92b94525..c7714e954cb5 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -372,7 +372,13 @@ out: } else { sbi->committed_atomic_block += fi->atomic_write_cnt; set_inode_flag(inode, FI_ATOMIC_COMMITTED); + + /* + * inode may has no FI_ATOMIC_DIRTIED flag due to no write + * before commit. + */ if (is_inode_flag_set(inode, FI_ATOMIC_DIRTIED)) { + /* clear atomic dirty status and set vfs dirty status */ clear_inode_flag(inode, FI_ATOMIC_DIRTIED); f2fs_mark_inode_dirty_sync(inode, true); } diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 50170e7cf3f9..702137eafaa6 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1500,7 +1500,9 @@ int f2fs_inode_dirtied(struct inode *inode, bool sync) } spin_unlock(&sbi->inode_lock[DIRTY_META]); - if (!ret && f2fs_is_atomic_file(inode)) + /* if atomic write is not committed, set inode w/ atomic dirty */ + if (!ret && f2fs_is_atomic_file(inode) && + !is_inode_flag_set(inode, FI_ATOMIC_COMMITTED)) set_inode_flag(inode, FI_ATOMIC_DIRTIED); return ret; From 38c4106cb4e99ab019ebd634c1e72067489adef8 Mon Sep 17 00:00:00 2001 From: Jiayuan Chen Date: Mon, 7 Apr 2025 22:21:20 +0800 Subject: [PATCH 585/971] bpf, sockmap: Fix data lost during EAGAIN retries [ Upstream commit 7683167196bd727ad5f3c3fc6a9ca70f54520a81 ] We call skb_bpf_redirect_clear() to clean _sk_redir before handling skb in backlog, but when sk_psock_handle_skb() return EAGAIN due to sk_rcvbuf limit, the redirect info in _sk_redir is not recovered. Fix skb redir loss during EAGAIN retries by restoring _sk_redir information using skb_bpf_set_redir(). Before this patch: ''' ./bench sockmap -c 2 -p 1 -a --rx-verdict-ingress Setting up benchmark 'sockmap'... create socket fd c1:13 p1:14 c2:15 p2:16 Benchmark 'sockmap' started. Send Speed 1343.172 MB/s, BPF Speed 1343.238 MB/s, Rcv Speed 65.271 MB/s Send Speed 1352.022 MB/s, BPF Speed 1352.088 MB/s, Rcv Speed 0 MB/s Send Speed 1354.105 MB/s, BPF Speed 1354.105 MB/s, Rcv Speed 0 MB/s Send Speed 1355.018 MB/s, BPF Speed 1354.887 MB/s, Rcv Speed 0 MB/s ''' Due to the high send rate, the RX processing path may frequently hit the sk_rcvbuf limit. Once triggered, incorrect _sk_redir will cause the flow to mistakenly enter the "!ingress" path, leading to send failures. (The Rcv speed depends on tcp_rmem). After this patch: ''' ./bench sockmap -c 2 -p 1 -a --rx-verdict-ingress Setting up benchmark 'sockmap'... create socket fd c1:13 p1:14 c2:15 p2:16 Benchmark 'sockmap' started. Send Speed 1347.236 MB/s, BPF Speed 1347.367 MB/s, Rcv Speed 65.402 MB/s Send Speed 1353.320 MB/s, BPF Speed 1353.320 MB/s, Rcv Speed 65.536 MB/s Send Speed 1353.186 MB/s, BPF Speed 1353.121 MB/s, Rcv Speed 65.536 MB/s ''' Signed-off-by: Jiayuan Chen Link: https://lore.kernel.org/r/20250407142234.47591-2-jiayuan.chen@linux.dev Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin --- net/core/skmsg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/core/skmsg.c b/net/core/skmsg.c index 2076db464e93..c3169e1e6352 100644 --- a/net/core/skmsg.c +++ b/net/core/skmsg.c @@ -689,7 +689,8 @@ static void sk_psock_backlog(struct work_struct *work) if (ret <= 0) { if (ret == -EAGAIN) { sk_psock_skb_state(psock, state, len, off); - + /* Restore redir info we cleared before */ + skb_bpf_set_redir(skb, psock->sk, ingress); /* Delay slightly to prioritize any * other work that might be here. */ From a37888a435b0737128d2d9c6f67b8d608f83df7a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 8 Apr 2025 11:26:58 +0200 Subject: [PATCH 586/971] net: ethernet: cortina: Use TOE/TSO on all TCP [ Upstream commit 6a07e3af4973402fa199a80036c10060b922c92c ] It is desireable to push the hardware accelerator to also process non-segmented TCP frames: we pass the skb->len to the "TOE/TSO" offloader and it will handle them. Without this quirk the driver becomes unstable and lock up and and crash. I do not know exactly why, but it is probably due to the TOE (TCP offload engine) feature that is coupled with the segmentation feature - it is not possible to turn one part off and not the other, either both TOE and TSO are active, or neither of them. Not having the TOE part active seems detrimental, as if that hardware feature is not really supposed to be turned off. The datasheet says: "Based on packet parsing and TCP connection/NAT table lookup results, the NetEngine puts the packets belonging to the same TCP connection to the same queue for the software to process. The NetEngine puts incoming packets to the buffer or series of buffers for a jumbo packet. With this hardware acceleration, IP/TCP header parsing, checksum validation and connection lookup are offloaded from the software processing." After numerous tests with the hardware locking up after something between minutes and hours depending on load using iperf3 I have concluded this is necessary to stabilize the hardware. Signed-off-by: Linus Walleij Link: https://patch.msgid.link/20250408-gemini-ethernet-tso-always-v1-1-e669f932359c@linaro.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/cortina/gemini.c | 37 +++++++++++++++++++++------ 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c index 5af98fba7480..fce2ff1e1d83 100644 --- a/drivers/net/ethernet/cortina/gemini.c +++ b/drivers/net/ethernet/cortina/gemini.c @@ -1148,6 +1148,7 @@ static int gmac_map_tx_bufs(struct net_device *netdev, struct sk_buff *skb, struct gmac_txdesc *txd; skb_frag_t *skb_frag; dma_addr_t mapping; + bool tcp = false; void *buffer; u16 mss; int ret; @@ -1155,6 +1156,13 @@ static int gmac_map_tx_bufs(struct net_device *netdev, struct sk_buff *skb, word1 = skb->len; word3 = SOF_BIT; + /* Determine if we are doing TCP */ + if (skb->protocol == htons(ETH_P_IP)) + tcp = (ip_hdr(skb)->protocol == IPPROTO_TCP); + else + /* IPv6 */ + tcp = (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP); + mss = skb_shinfo(skb)->gso_size; if (mss) { /* This means we are dealing with TCP and skb->len is the @@ -1167,8 +1175,26 @@ static int gmac_map_tx_bufs(struct net_device *netdev, struct sk_buff *skb, mss, skb->len); word1 |= TSS_MTU_ENABLE_BIT; word3 |= mss; + } else if (tcp) { + /* Even if we are not using TSO, use the hardware offloader + * for transferring the TCP frame: this hardware has partial + * TCP awareness (called TOE - TCP Offload Engine) and will + * according to the datasheet put packets belonging to the + * same TCP connection in the same queue for the TOE/TSO + * engine to process. The engine will deal with chopping + * up frames that exceed ETH_DATA_LEN which the + * checksumming engine cannot handle (see below) into + * manageable chunks. It flawlessly deals with quite big + * frames and frames containing custom DSA EtherTypes. + */ + mss = netdev->mtu + skb_tcp_all_headers(skb); + mss = min(mss, skb->len); + netdev_dbg(netdev, "TOE/TSO len %04x mtu %04x mss %04x\n", + skb->len, netdev->mtu, mss); + word1 |= TSS_MTU_ENABLE_BIT; + word3 |= mss; } else if (skb->len >= ETH_FRAME_LEN) { - /* Hardware offloaded checksumming isn't working on frames + /* Hardware offloaded checksumming isn't working on non-TCP frames * bigger than 1514 bytes. A hypothesis about this is that the * checksum buffer is only 1518 bytes, so when the frames get * bigger they get truncated, or the last few bytes get @@ -1185,21 +1211,16 @@ static int gmac_map_tx_bufs(struct net_device *netdev, struct sk_buff *skb, } if (skb->ip_summed == CHECKSUM_PARTIAL) { - int tcp = 0; - /* We do not switch off the checksumming on non TCP/UDP * frames: as is shown from tests, the checksumming engine * is smart enough to see that a frame is not actually TCP * or UDP and then just pass it through without any changes * to the frame. */ - if (skb->protocol == htons(ETH_P_IP)) { + if (skb->protocol == htons(ETH_P_IP)) word1 |= TSS_IP_CHKSUM_BIT; - tcp = ip_hdr(skb)->protocol == IPPROTO_TCP; - } else { /* IPv6 */ + else word1 |= TSS_IPV6_ENABLE_BIT; - tcp = ipv6_hdr(skb)->nexthdr == IPPROTO_TCP; - } word1 |= tcp ? TSS_TCP_CHKSUM_BIT : TSS_UDP_CHKSUM_BIT; } From 42d0bfbe029640fb1227ba9b310a271bc0ee589d Mon Sep 17 00:00:00 2001 From: Wentao Liang Date: Tue, 8 Apr 2025 11:26:02 +0800 Subject: [PATCH 587/971] octeontx2-pf: Add error log forcn10k_map_unmap_rq_policer() [ Upstream commit 9c056ec6dd1654b1420dafbbe2a69718850e6ff2 ] The cn10k_free_matchall_ipolicer() calls the cn10k_map_unmap_rq_policer() for each queue in a for loop without checking for any errors. Check the return value of the cn10k_map_unmap_rq_policer() function during each loop, and report a warning if the function fails. Signed-off-by: Wentao Liang Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250408032602.2909-1-vulab@iscas.ac.cn Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c index 7417087b6db5..a2807a1e4f4a 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c @@ -352,9 +352,12 @@ int cn10k_free_matchall_ipolicer(struct otx2_nic *pfvf) mutex_lock(&pfvf->mbox.lock); /* Remove RQ's policer mapping */ - for (qidx = 0; qidx < hw->rx_queues; qidx++) - cn10k_map_unmap_rq_policer(pfvf, qidx, - hw->matchall_ipolicer, false); + for (qidx = 0; qidx < hw->rx_queues; qidx++) { + rc = cn10k_map_unmap_rq_policer(pfvf, qidx, hw->matchall_ipolicer, false); + if (rc) + dev_warn(pfvf->dev, "Failed to unmap RQ %d's policer (error %d).", + qidx, rc); + } rc = cn10k_free_leaf_profile(pfvf, hw->matchall_ipolicer); From 6bd0f2e71b15589d4cbbc5fb09ebd12e0035c8c8 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Fri, 28 Mar 2025 13:32:24 +0800 Subject: [PATCH 588/971] wifi: ath11k: determine PM policy based on machine model [ Upstream commit ce8669a27016354dfa8bf3c954255cb9f3583bae ] To handle the Lenovo unexpected wakeup issue [1], previously we revert commit 166a490f59ac ("wifi: ath11k: support hibernation"). So currently WLAN target is put into WoWLAN mode during suspend. This is a temporary solution as it does not work on machines where WLAN power is cut off. The thought here is that we do WoWLAN suspend on Lenovo machines while do non-WoWLAN suspend (which is done in the reverted commit) on other machines. This requires us to identify Lenovo machines from others. For that purpose, read board vendor and product name from DMI interface, match it against all known affected machines. If there is a match, choose WoWLAN suspend mode, else choose non-WoWLAN mode. Save the mode in ab for later reference. [1] https://bugzilla.kernel.org/show_bug.cgi?id=219196 Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30 Tested-by: Muhammad Usama Anjum Tested-by: Takashi Iwai Signed-off-by: Baochen Qiang Link: https://patch.msgid.link/20250328-ath11k-bring-hibernation-back-v3-1-23405ae23431@quicinc.com Signed-off-by: Jeff Johnson Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath11k/core.c | 55 ++++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/core.h | 7 ++++ 2 files changed, 62 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 609d8387c41f..0e8ff839cae2 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -704,6 +704,52 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { }, }; +static const struct dmi_system_id ath11k_pm_quirk_table[] = { + { + .driver_data = (void *)ATH11K_PM_WOW, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21J4"), + }, + }, + { + .driver_data = (void *)ATH11K_PM_WOW, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21K4"), + }, + }, + { + .driver_data = (void *)ATH11K_PM_WOW, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21K6"), + }, + }, + { + .driver_data = (void *)ATH11K_PM_WOW, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21K8"), + }, + }, + { + .driver_data = (void *)ATH11K_PM_WOW, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21KA"), + }, + }, + { + .driver_data = (void *)ATH11K_PM_WOW, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21F9"), + }, + }, + {} +}; + static inline struct ath11k_pdev *ath11k_core_get_single_pdev(struct ath11k_base *ab) { WARN_ON(!ab->hw_params.single_pdev_only); @@ -2018,8 +2064,17 @@ EXPORT_SYMBOL(ath11k_core_pre_init); int ath11k_core_init(struct ath11k_base *ab) { + const struct dmi_system_id *dmi_id; int ret; + dmi_id = dmi_first_match(ath11k_pm_quirk_table); + if (dmi_id) + ab->pm_policy = (kernel_ulong_t)dmi_id->driver_data; + else + ab->pm_policy = ATH11K_PM_DEFAULT; + + ath11k_dbg(ab, ATH11K_DBG_BOOT, "pm policy %u\n", ab->pm_policy); + ret = ath11k_core_soc_create(ab); if (ret) { ath11k_err(ab, "failed to create soc core: %d\n", ret); diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 555deafd8399..812a174f74c0 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -842,6 +842,11 @@ struct ath11k_msi_config { u16 hw_rev; }; +enum ath11k_pm_policy { + ATH11K_PM_DEFAULT, + ATH11K_PM_WOW, +}; + /* Master structure to hold the hw data which may be used in core module */ struct ath11k_base { enum ath11k_hw_rev hw_rev; @@ -994,6 +999,8 @@ struct ath11k_base { } testmode; #endif + enum ath11k_pm_policy pm_policy; + /* must be last */ u8 drv_priv[] __aligned(sizeof(void *)); }; From 9db1bf90147c46a23d2c471828bf4a2de8827801 Mon Sep 17 00:00:00 2001 From: Hari Chandrakanthan Date: Mon, 24 Mar 2025 11:55:09 +0530 Subject: [PATCH 589/971] wifi: ath12k: fix link valid field initialization in the monitor Rx [ Upstream commit 2826139f9295821fe2b049318a1cc057ec003131 ] Currently, the link_valid field is not initialized in the monitor Rx path. This can result in random values for the link_valid and link_id leads to undefined behaviour in mac80211. Therefore, initialize the link_valid field in the monitor Rx path. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Hari Chandrakanthan Tested-by: Nicolas Escande Reviewed-by: Vasanthakumar Thiagarajan Signed-off-by: Karthikeyan Periyasamy Link: https://patch.msgid.link/20250324062518.2752822-2-quic_periyasa@quicinc.com Signed-off-by: Jeff Johnson Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath12k/dp_mon.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 35f22a4a16cf..69bf75ebd751 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -1077,6 +1077,8 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct bool is_mcbc = rxcb->is_mcbc; bool is_eapol_tkip = rxcb->is_eapol; + status->link_valid = 0; + if ((status->encoding == RX_ENC_HE) && !(status->flag & RX_FLAG_RADIOTAP_HE) && !(status->flag & RX_FLAG_SKIP_MONITOR)) { he = skb_push(msdu, sizeof(known)); From 2304e2b5e4701ee334650743467febe604d49a9b Mon Sep 17 00:00:00 2001 From: Balamurugan S Date: Fri, 21 Mar 2025 16:22:39 +0530 Subject: [PATCH 590/971] wifi: ath12k: fix incorrect CE addresses [ Upstream commit 60031d9c3589c7983fd1deb4a4c0bebf0929890e ] In the current ath12k implementation, the CE addresses CE_HOST_IE_ADDRESS and CE_HOST_IE_2_ADDRESS are incorrect. These values were inherited from ath11k, but ath12k does not currently use them. However, the Ath12k AHB support relies on these addresses. Therefore, correct the CE addresses for ath12k. Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.3.1-00130-QCAHKSWPL_SILICONZ-1 Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.1.1-00210-QCAHKSWPL_SILICONZ-1 Signed-off-by: Balamurugan S Reviewed-by: Vasanthakumar Thiagarajan Signed-off-by: Raj Kumar Bhagat Link: https://patch.msgid.link/20250321-ath12k-ahb-v12-2-bb389ed76ae5@quicinc.com Signed-off-by: Jeff Johnson Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath12k/ce.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ce.h b/drivers/net/wireless/ath/ath12k/ce.h index 857bc5f9e946..f9547a3945e4 100644 --- a/drivers/net/wireless/ath/ath12k/ce.h +++ b/drivers/net/wireless/ath/ath12k/ce.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022, 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef ATH12K_CE_H @@ -39,8 +39,8 @@ #define PIPEDIR_INOUT_H2H 4 /* bidirectional, host to host */ /* CE address/mask */ -#define CE_HOST_IE_ADDRESS 0x00A1803C -#define CE_HOST_IE_2_ADDRESS 0x00A18040 +#define CE_HOST_IE_ADDRESS 0x75804C +#define CE_HOST_IE_2_ADDRESS 0x758050 #define CE_HOST_IE_3_ADDRESS CE_HOST_IE_ADDRESS #define CE_HOST_IE_3_SHIFT 0xC From 8df53ee74cac0cd1ed8357df6e84538a54b87bd6 Mon Sep 17 00:00:00 2001 From: Suraj P Kizhakkethil Date: Tue, 4 Mar 2025 15:23:14 +0530 Subject: [PATCH 591/971] wifi: ath12k: Pass correct values of center freq1 and center freq2 for 160 MHz [ Upstream commit b1b01e46a3db5ad44d1e4691ba37c1e0832cd5cf ] Currently, for 160 MHz bandwidth, center frequency1 and center frequency2 are not passed correctly to the firmware. Set center frequency1 as the center frequency of the primary 80 MHz channel segment and center frequency2 as the center frequency of the 160 MHz channel and pass the values to the firmware. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Signed-off-by: Suraj P Kizhakkethil Reviewed-by: Aditya Kumar Singh Link: https://patch.msgid.link/20250304095315.3050325-2-quic_surapk@quicinc.com Signed-off-by: Jeff Johnson Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath12k/wmi.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index 31af940bc572..958ac4ed5c34 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -951,14 +951,24 @@ int ath12k_wmi_vdev_down(struct ath12k *ar, u8 vdev_id) static void ath12k_wmi_put_wmi_channel(struct ath12k_wmi_channel_params *chan, struct wmi_vdev_start_req_arg *arg) { + u32 center_freq1 = arg->band_center_freq1; + memset(chan, 0, sizeof(*chan)); chan->mhz = cpu_to_le32(arg->freq); - chan->band_center_freq1 = cpu_to_le32(arg->band_center_freq1); - if (arg->mode == MODE_11AC_VHT80_80) + chan->band_center_freq1 = cpu_to_le32(center_freq1); + if (arg->mode == MODE_11BE_EHT160) { + if (arg->freq > center_freq1) + chan->band_center_freq1 = cpu_to_le32(center_freq1 + 40); + else + chan->band_center_freq1 = cpu_to_le32(center_freq1 - 40); + + chan->band_center_freq2 = cpu_to_le32(center_freq1); + } else if (arg->mode == MODE_11BE_EHT80_80) { chan->band_center_freq2 = cpu_to_le32(arg->band_center_freq2); - else + } else { chan->band_center_freq2 = 0; + } chan->info |= le32_encode_bits(arg->mode, WMI_CHAN_INFO_MODE); if (arg->passive) From 519ba75728ee8cd561dce25fc52a2ec5c47171dc Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 9 May 2025 13:06:47 -0700 Subject: [PATCH 592/971] fbcon: Make sure modelist not set on unregistered console [ Upstream commit cedc1b63394a866bf8663a3e40f4546f1d28c8d8 ] It looks like attempting to write to the "store_modes" sysfs node will run afoul of unregistered consoles: UBSAN: array-index-out-of-bounds in drivers/video/fbdev/core/fbcon.c:122:28 index -1 is out of range for type 'fb_info *[32]' ... fbcon_info_from_console+0x192/0x1a0 drivers/video/fbdev/core/fbcon.c:122 fbcon_new_modelist+0xbf/0x2d0 drivers/video/fbdev/core/fbcon.c:3048 fb_new_modelist+0x328/0x440 drivers/video/fbdev/core/fbmem.c:673 store_modes+0x1c9/0x3e0 drivers/video/fbdev/core/fbsysfs.c:113 dev_attr_store+0x55/0x80 drivers/base/core.c:2439 static struct fb_info *fbcon_registered_fb[FB_MAX]; ... static signed char con2fb_map[MAX_NR_CONSOLES]; ... static struct fb_info *fbcon_info_from_console(int console) ... return fbcon_registered_fb[con2fb_map[console]]; If con2fb_map contains a -1 things go wrong here. Instead, return NULL, as callers of fbcon_info_from_console() are trying to compare against existing "info" pointers, so error handling should kick in correctly. Reported-by: syzbot+a7d4444e7b6e743572f7@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/679d0a8f.050a0220.163cdc.000c.GAE@google.com/ Signed-off-by: Kees Cook Signed-off-by: Helge Deller Signed-off-by: Sasha Levin --- drivers/video/fbdev/core/fbcon.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 7a6f9a3cb3ba..75996ef9992e 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -115,9 +115,14 @@ static signed char con2fb_map_boot[MAX_NR_CONSOLES]; static struct fb_info *fbcon_info_from_console(int console) { + signed char fb; WARN_CONSOLE_UNLOCKED(); - return fbcon_registered_fb[con2fb_map[console]]; + fb = con2fb_map[console]; + if (fb < 0 || fb >= ARRAY_SIZE(fbcon_registered_fb)) + return NULL; + + return fbcon_registered_fb[fb]; } static int logo_lines; From c85311a73d7431de6981576bfc8e16bd60397bf8 Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Wed, 26 Mar 2025 09:29:51 +0100 Subject: [PATCH 593/971] watchdog: da9052_wdt: respect TWDMIN [ Upstream commit 325f510fcd9cda5a44bcb662b74ba4e3dabaca10 ] We have to wait at least the minimium time for the watchdog window (TWDMIN) before writings to the wdt register after the watchdog is activated. Otherwise the chip will assert TWD_ERROR and power down to reset mode. Signed-off-by: Marcus Folkesson Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20250326-da9052-fixes-v3-4-a38a560fef0e@gmail.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Signed-off-by: Sasha Levin --- drivers/watchdog/da9052_wdt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c index d708c091bf1b..180526220d8c 100644 --- a/drivers/watchdog/da9052_wdt.c +++ b/drivers/watchdog/da9052_wdt.c @@ -164,6 +164,7 @@ static int da9052_wdt_probe(struct platform_device *pdev) da9052_wdt = &driver_data->wdt; da9052_wdt->timeout = DA9052_DEF_TIMEOUT; + da9052_wdt->min_hw_heartbeat_ms = DA9052_TWDMIN; da9052_wdt->info = &da9052_wdt_info; da9052_wdt->ops = &da9052_wdt_ops; da9052_wdt->parent = dev; From bca6fe52bd950a08790213741993dc090c47feca Mon Sep 17 00:00:00 2001 From: Laurentiu Tudor Date: Tue, 8 Apr 2025 13:58:14 +0300 Subject: [PATCH 594/971] bus: fsl-mc: increase MC_CMD_COMPLETION_TIMEOUT_MS value [ Upstream commit 23d060136841c58c2f9ee8c08ad945d1879ead4b ] In case the MC firmware runs in debug mode with extensive prints pushed to the console, the current timeout of 500ms is not enough. Increase the timeout value so that we don't have any chance of wrongly assuming that the firmware is not responding when it's just taking more time. Signed-off-by: Laurentiu Tudor Signed-off-by: Ioana Ciornei Link: https://lore.kernel.org/r/20250408105814.2837951-7-ioana.ciornei@nxp.com Signed-off-by: Christophe Leroy Signed-off-by: Sasha Levin --- drivers/bus/fsl-mc/mc-sys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bus/fsl-mc/mc-sys.c b/drivers/bus/fsl-mc/mc-sys.c index f2052cd0a051..b22c59d57c8f 100644 --- a/drivers/bus/fsl-mc/mc-sys.c +++ b/drivers/bus/fsl-mc/mc-sys.c @@ -19,7 +19,7 @@ /* * Timeout in milliseconds to wait for the completion of an MC command */ -#define MC_CMD_COMPLETION_TIMEOUT_MS 500 +#define MC_CMD_COMPLETION_TIMEOUT_MS 15000 /* * usleep_range() min and max values used to throttle down polling From 59b7304d0dffa5ce74c87fd769cdf1e3ebc21cd2 Mon Sep 17 00:00:00 2001 From: Sukrut Bellary Date: Tue, 18 Mar 2025 16:00:39 -0700 Subject: [PATCH 595/971] ARM: OMAP2+: Fix l4ls clk domain handling in STANDBY [ Upstream commit 47fe74098f3dadba2f9cc1e507d813a4aa93f5f3 ] Don't put the l4ls clk domain to sleep in case of standby. Since CM3 PM FW[1](ti-v4.1.y) doesn't wake-up/enable the l4ls clk domain upon wake-up, CM3 PM FW fails to wake-up the MPU. [1] https://git.ti.com/cgit/processor-firmware/ti-amx3-cm3-pm-firmware/ Signed-off-by: Sukrut Bellary Tested-by: Judith Mendez Link: https://lore.kernel.org/r/20250318230042.3138542-2-sbellary@baylibre.com Signed-off-by: Kevin Hilman Signed-off-by: Sasha Levin --- arch/arm/mach-omap2/clockdomain.h | 1 + arch/arm/mach-omap2/clockdomains33xx_data.c | 2 +- arch/arm/mach-omap2/cm33xx.c | 14 +++++++++++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h index c36fb2721261..86a2f9e5d0ef 100644 --- a/arch/arm/mach-omap2/clockdomain.h +++ b/arch/arm/mach-omap2/clockdomain.h @@ -48,6 +48,7 @@ #define CLKDM_NO_AUTODEPS (1 << 4) #define CLKDM_ACTIVE_WITH_MPU (1 << 5) #define CLKDM_MISSING_IDLE_REPORTING (1 << 6) +#define CLKDM_STANDBY_FORCE_WAKEUP BIT(7) #define CLKDM_CAN_HWSUP (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO) #define CLKDM_CAN_SWSUP (CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP) diff --git a/arch/arm/mach-omap2/clockdomains33xx_data.c b/arch/arm/mach-omap2/clockdomains33xx_data.c index 87f4e927eb18..c05a3c07d448 100644 --- a/arch/arm/mach-omap2/clockdomains33xx_data.c +++ b/arch/arm/mach-omap2/clockdomains33xx_data.c @@ -19,7 +19,7 @@ static struct clockdomain l4ls_am33xx_clkdm = { .pwrdm = { .name = "per_pwrdm" }, .cm_inst = AM33XX_CM_PER_MOD, .clkdm_offs = AM33XX_CM_PER_L4LS_CLKSTCTRL_OFFSET, - .flags = CLKDM_CAN_SWSUP, + .flags = CLKDM_CAN_SWSUP | CLKDM_STANDBY_FORCE_WAKEUP, }; static struct clockdomain l3s_am33xx_clkdm = { diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c index c824d4e3db63..aaee67d09791 100644 --- a/arch/arm/mach-omap2/cm33xx.c +++ b/arch/arm/mach-omap2/cm33xx.c @@ -20,6 +20,9 @@ #include "cm-regbits-34xx.h" #include "cm-regbits-33xx.h" #include "prm33xx.h" +#if IS_ENABLED(CONFIG_SUSPEND) +#include +#endif /* * CLKCTRL_IDLEST_*: possible values for the CM_*_CLKCTRL.IDLEST bitfield: @@ -328,8 +331,17 @@ static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm) { bool hwsup = false; +#if IS_ENABLED(CONFIG_SUSPEND) + /* + * In case of standby, Don't put the l4ls clk domain to sleep. + * Since CM3 PM FW doesn't wake-up/enable the l4ls clk domain + * upon wake-up, CM3 PM FW fails to wake-up th MPU. + */ + if (pm_suspend_target_state == PM_SUSPEND_STANDBY && + (clkdm->flags & CLKDM_STANDBY_FORCE_WAKEUP)) + return 0; +#endif hwsup = am33xx_cm_is_clkdm_in_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); - if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) am33xx_clkdm_sleep(clkdm); From cdc1b9b47bc574bbb6e2e2bc25843249b76d46d9 Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Mon, 28 Apr 2025 15:06:43 +0200 Subject: [PATCH 596/971] tee: Prevent size calculation wraparound on 32-bit kernels [ Upstream commit 39bb67edcc582b3b386a9ec983da67fa8a10ec03 ] The current code around TEE_IOCTL_PARAM_SIZE() is a bit wrong on 32-bit kernels: Multiplying a user-provided 32-bit value with the size of a structure can wrap around on such platforms. Fix it by using saturating arithmetic for the size calculation. This has no security consequences because, in all users of TEE_IOCTL_PARAM_SIZE(), the subsequent kcalloc() implicitly checks for wrapping. Signed-off-by: Jann Horn Signed-off-by: Jens Wiklander Tested-by: Rouven Czerwinski Signed-off-by: Sasha Levin --- drivers/tee/tee_core.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index 0eb342de0b00..d7ad16f262b2 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -19,7 +20,7 @@ #define TEE_NUM_DEVICES 32 -#define TEE_IOCTL_PARAM_SIZE(x) (sizeof(struct tee_param) * (x)) +#define TEE_IOCTL_PARAM_SIZE(x) (size_mul(sizeof(struct tee_param), (x))) #define TEE_UUID_NS_NAME_SIZE 128 @@ -487,7 +488,7 @@ static int tee_ioctl_open_session(struct tee_context *ctx, if (copy_from_user(&arg, uarg, sizeof(arg))) return -EFAULT; - if (sizeof(arg) + TEE_IOCTL_PARAM_SIZE(arg.num_params) != buf.buf_len) + if (size_add(sizeof(arg), TEE_IOCTL_PARAM_SIZE(arg.num_params)) != buf.buf_len) return -EINVAL; if (arg.num_params) { @@ -565,7 +566,7 @@ static int tee_ioctl_invoke(struct tee_context *ctx, if (copy_from_user(&arg, uarg, sizeof(arg))) return -EFAULT; - if (sizeof(arg) + TEE_IOCTL_PARAM_SIZE(arg.num_params) != buf.buf_len) + if (size_add(sizeof(arg), TEE_IOCTL_PARAM_SIZE(arg.num_params)) != buf.buf_len) return -EINVAL; if (arg.num_params) { @@ -699,7 +700,7 @@ static int tee_ioctl_supp_recv(struct tee_context *ctx, if (get_user(num_params, &uarg->num_params)) return -EFAULT; - if (sizeof(*uarg) + TEE_IOCTL_PARAM_SIZE(num_params) != buf.buf_len) + if (size_add(sizeof(*uarg), TEE_IOCTL_PARAM_SIZE(num_params)) != buf.buf_len) return -EINVAL; params = kcalloc(num_params, sizeof(struct tee_param), GFP_KERNEL); @@ -798,7 +799,7 @@ static int tee_ioctl_supp_send(struct tee_context *ctx, get_user(num_params, &uarg->num_params)) return -EFAULT; - if (sizeof(*uarg) + TEE_IOCTL_PARAM_SIZE(num_params) > buf.buf_len) + if (size_add(sizeof(*uarg), TEE_IOCTL_PARAM_SIZE(num_params)) > buf.buf_len) return -EINVAL; params = kcalloc(num_params, sizeof(struct tee_param), GFP_KERNEL); From 897e6d88f0e306285905ffb70bfa68bda909b132 Mon Sep 17 00:00:00 2001 From: Alexander Sverdlin Date: Tue, 1 Apr 2025 11:06:34 +0200 Subject: [PATCH 597/971] Revert "bus: ti-sysc: Probe for l4_wkup and l4_cfg interconnect devices first" [ Upstream commit 36305857b1ead8f6ca033a913162ebc09bee0b43 ] This reverts commit 4700a00755fb5a4bb5109128297d6fd2d1272ee6. It breaks target-module@2b300050 ("ti,sysc-omap2") probe on AM62x in a case when minimally-configured system tries to network-boot: [ 6.888776] probe of 2b300050.target-module returned 517 after 258 usecs [ 17.129637] probe of 2b300050.target-module returned 517 after 708 usecs [ 17.137397] platform 2b300050.target-module: deferred probe pending: (reason unknown) [ 26.878471] Waiting up to 100 more seconds for network. There are minimal configurations possible when the deferred device is not being probed any more (because everything else has been successfully probed) and deferral lists are not processed any more. Stable mmc enumeration can be achieved by filling /aliases node properly (4700a00755fb commit's rationale). After revert: [ 9.006816] IP-Config: Complete: [ 9.010058] device=lan0, ... Tested-by: Andreas Kemnade # GTA04, Panda, BT200 Reviewed-by: Tony Lindgren Signed-off-by: Alexander Sverdlin Link: https://lore.kernel.org/r/20250401090643.2776793-1-alexander.sverdlin@siemens.com Signed-off-by: Kevin Hilman Signed-off-by: Sasha Levin --- drivers/bus/ti-sysc.c | 49 ------------------------------------------- 1 file changed, 49 deletions(-) diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index 65163312dab8..46d7410f6f0f 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -667,51 +667,6 @@ static int sysc_parse_and_check_child_range(struct sysc *ddata) return 0; } -/* Interconnect instances to probe before l4_per instances */ -static struct resource early_bus_ranges[] = { - /* am3/4 l4_wkup */ - { .start = 0x44c00000, .end = 0x44c00000 + 0x300000, }, - /* omap4/5 and dra7 l4_cfg */ - { .start = 0x4a000000, .end = 0x4a000000 + 0x300000, }, - /* omap4 l4_wkup */ - { .start = 0x4a300000, .end = 0x4a300000 + 0x30000, }, - /* omap5 and dra7 l4_wkup without dra7 dcan segment */ - { .start = 0x4ae00000, .end = 0x4ae00000 + 0x30000, }, -}; - -static atomic_t sysc_defer = ATOMIC_INIT(10); - -/** - * sysc_defer_non_critical - defer non_critical interconnect probing - * @ddata: device driver data - * - * We want to probe l4_cfg and l4_wkup interconnect instances before any - * l4_per instances as l4_per instances depend on resources on l4_cfg and - * l4_wkup interconnects. - */ -static int sysc_defer_non_critical(struct sysc *ddata) -{ - struct resource *res; - int i; - - if (!atomic_read(&sysc_defer)) - return 0; - - for (i = 0; i < ARRAY_SIZE(early_bus_ranges); i++) { - res = &early_bus_ranges[i]; - if (ddata->module_pa >= res->start && - ddata->module_pa <= res->end) { - atomic_set(&sysc_defer, 0); - - return 0; - } - } - - atomic_dec_if_positive(&sysc_defer); - - return -EPROBE_DEFER; -} - static struct device_node *stdout_path; static void sysc_init_stdout_path(struct sysc *ddata) @@ -937,10 +892,6 @@ static int sysc_map_and_check_registers(struct sysc *ddata) if (error) return error; - error = sysc_defer_non_critical(ddata); - if (error) - return error; - sysc_check_children(ddata); if (!of_property_present(np, "reg")) From 7d71ba5b0a01c57e7199a5e930d8deb0f92be809 Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Thu, 5 Jun 2025 12:51:16 -0400 Subject: [PATCH 598/971] fs/xattr.c: fix simple_xattr_list() [ Upstream commit 800d0b9b6a8b1b354637b4194cc167ad1ce2bdd3 ] commit 8b0ba61df5a1 ("fs/xattr.c: fix simple_xattr_list to always include security.* xattrs") failed to reset err after the call to security_inode_listsecurity(), which returns the length of the returned xattr name. This results in simple_xattr_list() incorrectly returning this length even if a POSIX acl is also set on the inode. Reported-by: Collin Funk Closes: https://lore.kernel.org/selinux/8734ceal7q.fsf@gmail.com/ Reported-by: Paul Eggert Closes: https://bugzilla.redhat.com/show_bug.cgi?id=2369561 Fixes: 8b0ba61df5a1 ("fs/xattr.c: fix simple_xattr_list to always include security.* xattrs") Signed-off-by: Stephen Smalley Link: https://lore.kernel.org/20250605165116.2063-1-stephen.smalley.work@gmail.com Signed-off-by: Christian Brauner Signed-off-by: Sasha Levin --- fs/xattr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/xattr.c b/fs/xattr.c index 5fed22c22a2b..7574d24b982e 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -1342,6 +1342,7 @@ ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs, buffer += err; } remaining_size -= err; + err = 0; read_lock(&xattrs->lock); for (rbp = rb_first(&xattrs->rb_root); rbp; rbp = rb_next(rbp)) { From 523e2f8a7f83261377cd6ca72c5954408f0a3410 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Tue, 3 Jun 2025 08:24:08 -0500 Subject: [PATCH 599/971] platform/x86/amd: pmc: Clear metrics table at start of cycle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 4dbd11796f3a8eb95647507befc41995458a4023 ] The area of memory that contains the metrics table may contain garbage when the cycle starts. This normally doesn't matter because the cycle itself will populate it with valid data, however commit 9f5595d5f03fd ("platform/x86/amd: pmc: Require at least 2.5 seconds between HW sleep cycles") started to use it during the check() phase. Depending upon what garbage is in the table it's possible that the system will wait 2.5 seconds for even the first cycle, which will be visible to a user. To prevent this from happening explicitly clear the table when logging is started. Fixes: 9f5595d5f03fd ("platform/x86/amd: pmc: Require at least 2.5 seconds between HW sleep cycles") Signed-off-by: Mario Limonciello Link: https://lore.kernel.org/r/20250603132412.3555302-1-superm1@kernel.org Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin --- drivers/platform/x86/amd/pmc/pmc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/platform/x86/amd/pmc/pmc.c b/drivers/platform/x86/amd/pmc/pmc.c index 946a546cd9dd..af5cc8aa7988 100644 --- a/drivers/platform/x86/amd/pmc/pmc.c +++ b/drivers/platform/x86/amd/pmc/pmc.c @@ -332,6 +332,8 @@ static int amd_pmc_setup_smu_logging(struct amd_pmc_dev *dev) return -ENOMEM; } + memset_io(dev->smu_virt_addr, 0, sizeof(struct smu_metrics)); + /* Start the logging */ amd_pmc_send_cmd(dev, 0, NULL, SMU_MSG_LOG_RESET, false); amd_pmc_send_cmd(dev, 0, NULL, SMU_MSG_LOG_START, false); From f3b840fb1508a80cd8a0efb5c886ae1995a88b24 Mon Sep 17 00:00:00 2001 From: Stuart Hayes Date: Mon, 9 Jun 2025 13:46:56 -0500 Subject: [PATCH 600/971] platform/x86: dell_rbu: Fix list usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 61ce04601e0d8265ec6d2ffa6df5a7e1bce64854 ] Pass the correct list head to list_for_each_entry*() when looping through the packet list. Without this patch, reading the packet data via sysfs will show the data incorrectly (because it starts at the wrong packet), and clearing the packet list will result in a NULL pointer dereference. Fixes: d19f359fbdc6 ("platform/x86: dell_rbu: don't open code list_for_each_entry*()") Signed-off-by: Stuart Hayes Link: https://lore.kernel.org/r/20250609184659.7210-3-stuart.w.hayes@gmail.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin --- drivers/platform/x86/dell/dell_rbu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/dell/dell_rbu.c b/drivers/platform/x86/dell/dell_rbu.c index 9f51e0fcab04..4d2b5f6dd513 100644 --- a/drivers/platform/x86/dell/dell_rbu.c +++ b/drivers/platform/x86/dell/dell_rbu.c @@ -292,7 +292,7 @@ static int packet_read_list(char *data, size_t * pread_length) remaining_bytes = *pread_length; bytes_read = rbu_data.packet_read_count; - list_for_each_entry(newpacket, (&packet_data_head.list)->next, list) { + list_for_each_entry(newpacket, &packet_data_head.list, list) { bytes_copied = do_packet_read(pdest, newpacket, remaining_bytes, bytes_read, &temp_count); remaining_bytes -= bytes_copied; @@ -315,7 +315,7 @@ static void packet_empty_list(void) { struct packet_data *newpacket, *tmp; - list_for_each_entry_safe(newpacket, tmp, (&packet_data_head.list)->next, list) { + list_for_each_entry_safe(newpacket, tmp, &packet_data_head.list, list) { list_del(&newpacket->list); /* From dd95b3e00346b69eba06daf774f3ff0be0c0fdb0 Mon Sep 17 00:00:00 2001 From: Stuart Hayes Date: Mon, 9 Jun 2025 13:46:58 -0500 Subject: [PATCH 601/971] platform/x86: dell_rbu: Stop overwriting data buffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit f4b0fa38d5fefe9aed6ed831f3bd3538c168ee19 ] The dell_rbu driver will use memset() to clear the data held by each packet when it is no longer needed (when the driver is unloaded, the packet size is changed, etc). The amount of memory that is cleared (before this patch) is the normal packet size. However, the last packet in the list may be smaller. Fix this to only clear the memory actually used by each packet, to prevent it from writing past the end of data buffer. Because the packet data buffers are allocated with __get_free_pages() (in page-sized increments), this bug could only result in a buffer being overwritten when a packet size larger than one page is used. The only user of the dell_rbu module should be the Dell BIOS update program, which uses a packet size of 4096, so no issues should be seen without the patch, it just blocks the possiblity. Fixes: 6c54c28e69f2 ("[PATCH] dell_rbu: new Dell BIOS update driver") Signed-off-by: Stuart Hayes Link: https://lore.kernel.org/r/20250609184659.7210-5-stuart.w.hayes@gmail.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin --- drivers/platform/x86/dell/dell_rbu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/dell/dell_rbu.c b/drivers/platform/x86/dell/dell_rbu.c index 4d2b5f6dd513..fee20866b41e 100644 --- a/drivers/platform/x86/dell/dell_rbu.c +++ b/drivers/platform/x86/dell/dell_rbu.c @@ -322,7 +322,7 @@ static void packet_empty_list(void) * zero out the RBU packet memory before freeing * to make sure there are no stale RBU packets left in memory */ - memset(newpacket->data, 0, rbu_data.packetsize); + memset(newpacket->data, 0, newpacket->length); set_memory_wb((unsigned long)newpacket->data, 1 << newpacket->ordernum); free_pages((unsigned long) newpacket->data, From a7f3cfc1eb9920cfb0d86ea87d3d4e941a77e9a1 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Mon, 12 May 2025 20:14:55 +0200 Subject: [PATCH 602/971] powerpc/vdso: Fix build of VDSO32 with pcrel [ Upstream commit b93755f408325170edb2156c6a894ed1cae5f4f6 ] Building vdso32 on power10 with pcrel leads to following errors: VDSO32A arch/powerpc/kernel/vdso/gettimeofday-32.o arch/powerpc/kernel/vdso/gettimeofday.S: Assembler messages: arch/powerpc/kernel/vdso/gettimeofday.S:40: Error: syntax error; found `@', expected `,' arch/powerpc/kernel/vdso/gettimeofday.S:71: Info: macro invoked from here arch/powerpc/kernel/vdso/gettimeofday.S:40: Error: junk at end of line: `@notoc' arch/powerpc/kernel/vdso/gettimeofday.S:71: Info: macro invoked from here ... make[2]: *** [arch/powerpc/kernel/vdso/Makefile:85: arch/powerpc/kernel/vdso/gettimeofday-32.o] Error 1 make[1]: *** [arch/powerpc/Makefile:388: vdso_prepare] Error 2 Once the above is fixed, the following happens: VDSO32C arch/powerpc/kernel/vdso/vgettimeofday-32.o cc1: error: '-mpcrel' requires '-mcmodel=medium' make[2]: *** [arch/powerpc/kernel/vdso/Makefile:89: arch/powerpc/kernel/vdso/vgettimeofday-32.o] Error 1 make[1]: *** [arch/powerpc/Makefile:388: vdso_prepare] Error 2 make: *** [Makefile:251: __sub-make] Error 2 Make sure pcrel version of CFUNC() macro is used only for powerpc64 builds and remove -mpcrel for powerpc32 builds. Fixes: 7e3a68be42e1 ("powerpc/64: vmlinux support building with PCREL addresing") Signed-off-by: Christophe Leroy Signed-off-by: Madhavan Srinivasan Link: https://patch.msgid.link/1fa3453f07d42a50a70114da9905bf7b73304fca.1747073669.git.christophe.leroy@csgroup.eu Signed-off-by: Sasha Levin --- arch/powerpc/include/asm/ppc_asm.h | 2 +- arch/powerpc/kernel/vdso/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index e7792aa13510..fa7926532866 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h @@ -183,7 +183,7 @@ /* * Used to name C functions called from asm */ -#ifdef CONFIG_PPC_KERNEL_PCREL +#if defined(__powerpc64__) && defined(CONFIG_PPC_KERNEL_PCREL) #define CFUNC(name) name@notoc #else #define CFUNC(name) name diff --git a/arch/powerpc/kernel/vdso/Makefile b/arch/powerpc/kernel/vdso/Makefile index d5defff8472d..47a9533a4dc1 100644 --- a/arch/powerpc/kernel/vdso/Makefile +++ b/arch/powerpc/kernel/vdso/Makefile @@ -50,7 +50,7 @@ ldflags-$(CONFIG_LD_ORPHAN_WARN) += -Wl,--orphan-handling=$(CONFIG_LD_ORPHAN_WAR ldflags-y += $(filter-out $(CC_AUTO_VAR_INIT_ZERO_ENABLER) $(CC_FLAGS_FTRACE) -Wa$(comma)%, $(KBUILD_CFLAGS)) CC32FLAGS := -m32 -CC32FLAGSREMOVE := -mcmodel=medium -mabi=elfv1 -mabi=elfv2 -mcall-aixdesc +CC32FLAGSREMOVE := -mcmodel=medium -mabi=elfv1 -mabi=elfv2 -mcall-aixdesc -mpcrel ifdef CONFIG_CC_IS_CLANG # This flag is supported by clang for 64-bit but not 32-bit so it will cause # an unused command line flag warning for this file. From af4ed5262d30734be6a44416f1a9dc241d609701 Mon Sep 17 00:00:00 2001 From: Narayana Murty N Date: Thu, 8 May 2025 02:29:28 -0400 Subject: [PATCH 603/971] powerpc/eeh: Fix missing PE bridge reconfiguration during VFIO EEH recovery [ Upstream commit 33bc69cf6655cf60829a803a45275f11a74899e5 ] VFIO EEH recovery for PCI passthrough devices fails on PowerNV and pseries platforms due to missing host-side PE bridge reconfiguration. In the current implementation, eeh_pe_configure() only performs RTAS or OPAL-based bridge reconfiguration for native host devices, but skips it entirely for PEs managed through VFIO in guest passthrough scenarios. This leads to incomplete EEH recovery when a PCI error affects a passthrough device assigned to a QEMU/KVM guest. Although VFIO triggers the EEH recovery flow through VFIO_EEH_PE_ENABLE ioctl, the platform-specific bridge reconfiguration step is silently bypassed. As a result, the PE's config space is not fully restored, causing subsequent config space access failures or EEH freeze-on-access errors inside the guest. This patch fixes the issue by ensuring that eeh_pe_configure() always invokes the platform's configure_bridge() callback (e.g., pseries_eeh_phb_configure_bridge) even for VFIO-managed PEs. This ensures that RTAS or OPAL calls to reconfigure the PE bridge are correctly issued on the host side, restoring the PE's configuration space after an EEH event. This fix is essential for reliable EEH recovery in QEMU/KVM guests using VFIO PCI passthrough on PowerNV and pseries systems. Tested with: - QEMU/KVM guest using VFIO passthrough (IBM Power9,(lpar)Power11 host) - Injected EEH errors with pseries EEH errinjct tool on host, recovery verified on qemu guest. - Verified successful config space access and CAP_EXP DevCtl restoration after recovery Fixes: 212d16cdca2d ("powerpc/eeh: EEH support for VFIO PCI device") Signed-off-by: Narayana Murty N Reviewed-by: Vaibhav Jain Reviewed-by: Ganesh Goudar Signed-off-by: Madhavan Srinivasan Link: https://patch.msgid.link/20250508062928.146043-1-nnmlinux@linux.ibm.com Signed-off-by: Sasha Levin --- arch/powerpc/kernel/eeh.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index ab316e155ea9..2e286bba2f64 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -1516,6 +1516,8 @@ int eeh_pe_configure(struct eeh_pe *pe) /* Invalid PE ? */ if (!pe) return -ENODEV; + else + ret = eeh_ops->configure_bridge(pe); return ret; } From 3c3c7c66bdfaf07dde99966706b834fad21841a7 Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Fri, 20 Jun 2025 06:51:23 -0700 Subject: [PATCH 604/971] Revert "x86/bugs: Make spectre user default depend on MITIGATION_SPECTRE_V2" on v6.6 and older This reverts commit 7adb96687ce8819de5c7bb172c4eeb6e45736e06 which is commit 98fdaeb296f51ef08e727a7cc72e5b5c864c4f4d upstream. commit 7adb96687ce8 ("x86/bugs: Make spectre user default depend on MITIGATION_SPECTRE_V2") depends on commit 72c70f480a70 ("x86/bugs: Add a separate config for Spectre V2"), which introduced MITIGATION_SPECTRE_V2. commit 72c70f480a70 ("x86/bugs: Add a separate config for Spectre V2") never landed in stable tree, thus, stable tree doesn't have MITIGATION_SPECTRE_V2, that said, commit 7adb96687ce8 ("x86/bugs: Make spectre user default depend on MITIGATION_SPECTRE_V2") has no value if the dependecy was not applied. Revert commit 7adb96687ce8 ("x86/bugs: Make spectre user default depend on MITIGATION_SPECTRE_V2") in stable kernel which landed in in 5.4.294, 5.10.238, 5.15.185, 6.1.141 and 6.6.93 stable versions. Cc: David.Kaplan@amd.com Cc: peterz@infradead.org Cc: pawan.kumar.gupta@linux.intel.com Cc: mingo@kernel.org Cc: brad.spengler@opensrcsec.com Cc: stable@vger.kernel.org # 6.6 6.1 5.15 5.10 5.4 Reported-by: Brad Spengler Reported-by: Salvatore Bonaccorso Signed-off-by: Breno Leitao Signed-off-by: Greg Kroah-Hartman --- Documentation/admin-guide/kernel-parameters.txt | 2 -- arch/x86/kernel/cpu/bugs.c | 10 +++------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 315a817e3380..f95734ceb82b 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -5978,8 +5978,6 @@ Selecting 'on' will also enable the mitigation against user space to user space task attacks. - Selecting specific mitigation does not force enable - user mitigations. Selecting 'off' will disable both the kernel and the user space protections. diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index e9c4bcb38f45..07b45bbf6348 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -1442,13 +1442,9 @@ static __ro_after_init enum spectre_v2_mitigation_cmd spectre_v2_cmd; static enum spectre_v2_user_cmd __init spectre_v2_parse_user_cmdline(void) { - enum spectre_v2_user_cmd mode; char arg[20]; int ret, i; - mode = IS_ENABLED(CONFIG_MITIGATION_SPECTRE_V2) ? - SPECTRE_V2_USER_CMD_AUTO : SPECTRE_V2_USER_CMD_NONE; - switch (spectre_v2_cmd) { case SPECTRE_V2_CMD_NONE: return SPECTRE_V2_USER_CMD_NONE; @@ -1461,7 +1457,7 @@ spectre_v2_parse_user_cmdline(void) ret = cmdline_find_option(boot_command_line, "spectre_v2_user", arg, sizeof(arg)); if (ret < 0) - return mode; + return SPECTRE_V2_USER_CMD_AUTO; for (i = 0; i < ARRAY_SIZE(v2_user_options); i++) { if (match_option(arg, ret, v2_user_options[i].option)) { @@ -1471,8 +1467,8 @@ spectre_v2_parse_user_cmdline(void) } } - pr_err("Unknown user space protection option (%s). Switching to default\n", arg); - return mode; + pr_err("Unknown user space protection option (%s). Switching to AUTO select\n", arg); + return SPECTRE_V2_USER_CMD_AUTO; } static inline bool spectre_v2_in_ibrs_mode(enum spectre_v2_mitigation mode) From 675d90ee874c5ac0fd682d8b97daf0aa08dc739d Mon Sep 17 00:00:00 2001 From: Penglei Jiang Date: Sun, 15 Jun 2025 09:39:06 -0700 Subject: [PATCH 605/971] io_uring: fix task leak issue in io_wq_create() commit 89465d923bda180299e69ee2800aab84ad0ba689 upstream. Add missing put_task_struct() in the error path Cc: stable@vger.kernel.org Fixes: 0f8baa3c9802 ("io-wq: fully initialize wqe before calling cpuhp_state_add_instance_nocalls()") Signed-off-by: Penglei Jiang Link: https://lore.kernel.org/r/20250615163906.2367-1-superman.xpt@gmail.com Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- io_uring/io-wq.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c index 93f3e4d1df85..1c4ef4e4eb52 100644 --- a/io_uring/io-wq.c +++ b/io_uring/io-wq.c @@ -1206,8 +1206,10 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data) atomic_set(&wq->worker_refs, 1); init_completion(&wq->worker_done); ret = cpuhp_state_add_instance_nocalls(io_wq_online, &wq->cpuhp_node); - if (ret) + if (ret) { + put_task_struct(wq->task); goto err; + } return wq; err: From 1921781ec4a8824bd0c520bf9363e28a880d14ec Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sat, 7 Jun 2025 17:43:18 -0700 Subject: [PATCH 606/971] drivers/rapidio/rio_cm.c: prevent possible heap overwrite commit 50695153d7ddde3b1696dbf0085be0033bf3ddb3 upstream. In riocm_cdev_ioctl(RIO_CM_CHAN_SEND) -> cm_chan_msg_send() -> riocm_ch_send() cm_chan_msg_send() checks that userspace didn't send too much data but riocm_ch_send() failed to check that userspace sent sufficient data. The result is that riocm_ch_send() can write to fields in the rio_ch_chan_hdr which were outside the bounds of the space which cm_chan_msg_send() allocated. Address this by teaching riocm_ch_send() to check that the entire rio_ch_chan_hdr was copied in from userspace. Reported-by: maher azz Cc: Matt Porter Cc: Alexandre Bounine Cc: Linus Torvalds Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/rapidio/rio_cm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/rapidio/rio_cm.c b/drivers/rapidio/rio_cm.c index 49f8d111e546..897642e62068 100644 --- a/drivers/rapidio/rio_cm.c +++ b/drivers/rapidio/rio_cm.c @@ -787,6 +787,9 @@ static int riocm_ch_send(u16 ch_id, void *buf, int len) if (buf == NULL || ch_id == 0 || len == 0 || len > RIO_MAX_MSG_SIZE) return -EINVAL; + if (len < sizeof(struct rio_ch_chan_hdr)) + return -EINVAL; /* insufficient data from user */ + ch = riocm_get_channel(ch_id); if (!ch) { riocm_error("%s(%d) ch_%d not found", current->comm, From 3bce9e6be030eb18e9253c9441189d43946069a2 Mon Sep 17 00:00:00 2001 From: Yao Zi Date: Thu, 5 Jun 2025 20:34:46 +0800 Subject: [PATCH 607/971] platform/loongarch: laptop: Get brightness setting from EC on probe commit 1205088fd0393bd9eae96b62bf1e4b9eb1b73edf upstream. Previously during driver probe, 1 is unconditionally taken as current brightness value and set to props.brightness, which will be considered as the brightness before suspend and restored to EC on resume. Since a brightness value of 1 almost never matches EC's state on coldboot (my laptop's EC defaults to 80), this causes surprising changes of screen brightness on the first time of resume after coldboot. Let's get brightness from EC and take it as the current brightness on probe of the laptop driver to avoid the surprising behavior. Tested on TongFang L860-T2 Loongson-3A5000 laptop. Cc: stable@vger.kernel.org Fixes: 6246ed09111f ("LoongArch: Add ACPI-based generic laptop driver") Signed-off-by: Yao Zi Signed-off-by: Huacai Chen Signed-off-by: Greg Kroah-Hartman --- drivers/platform/loongarch/loongson-laptop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/loongarch/loongson-laptop.c b/drivers/platform/loongarch/loongson-laptop.c index 99203584949d..ba9a90818c92 100644 --- a/drivers/platform/loongarch/loongson-laptop.c +++ b/drivers/platform/loongarch/loongson-laptop.c @@ -392,8 +392,8 @@ static int laptop_backlight_register(void) if (!acpi_evalf(hotkey_handle, &status, "ECLL", "d")) return -EIO; - props.brightness = 1; props.max_brightness = status; + props.brightness = ec_get_brightness(); props.type = BACKLIGHT_PLATFORM; backlight_device_register("loongson_laptop", From 782baee5d91765bf4ca9469b027cbc44080cbc95 Mon Sep 17 00:00:00 2001 From: Yao Zi Date: Thu, 5 Jun 2025 20:34:46 +0800 Subject: [PATCH 608/971] platform/loongarch: laptop: Unregister generic_sub_drivers on exit commit f78fb2576f22b0ba5297412a9aa7691920666c41 upstream. Without correct unregisteration, ACPI notify handlers and the platform drivers installed by generic_subdriver_init() will become dangling references after removing the loongson_laptop module, triggering various kernel faults when a hotkey is sent or at kernel shutdown. Cc: stable@vger.kernel.org Fixes: 6246ed09111f ("LoongArch: Add ACPI-based generic laptop driver") Signed-off-by: Yao Zi Signed-off-by: Huacai Chen Signed-off-by: Greg Kroah-Hartman --- drivers/platform/loongarch/loongson-laptop.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/platform/loongarch/loongson-laptop.c b/drivers/platform/loongarch/loongson-laptop.c index ba9a90818c92..fe4fec2d4f94 100644 --- a/drivers/platform/loongarch/loongson-laptop.c +++ b/drivers/platform/loongarch/loongson-laptop.c @@ -611,11 +611,17 @@ static int __init generic_acpi_laptop_init(void) static void __exit generic_acpi_laptop_exit(void) { + int i; + if (generic_inputdev) { - if (input_device_registered) - input_unregister_device(generic_inputdev); - else + if (!input_device_registered) { input_free_device(generic_inputdev); + } else { + input_unregister_device(generic_inputdev); + + for (i = 0; i < ARRAY_SIZE(generic_sub_drivers); i++) + generic_subdriver_exit(&generic_sub_drivers[i]); + } } } From 099cfcb98fb4ed2997f6a24399db9d4d2f7a29d1 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Fri, 30 May 2025 21:45:48 +0800 Subject: [PATCH 609/971] LoongArch: Avoid using $r0/$r1 as "mask" for csrxchg commit 52c22661c79a7b6af7fad9f77200738fc6c51878 upstream. When building kernel with LLVM there are occasionally such errors: In file included from ./include/linux/spinlock.h:59: In file included from ./include/linux/irqflags.h:17: arch/loongarch/include/asm/irqflags.h:38:3: error: must not be $r0 or $r1 38 | "csrxchg %[val], %[mask], %[reg]\n\t" | ^ :1:16: note: instantiated into assembly here 1 | csrxchg $a1, $ra, 0 | ^ To prevent the compiler from allocating $r0 or $r1 for the "mask" of the csrxchg instruction, the 'q' constraint must be used but Clang < 21 does not support it. So force to use $t0 in the inline asm, in order to avoid using $r0/$r1 while keeping the backward compatibility. Cc: stable@vger.kernel.org Link: https://github.com/llvm/llvm-project/pull/141037 Reviewed-by: Yanteng Si Suggested-by: WANG Rui Signed-off-by: Huacai Chen Signed-off-by: Greg Kroah-Hartman --- arch/loongarch/include/asm/irqflags.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/arch/loongarch/include/asm/irqflags.h b/arch/loongarch/include/asm/irqflags.h index 319a8c616f1f..003172b8406b 100644 --- a/arch/loongarch/include/asm/irqflags.h +++ b/arch/loongarch/include/asm/irqflags.h @@ -14,40 +14,48 @@ static inline void arch_local_irq_enable(void) { u32 flags = CSR_CRMD_IE; + register u32 mask asm("t0") = CSR_CRMD_IE; + __asm__ __volatile__( "csrxchg %[val], %[mask], %[reg]\n\t" : [val] "+r" (flags) - : [mask] "r" (CSR_CRMD_IE), [reg] "i" (LOONGARCH_CSR_CRMD) + : [mask] "r" (mask), [reg] "i" (LOONGARCH_CSR_CRMD) : "memory"); } static inline void arch_local_irq_disable(void) { u32 flags = 0; + register u32 mask asm("t0") = CSR_CRMD_IE; + __asm__ __volatile__( "csrxchg %[val], %[mask], %[reg]\n\t" : [val] "+r" (flags) - : [mask] "r" (CSR_CRMD_IE), [reg] "i" (LOONGARCH_CSR_CRMD) + : [mask] "r" (mask), [reg] "i" (LOONGARCH_CSR_CRMD) : "memory"); } static inline unsigned long arch_local_irq_save(void) { u32 flags = 0; + register u32 mask asm("t0") = CSR_CRMD_IE; + __asm__ __volatile__( "csrxchg %[val], %[mask], %[reg]\n\t" : [val] "+r" (flags) - : [mask] "r" (CSR_CRMD_IE), [reg] "i" (LOONGARCH_CSR_CRMD) + : [mask] "r" (mask), [reg] "i" (LOONGARCH_CSR_CRMD) : "memory"); return flags; } static inline void arch_local_irq_restore(unsigned long flags) { + register u32 mask asm("t0") = CSR_CRMD_IE; + __asm__ __volatile__( "csrxchg %[val], %[mask], %[reg]\n\t" : [val] "+r" (flags) - : [mask] "r" (CSR_CRMD_IE), [reg] "i" (LOONGARCH_CSR_CRMD) + : [mask] "r" (mask), [reg] "i" (LOONGARCH_CSR_CRMD) : "memory"); } From b427d98d55217b53c88643579fbbd8a4c351a105 Mon Sep 17 00:00:00 2001 From: Tianyang Zhang Date: Fri, 30 May 2025 21:45:57 +0800 Subject: [PATCH 610/971] LoongArch: Fix panic caused by NULL-PMD in huge_pte_offset() commit ee084fa96123ede8b0563a1b5a9b23adc43cd50d upstream. ERROR INFO: CPU 25 Unable to handle kernel paging request at virtual address 0x0 ... Call Trace: [<900000000023c30c>] huge_pte_offset+0x3c/0x58 [<900000000057fd4c>] hugetlb_follow_page_mask+0x74/0x438 [<900000000051fee8>] __get_user_pages+0xe0/0x4c8 [<9000000000522414>] faultin_page_range+0x84/0x380 [<9000000000564e8c>] madvise_vma_behavior+0x534/0xa48 [<900000000056689c>] do_madvise+0x1bc/0x3e8 [<9000000000566df4>] sys_madvise+0x24/0x38 [<90000000015b9e88>] do_syscall+0x78/0x98 [<9000000000221f18>] handle_syscall+0xb8/0x158 In some cases, pmd may be NULL and rely on NULL as the return value for processing, so it is necessary to determine this situation here. Cc: stable@vger.kernel.org Fixes: bd51834d1cf6 ("LoongArch: Return NULL from huge_pte_offset() for invalid PMD") Signed-off-by: Tianyang Zhang Signed-off-by: Huacai Chen Signed-off-by: Greg Kroah-Hartman --- arch/loongarch/mm/hugetlbpage.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/loongarch/mm/hugetlbpage.c b/arch/loongarch/mm/hugetlbpage.c index 41308429f446..58277fd9fb2f 100644 --- a/arch/loongarch/mm/hugetlbpage.c +++ b/arch/loongarch/mm/hugetlbpage.c @@ -47,7 +47,8 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, pmd = pmd_offset(pud, addr); } } - return pmd_none(pmdp_get(pmd)) ? NULL : (pte_t *) pmd; + + return (!pmd || pmd_none(pmdp_get(pmd))) ? NULL : (pte_t *) pmd; } int pmd_huge(pmd_t pmd) From 3f46644a5131a4793fc95c32a7d0a769745b06e7 Mon Sep 17 00:00:00 2001 From: Artem Sadovnikov Date: Fri, 7 Mar 2025 16:34:09 +0000 Subject: [PATCH 611/971] jffs2: check that raw node were preallocated before writing summary commit ec9e6f22bce433b260ea226de127ec68042849b0 upstream. Syzkaller detected a kernel bug in jffs2_link_node_ref, caused by fault injection in jffs2_prealloc_raw_node_refs. jffs2_sum_write_sumnode doesn't check return value of jffs2_prealloc_raw_node_refs and simply lets any error propagate into jffs2_sum_write_data, which eventually calls jffs2_link_node_ref in order to link the summary to an expectedly allocated node. kernel BUG at fs/jffs2/nodelist.c:592! invalid opcode: 0000 [#1] PREEMPT SMP KASAN NOPTI CPU: 1 PID: 31277 Comm: syz-executor.7 Not tainted 6.1.128-syzkaller-00139-ge10f83ca10a1 #0 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 RIP: 0010:jffs2_link_node_ref+0x570/0x690 fs/jffs2/nodelist.c:592 Call Trace: jffs2_sum_write_data fs/jffs2/summary.c:841 [inline] jffs2_sum_write_sumnode+0xd1a/0x1da0 fs/jffs2/summary.c:874 jffs2_do_reserve_space+0xa18/0xd60 fs/jffs2/nodemgmt.c:388 jffs2_reserve_space+0x55f/0xaa0 fs/jffs2/nodemgmt.c:197 jffs2_write_inode_range+0x246/0xb50 fs/jffs2/write.c:362 jffs2_write_end+0x726/0x15d0 fs/jffs2/file.c:301 generic_perform_write+0x314/0x5d0 mm/filemap.c:3856 __generic_file_write_iter+0x2ae/0x4d0 mm/filemap.c:3973 generic_file_write_iter+0xe3/0x350 mm/filemap.c:4005 call_write_iter include/linux/fs.h:2265 [inline] do_iter_readv_writev+0x20f/0x3c0 fs/read_write.c:735 do_iter_write+0x186/0x710 fs/read_write.c:861 vfs_iter_write+0x70/0xa0 fs/read_write.c:902 iter_file_splice_write+0x73b/0xc90 fs/splice.c:685 do_splice_from fs/splice.c:763 [inline] direct_splice_actor+0x10c/0x170 fs/splice.c:950 splice_direct_to_actor+0x337/0xa10 fs/splice.c:896 do_splice_direct+0x1a9/0x280 fs/splice.c:1002 do_sendfile+0xb13/0x12c0 fs/read_write.c:1255 __do_sys_sendfile64 fs/read_write.c:1323 [inline] __se_sys_sendfile64 fs/read_write.c:1309 [inline] __x64_sys_sendfile64+0x1cf/0x210 fs/read_write.c:1309 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x35/0x80 arch/x86/entry/common.c:81 entry_SYSCALL_64_after_hwframe+0x6e/0xd8 Fix this issue by checking return value of jffs2_prealloc_raw_node_refs before calling jffs2_sum_write_data. Found by Linux Verification Center (linuxtesting.org) with Syzkaller. Cc: stable@vger.kernel.org Fixes: 2f785402f39b ("[JFFS2] Reduce visibility of raw_node_ref to upper layers of JFFS2 code.") Signed-off-by: Artem Sadovnikov Reviewed-by: Zhihao Cheng Signed-off-by: Richard Weinberger Signed-off-by: Greg Kroah-Hartman --- fs/jffs2/summary.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c index 4fe64519870f..d83372d3e1a0 100644 --- a/fs/jffs2/summary.c +++ b/fs/jffs2/summary.c @@ -858,7 +858,10 @@ int jffs2_sum_write_sumnode(struct jffs2_sb_info *c) spin_unlock(&c->erase_completion_lock); jeb = c->nextblock; - jffs2_prealloc_raw_node_refs(c, jeb, 1); + ret = jffs2_prealloc_raw_node_refs(c, jeb, 1); + + if (ret) + goto out; if (!c->summary->sum_num || !c->summary->sum_list_head) { JFFS2_WARNING("Empty summary info!!!\n"); @@ -872,6 +875,8 @@ int jffs2_sum_write_sumnode(struct jffs2_sb_info *c) datasize += padsize; ret = jffs2_sum_write_data(c, jeb, infosize, datasize, padsize); + +out: spin_lock(&c->erase_completion_lock); return ret; } From cd42ddddd70abc7127c12b96c8c85dbd080ea56f Mon Sep 17 00:00:00 2001 From: Fedor Pchelkin Date: Tue, 25 Mar 2025 19:32:13 +0300 Subject: [PATCH 612/971] jffs2: check jffs2_prealloc_raw_node_refs() result in few other places commit 2b6d96503255a3ed676cd70f8368870c6d6a25c6 upstream. Fuzzing hit another invalid pointer dereference due to the lack of checking whether jffs2_prealloc_raw_node_refs() completed successfully. Subsequent logic implies that the node refs have been allocated. Handle that. The code is ready for propagating the error upwards. KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f] CPU: 1 PID: 5835 Comm: syz-executor145 Not tainted 5.10.234-syzkaller #0 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 RIP: 0010:jffs2_link_node_ref+0xac/0x690 fs/jffs2/nodelist.c:600 Call Trace: jffs2_mark_erased_block fs/jffs2/erase.c:460 [inline] jffs2_erase_pending_blocks+0x688/0x1860 fs/jffs2/erase.c:118 jffs2_garbage_collect_pass+0x638/0x1a00 fs/jffs2/gc.c:253 jffs2_reserve_space+0x3f4/0xad0 fs/jffs2/nodemgmt.c:167 jffs2_write_inode_range+0x246/0xb50 fs/jffs2/write.c:362 jffs2_write_end+0x712/0x1110 fs/jffs2/file.c:302 generic_perform_write+0x2c2/0x500 mm/filemap.c:3347 __generic_file_write_iter+0x252/0x610 mm/filemap.c:3465 generic_file_write_iter+0xdb/0x230 mm/filemap.c:3497 call_write_iter include/linux/fs.h:2039 [inline] do_iter_readv_writev+0x46d/0x750 fs/read_write.c:740 do_iter_write+0x18c/0x710 fs/read_write.c:866 vfs_writev+0x1db/0x6a0 fs/read_write.c:939 do_pwritev fs/read_write.c:1036 [inline] __do_sys_pwritev fs/read_write.c:1083 [inline] __se_sys_pwritev fs/read_write.c:1078 [inline] __x64_sys_pwritev+0x235/0x310 fs/read_write.c:1078 do_syscall_64+0x30/0x40 arch/x86/entry/common.c:46 entry_SYSCALL_64_after_hwframe+0x67/0xd1 Found by Linux Verification Center (linuxtesting.org) with Syzkaller. Fixes: 2f785402f39b ("[JFFS2] Reduce visibility of raw_node_ref to upper layers of JFFS2 code.") Fixes: f560928baa60 ("[JFFS2] Allocate node_ref for wasted space when skipping to page boundary") Cc: stable@vger.kernel.org Signed-off-by: Fedor Pchelkin Reviewed-by: Zhihao Cheng Signed-off-by: Richard Weinberger Signed-off-by: Greg Kroah-Hartman --- fs/jffs2/erase.c | 4 +++- fs/jffs2/scan.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c index ef3a1e1b6cb0..fda9f4d6093f 100644 --- a/fs/jffs2/erase.c +++ b/fs/jffs2/erase.c @@ -425,7 +425,9 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb .totlen = cpu_to_je32(c->cleanmarker_size) }; - jffs2_prealloc_raw_node_refs(c, jeb, 1); + ret = jffs2_prealloc_raw_node_refs(c, jeb, 1); + if (ret) + goto filebad; marker.hdr_crc = cpu_to_je32(crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4)); diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 29671e33a171..62879c218d4b 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c @@ -256,7 +256,9 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) jffs2_dbg(1, "%s(): Skipping %d bytes in nextblock to ensure page alignment\n", __func__, skip); - jffs2_prealloc_raw_node_refs(c, c->nextblock, 1); + ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, 1); + if (ret) + goto out; jffs2_scan_dirty_space(c, c->nextblock, skip); } #endif From b530c44e1f383ac9ba22cff241e63c5609a13fd7 Mon Sep 17 00:00:00 2001 From: Shyam Prasad N Date: Mon, 2 Jun 2025 22:37:12 +0530 Subject: [PATCH 613/971] cifs: deal with the channel loading lag while picking channels commit 66d590b828b1fd9fa337047ae58fe1c4c6f43609 upstream. Our current approach to select a channel for sending requests is this: 1. iterate all channels to find the min and max queue depth 2. if min and max are not the same, pick the channel with min depth 3. if min and max are same, round robin, as all channels are equally loaded The problem with this approach is that there's a lag between selecting a channel and sending the request (that increases the queue depth on the channel). While these numbers will eventually catch up, there could be a skew in the channel usage, depending on the application's I/O parallelism and the server's speed of handling requests. With sufficient parallelism, this lag can artificially increase the queue depth, thereby impacting the performance negatively. This change will change the step 1 above to start the iteration from the last selected channel. This is to reduce the skew in channel usage even in the presence of this lag. Fixes: ea90708d3cf3 ("cifs: use the least loaded channel for sending requests") Cc: Signed-off-by: Shyam Prasad N Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/smb/client/transport.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c index 2269963e5008..7b2560612bd6 100644 --- a/fs/smb/client/transport.c +++ b/fs/smb/client/transport.c @@ -1025,14 +1025,16 @@ struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses) uint index = 0; unsigned int min_in_flight = UINT_MAX, max_in_flight = 0; struct TCP_Server_Info *server = NULL; - int i; + int i, start, cur; if (!ses) return NULL; spin_lock(&ses->chan_lock); + start = atomic_inc_return(&ses->chan_seq); for (i = 0; i < ses->chan_count; i++) { - server = ses->chans[i].server; + cur = (start + i) % ses->chan_count; + server = ses->chans[cur].server; if (!server || server->terminate) continue; @@ -1049,17 +1051,15 @@ struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses) */ if (server->in_flight < min_in_flight) { min_in_flight = server->in_flight; - index = i; + index = cur; } if (server->in_flight > max_in_flight) max_in_flight = server->in_flight; } /* if all channels are equally loaded, fall back to round-robin */ - if (min_in_flight == max_in_flight) { - index = (uint)atomic_inc_return(&ses->chan_seq); - index %= ses->chan_count; - } + if (min_in_flight == max_in_flight) + index = (uint)start % ses->chan_count; server = ses->chans[index].server; spin_unlock(&ses->chan_lock); From 58021a32f25e1f9ccd0c93b6dbecf11c6c8955d0 Mon Sep 17 00:00:00 2001 From: Shyam Prasad N Date: Mon, 2 Jun 2025 22:37:15 +0530 Subject: [PATCH 614/971] cifs: serialize other channels when query server interfaces is pending commit b5e3e6e28cf3853566ba5d816f79aba5be579158 upstream. Today, during smb2_reconnect, session_mutex is released as soon as the tcon is reconnected and is in a good state. However, in case multichannel is enabled, there is also a query of server interfaces that follows. We've seen that this query can race with reconnects of other channels, causing them to step on each other with reconnects. This change extends the hold of session_mutex till after the query of server interfaces is complete. In order to avoid recursive smb2_reconnect checks during query ioctl, this change also introduces a session flag for sessions where such a query is in progress. Signed-off-by: Shyam Prasad N Cc: stable@vger.kernel.org Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/smb/client/cifsglob.h | 1 + fs/smb/client/smb2pdu.c | 24 ++++++++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 39117343b703..6a4ed99e162c 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -1053,6 +1053,7 @@ struct cifs_chan { }; #define CIFS_SES_FLAG_SCALE_CHANNELS (0x1) +#define CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES (0x2) /* * Session structure. One of these for each uid session with a particular host diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c index 3e88e8b3c16e..42617f30d68b 100644 --- a/fs/smb/client/smb2pdu.c +++ b/fs/smb/client/smb2pdu.c @@ -425,14 +425,19 @@ skip_sess_setup: if (!rc && (server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL) && server->ops->query_server_interfaces) { - mutex_unlock(&ses->session_mutex); - /* - * query server network interfaces, in case they change + * query server network interfaces, in case they change. + * Also mark the session as pending this update while the query + * is in progress. This will be used to avoid calling + * smb2_reconnect recursively. */ + ses->flags |= CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES; xid = get_xid(); rc = server->ops->query_server_interfaces(xid, tcon, false); free_xid(xid); + ses->flags &= ~CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES; + + mutex_unlock(&ses->session_mutex); if (rc == -EOPNOTSUPP && ses->chan_count > 1) { /* @@ -574,11 +579,18 @@ static int smb2_ioctl_req_init(u32 opcode, struct cifs_tcon *tcon, struct TCP_Server_Info *server, void **request_buf, unsigned int *total_len) { - /* Skip reconnect only for FSCTL_VALIDATE_NEGOTIATE_INFO IOCTLs */ - if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO) { + /* + * Skip reconnect in one of the following cases: + * 1. For FSCTL_VALIDATE_NEGOTIATE_INFO IOCTLs + * 2. For FSCTL_QUERY_NETWORK_INTERFACE_INFO IOCTL when called from + * smb2_reconnect (indicated by CIFS_SES_FLAG_SCALE_CHANNELS ses flag) + */ + if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO || + (opcode == FSCTL_QUERY_NETWORK_INTERFACE_INFO && + (tcon->ses->flags & CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES))) return __smb2_plain_req_init(SMB2_IOCTL, tcon, server, request_buf, total_len); - } + return smb2_plain_req_init(SMB2_IOCTL, tcon, server, request_buf, total_len); } From 202d7e838967dda02855cd925db7fd8c52c56af7 Mon Sep 17 00:00:00 2001 From: Shyam Prasad N Date: Mon, 2 Jun 2025 22:37:17 +0530 Subject: [PATCH 615/971] cifs: do not disable interface polling on failure commit 42ca547b13a20e7cbb04fbdf8d5f089ac4bb35b7 upstream. When a server has multichannel enabled, we keep polling the server for interfaces periodically. However, when this query fails, we disable the polling. This can be problematic as it takes away the chance for the server to start advertizing again. This change reschedules the delayed work, even if the current call failed. That way, multichannel sessions can recover. Signed-off-by: Shyam Prasad N Cc: stable@vger.kernel.org Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/smb/client/connect.c | 6 +----- fs/smb/client/smb2pdu.c | 9 +++++---- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c index ccf0a2c67479..ed88ec0f2533 100644 --- a/fs/smb/client/connect.c +++ b/fs/smb/client/connect.c @@ -132,13 +132,9 @@ static void smb2_query_server_interfaces(struct work_struct *work) rc = server->ops->query_server_interfaces(xid, tcon, false); free_xid(xid); - if (rc) { - if (rc == -EOPNOTSUPP) - return; - + if (rc) cifs_dbg(FYI, "%s: failed to query server interfaces: %d\n", __func__, rc); - } queue_delayed_work(cifsiod_wq, &tcon->query_interfaces, (SMB_INTERFACE_POLL_INTERVAL * HZ)); diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c index 42617f30d68b..e0f586009330 100644 --- a/fs/smb/client/smb2pdu.c +++ b/fs/smb/client/smb2pdu.c @@ -437,6 +437,10 @@ skip_sess_setup: free_xid(xid); ses->flags &= ~CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES; + /* regardless of rc value, setup polling */ + queue_delayed_work(cifsiod_wq, &tcon->query_interfaces, + (SMB_INTERFACE_POLL_INTERVAL * HZ)); + mutex_unlock(&ses->session_mutex); if (rc == -EOPNOTSUPP && ses->chan_count > 1) { @@ -457,11 +461,8 @@ skip_sess_setup: if (ses->chan_max > ses->chan_count && ses->iface_count && !SERVER_IS_CHAN(server)) { - if (ses->chan_count == 1) { + if (ses->chan_count == 1) cifs_server_dbg(VFS, "supports multichannel now\n"); - queue_delayed_work(cifsiod_wq, &tcon->query_interfaces, - (SMB_INTERFACE_POLL_INTERVAL * HZ)); - } cifs_try_adding_channels(ses); } From a504536c2923a4ac62a0889bbcb47a5f6ff14f00 Mon Sep 17 00:00:00 2001 From: Bharath SM Date: Wed, 11 Jun 2025 16:59:02 +0530 Subject: [PATCH 616/971] smb: improve directory cache reuse for readdir operations commit 72dd7961a4bb4fa1fc456169a61dd12e68e50645 upstream. Currently, cached directory contents were not reused across subsequent 'ls' operations because the cache validity check relied on comparing the ctx pointer, which changes with each readdir invocation. As a result, the cached dir entries was not marked as valid and the cache was not utilized for subsequent 'ls' operations. This change uses the file pointer, which remains consistent across all readdir calls for a given directory instance, to associate and validate the cache. As a result, cached directory contents can now be correctly reused, improving performance for repeated directory listings. Performance gains with local windows SMB server: Without the patch and default actimeo=1: 1000 directory enumeration operations on dir with 10k files took 135.0s With this patch and actimeo=0: 1000 directory enumeration operations on dir with 10k files took just 5.1s Signed-off-by: Bharath SM Reviewed-by: Shyam Prasad N Cc: stable@vger.kernel.org Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/smb/client/cached_dir.h | 8 ++++---- fs/smb/client/readdir.c | 28 +++++++++++++++------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h index 1dfe79d947a6..bc8a812ff95f 100644 --- a/fs/smb/client/cached_dir.h +++ b/fs/smb/client/cached_dir.h @@ -21,10 +21,10 @@ struct cached_dirent { struct cached_dirents { bool is_valid:1; bool is_failed:1; - struct dir_context *ctx; /* - * Only used to make sure we only take entries - * from a single context. Never dereferenced. - */ + struct file *file; /* + * Used to associate the cache with a single + * open file instance. + */ struct mutex de_mutex; int pos; /* Expected ctx->pos */ struct list_head entries; diff --git a/fs/smb/client/readdir.c b/fs/smb/client/readdir.c index e616be8196de..222348ae6258 100644 --- a/fs/smb/client/readdir.c +++ b/fs/smb/client/readdir.c @@ -850,9 +850,9 @@ static bool emit_cached_dirents(struct cached_dirents *cde, } static void update_cached_dirents_count(struct cached_dirents *cde, - struct dir_context *ctx) + struct file *file) { - if (cde->ctx != ctx) + if (cde->file != file) return; if (cde->is_valid || cde->is_failed) return; @@ -861,9 +861,9 @@ static void update_cached_dirents_count(struct cached_dirents *cde, } static void finished_cached_dirents_count(struct cached_dirents *cde, - struct dir_context *ctx) + struct dir_context *ctx, struct file *file) { - if (cde->ctx != ctx) + if (cde->file != file) return; if (cde->is_valid || cde->is_failed) return; @@ -876,11 +876,12 @@ static void finished_cached_dirents_count(struct cached_dirents *cde, static void add_cached_dirent(struct cached_dirents *cde, struct dir_context *ctx, const char *name, int namelen, - struct cifs_fattr *fattr) + struct cifs_fattr *fattr, + struct file *file) { struct cached_dirent *de; - if (cde->ctx != ctx) + if (cde->file != file) return; if (cde->is_valid || cde->is_failed) return; @@ -910,7 +911,8 @@ static void add_cached_dirent(struct cached_dirents *cde, static bool cifs_dir_emit(struct dir_context *ctx, const char *name, int namelen, struct cifs_fattr *fattr, - struct cached_fid *cfid) + struct cached_fid *cfid, + struct file *file) { bool rc; ino_t ino = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid); @@ -922,7 +924,7 @@ static bool cifs_dir_emit(struct dir_context *ctx, if (cfid) { mutex_lock(&cfid->dirents.de_mutex); add_cached_dirent(&cfid->dirents, ctx, name, namelen, - fattr); + fattr, file); mutex_unlock(&cfid->dirents.de_mutex); } @@ -1022,7 +1024,7 @@ static int cifs_filldir(char *find_entry, struct file *file, cifs_prime_dcache(file_dentry(file), &name, &fattr); return !cifs_dir_emit(ctx, name.name, name.len, - &fattr, cfid); + &fattr, cfid, file); } @@ -1073,8 +1075,8 @@ int cifs_readdir(struct file *file, struct dir_context *ctx) * we need to initialize scanning and storing the * directory content. */ - if (ctx->pos == 0 && cfid->dirents.ctx == NULL) { - cfid->dirents.ctx = ctx; + if (ctx->pos == 0 && cfid->dirents.file == NULL) { + cfid->dirents.file = file; cfid->dirents.pos = 2; } /* @@ -1142,7 +1144,7 @@ int cifs_readdir(struct file *file, struct dir_context *ctx) } else { if (cfid) { mutex_lock(&cfid->dirents.de_mutex); - finished_cached_dirents_count(&cfid->dirents, ctx); + finished_cached_dirents_count(&cfid->dirents, ctx, file); mutex_unlock(&cfid->dirents.de_mutex); } cifs_dbg(FYI, "Could not find entry\n"); @@ -1183,7 +1185,7 @@ int cifs_readdir(struct file *file, struct dir_context *ctx) ctx->pos++; if (cfid) { mutex_lock(&cfid->dirents.de_mutex); - update_cached_dirents_count(&cfid->dirents, ctx); + update_cached_dirents_count(&cfid->dirents, file); mutex_unlock(&cfid->dirents.de_mutex); } From 8d60df50e62f5e01722cb9fa0a3453fbaa8c3bc3 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Fri, 6 Jun 2025 13:57:39 -0700 Subject: [PATCH 617/971] scsi: storvsc: Increase the timeouts to storvsc_timeout commit b2f966568faaad326de97481096d0f3dc0971c43 upstream. Currently storvsc_timeout is only used in storvsc_sdev_configure(), and 5s and 10s are used elsewhere. It turns out that rarely the 5s is not enough on Azure, so let's use storvsc_timeout everywhere. In case a timeout happens and storvsc_channel_init() returns an error, close the VMBus channel so that any host-to-guest messages in the channel's ringbuffer, which might come late, can be safely ignored. Add a "const" to storvsc_timeout. Cc: stable@kernel.org Signed-off-by: Dexuan Cui Link: https://lore.kernel.org/r/1749243459-10419-1-git-send-email-decui@microsoft.com Reviewed-by: Long Li Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/storvsc_drv.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 48b0ca92b44f..954a1cc50ba7 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -362,7 +362,7 @@ MODULE_PARM_DESC(ring_avail_percent_lowater, /* * Timeout in seconds for all devices managed by this driver. */ -static int storvsc_timeout = 180; +static const int storvsc_timeout = 180; #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) static struct scsi_transport_template *fc_transport_template; @@ -768,7 +768,7 @@ static void handle_multichannel_storage(struct hv_device *device, int max_chns) return; } - t = wait_for_completion_timeout(&request->wait_event, 10*HZ); + t = wait_for_completion_timeout(&request->wait_event, storvsc_timeout * HZ); if (t == 0) { dev_err(dev, "Failed to create sub-channel: timed out\n"); return; @@ -833,7 +833,7 @@ static int storvsc_execute_vstor_op(struct hv_device *device, if (ret != 0) return ret; - t = wait_for_completion_timeout(&request->wait_event, 5*HZ); + t = wait_for_completion_timeout(&request->wait_event, storvsc_timeout * HZ); if (t == 0) return -ETIMEDOUT; @@ -1351,6 +1351,8 @@ static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size, return ret; ret = storvsc_channel_init(device, is_fc); + if (ret) + vmbus_close(device->channel); return ret; } @@ -1668,7 +1670,7 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) if (ret != 0) return FAILED; - t = wait_for_completion_timeout(&request->wait_event, 5*HZ); + t = wait_for_completion_timeout(&request->wait_event, storvsc_timeout * HZ); if (t == 0) return TIMEOUT_ERROR; From bb9d4ffff6d83c9439fdf0a52b6c4d4994812890 Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Tue, 3 Jun 2025 20:21:56 +0200 Subject: [PATCH 618/971] scsi: s390: zfcp: Ensure synchronous unit_add commit 9697ca0d53e3db357be26d2414276143c4a2cd49 upstream. Improve the usability of the unit_add sysfs attribute by ensuring that the associated FCP LUN scan processing is completed synchronously. This enables configuration tooling to consistently determine the end of the scan process to allow for serialization of follow-on actions. While the scan process associated with unit_add typically completes synchronously, it is deferred to an asynchronous background process if unit_add is used before initial remote port scanning has completed. This occurs when unit_add is used immediately after setting the associated FCP device online. To ensure synchronous unit_add processing, wait for remote port scanning to complete before initiating the FCP LUN scan. Cc: stable@vger.kernel.org Reviewed-by: M Nikhil Reviewed-by: Nihar Panda Signed-off-by: Peter Oberparleiter Signed-off-by: Nihar Panda Link: https://lore.kernel.org/r/20250603182252.2287285-2-niharp@linux.ibm.com Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/s390/scsi/zfcp_sysfs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index cb67fa80fb12..a95da6768f66 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c @@ -450,6 +450,8 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev, if (kstrtoull(buf, 0, (unsigned long long *) &fcp_lun)) return -EINVAL; + flush_work(&port->rport_work); + retval = zfcp_unit_add(port, fcp_lun); if (retval) return retval; From 0357da9149eac621f39e235a135ebf155f01f7c3 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 11 Jun 2025 08:35:01 +0000 Subject: [PATCH 619/971] net_sched: sch_sfq: reject invalid perturb period commit 7ca52541c05c832d32b112274f81a985101f9ba8 upstream. Gerrard Tai reported that SFQ perturb_period has no range check yet, and this can be used to trigger a race condition fixed in a separate patch. We want to make sure ctl->perturb_period * HZ will not overflow and is positive. Tested: tc qd add dev lo root sfq perturb -10 # negative value : error Error: sch_sfq: invalid perturb period. tc qd add dev lo root sfq perturb 1000000000 # too big : error Error: sch_sfq: invalid perturb period. tc qd add dev lo root sfq perturb 2000000 # acceptable value tc -s -d qd sh dev lo qdisc sfq 8005: root refcnt 2 limit 127p quantum 64Kb depth 127 flows 128 divisor 1024 perturb 2000000sec Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) backlog 0b 0p requeues 0 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: Gerrard Tai Signed-off-by: Eric Dumazet Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20250611083501.1810459-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/sched/sch_sfq.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index d564675a8be4..e871cb53946a 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -656,6 +656,14 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt, NL_SET_ERR_MSG_MOD(extack, "invalid quantum"); return -EINVAL; } + + if (ctl->perturb_period < 0 || + ctl->perturb_period > INT_MAX / HZ) { + NL_SET_ERR_MSG_MOD(extack, "invalid perturb period"); + return -EINVAL; + } + perturb_period = ctl->perturb_period * HZ; + if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max, ctl_v1->Wlog, ctl_v1->Scell_log, NULL)) return -EINVAL; @@ -672,14 +680,12 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt, headdrop = q->headdrop; maxdepth = q->maxdepth; maxflows = q->maxflows; - perturb_period = q->perturb_period; quantum = q->quantum; flags = q->flags; /* update and validate configuration */ if (ctl->quantum) quantum = ctl->quantum; - perturb_period = ctl->perturb_period * HZ; if (ctl->flows) maxflows = min_t(u32, ctl->flows, SFQ_MAX_FLOWS); if (ctl->divisor) { From bfa4d86e130a09f67607482e988313430e38f6c4 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Mon, 9 Jun 2025 17:12:44 -0700 Subject: [PATCH 620/971] net: clear the dst when changing skb protocol MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit ba9db6f907ac02215e30128770f85fbd7db2fcf9 upstream. A not-so-careful NAT46 BPF program can crash the kernel if it indiscriminately flips ingress packets from v4 to v6: BUG: kernel NULL pointer dereference, address: 0000000000000000 ip6_rcv_core (net/ipv6/ip6_input.c:190:20) ipv6_rcv (net/ipv6/ip6_input.c:306:8) process_backlog (net/core/dev.c:6186:4) napi_poll (net/core/dev.c:6906:9) net_rx_action (net/core/dev.c:7028:13) do_softirq (kernel/softirq.c:462:3) netif_rx (net/core/dev.c:5326:3) dev_loopback_xmit (net/core/dev.c:4015:2) ip_mc_finish_output (net/ipv4/ip_output.c:363:8) NF_HOOK (./include/linux/netfilter.h:314:9) ip_mc_output (net/ipv4/ip_output.c:400:5) dst_output (./include/net/dst.h:459:9) ip_local_out (net/ipv4/ip_output.c:130:9) ip_send_skb (net/ipv4/ip_output.c:1496:8) udp_send_skb (net/ipv4/udp.c:1040:8) udp_sendmsg (net/ipv4/udp.c:1328:10) The output interface has a 4->6 program attached at ingress. We try to loop the multicast skb back to the sending socket. Ingress BPF runs as part of netif_rx(), pushes a valid v6 hdr and changes skb->protocol to v6. We enter ip6_rcv_core which tries to use skb_dst(). But the dst is still an IPv4 one left after IPv4 mcast output. Clear the dst in all BPF helpers which change the protocol. Try to preserve metadata dsts, those may carry non-routing metadata. Cc: stable@vger.kernel.org Reviewed-by: Maciej Żenczykowski Acked-by: Daniel Borkmann Fixes: d219df60a70e ("bpf: Add ipip6 and ip6ip decap support for bpf_skb_adjust_room()") Fixes: 1b00e0dfe7d0 ("bpf: update skb->protocol in bpf_skb_net_grow") Fixes: 6578171a7ff0 ("bpf: add bpf_skb_change_proto helper") Reviewed-by: Willem de Bruijn Link: https://patch.msgid.link/20250610001245.1981782-1-kuba@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/core/filter.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index 5143c8a9e52c..b020cbddb2b3 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3229,6 +3229,13 @@ static const struct bpf_func_proto bpf_skb_vlan_pop_proto = { .arg1_type = ARG_PTR_TO_CTX, }; +static void bpf_skb_change_protocol(struct sk_buff *skb, u16 proto) +{ + skb->protocol = htons(proto); + if (skb_valid_dst(skb)) + skb_dst_drop(skb); +} + static int bpf_skb_generic_push(struct sk_buff *skb, u32 off, u32 len) { /* Caller already did skb_cow() with len as headroom, @@ -3325,7 +3332,7 @@ static int bpf_skb_proto_4_to_6(struct sk_buff *skb) } } - skb->protocol = htons(ETH_P_IPV6); + bpf_skb_change_protocol(skb, ETH_P_IPV6); skb_clear_hash(skb); return 0; @@ -3355,7 +3362,7 @@ static int bpf_skb_proto_6_to_4(struct sk_buff *skb) } } - skb->protocol = htons(ETH_P_IP); + bpf_skb_change_protocol(skb, ETH_P_IP); skb_clear_hash(skb); return 0; @@ -3546,10 +3553,10 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff, /* Match skb->protocol to new outer l3 protocol */ if (skb->protocol == htons(ETH_P_IP) && flags & BPF_F_ADJ_ROOM_ENCAP_L3_IPV6) - skb->protocol = htons(ETH_P_IPV6); + bpf_skb_change_protocol(skb, ETH_P_IPV6); else if (skb->protocol == htons(ETH_P_IPV6) && flags & BPF_F_ADJ_ROOM_ENCAP_L3_IPV4) - skb->protocol = htons(ETH_P_IP); + bpf_skb_change_protocol(skb, ETH_P_IP); } if (skb_is_gso(skb)) { @@ -3602,10 +3609,10 @@ static int bpf_skb_net_shrink(struct sk_buff *skb, u32 off, u32 len_diff, /* Match skb->protocol to new outer l3 protocol */ if (skb->protocol == htons(ETH_P_IP) && flags & BPF_F_ADJ_ROOM_DECAP_L3_IPV6) - skb->protocol = htons(ETH_P_IPV6); + bpf_skb_change_protocol(skb, ETH_P_IPV6); else if (skb->protocol == htons(ETH_P_IPV6) && flags & BPF_F_ADJ_ROOM_DECAP_L3_IPV4) - skb->protocol = htons(ETH_P_IP); + bpf_skb_change_protocol(skb, ETH_P_IP); if (skb_is_gso(skb)) { struct skb_shared_info *shinfo = skb_shinfo(skb); From 372b511e934575d04e091c880011ebc183bdf779 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 7 May 2025 18:09:12 +0200 Subject: [PATCH 621/971] udmabuf: use sgtable-based scatterlist wrappers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit afe382843717d44b24ef5014d57dcbaab75a4052 upstream. Use common wrappers operating directly on the struct sg_table objects to fix incorrect use of scatterlists sync calls. dma_sync_sg_for_*() functions have to be called with the number of elements originally passed to dma_map_sg_*() function, not the one returned in sgtable's nents. Fixes: 1ffe09590121 ("udmabuf: fix dma-buf cpu access") CC: stable@vger.kernel.org Signed-off-by: Marek Szyprowski Acked-by: Vivek Kasireddy Reviewed-by: Christian König Signed-off-by: Christian König Link: https://lore.kernel.org/r/20250507160913.2084079-3-m.szyprowski@samsung.com Signed-off-by: Greg Kroah-Hartman --- drivers/dma-buf/udmabuf.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index 373282beeb60..980975ffc55d 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -161,8 +161,7 @@ static int begin_cpu_udmabuf(struct dma_buf *buf, ubuf->sg = NULL; } } else { - dma_sync_sg_for_cpu(dev, ubuf->sg->sgl, ubuf->sg->nents, - direction); + dma_sync_sgtable_for_cpu(dev, ubuf->sg, direction); } return ret; @@ -177,7 +176,7 @@ static int end_cpu_udmabuf(struct dma_buf *buf, if (!ubuf->sg) return -EINVAL; - dma_sync_sg_for_device(dev, ubuf->sg->sgl, ubuf->sg->nents, direction); + dma_sync_sgtable_for_device(dev, ubuf->sg, direction); return 0; } From 2a03531c00b22aa0f9bf985620072b76df4c46fd Mon Sep 17 00:00:00 2001 From: "Xin Li (Intel)" Date: Mon, 9 Jun 2025 01:40:54 -0700 Subject: [PATCH 622/971] selftests/x86: Add a test to detect infinite SIGTRAP handler loop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit f287822688eeb44ae1cf6ac45701d965efc33218 upstream. When FRED is enabled, if the Trap Flag (TF) is set without an external debugger attached, it can lead to an infinite loop in the SIGTRAP handler. To avoid this, the software event flag in the augmented SS must be cleared, ensuring that no single-step trap remains pending when ERETU completes. This test checks for that specific scenario—verifying whether the kernel correctly prevents an infinite SIGTRAP loop in this edge case when FRED is enabled. The test should _always_ pass with IDT event delivery, thus no need to disable the test even when FRED is not enabled. Signed-off-by: Xin Li (Intel) Signed-off-by: Dave Hansen Tested-by: Sohil Mehta Cc:stable@vger.kernel.org Link: https://lore.kernel.org/all/20250609084054.2083189-3-xin%40zytor.com Signed-off-by: Greg Kroah-Hartman --- tools/testing/selftests/x86/Makefile | 2 +- tools/testing/selftests/x86/sigtrap_loop.c | 101 +++++++++++++++++++++ 2 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/x86/sigtrap_loop.c diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index 7e8c937627dd..13ce9a53d5de 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile @@ -12,7 +12,7 @@ CAN_BUILD_WITH_NOPIE := $(shell ./check_cc.sh "$(CC)" trivial_program.c -no-pie) TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt test_mremap_vdso \ check_initial_reg_state sigreturn iopl ioperm \ - test_vsyscall mov_ss_trap \ + test_vsyscall mov_ss_trap sigtrap_loop \ syscall_arg_fault fsgsbase_restore sigaltstack TARGETS_C_32BIT_ONLY := entry_from_vm86 test_syscall_vdso unwind_vdso \ test_FCMOV test_FCOMI test_FISTTP \ diff --git a/tools/testing/selftests/x86/sigtrap_loop.c b/tools/testing/selftests/x86/sigtrap_loop.c new file mode 100644 index 000000000000..9d065479e89f --- /dev/null +++ b/tools/testing/selftests/x86/sigtrap_loop.c @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 Intel Corporation + */ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include + +#ifdef __x86_64__ +# define REG_IP REG_RIP +#else +# define REG_IP REG_EIP +#endif + +static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), int flags) +{ + struct sigaction sa; + + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = handler; + sa.sa_flags = SA_SIGINFO | flags; + sigemptyset(&sa.sa_mask); + + if (sigaction(sig, &sa, 0)) + err(1, "sigaction"); + + return; +} + +static void sigtrap(int sig, siginfo_t *info, void *ctx_void) +{ + ucontext_t *ctx = (ucontext_t *)ctx_void; + static unsigned int loop_count_on_same_ip; + static unsigned long last_trap_ip; + + if (last_trap_ip == ctx->uc_mcontext.gregs[REG_IP]) { + printf("\tTrapped at %016lx\n", last_trap_ip); + + /* + * If the same IP is hit more than 10 times in a row, it is + * _considered_ an infinite loop. + */ + if (++loop_count_on_same_ip > 10) { + printf("[FAIL]\tDetected SIGTRAP infinite loop\n"); + exit(1); + } + + return; + } + + loop_count_on_same_ip = 0; + last_trap_ip = ctx->uc_mcontext.gregs[REG_IP]; + printf("\tTrapped at %016lx\n", last_trap_ip); +} + +int main(int argc, char *argv[]) +{ + sethandler(SIGTRAP, sigtrap, 0); + + /* + * Set the Trap Flag (TF) to single-step the test code, therefore to + * trigger a SIGTRAP signal after each instruction until the TF is + * cleared. + * + * Because the arithmetic flags are not significant here, the TF is + * set by pushing 0x302 onto the stack and then popping it into the + * flags register. + * + * Four instructions in the following asm code are executed with the + * TF set, thus the SIGTRAP handler is expected to run four times. + */ + printf("[RUN]\tSIGTRAP infinite loop detection\n"); + asm volatile( +#ifdef __x86_64__ + /* + * Avoid clobbering the redzone + * + * Equivalent to "sub $128, %rsp", however -128 can be encoded + * in a single byte immediate while 128 uses 4 bytes. + */ + "add $-128, %rsp\n\t" +#endif + "push $0x302\n\t" + "popf\n\t" + "nop\n\t" + "nop\n\t" + "push $0x202\n\t" + "popf\n\t" +#ifdef __x86_64__ + "sub $-128, %rsp\n\t" +#endif + ); + + printf("[OK]\tNo SIGTRAP infinite loop detected\n"); + return 0; +} From 0902625a24eea7fdc187faa5d97df244d159dd6e Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Fri, 13 Jun 2025 10:12:43 +0900 Subject: [PATCH 623/971] ksmbd: fix null pointer dereference in destroy_previous_session commit 7ac5b66acafcc9292fb935d7e03790f2b8b2dc0e upstream. If client set ->PreviousSessionId on kerberos session setup stage, NULL pointer dereference error will happen. Since sess->user is not set yet, It can pass the user argument as NULL to destroy_previous_session. sess->user will be set in ksmbd_krb5_authenticate(). So this patch move calling destroy_previous_session() after ksmbd_krb5_authenticate(). Cc: stable@vger.kernel.org Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-27391 Signed-off-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/smb/server/smb2pdu.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 9bd817427a34..d8325504a162 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -1599,17 +1599,18 @@ static int krb5_authenticate(struct ksmbd_work *work, out_len = work->response_sz - (le16_to_cpu(rsp->SecurityBufferOffset) + 4); - /* Check previous session */ - prev_sess_id = le64_to_cpu(req->PreviousSessionId); - if (prev_sess_id && prev_sess_id != sess->id) - destroy_previous_session(conn, sess->user, prev_sess_id); - retval = ksmbd_krb5_authenticate(sess, in_blob, in_len, out_blob, &out_len); if (retval) { ksmbd_debug(SMB, "krb5 authentication failed\n"); return -EINVAL; } + + /* Check previous session */ + prev_sess_id = le64_to_cpu(req->PreviousSessionId); + if (prev_sess_id && prev_sess_id != sess->id) + destroy_previous_session(conn, sess->user, prev_sess_id); + rsp->SecurityBufferLength = cpu_to_le16(out_len); if ((conn->sign || server_conf.enforced_signing) || From 2753481c40af6feb897944369dd1279d7e2596d5 Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Fri, 13 Jun 2025 15:37:05 -0400 Subject: [PATCH 624/971] selinux: fix selinux_xfrm_alloc_user() to set correct ctx_len MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 86c8db86af43f52f682e53a0f2f0828683be1e52 upstream. We should count the terminating NUL byte as part of the ctx_len. Otherwise, UBSAN logs a warning: UBSAN: array-index-out-of-bounds in security/selinux/xfrm.c:99:14 index 60 is out of range for type 'char [*]' The allocation itself is correct so there is no actual out of bounds indexing, just a warning. Cc: stable@vger.kernel.org Suggested-by: Christian Göttsche Link: https://lore.kernel.org/selinux/CAEjxPJ6tA5+LxsGfOJokzdPeRomBHjKLBVR6zbrg+_w3ZZbM3A@mail.gmail.com/ Signed-off-by: Stephen Smalley Signed-off-by: Paul Moore Signed-off-by: Greg Kroah-Hartman --- security/selinux/xfrm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index 95fcd2d3433e..0fbbc62ed3ed 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c @@ -95,7 +95,7 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp, ctx->ctx_doi = XFRM_SC_DOI_LSM; ctx->ctx_alg = XFRM_SC_ALG_SELINUX; - ctx->ctx_len = str_len; + ctx->ctx_len = str_len + 1; memcpy(ctx->ctx_str, &uctx[1], str_len); ctx->ctx_str[str_len] = '\0'; rc = security_context_to_sid(ctx->ctx_str, str_len, From c1a2081f0347f2978f45588dc5b48ce991e00084 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Fri, 6 Jun 2025 13:53:00 -0700 Subject: [PATCH 625/971] platform/x86/intel-uncore-freq: Fail module load when plat_info is NULL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 685f88c72a0c4d12d3bd2ff50286938f14486f85 upstream. Address a Smatch static checker warning regarding an unchecked dereference in the function call: set_cdie_id(i, cluster_info, plat_info) when plat_info is NULL. Instead of addressing this one case, in general if plat_info is NULL then it can cause other issues. For example in a two package system it will give warning for duplicate sysfs entry as package ID will be always zero for both packages when creating string for attribute group name. plat_info is derived from TPMI ID TPMI_BUS_INFO, which is integral to the core TPMI design. Therefore, it should not be NULL on a production platform. Consequently, the module should fail to load if plat_info is NULL. Reported-by: Dan Carpenter Closes: https://lore.kernel.org/platform-driver-x86/aEKvGCLd1qmX04Tc@stanley.mountain/T/#u Fixes: 8a54e2253e4c ("platform/x86/intel-uncore-freq: Uncore frequency control via TPMI") Signed-off-by: Srinivas Pandruvada Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20250606205300.2384494-1-srinivas.pandruvada@linux.intel.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Greg Kroah-Hartman --- .../x86/intel/uncore-frequency/uncore-frequency-tpmi.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c index 105022164548..5be3b2687615 100644 --- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c +++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c @@ -269,10 +269,13 @@ static int uncore_probe(struct auxiliary_device *auxdev, const struct auxiliary_ /* Get the package ID from the TPMI core */ plat_info = tpmi_get_platform_data(auxdev); - if (plat_info) - pkg = plat_info->package_id; - else + if (unlikely(!plat_info)) { dev_info(&auxdev->dev, "Platform information is NULL\n"); + ret = -ENODEV; + goto err_rem_common; + } + + pkg = plat_info->package_id; for (i = 0; i < num_resources; ++i) { struct tpmi_uncore_power_domain_info *pd_info; From 3902205eadf35db59dbc2186c2a98b9e6182efa5 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Mon, 16 Jun 2025 11:21:15 -0700 Subject: [PATCH 626/971] atm: Revert atm_account_tx() if copy_from_iter_full() fails. commit 7851263998d4269125fd6cb3fdbfc7c6db853859 upstream. In vcc_sendmsg(), we account skb->truesize to sk->sk_wmem_alloc by atm_account_tx(). It is expected to be reverted by atm_pop_raw() later called by vcc->dev->ops->send(vcc, skb). However, vcc_sendmsg() misses the same revert when copy_from_iter_full() fails, and then we will leak a socket. Let's factorise the revert part as atm_return_tx() and call it in the failure path. Note that the corresponding sk_wmem_alloc operation can be found in alloc_tx() as of the blamed commit. $ git blame -L:alloc_tx net/atm/common.c c55fa3cccbc2c~ Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: Simon Horman Closes: https://lore.kernel.org/netdev/20250614161959.GR414686@horms.kernel.org/ Signed-off-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20250616182147.963333-3-kuni1840@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- include/linux/atmdev.h | 6 ++++++ net/atm/common.c | 1 + net/atm/raw.c | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h index 9b02961d65ee..45f2f278b50a 100644 --- a/include/linux/atmdev.h +++ b/include/linux/atmdev.h @@ -249,6 +249,12 @@ static inline void atm_account_tx(struct atm_vcc *vcc, struct sk_buff *skb) ATM_SKB(skb)->atm_options = vcc->atm_options; } +static inline void atm_return_tx(struct atm_vcc *vcc, struct sk_buff *skb) +{ + WARN_ON_ONCE(refcount_sub_and_test(ATM_SKB(skb)->acct_truesize, + &sk_atm(vcc)->sk_wmem_alloc)); +} + static inline void atm_force_charge(struct atm_vcc *vcc,int truesize) { atomic_add(truesize, &sk_atm(vcc)->sk_rmem_alloc); diff --git a/net/atm/common.c b/net/atm/common.c index f7019df41c3e..9cc82acbc735 100644 --- a/net/atm/common.c +++ b/net/atm/common.c @@ -635,6 +635,7 @@ int vcc_sendmsg(struct socket *sock, struct msghdr *m, size_t size) skb->dev = NULL; /* for paths shared with net_device interfaces */ if (!copy_from_iter_full(skb_put(skb, size), size, &m->msg_iter)) { + atm_return_tx(vcc, skb); kfree_skb(skb); error = -EFAULT; goto out; diff --git a/net/atm/raw.c b/net/atm/raw.c index 2b5f78a7ec3e..1e6511ec842c 100644 --- a/net/atm/raw.c +++ b/net/atm/raw.c @@ -36,7 +36,7 @@ static void atm_pop_raw(struct atm_vcc *vcc, struct sk_buff *skb) pr_debug("(%d) %d -= %d\n", vcc->vci, sk_wmem_alloc_get(sk), ATM_SKB(skb)->acct_truesize); - WARN_ON(refcount_sub_and_test(ATM_SKB(skb)->acct_truesize, &sk->sk_wmem_alloc)); + atm_return_tx(vcc, skb); dev_kfree_skb_any(skb); sk->sk_write_space(sk); } From 6d60d822809be3db14b1fe609d802a80a79be14e Mon Sep 17 00:00:00 2001 From: WangYuli Date: Fri, 18 Apr 2025 18:37:18 -0700 Subject: [PATCH 627/971] Input: sparcspkr - avoid unannotated fall-through commit 8b1d858cbd4e1800e9336404ba7892b5a721230d upstream. Fix follow warnings with clang-21i (and reformat for clarity): drivers/input/misc/sparcspkr.c:78:3: warning: unannotated fall-through between switch labels [-Wimplicit-fallthrough] 78 | case SND_TONE: break; | ^ drivers/input/misc/sparcspkr.c:78:3: note: insert 'break;' to avoid fall-through 78 | case SND_TONE: break; | ^ | break; drivers/input/misc/sparcspkr.c:113:3: warning: unannotated fall-through between switch labels [-Wimplicit-fallthrough] 113 | case SND_TONE: break; | ^ drivers/input/misc/sparcspkr.c:113:3: note: insert 'break;' to avoid fall-through 113 | case SND_TONE: break; | ^ | break; 2 warnings generated. Signed-off-by: WangYuli Link: https://lore.kernel.org/r/6730E40353C76908+20250415052439.155051-1-wangyuli@uniontech.com Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/misc/sparcspkr.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index e5dd84725c6e..d715fd736426 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c @@ -75,9 +75,14 @@ static int bbc_spkr_event(struct input_dev *dev, unsigned int type, unsigned int return -1; switch (code) { - case SND_BELL: if (value) value = 1000; - case SND_TONE: break; - default: return -1; + case SND_BELL: + if (value) + value = 1000; + break; + case SND_TONE: + break; + default: + return -1; } if (value > 20 && value < 32767) @@ -113,9 +118,14 @@ static int grover_spkr_event(struct input_dev *dev, unsigned int type, unsigned return -1; switch (code) { - case SND_BELL: if (value) value = 1000; - case SND_TONE: break; - default: return -1; + case SND_BELL: + if (value) + value = 1000; + break; + case SND_TONE: + break; + default: + return -1; } if (value > 20 && value < 32767) From eeacfbab984200dcdcd68fcf4c6e91e2c6b38792 Mon Sep 17 00:00:00 2001 From: Edward Adam Davis Date: Tue, 18 Mar 2025 11:13:45 +0800 Subject: [PATCH 628/971] wifi: cfg80211: init wiphy_work before allocating rfkill fails commit fc88dee89d7b63eeb17699393eb659aadf9d9b7c upstream. syzbort reported a uninitialize wiphy_work_lock in cfg80211_dev_free. [1] After rfkill allocation fails, the wiphy release process will be performed, which will cause cfg80211_dev_free to access the uninitialized wiphy_work related data. Move the initialization of wiphy_work to before rfkill initialization to avoid this issue. [1] INFO: trying to register non-static key. The code is fine but needs lockdep annotation, or maybe you didn't initialize this object before use? turning off the locking correctness validator. CPU: 0 UID: 0 PID: 5935 Comm: syz-executor550 Not tainted 6.14.0-rc6-syzkaller-00103-g4003c9e78778 #0 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 Call Trace: __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x116/0x1f0 lib/dump_stack.c:120 assign_lock_key kernel/locking/lockdep.c:983 [inline] register_lock_class+0xc39/0x1240 kernel/locking/lockdep.c:1297 __lock_acquire+0x135/0x3c40 kernel/locking/lockdep.c:5103 lock_acquire.part.0+0x11b/0x380 kernel/locking/lockdep.c:5851 __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline] _raw_spin_lock_irqsave+0x3a/0x60 kernel/locking/spinlock.c:162 cfg80211_dev_free+0x30/0x3d0 net/wireless/core.c:1196 device_release+0xa1/0x240 drivers/base/core.c:2568 kobject_cleanup lib/kobject.c:689 [inline] kobject_release lib/kobject.c:720 [inline] kref_put include/linux/kref.h:65 [inline] kobject_put+0x1e4/0x5a0 lib/kobject.c:737 put_device+0x1f/0x30 drivers/base/core.c:3774 wiphy_free net/wireless/core.c:1224 [inline] wiphy_new_nm+0x1c1f/0x2160 net/wireless/core.c:562 ieee80211_alloc_hw_nm+0x1b7a/0x2260 net/mac80211/main.c:835 mac80211_hwsim_new_radio+0x1d6/0x54e0 drivers/net/wireless/virtual/mac80211_hwsim.c:5185 hwsim_new_radio_nl+0xb42/0x12b0 drivers/net/wireless/virtual/mac80211_hwsim.c:6242 genl_family_rcv_msg_doit+0x202/0x2f0 net/netlink/genetlink.c:1115 genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline] genl_rcv_msg+0x565/0x800 net/netlink/genetlink.c:1210 netlink_rcv_skb+0x16b/0x440 net/netlink/af_netlink.c:2533 genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219 netlink_unicast_kernel net/netlink/af_netlink.c:1312 [inline] netlink_unicast+0x53c/0x7f0 net/netlink/af_netlink.c:1338 netlink_sendmsg+0x8b8/0xd70 net/netlink/af_netlink.c:1882 sock_sendmsg_nosec net/socket.c:718 [inline] __sock_sendmsg net/socket.c:733 [inline] ____sys_sendmsg+0xaaf/0xc90 net/socket.c:2573 ___sys_sendmsg+0x135/0x1e0 net/socket.c:2627 __sys_sendmsg+0x16e/0x220 net/socket.c:2659 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcd/0x250 arch/x86/entry/common.c:83 Fixes: 72d520476a2f ("wifi: cfg80211: cancel wiphy_work before freeing wiphy") Reported-by: syzbot+aaf0488c83d1d5f4f029@syzkaller.appspotmail.com Close: https://syzkaller.appspot.com/bug?extid=aaf0488c83d1d5f4f029 Tested-by: syzbot+aaf0488c83d1d5f4f029@syzkaller.appspotmail.com Signed-off-by: Edward Adam Davis Link: https://patch.msgid.link/tencent_258DD9121DDDB9DD9A1939CFAA0D8625B107@qq.com Signed-off-by: Johannes Berg Signed-off-by: WangYuli Signed-off-by: Greg Kroah-Hartman --- net/wireless/core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/wireless/core.c b/net/wireless/core.c index a2b15349324b..f6693983b5e9 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -550,6 +550,9 @@ use_default_name: INIT_WORK(&rdev->mgmt_registrations_update_wk, cfg80211_mgmt_registrations_update_wk); spin_lock_init(&rdev->mgmt_registrations_lock); + INIT_WORK(&rdev->wiphy_work, cfg80211_wiphy_work); + INIT_LIST_HEAD(&rdev->wiphy_work_list); + spin_lock_init(&rdev->wiphy_work_lock); #ifdef CONFIG_CFG80211_DEFAULT_PS rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; @@ -567,9 +570,6 @@ use_default_name: return NULL; } - INIT_WORK(&rdev->wiphy_work, cfg80211_wiphy_work); - INIT_LIST_HEAD(&rdev->wiphy_work_list); - spin_lock_init(&rdev->wiphy_work_lock); INIT_WORK(&rdev->rfkill_block, cfg80211_rfkill_block_work); INIT_WORK(&rdev->conn_work, cfg80211_conn_work); INIT_WORK(&rdev->event_work, cfg80211_event_work); From 66bde385a1d3c514b1268c859b1cd0bc765068c1 Mon Sep 17 00:00:00 2001 From: Chin-Yen Lee Date: Wed, 3 Jan 2024 09:23:46 +0800 Subject: [PATCH 629/971] wifi: rtw89: pci: use DBI function for 8852AE/8852BE/8851BE commit 9496d62f3877bc0f97b415bc04af98d092878026 upstream. Sometimes driver can't use kernel API pci_read/write_config_byte to access the PCI config space of above address 0x100 due to the negotiated PCI setting. 8852AE/8852BE/8851BE provide another way called DBI function, which belongs to WiFi mac and could access all PCI config space for this case. Link: https://lore.kernel.org/linux-wireless/79fe81b7db7148b9a7da2353c16d70fb@realtek.com/T/#t Signed-off-by: Chin-Yen Lee Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://msgid.link/20240103012346.6822-1-pkshih@realtek.com Signed-off-by: Zenm Chen Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/realtek/rtw89/pci.c | 69 +++++++++++++++++++++++- drivers/net/wireless/realtek/rtw89/pci.h | 1 + 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 30cc6e03c355..33b2543ee4d2 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -1822,22 +1822,87 @@ static int rtw89_write16_mdio_clr(struct rtw89_dev *rtwdev, u8 addr, u16 mask, u return 0; } +static int rtw89_dbi_write8(struct rtw89_dev *rtwdev, u16 addr, u8 data) +{ + u16 addr_2lsb = addr & B_AX_DBI_2LSB; + u16 write_addr; + u8 flag; + int ret; + + write_addr = addr & B_AX_DBI_ADDR_MSK; + write_addr |= u16_encode_bits(BIT(addr_2lsb), B_AX_DBI_WREN_MSK); + rtw89_write8(rtwdev, R_AX_DBI_WDATA + addr_2lsb, data); + rtw89_write16(rtwdev, R_AX_DBI_FLAG, write_addr); + rtw89_write8(rtwdev, R_AX_DBI_FLAG + 2, B_AX_DBI_WFLAG >> 16); + + ret = read_poll_timeout_atomic(rtw89_read8, flag, !flag, 10, + 10 * RTW89_PCI_WR_RETRY_CNT, false, + rtwdev, R_AX_DBI_FLAG + 2); + if (ret) + rtw89_err(rtwdev, "failed to write DBI register, addr=0x%X\n", + addr); + + return ret; +} + +static int rtw89_dbi_read8(struct rtw89_dev *rtwdev, u16 addr, u8 *value) +{ + u16 read_addr = addr & B_AX_DBI_ADDR_MSK; + u8 flag; + int ret; + + rtw89_write16(rtwdev, R_AX_DBI_FLAG, read_addr); + rtw89_write8(rtwdev, R_AX_DBI_FLAG + 2, B_AX_DBI_RFLAG >> 16); + + ret = read_poll_timeout_atomic(rtw89_read8, flag, !flag, 10, + 10 * RTW89_PCI_WR_RETRY_CNT, false, + rtwdev, R_AX_DBI_FLAG + 2); + if (ret) { + rtw89_err(rtwdev, "failed to read DBI register, addr=0x%X\n", + addr); + return ret; + } + + read_addr = R_AX_DBI_RDATA + (addr & 3); + *value = rtw89_read8(rtwdev, read_addr); + + return 0; +} + static int rtw89_pci_write_config_byte(struct rtw89_dev *rtwdev, u16 addr, u8 data) { struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; struct pci_dev *pdev = rtwpci->pdev; + int ret; - return pci_write_config_byte(pdev, addr, data); + ret = pci_write_config_byte(pdev, addr, data); + if (!ret) + return 0; + + if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) + ret = rtw89_dbi_write8(rtwdev, addr, data); + + return ret; } static int rtw89_pci_read_config_byte(struct rtw89_dev *rtwdev, u16 addr, u8 *value) { struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; struct pci_dev *pdev = rtwpci->pdev; + int ret; - return pci_read_config_byte(pdev, addr, value); + ret = pci_read_config_byte(pdev, addr, value); + if (!ret) + return 0; + + if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) + ret = rtw89_dbi_read8(rtwdev, addr, value); + + return ret; } static int rtw89_pci_config_byte_set(struct rtw89_dev *rtwdev, u16 addr, diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h index 4259b79b138f..119c0608b91a 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.h +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -42,6 +42,7 @@ #define B_AX_DBI_WFLAG BIT(16) #define B_AX_DBI_WREN_MSK GENMASK(15, 12) #define B_AX_DBI_ADDR_MSK GENMASK(11, 2) +#define B_AX_DBI_2LSB GENMASK(1, 0) #define R_AX_DBI_WDATA 0x1094 #define R_AX_DBI_RDATA 0x1098 From 6562806f3200bd9008d5300eabbda5c08a4b0a0c Mon Sep 17 00:00:00 2001 From: Dev Jain Date: Tue, 27 May 2025 13:56:33 +0530 Subject: [PATCH 630/971] arm64: Restrict pagetable teardown to avoid false warning commit 650768c512faba8070bf4cfbb28c95eb5cd203f3 upstream. Commit 9c006972c3fe ("arm64: mmu: drop pXd_present() checks from pXd_free_pYd_table()") removes the pxd_present() checks because the caller checks pxd_present(). But, in case of vmap_try_huge_pud(), the caller only checks pud_present(); pud_free_pmd_page() recurses on each pmd through pmd_free_pte_page(), wherein the pmd may be none. Thus it is possible to hit a warning in the latter, since pmd_none => !pmd_table(). Thus, add a pmd_present() check in pud_free_pmd_page(). This problem was found by code inspection. Fixes: 9c006972c3fe ("arm64: mmu: drop pXd_present() checks from pXd_free_pYd_table()") Cc: stable@vger.kernel.org Reported-by: Ryan Roberts Acked-by: David Hildenbrand Signed-off-by: Dev Jain Reviewed-by: Catalin Marinas Reviewed-by: Anshuman Khandual Reviewed-by: Ryan Roberts Link: https://lore.kernel.org/r/20250527082633.61073-1-dev.jain@arm.com Signed-off-by: Will Deacon Signed-off-by: Greg Kroah-Hartman --- arch/arm64/mm/mmu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index bc97916a035a..c8e83fe1cd5a 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -1253,7 +1253,8 @@ int pud_free_pmd_page(pud_t *pudp, unsigned long addr) next = addr; end = addr + PUD_SIZE; do { - pmd_free_pte_page(pmdp, next); + if (pmd_present(pmdp_get(pmdp))) + pmd_free_pte_page(pmdp, next); } while (pmdp++, next += PMD_SIZE, next != end); pud_clear(pudp); From d61975567d9db192339b8d3884f09b3efe2803dd Mon Sep 17 00:00:00 2001 From: wangdicheng Date: Fri, 13 Jun 2025 14:36:36 +0800 Subject: [PATCH 631/971] ALSA: usb-audio: Rename ALSA kcontrol PCM and PCM1 for the KTMicro sound card commit 93adf20ff4d6e865e0b974110d3cf2f07c057177 upstream. PCM1 not in Pulseaudio's control list; standardize control to "Speaker" and "Headphone". Signed-off-by: wangdicheng Cc: Link: https://patch.msgid.link/20250613063636.239683-1-wangdich9700@163.com Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/usb/mixer_maps.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c index 0e9b5431a47f..faac7df1fbcf 100644 --- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c @@ -383,6 +383,13 @@ static const struct usbmix_name_map ms_usb_link_map[] = { { 0 } /* terminator */ }; +/* KTMicro USB */ +static struct usbmix_name_map s31b2_0022_map[] = { + { 23, "Speaker Playback" }, + { 18, "Headphone Playback" }, + { 0 } +}; + /* ASUS ROG Zenith II with Realtek ALC1220-VB */ static const struct usbmix_name_map asus_zenith_ii_map[] = { { 19, NULL, 12 }, /* FU, Input Gain Pad - broken response, disabled */ @@ -692,6 +699,11 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = { .id = USB_ID(0x045e, 0x083c), .map = ms_usb_link_map, }, + { + /* KTMicro USB */ + .id = USB_ID(0X31b2, 0x0022), + .map = s31b2_0022_map, + }, { 0 } /* terminator */ }; From f6393e5cb913b762bb05bc44a344e7f2476a0423 Mon Sep 17 00:00:00 2001 From: Paul Chaignon Date: Thu, 29 May 2025 12:28:05 +0200 Subject: [PATCH 632/971] net: Fix checksum update for ILA adj-transport commit 6043b794c7668c19dabc4a93c75b924a19474d59 upstream. During ILA address translations, the L4 checksums can be handled in different ways. One of them, adj-transport, consist in parsing the transport layer and updating any found checksum. This logic relies on inet_proto_csum_replace_by_diff and produces an incorrect skb->csum when in state CHECKSUM_COMPLETE. This bug can be reproduced with a simple ILA to SIR mapping, assuming packets are received with CHECKSUM_COMPLETE: $ ip a show dev eth0 14: eth0@if15: mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 62:ae:35:9e:0f:8d brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 3333:0:0:1::c078/64 scope global valid_lft forever preferred_lft forever inet6 fd00:10:244:1::c078/128 scope global nodad valid_lft forever preferred_lft forever inet6 fe80::60ae:35ff:fe9e:f8d/64 scope link proto kernel_ll valid_lft forever preferred_lft forever $ ip ila add loc_match fd00:10:244:1 loc 3333:0:0:1 \ csum-mode adj-transport ident-type luid dev eth0 Then I hit [fd00:10:244:1::c078]:8000 with a server listening only on [3333:0:0:1::c078]:8000. With the bug, the SYN packet is dropped with SKB_DROP_REASON_TCP_CSUM after inet_proto_csum_replace_by_diff changed skb->csum. The translation and drop are visible on pwru [1] traces: IFACE TUPLE FUNC eth0:9 [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp) ipv6_rcv eth0:9 [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp) ip6_rcv_core eth0:9 [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp) nf_hook_slow eth0:9 [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp) inet_proto_csum_replace_by_diff eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) tcp_v6_early_demux eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ip6_route_input eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ip6_input eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ip6_input_finish eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ip6_protocol_deliver_rcu eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) raw6_local_deliver eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ipv6_raw_deliver eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) tcp_v6_rcv eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) __skb_checksum_complete eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) kfree_skb_reason(SKB_DROP_REASON_TCP_CSUM) eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) skb_release_head_state eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) skb_release_data eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) skb_free_head eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) kfree_skbmem This is happening because inet_proto_csum_replace_by_diff is updating skb->csum when it shouldn't. The L4 checksum is updated such that it "cancels" the IPv6 address change in terms of checksum computation, so the impact on skb->csum is null. Note this would be different for an IPv4 packet since three fields would be updated: the IPv4 address, the IP checksum, and the L4 checksum. Two would cancel each other and skb->csum would still need to be updated to take the L4 checksum change into account. This patch fixes it by passing an ipv6 flag to inet_proto_csum_replace_by_diff, to skip the skb->csum update if we're in the IPv6 case. Note the behavior of the only other user of inet_proto_csum_replace_by_diff, the BPF subsystem, is left as is in this patch and fixed in the subsequent patch. With the fix, using the reproduction from above, I can confirm skb->csum is not touched by inet_proto_csum_replace_by_diff and the TCP SYN proceeds to the application after the ILA translation. Link: https://github.com/cilium/pwru [1] Fixes: 65d7ab8de582 ("net: Identifier Locator Addressing module") Signed-off-by: Paul Chaignon Acked-by: Daniel Borkmann Link: https://patch.msgid.link/b5539869e3550d46068504feb02d37653d939c0b.1748509484.git.paul.chaignon@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Paul Chaignon Signed-off-by: Greg Kroah-Hartman --- include/net/checksum.h | 2 +- net/core/filter.c | 2 +- net/core/utils.c | 4 ++-- net/ipv6/ila/ila_common.c | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/net/checksum.h b/include/net/checksum.h index 1338cb92c8e7..28b101f26636 100644 --- a/include/net/checksum.h +++ b/include/net/checksum.h @@ -158,7 +158,7 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb, const __be32 *from, const __be32 *to, bool pseudohdr); void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb, - __wsum diff, bool pseudohdr); + __wsum diff, bool pseudohdr, bool ipv6); static __always_inline void inet_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb, diff --git a/net/core/filter.c b/net/core/filter.c index b020cbddb2b3..11ce36fd8392 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -1987,7 +1987,7 @@ BPF_CALL_5(bpf_l4_csum_replace, struct sk_buff *, skb, u32, offset, if (unlikely(from != 0)) return -EINVAL; - inet_proto_csum_replace_by_diff(ptr, skb, to, is_pseudo); + inet_proto_csum_replace_by_diff(ptr, skb, to, is_pseudo, false); break; case 2: inet_proto_csum_replace2(ptr, skb, from, to, is_pseudo); diff --git a/net/core/utils.c b/net/core/utils.c index c994e95172ac..5895d034bf27 100644 --- a/net/core/utils.c +++ b/net/core/utils.c @@ -473,11 +473,11 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb, EXPORT_SYMBOL(inet_proto_csum_replace16); void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb, - __wsum diff, bool pseudohdr) + __wsum diff, bool pseudohdr, bool ipv6) { if (skb->ip_summed != CHECKSUM_PARTIAL) { csum_replace_by_diff(sum, diff); - if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr) + if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr && !ipv6) skb->csum = ~csum_sub(diff, skb->csum); } else if (pseudohdr) { *sum = ~csum_fold(csum_add(diff, csum_unfold(*sum))); diff --git a/net/ipv6/ila/ila_common.c b/net/ipv6/ila/ila_common.c index 95e9146918cc..b8d43ed4689d 100644 --- a/net/ipv6/ila/ila_common.c +++ b/net/ipv6/ila/ila_common.c @@ -86,7 +86,7 @@ static void ila_csum_adjust_transport(struct sk_buff *skb, diff = get_csum_diff(ip6h, p); inet_proto_csum_replace_by_diff(&th->check, skb, - diff, true); + diff, true, true); } break; case NEXTHDR_UDP: @@ -97,7 +97,7 @@ static void ila_csum_adjust_transport(struct sk_buff *skb, if (uh->check || skb->ip_summed == CHECKSUM_PARTIAL) { diff = get_csum_diff(ip6h, p); inet_proto_csum_replace_by_diff(&uh->check, skb, - diff, true); + diff, true, true); if (!uh->check) uh->check = CSUM_MANGLED_0; } @@ -111,7 +111,7 @@ static void ila_csum_adjust_transport(struct sk_buff *skb, diff = get_csum_diff(ip6h, p); inet_proto_csum_replace_by_diff(&ih->icmp6_cksum, skb, - diff, true); + diff, true, true); } break; } From f80e551050e456ae7292dd697a68a9319f83ad35 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sun, 8 Jun 2025 11:14:14 +0200 Subject: [PATCH 633/971] ALSA: hda/intel: Add Thinkpad E15 to PM deny list commit c987a390f1b3b8bdac11031d7004e3410fe259bd upstream. Lenovo Thinkpad E15 with Conexant CX8070 codec seems causing ugly noises after runtime-PM suspend. Disable the codec runtime PM as a workaround. Link: https://bugzilla.kernel.org/show_bug.cgi?id=220210 Cc: Link: https://patch.msgid.link/20250608091415.21170-1-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/hda_intel.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 3a0df631d25d..3cd5b7da8e15 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2266,6 +2266,8 @@ static const struct snd_pci_quirk power_save_denylist[] = { SND_PCI_QUIRK(0x1734, 0x1232, "KONTRON SinglePC", 0), /* Dell ALC3271 */ SND_PCI_QUIRK(0x1028, 0x0962, "Dell ALC3271", 0), + /* https://bugzilla.kernel.org/show_bug.cgi?id=220210 */ + SND_PCI_QUIRK(0x17aa, 0x5079, "Lenovo Thinkpad E15", 0), {} }; #endif /* CONFIG_PM */ From 2536810df13fd0190e9e229b475d57ba434453c7 Mon Sep 17 00:00:00 2001 From: Paul Chaignon Date: Thu, 29 May 2025 12:28:35 +0200 Subject: [PATCH 634/971] bpf: Fix L4 csum update on IPv6 in CHECKSUM_COMPLETE commit ead7f9b8de65632ef8060b84b0c55049a33cfea1 upstream. In Cilium, we use bpf_csum_diff + bpf_l4_csum_replace to, among other things, update the L4 checksum after reverse SNATing IPv6 packets. That use case is however not currently supported and leads to invalid skb->csum values in some cases. This patch adds support for IPv6 address changes in bpf_l4_csum_update via a new flag. When calling bpf_l4_csum_replace in Cilium, it ends up calling inet_proto_csum_replace_by_diff: 1: void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb, 2: __wsum diff, bool pseudohdr) 3: { 4: if (skb->ip_summed != CHECKSUM_PARTIAL) { 5: csum_replace_by_diff(sum, diff); 6: if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr) 7: skb->csum = ~csum_sub(diff, skb->csum); 8: } else if (pseudohdr) { 9: *sum = ~csum_fold(csum_add(diff, csum_unfold(*sum))); 10: } 11: } The bug happens when we're in the CHECKSUM_COMPLETE state. We've just updated one of the IPv6 addresses. The helper now updates the L4 header checksum on line 5. Next, it updates skb->csum on line 7. It shouldn't. For an IPv6 packet, the updates of the IPv6 address and of the L4 checksum will cancel each other. The checksums are set such that computing a checksum over the packet including its checksum will result in a sum of 0. So the same is true here when we update the L4 checksum on line 5. We'll update it as to cancel the previous IPv6 address update. Hence skb->csum should remain untouched in this case. The same bug doesn't affect IPv4 packets because, in that case, three fields are updated: the IPv4 address, the IP checksum, and the L4 checksum. The change to the IPv4 address and one of the checksums still cancel each other in skb->csum, but we're left with one checksum update and should therefore update skb->csum accordingly. That's exactly what inet_proto_csum_replace_by_diff does. This special case for IPv6 L4 checksums is also described atop inet_proto_csum_replace16, the function we should be using in this case. This patch introduces a new bpf_l4_csum_replace flag, BPF_F_IPV6, to indicate that we're updating the L4 checksum of an IPv6 packet. When the flag is set, inet_proto_csum_replace_by_diff will skip the skb->csum update. Fixes: 7d672345ed295 ("bpf: add generic bpf_csum_diff helper") Signed-off-by: Paul Chaignon Acked-by: Daniel Borkmann Link: https://patch.msgid.link/96a6bc3a443e6f0b21ff7b7834000e17fb549e05.1748509484.git.paul.chaignon@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Paul Chaignon Signed-off-by: Greg Kroah-Hartman --- include/uapi/linux/bpf.h | 2 ++ net/core/filter.c | 5 +++-- tools/include/uapi/linux/bpf.h | 2 ++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index c7f904a72af2..08a0494736e6 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -1913,6 +1913,7 @@ union bpf_attr { * for updates resulting in a null checksum the value is set to * **CSUM_MANGLED_0** instead. Flag **BPF_F_PSEUDO_HDR** indicates * the checksum is to be computed against a pseudo-header. + * Flag **BPF_F_IPV6** should be set for IPv6 packets. * * This helper works in combination with **bpf_csum_diff**\ (), * which does not update the checksum in-place, but offers more @@ -5920,6 +5921,7 @@ enum { BPF_F_PSEUDO_HDR = (1ULL << 4), BPF_F_MARK_MANGLED_0 = (1ULL << 5), BPF_F_MARK_ENFORCE = (1ULL << 6), + BPF_F_IPV6 = (1ULL << 7), }; /* BPF_FUNC_skb_set_tunnel_key and BPF_FUNC_skb_get_tunnel_key flags. */ diff --git a/net/core/filter.c b/net/core/filter.c index 11ce36fd8392..3e10b4c8338f 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -1968,10 +1968,11 @@ BPF_CALL_5(bpf_l4_csum_replace, struct sk_buff *, skb, u32, offset, bool is_pseudo = flags & BPF_F_PSEUDO_HDR; bool is_mmzero = flags & BPF_F_MARK_MANGLED_0; bool do_mforce = flags & BPF_F_MARK_ENFORCE; + bool is_ipv6 = flags & BPF_F_IPV6; __sum16 *ptr; if (unlikely(flags & ~(BPF_F_MARK_MANGLED_0 | BPF_F_MARK_ENFORCE | - BPF_F_PSEUDO_HDR | BPF_F_HDR_FIELD_MASK))) + BPF_F_PSEUDO_HDR | BPF_F_HDR_FIELD_MASK | BPF_F_IPV6))) return -EINVAL; if (unlikely(offset > 0xffff || offset & 1)) return -EFAULT; @@ -1987,7 +1988,7 @@ BPF_CALL_5(bpf_l4_csum_replace, struct sk_buff *, skb, u32, offset, if (unlikely(from != 0)) return -EINVAL; - inet_proto_csum_replace_by_diff(ptr, skb, to, is_pseudo, false); + inet_proto_csum_replace_by_diff(ptr, skb, to, is_pseudo, is_ipv6); break; case 2: inet_proto_csum_replace2(ptr, skb, from, to, is_pseudo); diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 2a90f04a4160..2e064a1032a0 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -1913,6 +1913,7 @@ union bpf_attr { * for updates resulting in a null checksum the value is set to * **CSUM_MANGLED_0** instead. Flag **BPF_F_PSEUDO_HDR** indicates * the checksum is to be computed against a pseudo-header. + * Flag **BPF_F_IPV6** should be set for IPv6 packets. * * This helper works in combination with **bpf_csum_diff**\ (), * which does not update the checksum in-place, but offers more @@ -5920,6 +5921,7 @@ enum { BPF_F_PSEUDO_HDR = (1ULL << 4), BPF_F_MARK_MANGLED_0 = (1ULL << 5), BPF_F_MARK_ENFORCE = (1ULL << 6), + BPF_F_IPV6 = (1ULL << 7), }; /* BPF_FUNC_clone_redirect and BPF_FUNC_redirect flags. */ From 3d849cc3dfd382220d0741487ebf8bd2870328f2 Mon Sep 17 00:00:00 2001 From: Jonathan Lane Date: Wed, 11 Jun 2025 12:31:25 -0700 Subject: [PATCH 635/971] ALSA: hda/realtek: enable headset mic on Latitude 5420 Rugged commit efa6bdf1bc75e26cafaa5f1d775e8bb7c5b0c431 upstream. Like many Dell laptops, the 3.5mm port by default can not detect a combined headphones+mic headset or even a pure microphone. This change enables the port's functionality. Signed-off-by: Jonathan Lane Cc: Link: https://patch.msgid.link/20250611193124.26141-2-jon@borg.moe Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 440b934cdc28..82210b1e3b97 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9952,6 +9952,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC), SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC), SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB), + SND_PCI_QUIRK(0x1028, 0x0879, "Dell Latitude 5420 Rugged", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), From 5e5d2ad9765a6e989debde5cbde499f3e245364b Mon Sep 17 00:00:00 2001 From: Gao Xiang Date: Tue, 17 Jun 2025 13:40:56 +0800 Subject: [PATCH 636/971] erofs: remove unused trace event erofs_destroy_inode commit 30b58444807c93bffeaba7d776110f2a909d2f9a upstream. The trace event `erofs_destroy_inode` was added but remains unused. This unused event contributes approximately 5KB to the kernel module size. Reported-by: Steven Rostedt Closes: https://lore.kernel.org/r/20250612224906.15000244@batman.local.home Fixes: 13f06f48f7bf ("staging: erofs: support tracepoint") Cc: stable@vger.kernel.org Reviewed-by: Hongbo Li Signed-off-by: Gao Xiang Link: https://lore.kernel.org/r/20250617054056.3232365-1-hsiangkao@linux.alibaba.com Signed-off-by: Greg Kroah-Hartman --- include/trace/events/erofs.h | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/include/trace/events/erofs.h b/include/trace/events/erofs.h index e18684b02c3d..0179af103d0f 100644 --- a/include/trace/events/erofs.h +++ b/include/trace/events/erofs.h @@ -237,24 +237,6 @@ DEFINE_EVENT(erofs__map_blocks_exit, z_erofs_map_blocks_iter_exit, TP_ARGS(inode, map, flags, ret) ); -TRACE_EVENT(erofs_destroy_inode, - TP_PROTO(struct inode *inode), - - TP_ARGS(inode), - - TP_STRUCT__entry( - __field( dev_t, dev ) - __field( erofs_nid_t, nid ) - ), - - TP_fast_assign( - __entry->dev = inode->i_sb->s_dev; - __entry->nid = EROFS_I(inode)->nid; - ), - - TP_printk("dev = (%d,%d), nid = %llu", show_dev_nid(__entry)) -); - #endif /* _TRACE_EROFS_H */ /* This part must be outside protection */ From 39c86833f973d6b7d0fb5ae9ebd557e078a4cce5 Mon Sep 17 00:00:00 2001 From: Sean Nyekjaer Date: Mon, 5 May 2025 21:20:07 +0200 Subject: [PATCH 637/971] iio: accel: fxls8962af: Fix temperature calculation commit 16038474e3a0263572f36326ef85057aaf341814 upstream. According to spec temperature should be returned in milli degrees Celsius. Add in_temp_scale to calculate from Celsius to milli Celsius. Fixes: a3e0b51884ee ("iio: accel: add support for FXLS8962AF/FXLS8964AF accelerometers") Cc: stable@vger.kernel.org Reviewed-by: Marcelo Schmitt Signed-off-by: Sean Nyekjaer Link: https://patch.msgid.link/20250505-fxls-v4-1-a38652e21738@geanix.com Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/accel/fxls8962af-core.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/iio/accel/fxls8962af-core.c b/drivers/iio/accel/fxls8962af-core.c index 9dc8b4530e86..17820b2c3a1d 100644 --- a/drivers/iio/accel/fxls8962af-core.c +++ b/drivers/iio/accel/fxls8962af-core.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -434,8 +435,16 @@ static int fxls8962af_read_raw(struct iio_dev *indio_dev, *val = FXLS8962AF_TEMP_CENTER_VAL; return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: - *val = 0; - return fxls8962af_read_full_scale(data, val2); + switch (chan->type) { + case IIO_TEMP: + *val = MILLIDEGREE_PER_DEGREE; + return IIO_VAL_INT; + case IIO_ACCEL: + *val = 0; + return fxls8962af_read_full_scale(data, val2); + default: + return -EINVAL; + } case IIO_CHAN_INFO_SAMP_FREQ: return fxls8962af_read_samp_freq(data, val, val2); default: @@ -734,6 +743,7 @@ static const struct iio_event_spec fxls8962af_event[] = { .type = IIO_TEMP, \ .address = FXLS8962AF_TEMP_OUT, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_OFFSET),\ .scan_index = -1, \ .scan_type = { \ From 599c489eea793821232a2f69a00fa57d82b0ac98 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Thu, 19 Jun 2025 06:01:55 -0400 Subject: [PATCH 638/971] sunrpc: handle SVC_GARBAGE during svc auth processing as auth error commit 94d10a4dba0bc482f2b01e39f06d5513d0f75742 upstream. tianshuo han reported a remotely-triggerable crash if the client sends a kernel RPC server a specially crafted packet. If decoding the RPC reply fails in such a way that SVC_GARBAGE is returned without setting the rq_accept_statp pointer, then that pointer can be dereferenced and a value stored there. If it's the first time the thread has processed an RPC, then that pointer will be set to NULL and the kernel will crash. In other cases, it could create a memory scribble. The server sunrpc code treats a SVC_GARBAGE return from svc_authenticate or pg_authenticate as if it should send a GARBAGE_ARGS reply. RFC 5531 says that if authentication fails that the RPC should be rejected instead with a status of AUTH_ERR. Handle a SVC_GARBAGE return as an AUTH_ERROR, with a reason of AUTH_BADCRED instead of returning GARBAGE_ARGS in that case. This sidesteps the whole problem of touching the rpc_accept_statp pointer in this situation and avoids the crash. Cc: stable@kernel.org Fixes: 29cd2927fb91 ("SUNRPC: Fix encoding of accepted but unsuccessful RPC replies") Reported-by: tianshuo han Reviewed-by: Chuck Lever Signed-off-by: Jeff Layton Signed-off-by: Chuck Lever Signed-off-by: Greg Kroah-Hartman --- net/sunrpc/svc.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index b43dc8409b1f..4d8d46074716 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -1344,7 +1344,8 @@ svc_process_common(struct svc_rqst *rqstp) case SVC_OK: break; case SVC_GARBAGE: - goto err_garbage_args; + rqstp->rq_auth_stat = rpc_autherr_badcred; + goto err_bad_auth; case SVC_SYSERR: goto err_system_err; case SVC_DENIED: @@ -1485,14 +1486,6 @@ err_bad_proc: *rqstp->rq_accept_statp = rpc_proc_unavail; goto sendit; -err_garbage_args: - svc_printk(rqstp, "failed to decode RPC header\n"); - - if (serv->sv_stats) - serv->sv_stats->rpcbadfmt++; - *rqstp->rq_accept_statp = rpc_garbage_args; - goto sendit; - err_system_err: if (serv->sv_stats) serv->sv_stats->rpcbadfmt++; From af6cfcd0efb7f051af221c418ec8b37a10211947 Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Tue, 27 May 2025 23:23:53 +0200 Subject: [PATCH 639/971] mm/hugetlb: unshare page tables during VMA split, not before commit 081056dc00a27bccb55ccc3c6f230a3d5fd3f7e0 upstream. Currently, __split_vma() triggers hugetlb page table unsharing through vm_ops->may_split(). This happens before the VMA lock and rmap locks are taken - which is too early, it allows racing VMA-locked page faults in our process and racing rmap walks from other processes to cause page tables to be shared again before we actually perform the split. Fix it by explicitly calling into the hugetlb unshare logic from __split_vma() in the same place where THP splitting also happens. At that point, both the VMA and the rmap(s) are write-locked. An annoying detail is that we can now call into the helper hugetlb_unshare_pmds() from two different locking contexts: 1. from hugetlb_split(), holding: - mmap lock (exclusively) - VMA lock - file rmap lock (exclusively) 2. hugetlb_unshare_all_pmds(), which I think is designed to be able to call us with only the mmap lock held (in shared mode), but currently only runs while holding mmap lock (exclusively) and VMA lock Backporting note: This commit fixes a racy protection that was introduced in commit b30c14cd6102 ("hugetlb: unshare some PMDs when splitting VMAs"); that commit claimed to fix an issue introduced in 5.13, but it should actually also go all the way back. [jannh@google.com: v2] Link: https://lkml.kernel.org/r/20250528-hugetlb-fixes-splitrace-v2-1-1329349bad1a@google.com Link: https://lkml.kernel.org/r/20250528-hugetlb-fixes-splitrace-v2-0-1329349bad1a@google.com Link: https://lkml.kernel.org/r/20250527-hugetlb-fixes-splitrace-v1-1-f4136f5ec58a@google.com Fixes: 39dde65c9940 ("[PATCH] shared page table for hugetlb page") Signed-off-by: Jann Horn Cc: Liam Howlett Reviewed-by: Lorenzo Stoakes Reviewed-by: Oscar Salvador Cc: Lorenzo Stoakes Cc: Vlastimil Babka Cc: [b30c14cd6102: hugetlb: unshare some PMDs when splitting VMAs] Cc: Signed-off-by: Andrew Morton [stable backport: code got moved from mmap.c to vma.c] Signed-off-by: Jann Horn Signed-off-by: Greg Kroah-Hartman --- include/linux/hugetlb.h | 3 +++ mm/hugetlb.c | 60 ++++++++++++++++++++++++++++++----------- mm/mmap.c | 6 +++++ 3 files changed, 53 insertions(+), 16 deletions(-) diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index fc2023d07f69..8b051b8c4034 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -281,6 +281,7 @@ long hugetlb_change_protection(struct vm_area_struct *vma, bool is_hugetlb_entry_migration(pte_t pte); void hugetlb_unshare_all_pmds(struct vm_area_struct *vma); +void hugetlb_split(struct vm_area_struct *vma, unsigned long addr); #else /* !CONFIG_HUGETLB_PAGE */ @@ -491,6 +492,8 @@ static inline vm_fault_t hugetlb_fault(struct mm_struct *mm, static inline void hugetlb_unshare_all_pmds(struct vm_area_struct *vma) { } +static inline void hugetlb_split(struct vm_area_struct *vma, unsigned long addr) {} + #endif /* !CONFIG_HUGETLB_PAGE */ /* * hugepages at page global directory. If arch support diff --git a/mm/hugetlb.c b/mm/hugetlb.c index b731f8e0e9d8..d57d8f1c2dfe 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -96,7 +96,7 @@ static void hugetlb_vma_lock_free(struct vm_area_struct *vma); static void hugetlb_vma_lock_alloc(struct vm_area_struct *vma); static void __hugetlb_vma_unlock_write_free(struct vm_area_struct *vma); static void hugetlb_unshare_pmds(struct vm_area_struct *vma, - unsigned long start, unsigned long end); + unsigned long start, unsigned long end, bool take_locks); static struct resv_map *vma_resv_map(struct vm_area_struct *vma); static inline bool subpool_is_free(struct hugepage_subpool *spool) @@ -4903,26 +4903,40 @@ static int hugetlb_vm_op_split(struct vm_area_struct *vma, unsigned long addr) { if (addr & ~(huge_page_mask(hstate_vma(vma)))) return -EINVAL; + return 0; +} +void hugetlb_split(struct vm_area_struct *vma, unsigned long addr) +{ /* * PMD sharing is only possible for PUD_SIZE-aligned address ranges * in HugeTLB VMAs. If we will lose PUD_SIZE alignment due to this * split, unshare PMDs in the PUD_SIZE interval surrounding addr now. + * This function is called in the middle of a VMA split operation, with + * MM, VMA and rmap all write-locked to prevent concurrent page table + * walks (except hardware and gup_fast()). */ + vma_assert_write_locked(vma); + i_mmap_assert_write_locked(vma->vm_file->f_mapping); + if (addr & ~PUD_MASK) { - /* - * hugetlb_vm_op_split is called right before we attempt to - * split the VMA. We will need to unshare PMDs in the old and - * new VMAs, so let's unshare before we split. - */ unsigned long floor = addr & PUD_MASK; unsigned long ceil = floor + PUD_SIZE; - if (floor >= vma->vm_start && ceil <= vma->vm_end) - hugetlb_unshare_pmds(vma, floor, ceil); + if (floor >= vma->vm_start && ceil <= vma->vm_end) { + /* + * Locking: + * Use take_locks=false here. + * The file rmap lock is already held. + * The hugetlb VMA lock can't be taken when we already + * hold the file rmap lock, and we don't need it because + * its purpose is to synchronize against concurrent page + * table walks, which are not possible thanks to the + * locks held by our caller. + */ + hugetlb_unshare_pmds(vma, floor, ceil, /* take_locks = */ false); + } } - - return 0; } static unsigned long hugetlb_vm_op_pagesize(struct vm_area_struct *vma) @@ -7305,9 +7319,16 @@ void move_hugetlb_state(struct folio *old_folio, struct folio *new_folio, int re } } +/* + * If @take_locks is false, the caller must ensure that no concurrent page table + * access can happen (except for gup_fast() and hardware page walks). + * If @take_locks is true, we take the hugetlb VMA lock (to lock out things like + * concurrent page fault handling) and the file rmap lock. + */ static void hugetlb_unshare_pmds(struct vm_area_struct *vma, unsigned long start, - unsigned long end) + unsigned long end, + bool take_locks) { struct hstate *h = hstate_vma(vma); unsigned long sz = huge_page_size(h); @@ -7331,8 +7352,12 @@ static void hugetlb_unshare_pmds(struct vm_area_struct *vma, mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, mm, start, end); mmu_notifier_invalidate_range_start(&range); - hugetlb_vma_lock_write(vma); - i_mmap_lock_write(vma->vm_file->f_mapping); + if (take_locks) { + hugetlb_vma_lock_write(vma); + i_mmap_lock_write(vma->vm_file->f_mapping); + } else { + i_mmap_assert_write_locked(vma->vm_file->f_mapping); + } for (address = start; address < end; address += PUD_SIZE) { ptep = hugetlb_walk(vma, address, sz); if (!ptep) @@ -7342,8 +7367,10 @@ static void hugetlb_unshare_pmds(struct vm_area_struct *vma, spin_unlock(ptl); } flush_hugetlb_tlb_range(vma, start, end); - i_mmap_unlock_write(vma->vm_file->f_mapping); - hugetlb_vma_unlock_write(vma); + if (take_locks) { + i_mmap_unlock_write(vma->vm_file->f_mapping); + hugetlb_vma_unlock_write(vma); + } /* * No need to call mmu_notifier_arch_invalidate_secondary_tlbs(), see * Documentation/mm/mmu_notifier.rst. @@ -7358,7 +7385,8 @@ static void hugetlb_unshare_pmds(struct vm_area_struct *vma, void hugetlb_unshare_all_pmds(struct vm_area_struct *vma) { hugetlb_unshare_pmds(vma, ALIGN(vma->vm_start, PUD_SIZE), - ALIGN_DOWN(vma->vm_end, PUD_SIZE)); + ALIGN_DOWN(vma->vm_end, PUD_SIZE), + /* take_locks = */ true); } #ifdef CONFIG_CMA diff --git a/mm/mmap.c b/mm/mmap.c index 03a24cb3951d..a9c70001e456 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2402,7 +2402,13 @@ int __split_vma(struct vma_iterator *vmi, struct vm_area_struct *vma, init_vma_prep(&vp, vma); vp.insert = new; vma_prepare(&vp); + /* + * Get rid of huge pages and shared page tables straddling the split + * boundary. + */ vma_adjust_trans_huge(vma, vma->vm_start, addr, 0); + if (is_vm_hugetlb_page(vma)) + hugetlb_split(vma, addr); if (new_below) { vma->vm_start = addr; From 3977946f61cdba87b6b5aaf7d7094e96089583a5 Mon Sep 17 00:00:00 2001 From: Gavin Guo Date: Mon, 21 Apr 2025 19:35:36 +0800 Subject: [PATCH 640/971] mm/huge_memory: fix dereferencing invalid pmd migration entry commit be6e843fc51a584672dfd9c4a6a24c8cb81d5fb7 upstream. When migrating a THP, concurrent access to the PMD migration entry during a deferred split scan can lead to an invalid address access, as illustrated below. To prevent this invalid access, it is necessary to check the PMD migration entry and return early. In this context, there is no need to use pmd_to_swp_entry and pfn_swap_entry_to_page to verify the equality of the target folio. Since the PMD migration entry is locked, it cannot be served as the target. Mailing list discussion and explanation from Hugh Dickins: "An anon_vma lookup points to a location which may contain the folio of interest, but might instead contain another folio: and weeding out those other folios is precisely what the "folio != pmd_folio((*pmd)" check (and the "risk of replacing the wrong folio" comment a few lines above it) is for." BUG: unable to handle page fault for address: ffffea60001db008 CPU: 0 UID: 0 PID: 2199114 Comm: tee Not tainted 6.14.0+ #4 NONE Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 RIP: 0010:split_huge_pmd_locked+0x3b5/0x2b60 Call Trace: try_to_migrate_one+0x28c/0x3730 rmap_walk_anon+0x4f6/0x770 unmap_folio+0x196/0x1f0 split_huge_page_to_list_to_order+0x9f6/0x1560 deferred_split_scan+0xac5/0x12a0 shrinker_debugfs_scan_write+0x376/0x470 full_proxy_write+0x15c/0x220 vfs_write+0x2fc/0xcb0 ksys_write+0x146/0x250 do_syscall_64+0x6a/0x120 entry_SYSCALL_64_after_hwframe+0x76/0x7e The bug is found by syzkaller on an internal kernel, then confirmed on upstream. Link: https://lkml.kernel.org/r/20250421113536.3682201-1-gavinguo@igalia.com Link: https://lore.kernel.org/all/20250414072737.1698513-1-gavinguo@igalia.com/ Link: https://lore.kernel.org/all/20250418085802.2973519-1-gavinguo@igalia.com/ Fixes: 84c3fc4e9c56 ("mm: thp: check pmd migration entry in common path") Signed-off-by: Gavin Guo Acked-by: David Hildenbrand Acked-by: Hugh Dickins Acked-by: Zi Yan Reviewed-by: Gavin Shan Cc: Florent Revest Cc: Matthew Wilcox (Oracle) Cc: Miaohe Lin Cc: Signed-off-by: Andrew Morton [gavin: backport the migration checking logic to __split_huge_pmd] Signed-off-by: Gavin Guo Signed-off-by: Greg Kroah-Hartman --- mm/huge_memory.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 635f0f0f6860..78f5df12b8eb 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2260,12 +2260,14 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, { spinlock_t *ptl; struct mmu_notifier_range range; + bool pmd_migration; mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma->vm_mm, address & HPAGE_PMD_MASK, (address & HPAGE_PMD_MASK) + HPAGE_PMD_SIZE); mmu_notifier_invalidate_range_start(&range); ptl = pmd_lock(vma->vm_mm, pmd); + pmd_migration = is_pmd_migration_entry(*pmd); /* * If caller asks to setup a migration entry, we need a folio to check @@ -2274,13 +2276,12 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, VM_BUG_ON(freeze && !folio); VM_WARN_ON_ONCE(folio && !folio_test_locked(folio)); - if (pmd_trans_huge(*pmd) || pmd_devmap(*pmd) || - is_pmd_migration_entry(*pmd)) { + if (pmd_trans_huge(*pmd) || pmd_devmap(*pmd) || pmd_migration) { /* - * It's safe to call pmd_page when folio is set because it's - * guaranteed that pmd is present. + * Do not apply pmd_folio() to a migration entry; and folio lock + * guarantees that it must be of the wrong folio anyway. */ - if (folio && folio != page_folio(pmd_page(*pmd))) + if (folio && (pmd_migration || folio != page_folio(pmd_page(*pmd)))) goto out; __split_huge_pmd_locked(vma, pmd, range.start, freeze); } From 7e6980c225c13e22f9c0ae62efa3bba5110797bb Mon Sep 17 00:00:00 2001 From: Bharath SM Date: Mon, 17 Mar 2025 15:57:27 +0530 Subject: [PATCH 641/971] smb: fix secondary channel creation issue with kerberos by populating hostname when adding channels commit 306cb65bb0cb243389fcbd0a66907d5bdea07d1e upstream. When mounting a share with kerberos authentication with multichannel support, share mounts correctly, but fails to create secondary channels. This occurs because the hostname is not populated when adding the channels. The hostname is necessary for the userspace cifs.upcall program to retrieve the required credentials and pass it back to kernel, without hostname secondary channels fails establish. Cc: stable@vger.kernel.org Reviewed-by: Shyam Prasad N Signed-off-by: Bharath SM Reported-by: xfuren Link: https://bugzilla.samba.org/show_bug.cgi?id=15824 Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/smb/client/sess.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c index c9e6de42eedb..8959206a0353 100644 --- a/fs/smb/client/sess.c +++ b/fs/smb/client/sess.c @@ -558,8 +558,7 @@ cifs_ses_add_channel(struct cifs_ses *ses, ctx->domainauto = ses->domainAuto; ctx->domainname = ses->domainName; - /* no hostname for extra channels */ - ctx->server_hostname = ""; + ctx->server_hostname = ses->server->hostname; ctx->username = ses->user_name; ctx->password = ses->password; From 77087a79779c8de3e486190180501468e44652de Mon Sep 17 00:00:00 2001 From: "James A. MacInnes" Date: Wed, 12 Feb 2025 15:03:47 -0800 Subject: [PATCH 642/971] drm/msm/disp: Correct porch timing for SDM845 [ Upstream commit 146e87f3e11de0dfa091ff87e34b4bc6eec761a4 ] Type-C DisplayPort inoperable due to incorrect porch settings. - Re-used wide_bus_en as flag to prevent porch shifting Fixes: c943b4948b58 ("drm/msm/dp: add displayPort driver support") Signed-off-by: James A. MacInnes Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/636945/ Link: https://lore.kernel.org/r/20250212-sdm845_dp-v2-2-4954e51458f4@gmail.com Signed-off-by: Dmitry Baryshkov Signed-off-by: Sasha Levin --- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c index 20c8b9af7a21..2cda9bbf68f9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c @@ -93,17 +93,21 @@ static void drm_mode_to_intf_timing_params( timing->vsync_polarity = 0; } - /* for DP/EDP, Shift timings to align it to bottom right */ - if (phys_enc->hw_intf->cap->type == INTF_DP) { + timing->wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent); + timing->compression_en = dpu_encoder_is_dsc_enabled(phys_enc->parent); + + /* + * For DP/EDP, Shift timings to align it to bottom right. + * wide_bus_en is set for everything excluding SDM845 & + * porch changes cause DisplayPort failure and HDMI tearing. + */ + if (phys_enc->hw_intf->cap->type == INTF_DP && timing->wide_bus_en) { timing->h_back_porch += timing->h_front_porch; timing->h_front_porch = 0; timing->v_back_porch += timing->v_front_porch; timing->v_front_porch = 0; } - timing->wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent); - timing->compression_en = dpu_encoder_is_dsc_enabled(phys_enc->parent); - /* * for DP, divide the horizonal parameters by 2 when * widebus is enabled From 002aa3ed19f3407622c2906d7f9eb2d5172cf648 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 20 May 2025 13:13:26 +0200 Subject: [PATCH 643/971] drm/msm/dsi/dsi_phy_10nm: Fix missing initial VCO rate [ Upstream commit 8a48e35becb214743214f5504e726c3ec131cd6d ] Driver unconditionally saves current state on first init in dsi_pll_10nm_init(), but does not save the VCO rate, only some of the divider registers. The state is then restored during probe/enable via msm_dsi_phy_enable() -> msm_dsi_phy_pll_restore_state() -> dsi_10nm_pll_restore_state(). Restoring calls dsi_pll_10nm_vco_set_rate() with pll_10nm->vco_current_rate=0, which basically overwrites existing rate of VCO and messes with clock hierarchy, by setting frequency to 0 to clock tree. This makes anyway little sense - VCO rate was not saved, so should not be restored. If PLL was not configured configure it to minimum rate to avoid glitches and configuring entire in clock hierarchy to 0 Hz. Suggested-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/sz4kbwy5nwsebgf64ia7uq4ee7wbsa5uy3xmlqwcstsbntzcov@ew3dcyjdzmi2/ Signed-off-by: Krzysztof Kozlowski Fixes: a4ccc37693a2 ("drm/msm/dsi_pll_10nm: restore VCO rate during Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/654796/ Link: https://lore.kernel.org/r/20250520111325.92352-2-krzysztof.kozlowski@linaro.org Signed-off-by: Dmitry Baryshkov Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index 27b592c776a3..1c111969342a 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -716,6 +716,13 @@ static int dsi_pll_10nm_init(struct msm_dsi_phy *phy) /* TODO: Remove this when we have proper display handover support */ msm_dsi_phy_pll_save_state(phy); + /* + * Store also proper vco_current_rate, because its value will be used in + * dsi_10nm_pll_restore_state(). + */ + if (!dsi_pll_10nm_vco_recalc_rate(&pll_10nm->clk_hw, VCO_REF_CLK_RATE)) + pll_10nm->vco_current_rate = pll_10nm->phy->cfg->min_pll_rate; + return 0; } From b599b310380a8ba4bfb8a9c4df6118540c0ddf78 Mon Sep 17 00:00:00 2001 From: Brett Creeley Date: Mon, 9 Jun 2025 14:28:27 -0700 Subject: [PATCH 644/971] ionic: Prevent driver/fw getting out of sync on devcmd(s) [ Upstream commit 5466491c9e3309ed5c7adbb8fad6e93fcc9a8fe9 ] Some stress/negative firmware testing around devcmd(s) returning EAGAIN found that the done bit could get out of sync in the firmware when it wasn't cleared in a retry case. While here, change the type of the local done variable to a bool to match the return type from ionic_dev_cmd_done(). Fixes: ec8ee714736e ("ionic: stretch heartbeat detection") Signed-off-by: Brett Creeley Signed-off-by: Shannon Nelson Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250609212827.53842-1-shannon.nelson@amd.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/pensando/ionic/ionic_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c b/drivers/net/ethernet/pensando/ionic/ionic_main.c index 3ca6893d1bf2..2869922cffe2 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_main.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c @@ -464,9 +464,9 @@ static int __ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_seconds, unsigned long start_time; unsigned long max_wait; unsigned long duration; - int done = 0; bool fw_up; int opcode; + bool done; int err; /* Wait for dev cmd to complete, retrying if we get EAGAIN, @@ -474,6 +474,7 @@ static int __ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_seconds, */ max_wait = jiffies + (max_seconds * HZ); try_again: + done = false; opcode = idev->opcode; start_time = jiffies; for (fw_up = ionic_is_fw_running(idev); From af2f5f21599a93788fc6f86b9fc176bcf46ffa28 Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Tue, 10 Jun 2025 14:54:51 -0700 Subject: [PATCH 645/971] drm/nouveau/bl: increase buffer size to avoid truncate warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 61b2b3737499f1fb361a54a16828db24a8345e85 ] The nouveau_get_backlight_name() function generates a unique name for the backlight interface, appending an id from 1 to 99 for all backlight devices after the first. GCC 15 (and likely other compilers) produce the following -Wformat-truncation warning: nouveau_backlight.c: In function ‘nouveau_backlight_init’: nouveau_backlight.c:56:69: error: ‘%d’ directive output may be truncated writing between 1 and 10 bytes into a region of size 3 [-Werror=format-truncation=] 56 | snprintf(backlight_name, BL_NAME_SIZE, "nv_backlight%d", nb); | ^~ In function ‘nouveau_get_backlight_name’, inlined from ‘nouveau_backlight_init’ at nouveau_backlight.c:351:7: nouveau_backlight.c:56:56: note: directive argument in the range [1, 2147483647] 56 | snprintf(backlight_name, BL_NAME_SIZE, "nv_backlight%d", nb); | ^~~~~~~~~~~~~~~~ nouveau_backlight.c:56:17: note: ‘snprintf’ output between 14 and 23 bytes into a destination of size 15 56 | snprintf(backlight_name, BL_NAME_SIZE, "nv_backlight%d", nb); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The warning started appearing after commit ab244be47a8f ("drm/nouveau: Fix a potential theorical leak in nouveau_get_backlight_name()") This fix for the ida usage removed the explicit value check for ids larger than 99. The compiler is unable to intuit that the ida_alloc_max() limits the returned value range between 0 and 99. Because the compiler can no longer infer that the number ranges from 0 to 99, it thinks that it could use as many as 11 digits (10 + the potential - sign for negative numbers). The warning has gone unfixed for some time, with at least one kernel test robot report. The code breaks W=1 builds, which is especially frustrating with the introduction of CONFIG_WERROR. The string is stored temporarily on the stack and then copied into the device name. Its not a big deal to use 11 more bytes of stack rounding out to an even 24 bytes. Increase BL_NAME_SIZE to 24 to avoid the truncation warning. This fixes the W=1 builds that include this driver. Compile tested only. Fixes: ab244be47a8f ("drm/nouveau: Fix a potential theorical leak in nouveau_get_backlight_name()") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202312050324.0kv4PnfZ-lkp@intel.com/ Suggested-by: Timur Tabi Signed-off-by: Jacob Keller Link: https://lore.kernel.org/r/20250610-jk-nouveua-drm-bl-snprintf-fix-v2-1-7fdd4b84b48e@intel.com Signed-off-by: Danilo Krummrich Signed-off-by: Sasha Levin --- drivers/gpu/drm/nouveau/nouveau_backlight.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index 91b5ecc57538..4e6f305c9e50 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c @@ -42,7 +42,7 @@ #include "nouveau_acpi.h" static struct ida bl_ida; -#define BL_NAME_SIZE 15 // 12 for name + 2 for digits + 1 for '\0' +#define BL_NAME_SIZE 24 // 12 for name + 11 for digits + 1 for '\0' static bool nouveau_get_backlight_name(char backlight_name[BL_NAME_SIZE], From ff3dcf7f818425a19a4c34fbbfd2a477e0e046de Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Thu, 12 Jun 2025 08:30:23 +0000 Subject: [PATCH 646/971] drm/i915/pmu: Fix build error with GCOV and AutoFDO enabled [ Upstream commit a7137b1825b535eb7258b25beeb0d5425e0037d2 ] i915_pmu.c may fail to build with GCOV and AutoFDO enabled. ../drivers/gpu/drm/i915/i915_pmu.c:116:3: error: call to '__compiletime_assert_487' declared with 'error' attribute: BUILD_BUG_ON failed: bit > BITS_PER_TYPE(typeof_member(struct i915_pmu, enable)) - 1 116 | BUILD_BUG_ON(bit > | ^ Here is a way to reproduce the issue: $ git checkout v6.15 $ mkdir build $ ./scripts/kconfig/merge_config.sh -O build -n -m <(cat < Signed-off-by: Tzung-Bi Shih Signed-off-by: Tvrtko Ursulin Link: https://lore.kernel.org/r/20250612083023.562585-1-tzungbi@kernel.org (cherry picked from commit 686d773186bf72b739bab7e12eb8665d914676ee) Signed-off-by: Joonas Lahtinen Signed-off-by: Sasha Levin --- drivers/gpu/drm/i915/i915_pmu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c index 7b1076b5e748..33ab82c334a8 100644 --- a/drivers/gpu/drm/i915/i915_pmu.c +++ b/drivers/gpu/drm/i915/i915_pmu.c @@ -105,7 +105,7 @@ static u32 config_mask(const u64 config) { unsigned int bit = config_bit(config); - if (__builtin_constant_p(config)) + if (__builtin_constant_p(bit)) BUILD_BUG_ON(bit > BITS_PER_TYPE(typeof_member(struct i915_pmu, enable)) - 1); @@ -114,7 +114,7 @@ static u32 config_mask(const u64 config) BITS_PER_TYPE(typeof_member(struct i915_pmu, enable)) - 1); - return BIT(config_bit(config)); + return BIT(bit); } static bool is_engine_event(struct perf_event *event) From 1312d9bf88befd69352b63d7459fbd92b42e53a9 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 10 Jun 2025 11:23:06 +0200 Subject: [PATCH 647/971] hwmon: (occ) Rework attribute registration for stack usage [ Upstream commit 744c2fe950e936c4d62430de899d6253424200ed ] clang produces an output with excessive stack usage when building the occ_setup_sensor_attrs() function, apparently the result of having a lot of struct literals and building with the -fno-strict-overflow option that leads clang to skip some optimization in case the 'attr' pointer overruns: drivers/hwmon/occ/common.c:775:12: error: stack frame size (1392) exceeds limit (1280) in 'occ_setup_sensor_attrs' [-Werror,-Wframe-larger-than] Replace the custom macros for initializing the attributes with a simpler function call that does not run into this corner case. Link: https://godbolt.org/z/Wf1Yx76a5 Fixes: 54076cb3b5ff ("hwmon (occ): Add sensor attributes and register hwmon device") Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20250610092315.2640039-1-arnd@kernel.org Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin --- drivers/hwmon/occ/common.c | 210 +++++++++++++++---------------------- 1 file changed, 84 insertions(+), 126 deletions(-) diff --git a/drivers/hwmon/occ/common.c b/drivers/hwmon/occ/common.c index dd690f700d49..256cda99fdc9 100644 --- a/drivers/hwmon/occ/common.c +++ b/drivers/hwmon/occ/common.c @@ -747,28 +747,29 @@ static ssize_t occ_show_extended(struct device *dev, } /* - * Some helper macros to make it easier to define an occ_attribute. Since these - * are dynamically allocated, we shouldn't use the existing kernel macros which + * A helper to make it easier to define an occ_attribute. Since these + * are dynamically allocated, we cannot use the existing kernel macros which * stringify the name argument. */ -#define ATTR_OCC(_name, _mode, _show, _store) { \ - .attr = { \ - .name = _name, \ - .mode = VERIFY_OCTAL_PERMISSIONS(_mode), \ - }, \ - .show = _show, \ - .store = _store, \ -} +static void occ_init_attribute(struct occ_attribute *attr, int mode, + ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf), + ssize_t (*store)(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count), + int nr, int index, const char *fmt, ...) +{ + va_list args; -#define SENSOR_ATTR_OCC(_name, _mode, _show, _store, _nr, _index) { \ - .dev_attr = ATTR_OCC(_name, _mode, _show, _store), \ - .index = _index, \ - .nr = _nr, \ -} + va_start(args, fmt); + vsnprintf(attr->name, sizeof(attr->name), fmt, args); + va_end(args); -#define OCC_INIT_ATTR(_name, _mode, _show, _store, _nr, _index) \ - ((struct sensor_device_attribute_2) \ - SENSOR_ATTR_OCC(_name, _mode, _show, _store, _nr, _index)) + attr->sensor.dev_attr.attr.name = attr->name; + attr->sensor.dev_attr.attr.mode = mode; + attr->sensor.dev_attr.show = show; + attr->sensor.dev_attr.store = store; + attr->sensor.index = index; + attr->sensor.nr = nr; +} /* * Allocate and instatiate sensor_device_attribute_2s. It's most efficient to @@ -855,14 +856,15 @@ static int occ_setup_sensor_attrs(struct occ *occ) sensors->extended.num_sensors = 0; } - occ->attrs = devm_kzalloc(dev, sizeof(*occ->attrs) * num_attrs, + occ->attrs = devm_kcalloc(dev, num_attrs, sizeof(*occ->attrs), GFP_KERNEL); if (!occ->attrs) return -ENOMEM; /* null-terminated list */ - occ->group.attrs = devm_kzalloc(dev, sizeof(*occ->group.attrs) * - num_attrs + 1, GFP_KERNEL); + occ->group.attrs = devm_kcalloc(dev, num_attrs + 1, + sizeof(*occ->group.attrs), + GFP_KERNEL); if (!occ->group.attrs) return -ENOMEM; @@ -872,43 +874,33 @@ static int occ_setup_sensor_attrs(struct occ *occ) s = i + 1; temp = ((struct temp_sensor_2 *)sensors->temp.data) + i; - snprintf(attr->name, sizeof(attr->name), "temp%d_label", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_temp, NULL, - 0, i); + occ_init_attribute(attr, 0444, show_temp, NULL, + 0, i, "temp%d_label", s); attr++; if (sensors->temp.version == 2 && temp->fru_type == OCC_FRU_TYPE_VRM) { - snprintf(attr->name, sizeof(attr->name), - "temp%d_alarm", s); + occ_init_attribute(attr, 0444, show_temp, NULL, + 1, i, "temp%d_alarm", s); } else { - snprintf(attr->name, sizeof(attr->name), - "temp%d_input", s); + occ_init_attribute(attr, 0444, show_temp, NULL, + 1, i, "temp%d_input", s); } - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_temp, NULL, - 1, i); attr++; if (sensors->temp.version > 1) { - snprintf(attr->name, sizeof(attr->name), - "temp%d_fru_type", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, - show_temp, NULL, 2, i); + occ_init_attribute(attr, 0444, show_temp, NULL, + 2, i, "temp%d_fru_type", s); attr++; - snprintf(attr->name, sizeof(attr->name), - "temp%d_fault", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, - show_temp, NULL, 3, i); + occ_init_attribute(attr, 0444, show_temp, NULL, + 3, i, "temp%d_fault", s); attr++; if (sensors->temp.version == 0x10) { - snprintf(attr->name, sizeof(attr->name), - "temp%d_max", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, - show_temp, NULL, - 4, i); + occ_init_attribute(attr, 0444, show_temp, NULL, + 4, i, "temp%d_max", s); attr++; } } @@ -917,14 +909,12 @@ static int occ_setup_sensor_attrs(struct occ *occ) for (i = 0; i < sensors->freq.num_sensors; ++i) { s = i + 1; - snprintf(attr->name, sizeof(attr->name), "freq%d_label", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_freq, NULL, - 0, i); + occ_init_attribute(attr, 0444, show_freq, NULL, + 0, i, "freq%d_label", s); attr++; - snprintf(attr->name, sizeof(attr->name), "freq%d_input", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_freq, NULL, - 1, i); + occ_init_attribute(attr, 0444, show_freq, NULL, + 1, i, "freq%d_input", s); attr++; } @@ -940,32 +930,24 @@ static int occ_setup_sensor_attrs(struct occ *occ) s = (i * 4) + 1; for (j = 0; j < 4; ++j) { - snprintf(attr->name, sizeof(attr->name), - "power%d_label", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, - show_power, NULL, - nr++, i); + occ_init_attribute(attr, 0444, show_power, + NULL, nr++, i, + "power%d_label", s); attr++; - snprintf(attr->name, sizeof(attr->name), - "power%d_average", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, - show_power, NULL, - nr++, i); + occ_init_attribute(attr, 0444, show_power, + NULL, nr++, i, + "power%d_average", s); attr++; - snprintf(attr->name, sizeof(attr->name), - "power%d_average_interval", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, - show_power, NULL, - nr++, i); + occ_init_attribute(attr, 0444, show_power, + NULL, nr++, i, + "power%d_average_interval", s); attr++; - snprintf(attr->name, sizeof(attr->name), - "power%d_input", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, - show_power, NULL, - nr++, i); + occ_init_attribute(attr, 0444, show_power, + NULL, nr++, i, + "power%d_input", s); attr++; s++; @@ -977,28 +959,20 @@ static int occ_setup_sensor_attrs(struct occ *occ) for (i = 0; i < sensors->power.num_sensors; ++i) { s = i + 1; - snprintf(attr->name, sizeof(attr->name), - "power%d_label", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, - show_power, NULL, 0, i); + occ_init_attribute(attr, 0444, show_power, NULL, + 0, i, "power%d_label", s); attr++; - snprintf(attr->name, sizeof(attr->name), - "power%d_average", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, - show_power, NULL, 1, i); + occ_init_attribute(attr, 0444, show_power, NULL, + 1, i, "power%d_average", s); attr++; - snprintf(attr->name, sizeof(attr->name), - "power%d_average_interval", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, - show_power, NULL, 2, i); + occ_init_attribute(attr, 0444, show_power, NULL, + 2, i, "power%d_average_interval", s); attr++; - snprintf(attr->name, sizeof(attr->name), - "power%d_input", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, - show_power, NULL, 3, i); + occ_init_attribute(attr, 0444, show_power, NULL, + 3, i, "power%d_input", s); attr++; } @@ -1006,56 +980,43 @@ static int occ_setup_sensor_attrs(struct occ *occ) } if (sensors->caps.num_sensors >= 1) { - snprintf(attr->name, sizeof(attr->name), "power%d_label", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL, - 0, 0); + occ_init_attribute(attr, 0444, show_caps, NULL, + 0, 0, "power%d_label", s); attr++; - snprintf(attr->name, sizeof(attr->name), "power%d_cap", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL, - 1, 0); + occ_init_attribute(attr, 0444, show_caps, NULL, + 1, 0, "power%d_cap", s); attr++; - snprintf(attr->name, sizeof(attr->name), "power%d_input", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL, - 2, 0); + occ_init_attribute(attr, 0444, show_caps, NULL, + 2, 0, "power%d_input", s); attr++; - snprintf(attr->name, sizeof(attr->name), - "power%d_cap_not_redundant", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL, - 3, 0); + occ_init_attribute(attr, 0444, show_caps, NULL, + 3, 0, "power%d_cap_not_redundant", s); attr++; - snprintf(attr->name, sizeof(attr->name), "power%d_cap_max", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL, - 4, 0); + occ_init_attribute(attr, 0444, show_caps, NULL, + 4, 0, "power%d_cap_max", s); attr++; - snprintf(attr->name, sizeof(attr->name), "power%d_cap_min", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL, - 5, 0); + occ_init_attribute(attr, 0444, show_caps, NULL, + 5, 0, "power%d_cap_min", s); attr++; - snprintf(attr->name, sizeof(attr->name), "power%d_cap_user", - s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0644, show_caps, - occ_store_caps_user, 6, 0); + occ_init_attribute(attr, 0644, show_caps, occ_store_caps_user, + 6, 0, "power%d_cap_user", s); attr++; if (sensors->caps.version > 1) { - snprintf(attr->name, sizeof(attr->name), - "power%d_cap_user_source", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, - show_caps, NULL, 7, 0); + occ_init_attribute(attr, 0444, show_caps, NULL, + 7, 0, "power%d_cap_user_source", s); attr++; if (sensors->caps.version > 2) { - snprintf(attr->name, sizeof(attr->name), - "power%d_cap_min_soft", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, - show_caps, NULL, - 8, 0); + occ_init_attribute(attr, 0444, show_caps, NULL, + 8, 0, + "power%d_cap_min_soft", s); attr++; } } @@ -1064,19 +1025,16 @@ static int occ_setup_sensor_attrs(struct occ *occ) for (i = 0; i < sensors->extended.num_sensors; ++i) { s = i + 1; - snprintf(attr->name, sizeof(attr->name), "extn%d_label", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, - occ_show_extended, NULL, 0, i); + occ_init_attribute(attr, 0444, occ_show_extended, NULL, + 0, i, "extn%d_label", s); attr++; - snprintf(attr->name, sizeof(attr->name), "extn%d_flags", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, - occ_show_extended, NULL, 1, i); + occ_init_attribute(attr, 0444, occ_show_extended, NULL, + 1, i, "extn%d_flags", s); attr++; - snprintf(attr->name, sizeof(attr->name), "extn%d_input", s); - attr->sensor = OCC_INIT_ATTR(attr->name, 0444, - occ_show_extended, NULL, 2, i); + occ_init_attribute(attr, 0444, occ_show_extended, NULL, + 2, i, "extn%d_input", s); attr++; } From 4c8f5b0483acd2d02b72bb29d1829a53208d4c46 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 10 Jun 2025 11:25:49 +0200 Subject: [PATCH 648/971] hwmon: (occ) fix unaligned accesses [ Upstream commit 2c021b45c154958566aad0cae9f74ab26a2d5732 ] Passing a pointer to an unaligned integer as a function argument is undefined behavior: drivers/hwmon/occ/common.c:492:27: warning: taking address of packed member 'accumulator' of class or structure 'power_sensor_2' may result in an unaligned pointer value [-Waddress-of-packed-member] 492 | val = occ_get_powr_avg(&power->accumulator, | ^~~~~~~~~~~~~~~~~~ drivers/hwmon/occ/common.c:493:13: warning: taking address of packed member 'update_tag' of class or structure 'power_sensor_2' may result in an unaligned pointer value [-Waddress-of-packed-member] 493 | &power->update_tag); | ^~~~~~~~~~~~~~~~~ Move the get_unaligned() calls out of the function and pass these through argument registers instead. Fixes: c10e753d43eb ("hwmon (occ): Add sensor types and versions") Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20250610092553.2641094-1-arnd@kernel.org Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin --- drivers/hwmon/occ/common.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/drivers/hwmon/occ/common.c b/drivers/hwmon/occ/common.c index 256cda99fdc9..483f79b39429 100644 --- a/drivers/hwmon/occ/common.c +++ b/drivers/hwmon/occ/common.c @@ -459,12 +459,10 @@ static ssize_t occ_show_power_1(struct device *dev, return sysfs_emit(buf, "%llu\n", val); } -static u64 occ_get_powr_avg(u64 *accum, u32 *samples) +static u64 occ_get_powr_avg(u64 accum, u32 samples) { - u64 divisor = get_unaligned_be32(samples); - - return (divisor == 0) ? 0 : - div64_u64(get_unaligned_be64(accum) * 1000000ULL, divisor); + return (samples == 0) ? 0 : + mul_u64_u32_div(accum, 1000000UL, samples); } static ssize_t occ_show_power_2(struct device *dev, @@ -489,8 +487,8 @@ static ssize_t occ_show_power_2(struct device *dev, get_unaligned_be32(&power->sensor_id), power->function_id, power->apss_channel); case 1: - val = occ_get_powr_avg(&power->accumulator, - &power->update_tag); + val = occ_get_powr_avg(get_unaligned_be64(&power->accumulator), + get_unaligned_be32(&power->update_tag)); break; case 2: val = (u64)get_unaligned_be32(&power->update_tag) * @@ -527,8 +525,8 @@ static ssize_t occ_show_power_a0(struct device *dev, return sysfs_emit(buf, "%u_system\n", get_unaligned_be32(&power->sensor_id)); case 1: - val = occ_get_powr_avg(&power->system.accumulator, - &power->system.update_tag); + val = occ_get_powr_avg(get_unaligned_be64(&power->system.accumulator), + get_unaligned_be32(&power->system.update_tag)); break; case 2: val = (u64)get_unaligned_be32(&power->system.update_tag) * @@ -541,8 +539,8 @@ static ssize_t occ_show_power_a0(struct device *dev, return sysfs_emit(buf, "%u_proc\n", get_unaligned_be32(&power->sensor_id)); case 5: - val = occ_get_powr_avg(&power->proc.accumulator, - &power->proc.update_tag); + val = occ_get_powr_avg(get_unaligned_be64(&power->proc.accumulator), + get_unaligned_be32(&power->proc.update_tag)); break; case 6: val = (u64)get_unaligned_be32(&power->proc.update_tag) * @@ -555,8 +553,8 @@ static ssize_t occ_show_power_a0(struct device *dev, return sysfs_emit(buf, "%u_vdd\n", get_unaligned_be32(&power->sensor_id)); case 9: - val = occ_get_powr_avg(&power->vdd.accumulator, - &power->vdd.update_tag); + val = occ_get_powr_avg(get_unaligned_be64(&power->vdd.accumulator), + get_unaligned_be32(&power->vdd.update_tag)); break; case 10: val = (u64)get_unaligned_be32(&power->vdd.update_tag) * @@ -569,8 +567,8 @@ static ssize_t occ_show_power_a0(struct device *dev, return sysfs_emit(buf, "%u_vdn\n", get_unaligned_be32(&power->sensor_id)); case 13: - val = occ_get_powr_avg(&power->vdn.accumulator, - &power->vdn.update_tag); + val = occ_get_powr_avg(get_unaligned_be64(&power->vdn.accumulator), + get_unaligned_be32(&power->vdn.update_tag)); break; case 14: val = (u64)get_unaligned_be32(&power->vdn.update_tag) * From 9311d6d1a54fa6d06478fbc027e60f1cc938d291 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Fri, 13 Jun 2025 17:46:20 +0100 Subject: [PATCH 649/971] pldmfw: Select CRC32 when PLDMFW is selected [ Upstream commit 1224b218a4b9203656ecc932152f4c81a97b4fcc ] pldmfw calls crc32 code and depends on it being enabled, else there is a link error as follows. So PLDMFW should select CRC32. lib/pldmfw/pldmfw.o: In function `pldmfw_flash_image': pldmfw.c:(.text+0x70f): undefined reference to `crc32_le_base' This problem was introduced by commit b8265621f488 ("Add pldmfw library for PLDM firmware update"). It manifests as of commit d69ea414c9b4 ("ice: implement device flash update via devlink"). And is more likely to occur as of commit 9ad19171b6d6 ("lib/crc: remove unnecessary prompt for CONFIG_CRC32 and drop 'default y'"). Found by chance while exercising builds based on tinyconfig. Fixes: b8265621f488 ("Add pldmfw library for PLDM firmware update") Signed-off-by: Simon Horman Reviewed-by: Jacob Keller Link: https://patch.msgid.link/20250613-pldmfw-crc32-v1-1-f3fad109eee6@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- lib/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Kconfig b/lib/Kconfig index ee365b7402f1..43d69669465a 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -751,6 +751,7 @@ config GENERIC_LIB_DEVMEM_IS_ALLOWED config PLDMFW bool + select CRC32 default n config ASN1_ENCODER From 8662ac79a63488e279b91c12a72b02bc0dc49f7b Mon Sep 17 00:00:00 2001 From: Justin Sanders Date: Tue, 10 Jun 2025 17:05:59 +0000 Subject: [PATCH 650/971] aoe: clean device rq_list in aoedev_downdev() [ Upstream commit 7f90d45e57cb2ef1f0adcaf925ddffdfc5e680ca ] An aoe device's rq_list contains accepted block requests that are waiting to be transmitted to the aoe target. This queue was added as part of the conversion to blk_mq. However, the queue was not cleaned out when an aoe device is downed which caused blk_mq_freeze_queue() to sleep indefinitely waiting for those requests to complete, causing a hang. This fix cleans out the queue before calling blk_mq_freeze_queue(). Link: https://bugzilla.kernel.org/show_bug.cgi?id=212665 Fixes: 3582dd291788 ("aoe: convert aoeblk to blk-mq") Signed-off-by: Justin Sanders Link: https://lore.kernel.org/r/20250610170600.869-1-jsanders.devel@gmail.com Tested-By: Valentin Kleibel Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- drivers/block/aoe/aoedev.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c index 3523dd82d7a0..280679bde3a5 100644 --- a/drivers/block/aoe/aoedev.c +++ b/drivers/block/aoe/aoedev.c @@ -198,6 +198,7 @@ aoedev_downdev(struct aoedev *d) { struct aoetgt *t, **tt, **te; struct list_head *head, *pos, *nx; + struct request *rq, *rqnext; int i; d->flags &= ~DEVFL_UP; @@ -223,6 +224,13 @@ aoedev_downdev(struct aoedev *d) /* clean out the in-process request (if any) */ aoe_failip(d); + /* clean out any queued block requests */ + list_for_each_entry_safe(rq, rqnext, &d->rq_list, queuelist) { + list_del_init(&rq->queuelist); + blk_mq_start_request(rq); + blk_mq_end_request(rq, BLK_STS_IOERR); + } + /* fast fail all pending I/O */ if (d->blkq) { /* UP is cleared, freeze+quiesce to insure all are errored */ From f4c19a8e51eeaf64bc0072e348c6858c4b28c296 Mon Sep 17 00:00:00 2001 From: Krishna Kumar Date: Tue, 20 May 2025 22:36:56 +0530 Subject: [PATCH 651/971] net: ice: Perform accurate aRFS flow match [ Upstream commit 5d3bc9e5e725aa36cca9b794e340057feb6880b4 ] This patch fixes an issue seen in a large-scale deployment under heavy incoming pkts where the aRFS flow wrongly matches a flow and reprograms the NIC with wrong settings. That mis-steering causes RX-path latency spikes and noisy neighbor effects when many connections collide on the same hash (some of our production servers have 20-30K connections). set_rps_cpu() calls ndo_rx_flow_steer() with flow_id that is calculated by hashing the skb sized by the per rx-queue table size. This results in multiple connections (even across different rx-queues) getting the same hash value. The driver steer function modifies the wrong flow to use this rx-queue, e.g.: Flow#1 is first added: Flow#1: , Hash 'h', q#10 Later when a new flow needs to be added: Flow#2: , Hash 'h', q#20 The driver finds the hash 'h' from Flow#1 and updates it to use q#20. This results in both flows getting un-optimized - packets for Flow#1 goes to q#20, and then reprogrammed back to q#10 later and so on; and Flow #2 programming is never done as Flow#1 is matched first for all misses. Many flows may wrongly share the same hash and reprogram rules of the original flow each with their own q#. Tested on two 144-core servers with 16K netperf sessions for 180s. Netperf clients are pinned to cores 0-71 sequentially (so that wrong packets on q#s 72-143 can be measured). IRQs are set 1:1 for queues -> CPUs, enable XPS, enable aRFS (global value is 144 * rps_flow_cnt). Test notes about results from ice_rx_flow_steer(): --------------------------------------------------- 1. "Skip:" counter increments here: if (fltr_info->q_index == rxq_idx || arfs_entry->fltr_state != ICE_ARFS_ACTIVE) goto out; 2. "Add:" counter increments here: ret = arfs_entry->fltr_info.fltr_id; INIT_HLIST_NODE(&arfs_entry->list_entry); 3. "Update:" counter increments here: /* update the queue to forward to on an already existing flow */ Runtime comparison: original code vs with the patch for different rps_flow_cnt values. +-------------------------------+--------------+--------------+ | rps_flow_cnt | 512 | 2048 | +-------------------------------+--------------+--------------+ | Ratio of Pkts on Good:Bad q's | 214 vs 822K | 1.1M vs 980K | | Avoid wrong aRFS programming | 0 vs 310K | 0 vs 30K | | CPU User | 216 vs 183 | 216 vs 206 | | CPU System | 1441 vs 1171 | 1447 vs 1320 | | CPU Softirq | 1245 vs 920 | 1238 vs 961 | | CPU Total | 29 vs 22.7 | 29 vs 24.9 | | aRFS Update | 533K vs 59 | 521K vs 32 | | aRFS Skip | 82M vs 77M | 7.2M vs 4.5M | +-------------------------------+--------------+--------------+ A separate TCP_STREAM and TCP_RR with 1,4,8,16,64,128,256,512 connections showed no performance degradation. Some points on the patch/aRFS behavior: 1. Enabling full tuple matching ensures flows are always correctly matched, even with smaller hash sizes. 2. 5-6% drop in CPU utilization as the packets arrive at the correct CPUs and fewer calls to driver for programming on misses. 3. Larger hash tables reduces mis-steering due to more unique flow hashes, but still has clashes. However, with larger per-device rps_flow_cnt, old flows take more time to expire and new aRFS flows cannot be added if h/w limits are reached (rps_may_expire_flow() succeeds when 10*rps_flow_cnt pkts have been processed by this cpu that are not part of the flow). Fixes: 28bf26724fdb0 ("ice: Implement aRFS") Signed-off-by: Krishna Kumar Reviewed-by: Simon Horman Tested-by: Rinitha S (A Contingent worker at Intel) Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/ice/ice_arfs.c | 48 +++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/drivers/net/ethernet/intel/ice/ice_arfs.c b/drivers/net/ethernet/intel/ice/ice_arfs.c index d7e0116f6773..7036070bc020 100644 --- a/drivers/net/ethernet/intel/ice/ice_arfs.c +++ b/drivers/net/ethernet/intel/ice/ice_arfs.c @@ -376,6 +376,50 @@ ice_arfs_is_perfect_flow_set(struct ice_hw *hw, __be16 l3_proto, u8 l4_proto) return false; } +/** + * ice_arfs_cmp - Check if aRFS filter matches this flow. + * @fltr_info: filter info of the saved ARFS entry. + * @fk: flow dissector keys. + * @n_proto: One of htons(ETH_P_IP) or htons(ETH_P_IPV6). + * @ip_proto: One of IPPROTO_TCP or IPPROTO_UDP. + * + * Since this function assumes limited values for n_proto and ip_proto, it + * is meant to be called only from ice_rx_flow_steer(). + * + * Return: + * * true - fltr_info refers to the same flow as fk. + * * false - fltr_info and fk refer to different flows. + */ +static bool +ice_arfs_cmp(const struct ice_fdir_fltr *fltr_info, const struct flow_keys *fk, + __be16 n_proto, u8 ip_proto) +{ + /* Determine if the filter is for IPv4 or IPv6 based on flow_type, + * which is one of ICE_FLTR_PTYPE_NONF_IPV{4,6}_{TCP,UDP}. + */ + bool is_v4 = fltr_info->flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP || + fltr_info->flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP; + + /* Following checks are arranged in the quickest and most discriminative + * fields first for early failure. + */ + if (is_v4) + return n_proto == htons(ETH_P_IP) && + fltr_info->ip.v4.src_port == fk->ports.src && + fltr_info->ip.v4.dst_port == fk->ports.dst && + fltr_info->ip.v4.src_ip == fk->addrs.v4addrs.src && + fltr_info->ip.v4.dst_ip == fk->addrs.v4addrs.dst && + fltr_info->ip.v4.proto == ip_proto; + + return fltr_info->ip.v6.src_port == fk->ports.src && + fltr_info->ip.v6.dst_port == fk->ports.dst && + fltr_info->ip.v6.proto == ip_proto && + !memcmp(&fltr_info->ip.v6.src_ip, &fk->addrs.v6addrs.src, + sizeof(struct in6_addr)) && + !memcmp(&fltr_info->ip.v6.dst_ip, &fk->addrs.v6addrs.dst, + sizeof(struct in6_addr)); +} + /** * ice_rx_flow_steer - steer the Rx flow to where application is being run * @netdev: ptr to the netdev being adjusted @@ -447,6 +491,10 @@ ice_rx_flow_steer(struct net_device *netdev, const struct sk_buff *skb, continue; fltr_info = &arfs_entry->fltr_info; + + if (!ice_arfs_cmp(fltr_info, &fk, n_proto, ip_proto)) + continue; + ret = fltr_info->fltr_id; if (fltr_info->q_index == rxq_idx || From aaef8e3a54b917234582f5ca268a3f3fac5be2e5 Mon Sep 17 00:00:00 2001 From: Vitaly Lifshits Date: Sun, 25 May 2025 11:38:43 +0300 Subject: [PATCH 652/971] e1000e: set fixed clock frequency indication for Nahum 11 and Nahum 13 [ Upstream commit 688a0d61b2d7427189c4eb036ce485d8fc957cbb ] On some systems with Nahum 11 and Nahum 13 the value of the XTAL clock in the software STRAP is incorrect. This causes the PTP timer to run at the wrong rate and can lead to synchronization issues. The STRAP value is configured by the system firmware, and a firmware update is not always possible. Since the XTAL clock on these systems always runs at 38.4MHz, the driver may ignore the STRAP and just set the correct value. Fixes: cc23f4f0b6b9 ("e1000e: Add support for Meteor Lake") Signed-off-by: Vitaly Lifshits Tested-by: Mor Bar-Gabay Reviewed-by: Gil Fine Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/e1000e/netdev.c | 14 +++++++++++--- drivers/net/ethernet/intel/e1000e/ptp.c | 8 +++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 721c098f2bb1..7e4fea0e186b 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -3540,9 +3540,6 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca) case e1000_pch_cnp: case e1000_pch_tgp: case e1000_pch_adp: - case e1000_pch_mtp: - case e1000_pch_lnp: - case e1000_pch_ptp: case e1000_pch_nvp: if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) { /* Stable 24MHz frequency */ @@ -3558,6 +3555,17 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca) adapter->cc.shift = shift; } break; + case e1000_pch_mtp: + case e1000_pch_lnp: + case e1000_pch_ptp: + /* System firmware can misreport this value, so set it to a + * stable 38400KHz frequency. + */ + incperiod = INCPERIOD_38400KHZ; + incvalue = INCVALUE_38400KHZ; + shift = INCVALUE_SHIFT_38400KHZ; + adapter->cc.shift = shift; + break; case e1000_82574: case e1000_82583: /* Stable 25MHz frequency */ diff --git a/drivers/net/ethernet/intel/e1000e/ptp.c b/drivers/net/ethernet/intel/e1000e/ptp.c index bbcfd529399b..d039dea48ca3 100644 --- a/drivers/net/ethernet/intel/e1000e/ptp.c +++ b/drivers/net/ethernet/intel/e1000e/ptp.c @@ -294,15 +294,17 @@ void e1000e_ptp_init(struct e1000_adapter *adapter) case e1000_pch_cnp: case e1000_pch_tgp: case e1000_pch_adp: - case e1000_pch_mtp: - case e1000_pch_lnp: - case e1000_pch_ptp: case e1000_pch_nvp: if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) adapter->ptp_clock_info.max_adj = MAX_PPB_24MHZ; else adapter->ptp_clock_info.max_adj = MAX_PPB_38400KHZ; break; + case e1000_pch_mtp: + case e1000_pch_lnp: + case e1000_pch_ptp: + adapter->ptp_clock_info.max_adj = MAX_PPB_38400KHZ; + break; case e1000_82574: case e1000_82583: adapter->ptp_clock_info.max_adj = MAX_PPB_25MHZ; From a8c669bbc831eec2094ed9e2054a9a0bb81a6c52 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Fri, 13 Jun 2025 20:47:48 +0300 Subject: [PATCH 653/971] ptp: fix breakage after ptp_vclock_in_use() rework [ Upstream commit 5ab73b010cad294851e558f1d4714a85c6f206c7 ] What is broken -------------- ptp4l, and any other application which calls clock_adjtime() on a physical clock, is greeted with error -EBUSY after commit 87f7ce260a3c ("ptp: remove ptp->n_vclocks check logic in ptp_vclock_in_use()"). Explanation for the breakage ---------------------------- The blamed commit was based on the false assumption that ptp_vclock_in_use() callers already test for n_vclocks prior to calling this function. This is notably incorrect for the code path below, in which there is, in fact, no n_vclocks test: ptp_clock_adjtime() -> ptp_clock_freerun() -> ptp_vclock_in_use() The result is that any clock adjustment on any physical clock is now impossible. This is _despite_ there not being any vclock over this physical clock. $ ptp4l -i eno0 -2 -P -m ptp4l[58.425]: selected /dev/ptp0 as PTP clock [ 58.429749] ptp: physical clock is free running ptp4l[58.431]: Failed to open /dev/ptp0: Device or resource busy failed to create a clock $ cat /sys/class/ptp/ptp0/n_vclocks 0 The patch makes the ptp_vclock_in_use() function say "if it's not a virtual clock, then this physical clock does have virtual clocks on top". Then ptp_clock_freerun() uses this information to say "this physical clock has virtual clocks on top, so it must stay free-running". Then ptp_clock_adjtime() uses this information to say "well, if this physical clock has to be free-running, I can't do it, return -EBUSY". Simply put, ptp_vclock_in_use() cannot be simplified so as to remove the test whether vclocks are in use. What did the blamed commit intend to fix ---------------------------------------- The blamed commit presents a lockdep warning stating "possible recursive locking detected", with the n_vclocks_store() and ptp_clock_unregister() functions involved. The recursive locking seems this: n_vclocks_store() -> mutex_lock_interruptible(&ptp->n_vclocks_mux) // 1 -> device_for_each_child_reverse(..., unregister_vclock) -> unregister_vclock() -> ptp_vclock_unregister() -> ptp_clock_unregister() -> ptp_vclock_in_use() -> mutex_lock_interruptible(&ptp->n_vclocks_mux) // 2 The issue can be triggered by creating and then deleting vclocks: $ echo 2 > /sys/class/ptp/ptp0/n_vclocks $ echo 0 > /sys/class/ptp/ptp0/n_vclocks But note that in the original stack trace, the address of the first lock is different from the address of the second lock. This is because at step 1 marked above, &ptp->n_vclocks_mux is the lock of the parent (physical) PTP clock, and at step 2, the lock is of the child (virtual) PTP clock. They are different locks of different devices. In this situation there is no real deadlock, the lockdep warning is caused by the fact that the mutexes have the same lock class on both the parent and the child. Functionally it is fine. Proposed alternative solution ----------------------------- We must reintroduce the body of ptp_vclock_in_use() mostly as it was structured prior to the blamed commit, but avoid the lockdep warning. Based on the fact that vclocks cannot be nested on top of one another (ptp_is_attribute_visible() hides n_vclocks for virtual clocks), we already know that ptp->n_vclocks is zero for a virtual clock. And ptp->is_virtual_clock is a runtime invariant, established at ptp_clock_register() time and never changed. There is no need to serialize on any mutex in order to read ptp->is_virtual_clock, and we take advantage of that by moving it outside the lock. Thus, virtual clocks do not need to acquire &ptp->n_vclocks_mux at all, and step 2 in the code walkthrough above can simply go away. We can simply return false to the question "ptp_vclock_in_use(a virtual clock)". Other notes ----------- Releasing &ptp->n_vclocks_mux before ptp_vclock_in_use() returns execution seems racy, because the returned value can become stale as soon as the function returns and before the return value is used (i.e. n_vclocks_store() can run any time). The locking requirement should somehow be transferred to the caller, to ensure a longer life time for the returned value, but this seems out of scope for this severe bug fix. Because we are also fixing up the logic from the original commit, there is another Fixes: tag for that. Fixes: 87f7ce260a3c ("ptp: remove ptp->n_vclocks check logic in ptp_vclock_in_use()") Fixes: 73f37068d540 ("ptp: support ptp physical/virtual clocks conversion") Signed-off-by: Vladimir Oltean Link: https://patch.msgid.link/20250613174749.406826-2-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/ptp/ptp_private.h | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h index d0eb4555720e..a54124269c2f 100644 --- a/drivers/ptp/ptp_private.h +++ b/drivers/ptp/ptp_private.h @@ -89,7 +89,27 @@ static inline int queue_cnt(const struct timestamp_event_queue *q) /* Check if ptp virtual clock is in use */ static inline bool ptp_vclock_in_use(struct ptp_clock *ptp) { - return !ptp->is_virtual_clock; + bool in_use = false; + + /* Virtual clocks can't be stacked on top of virtual clocks. + * Avoid acquiring the n_vclocks_mux on virtual clocks, to allow this + * function to be called from code paths where the n_vclocks_mux of the + * parent physical clock is already held. Functionally that's not an + * issue, but lockdep would complain, because they have the same lock + * class. + */ + if (ptp->is_virtual_clock) + return false; + + if (mutex_lock_interruptible(&ptp->n_vclocks_mux)) + return true; + + if (ptp->n_vclocks) + in_use = true; + + mutex_unlock(&ptp->n_vclocks_mux); + + return in_use; } /* Check if ptp clock shall be free running */ From 43e3433a48c303b9dac1e72cd7eebce0be1e2cb3 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Fri, 13 Jun 2025 20:47:49 +0300 Subject: [PATCH 654/971] ptp: allow reading of currently dialed frequency to succeed on free-running clocks [ Upstream commit aa112cbc5f0ac6f3b44d829005bf34005d9fe9bb ] There is a bug in ptp_clock_adjtime() which makes it refuse the operation even if we just want to read the current clock dialed frequency, not modify anything (tx->modes == 0). That should be possible even if the clock is free-running. For context, the kernel UAPI is the same for getting and setting the frequency of a POSIX clock. For example, ptp4l errors out at clock_create() -> clockadj_get_freq() -> clock_adjtime() time, when it should logically only have failed on actual adjustments to the clock, aka if the clock was configured as slave. But in master mode it should work. This was discovered when examining the issue described in the previous commit, where ptp_clock_freerun() returned true despite n_vclocks being zero. Fixes: 73f37068d540 ("ptp: support ptp physical/virtual clocks conversion") Signed-off-by: Vladimir Oltean Link: https://patch.msgid.link/20250613174749.406826-3-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/ptp/ptp_clock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index 6b7e8b7ebcef..b7fc260ed43b 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -104,7 +104,8 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct __kernel_timex *tx) struct ptp_clock_info *ops; int err = -EOPNOTSUPP; - if (ptp_clock_freerun(ptp)) { + if (tx->modes & (ADJ_SETOFFSET | ADJ_FREQUENCY | ADJ_OFFSET) && + ptp_clock_freerun(ptp)) { pr_err("ptp: physical clock is free running\n"); return -EBUSY; } From 4e9ab5c48ad5153cc908dd29abad0cd2a92951e4 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Mon, 16 Jun 2025 21:12:05 +0300 Subject: [PATCH 655/971] wifi: carl9170: do not ping device which has failed to load firmware [ Upstream commit 15d25307692312cec4b57052da73387f91a2e870 ] Syzkaller reports [1, 2] crashes caused by an attempts to ping the device which has failed to load firmware. Since such a device doesn't pass 'ieee80211_register_hw()', an internal workqueue managed by 'ieee80211_queue_work()' is not yet created and an attempt to queue work on it causes null-ptr-deref. [1] https://syzkaller.appspot.com/bug?extid=9a4aec827829942045ff [2] https://syzkaller.appspot.com/bug?extid=0d8afba53e8fb2633217 Fixes: e4a668c59080 ("carl9170: fix spurious restart due to high latency") Signed-off-by: Dmitry Antipov Acked-by: Christian Lamparter Link: https://patch.msgid.link/20250616181205.38883-1-dmantipov@yandex.ru Signed-off-by: Jeff Johnson Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/carl9170/usb.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index a5265997b576..debac4699687 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -438,14 +438,21 @@ static void carl9170_usb_rx_complete(struct urb *urb) if (atomic_read(&ar->rx_anch_urbs) == 0) { /* - * The system is too slow to cope with - * the enormous workload. We have simply - * run out of active rx urbs and this - * unfortunately leads to an unpredictable - * device. + * At this point, either the system is too slow to + * cope with the enormous workload (so we have simply + * run out of active rx urbs and this unfortunately + * leads to an unpredictable device), or the device + * is not fully functional after an unsuccessful + * firmware loading attempts (so it doesn't pass + * ieee80211_register_hw() and there is no internal + * workqueue at all). */ - ieee80211_queue_work(ar->hw, &ar->ping_work); + if (ar->registered) + ieee80211_queue_work(ar->hw, &ar->ping_work); + else + pr_warn_once("device %s is not registered\n", + dev_name(&ar->udev->dev)); } } else { /* From a060781640012d5d5105072f4c44ed6ad6830ef9 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Mon, 16 Jun 2025 13:15:12 -0700 Subject: [PATCH 656/971] mpls: Use rcu_dereference_rtnl() in mpls_route_input_rcu(). [ Upstream commit 6dbb0d97c5096072c78a6abffe393584e57ae945 ] As syzbot reported [0], mpls_route_input_rcu() can be called from mpls_getroute(), where is under RTNL. net->mpls.platform_label is only updated under RTNL. Let's use rcu_dereference_rtnl() in mpls_route_input_rcu() to silence the splat. [0]: WARNING: suspicious RCU usage 6.15.0-rc7-syzkaller-00082-g5cdb2c77c4c3 #0 Not tainted ---------------------------- net/mpls/af_mpls.c:84 suspicious rcu_dereference_check() usage! other info that might help us debug this: rcu_scheduler_active = 2, debug_locks = 1 1 lock held by syz.2.4451/17730: #0: ffffffff9012a3e8 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_lock net/core/rtnetlink.c:80 [inline] #0: ffffffff9012a3e8 (rtnl_mutex){+.+.}-{4:4}, at: rtnetlink_rcv_msg+0x371/0xe90 net/core/rtnetlink.c:6961 stack backtrace: CPU: 1 UID: 0 PID: 17730 Comm: syz.2.4451 Not tainted 6.15.0-rc7-syzkaller-00082-g5cdb2c77c4c3 #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/07/2025 Call Trace: __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x16c/0x1f0 lib/dump_stack.c:120 lockdep_rcu_suspicious+0x166/0x260 kernel/locking/lockdep.c:6865 mpls_route_input_rcu+0x1d4/0x200 net/mpls/af_mpls.c:84 mpls_getroute+0x621/0x1ea0 net/mpls/af_mpls.c:2381 rtnetlink_rcv_msg+0x3c9/0xe90 net/core/rtnetlink.c:6964 netlink_rcv_skb+0x16d/0x440 net/netlink/af_netlink.c:2534 netlink_unicast_kernel net/netlink/af_netlink.c:1313 [inline] netlink_unicast+0x53a/0x7f0 net/netlink/af_netlink.c:1339 netlink_sendmsg+0x8d1/0xdd0 net/netlink/af_netlink.c:1883 sock_sendmsg_nosec net/socket.c:712 [inline] __sock_sendmsg net/socket.c:727 [inline] ____sys_sendmsg+0xa98/0xc70 net/socket.c:2566 ___sys_sendmsg+0x134/0x1d0 net/socket.c:2620 __sys_sendmmsg+0x200/0x420 net/socket.c:2709 __do_sys_sendmmsg net/socket.c:2736 [inline] __se_sys_sendmmsg net/socket.c:2733 [inline] __x64_sys_sendmmsg+0x9c/0x100 net/socket.c:2733 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcd/0x230 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f0a2818e969 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f0a28f52038 EFLAGS: 00000246 ORIG_RAX: 0000000000000133 RAX: ffffffffffffffda RBX: 00007f0a283b5fa0 RCX: 00007f0a2818e969 RDX: 0000000000000003 RSI: 0000200000000080 RDI: 0000000000000003 RBP: 00007f0a28210ab1 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000000000 R14: 00007f0a283b5fa0 R15: 00007ffce5e9f268 Fixes: 0189197f4416 ("mpls: Basic routing support") Reported-by: syzbot+8a583bdd1a5cc0b0e068@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/68507981.a70a0220.395abc.01ef.GAE@google.com/ Signed-off-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20250616201532.1036568-1-kuni1840@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/mpls/af_mpls.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 43e8343df0db..5a4b175b78c8 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -81,8 +81,8 @@ static struct mpls_route *mpls_route_input_rcu(struct net *net, unsigned index) if (index < net->mpls.platform_labels) { struct mpls_route __rcu **platform_label = - rcu_dereference(net->mpls.platform_label); - rt = rcu_dereference(platform_label[index]); + rcu_dereference_rtnl(net->mpls.platform_label); + rt = rcu_dereference_rtnl(platform_label[index]); } return rt; } From 3261c017a7c5d2815c6a388c5a3280d1fba0e8db Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Mon, 16 Jun 2025 11:21:14 -0700 Subject: [PATCH 657/971] atm: atmtcp: Free invalid length skb in atmtcp_c_send(). [ Upstream commit 2f370ae1fb6317985f3497b1bb80d457508ca2f7 ] syzbot reported the splat below. [0] vcc_sendmsg() copies data passed from userspace to skb and passes it to vcc->dev->ops->send(). atmtcp_c_send() accesses skb->data as struct atmtcp_hdr after checking if skb->len is 0, but it's not enough. Also, when skb->len == 0, skb and sk (vcc) were leaked because dev_kfree_skb() is not called and sk_wmem_alloc adjustment is missing to revert atm_account_tx() in vcc_sendmsg(), which is expected to be done in atm_pop_raw(). Let's properly free skb with an invalid length in atmtcp_c_send(). [0]: BUG: KMSAN: uninit-value in atmtcp_c_send+0x255/0xed0 drivers/atm/atmtcp.c:294 atmtcp_c_send+0x255/0xed0 drivers/atm/atmtcp.c:294 vcc_sendmsg+0xd7c/0xff0 net/atm/common.c:644 sock_sendmsg_nosec net/socket.c:712 [inline] __sock_sendmsg+0x330/0x3d0 net/socket.c:727 ____sys_sendmsg+0x7e0/0xd80 net/socket.c:2566 ___sys_sendmsg+0x271/0x3b0 net/socket.c:2620 __sys_sendmsg net/socket.c:2652 [inline] __do_sys_sendmsg net/socket.c:2657 [inline] __se_sys_sendmsg net/socket.c:2655 [inline] __x64_sys_sendmsg+0x211/0x3e0 net/socket.c:2655 x64_sys_call+0x32fb/0x3db0 arch/x86/include/generated/asm/syscalls_64.h:47 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xd9/0x210 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f Uninit was created at: slab_post_alloc_hook mm/slub.c:4154 [inline] slab_alloc_node mm/slub.c:4197 [inline] kmem_cache_alloc_node_noprof+0x818/0xf00 mm/slub.c:4249 kmalloc_reserve+0x13c/0x4b0 net/core/skbuff.c:579 __alloc_skb+0x347/0x7d0 net/core/skbuff.c:670 alloc_skb include/linux/skbuff.h:1336 [inline] vcc_sendmsg+0xb40/0xff0 net/atm/common.c:628 sock_sendmsg_nosec net/socket.c:712 [inline] __sock_sendmsg+0x330/0x3d0 net/socket.c:727 ____sys_sendmsg+0x7e0/0xd80 net/socket.c:2566 ___sys_sendmsg+0x271/0x3b0 net/socket.c:2620 __sys_sendmsg net/socket.c:2652 [inline] __do_sys_sendmsg net/socket.c:2657 [inline] __se_sys_sendmsg net/socket.c:2655 [inline] __x64_sys_sendmsg+0x211/0x3e0 net/socket.c:2655 x64_sys_call+0x32fb/0x3db0 arch/x86/include/generated/asm/syscalls_64.h:47 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xd9/0x210 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f CPU: 1 UID: 0 PID: 5798 Comm: syz-executor192 Not tainted 6.16.0-rc1-syzkaller-00010-g2c4a1f3fe03e #0 PREEMPT(undef) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/07/2025 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: syzbot+1d3c235276f62963e93a@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=1d3c235276f62963e93a Tested-by: syzbot+1d3c235276f62963e93a@syzkaller.appspotmail.com Signed-off-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20250616182147.963333-2-kuni1840@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/atm/atmtcp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c index 96bea1ab1ecc..ff558908897f 100644 --- a/drivers/atm/atmtcp.c +++ b/drivers/atm/atmtcp.c @@ -288,7 +288,9 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb) struct sk_buff *new_skb; int result = 0; - if (!skb->len) return 0; + if (skb->len < sizeof(struct atmtcp_hdr)) + goto done; + dev = vcc->dev_data; hdr = (struct atmtcp_hdr *) skb->data; if (hdr->length == ATMTCP_HDR_MAGIC) { From 9d0ddfb574a2255ad84c036b15d84e1e6c06ba0e Mon Sep 17 00:00:00 2001 From: Neal Cardwell Date: Fri, 13 Jun 2025 15:30:56 -0400 Subject: [PATCH 658/971] tcp: fix tcp_packet_delayed() for tcp_is_non_sack_preventing_reopen() behavior [ Upstream commit d0fa59897e049e84432600e86df82aab3dce7aa5 ] After the following commit from 2024: commit e37ab7373696 ("tcp: fix to allow timestamp undo if no retransmits were sent") ...there was buggy behavior where TCP connections without SACK support could easily see erroneous undo events at the end of fast recovery or RTO recovery episodes. The erroneous undo events could cause those connections to suffer repeated loss recovery episodes and high retransmit rates. The problem was an interaction between the non-SACK behavior on these connections and the undo logic. The problem is that, for non-SACK connections at the end of a loss recovery episode, if snd_una == high_seq, then tcp_is_non_sack_preventing_reopen() holds steady in CA_Recovery or CA_Loss, but clears tp->retrans_stamp to 0. Then upon the next ACK the "tcp: fix to allow timestamp undo if no retransmits were sent" logic saw the tp->retrans_stamp at 0 and erroneously concluded that no data was retransmitted, and erroneously performed an undo of the cwnd reduction, restoring cwnd immediately to the value it had before loss recovery. This caused an immediate burst of traffic and build-up of queues and likely another immediate loss recovery episode. This commit fixes tcp_packet_delayed() to ignore zero retrans_stamp values for non-SACK connections when snd_una is at or above high_seq, because tcp_is_non_sack_preventing_reopen() clears retrans_stamp in this case, so it's not a valid signal that we can undo. Note that the commit named in the Fixes footer restored long-present behavior from roughly 2005-2019, so apparently this bug was present for a while during that era, and this was simply not caught. Fixes: e37ab7373696 ("tcp: fix to allow timestamp undo if no retransmits were sent") Reported-by: Eric Wheeler Closes: https://lore.kernel.org/netdev/64ea9333-e7f9-0df-b0f2-8d566143acab@ewheeler.net/ Signed-off-by: Neal Cardwell Co-developed-by: Yuchung Cheng Signed-off-by: Yuchung Cheng Reviewed-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/ipv4/tcp_input.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 66d6ad6d633c..f7b95bc8ad60 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -2463,20 +2463,33 @@ static inline bool tcp_packet_delayed(const struct tcp_sock *tp) { const struct sock *sk = (const struct sock *)tp; - if (tp->retrans_stamp && - tcp_tsopt_ecr_before(tp, tp->retrans_stamp)) - return true; /* got echoed TS before first retransmission */ + /* Received an echoed timestamp before the first retransmission? */ + if (tp->retrans_stamp) + return tcp_tsopt_ecr_before(tp, tp->retrans_stamp); - /* Check if nothing was retransmitted (retrans_stamp==0), which may - * happen in fast recovery due to TSQ. But we ignore zero retrans_stamp - * in TCP_SYN_SENT, since when we set FLAG_SYN_ACKED we also clear - * retrans_stamp even if we had retransmitted the SYN. + /* We set tp->retrans_stamp upon the first retransmission of a loss + * recovery episode, so normally if tp->retrans_stamp is 0 then no + * retransmission has happened yet (likely due to TSQ, which can cause + * fast retransmits to be delayed). So if snd_una advanced while + * (tp->retrans_stamp is 0 then apparently a packet was merely delayed, + * not lost. But there are exceptions where we retransmit but then + * clear tp->retrans_stamp, so we check for those exceptions. */ - if (!tp->retrans_stamp && /* no record of a retransmit/SYN? */ - sk->sk_state != TCP_SYN_SENT) /* not the FLAG_SYN_ACKED case? */ - return true; /* nothing was retransmitted */ - return false; + /* (1) For non-SACK connections, tcp_is_non_sack_preventing_reopen() + * clears tp->retrans_stamp when snd_una == high_seq. + */ + if (!tcp_is_sack(tp) && !before(tp->snd_una, tp->high_seq)) + return false; + + /* (2) In TCP_SYN_SENT tcp_clean_rtx_queue() clears tp->retrans_stamp + * when setting FLAG_SYN_ACKED is set, even if the SYN was + * retransmitted. + */ + if (sk->sk_state == TCP_SYN_SENT) + return false; + + return true; /* tp->retrans_stamp is zero; no retransmit yet */ } /* Undo procedures. */ From d3dfe821dfe091c0045044343c8d86596d66e2cf Mon Sep 17 00:00:00 2001 From: Haixia Qu Date: Tue, 17 Jun 2025 05:56:24 +0000 Subject: [PATCH 659/971] tipc: fix null-ptr-deref when acquiring remote ip of ethernet bearer [ Upstream commit f82727adcf2992822e12198792af450a76ebd5ef ] The reproduction steps: 1. create a tun interface 2. enable l2 bearer 3. TIPC_NL_UDP_GET_REMOTEIP with media name set to tun tipc: Started in network mode tipc: Node identity 8af312d38a21, cluster identity 4711 tipc: Enabled bearer , priority 1 Oops: general protection fault KASAN: null-ptr-deref in range CPU: 1 UID: 1000 PID: 559 Comm: poc Not tainted 6.16.0-rc1+ #117 PREEMPT Hardware name: QEMU Ubuntu 24.04 PC RIP: 0010:tipc_udp_nl_dump_remoteip+0x4a4/0x8f0 the ub was in fact a struct dev. when bid != 0 && skip_cnt != 0, bearer_list[bid] may be NULL or other media when other thread changes it. fix this by checking media_id. Fixes: 832629ca5c313 ("tipc: add UDP remoteip dump to netlink API") Signed-off-by: Haixia Qu Reviewed-by: Tung Nguyen Link: https://patch.msgid.link/20250617055624.2680-1-hxqu@hillstonenet.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/tipc/udp_media.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c index b16ca400ff55..e993bd6ed7c2 100644 --- a/net/tipc/udp_media.c +++ b/net/tipc/udp_media.c @@ -489,7 +489,7 @@ int tipc_udp_nl_dump_remoteip(struct sk_buff *skb, struct netlink_callback *cb) rtnl_lock(); b = tipc_bearer_find(net, bname); - if (!b) { + if (!b || b->bcast_addr.media_id != TIPC_MEDIA_TYPE_UDP) { rtnl_unlock(); return -EINVAL; } @@ -500,7 +500,7 @@ int tipc_udp_nl_dump_remoteip(struct sk_buff *skb, struct netlink_callback *cb) rtnl_lock(); b = rtnl_dereference(tn->bearer_list[bid]); - if (!b) { + if (!b || b->bcast_addr.media_id != TIPC_MEDIA_TYPE_UDP) { rtnl_unlock(); return -EINVAL; } From 235aa081e2d97f8548d0e362631f52bf59b2a676 Mon Sep 17 00:00:00 2001 From: David Wei Date: Tue, 17 Jun 2025 14:21:02 -0700 Subject: [PATCH 660/971] tcp: fix passive TFO socket having invalid NAPI ID [ Upstream commit dbe0ca8da1f62b6252e7be6337209f4d86d4a914 ] There is a bug with passive TFO sockets returning an invalid NAPI ID 0 from SO_INCOMING_NAPI_ID. Normally this is not an issue, but zero copy receive relies on a correct NAPI ID to process sockets on the right queue. Fix by adding a sk_mark_napi_id_set(). Fixes: e5907459ce7e ("tcp: Record Rx hash and NAPI ID in tcp_child_process") Signed-off-by: David Wei Reviewed-by: Kuniyuki Iwashima Reviewed-by: Eric Dumazet Link: https://patch.msgid.link/20250617212102.175711-5-dw@davidwei.uk Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/ipv4/tcp_fastopen.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c index 32b28fc21b63..408985eb74ee 100644 --- a/net/ipv4/tcp_fastopen.c +++ b/net/ipv4/tcp_fastopen.c @@ -3,6 +3,7 @@ #include #include #include +#include void tcp_fastopen_init_key_once(struct net *net) { @@ -279,6 +280,8 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk, refcount_set(&req->rsk_refcnt, 2); + sk_mark_napi_id_set(child, skb); + /* Now finish processing the fastopen child socket. */ tcp_init_transfer(child, BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB, skb); From 7382b6f7d1029baf94067afcbef71a31aa99937b Mon Sep 17 00:00:00 2001 From: Rengarajan S Date: Thu, 2 May 2024 10:33:00 +0530 Subject: [PATCH 661/971] net: microchip: lan743x: Reduce PTP timeout on HW failure [ Upstream commit b1de3c0df7abc41dc41862c0b08386411f2799d7 ] The PTP_CMD_CTL is a self clearing register which controls the PTP clock values. In the current implementation driver waits for a duration of 20 sec in case of HW failure to clear the PTP_CMD_CTL register bit. This timeout of 20 sec is very long to recognize a HW failure, as it is typically cleared in one clock(<16ns). Hence reducing the timeout to 1 sec would be sufficient to conclude if there is any HW failure observed. The usleep_range will sleep somewhere between 1 msec to 20 msec for each iteration. By setting the PTP_CMD_CTL_TIMEOUT_CNT to 50 the max timeout is extended to 1 sec. Signed-off-by: Rengarajan S Reviewed-by: Simon Horman Link: https://lore.kernel.org/r/20240502050300.38689-1-rengarajan.s@microchip.com Signed-off-by: Paolo Abeni Stable-dep-of: e353b0854d3a ("net: lan743x: fix potential out-of-bounds write in lan743x_ptp_io_event_clock_get()") Signed-off-by: Sasha Levin --- drivers/net/ethernet/microchip/lan743x_ptp.c | 2 +- drivers/net/ethernet/microchip/lan743x_ptp.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/microchip/lan743x_ptp.c b/drivers/net/ethernet/microchip/lan743x_ptp.c index 39e1066ecd5f..47f2531198f6 100644 --- a/drivers/net/ethernet/microchip/lan743x_ptp.c +++ b/drivers/net/ethernet/microchip/lan743x_ptp.c @@ -58,7 +58,7 @@ int lan743x_gpio_init(struct lan743x_adapter *adapter) static void lan743x_ptp_wait_till_cmd_done(struct lan743x_adapter *adapter, u32 bit_mask) { - int timeout = 1000; + int timeout = PTP_CMD_CTL_TIMEOUT_CNT; u32 data = 0; while (timeout && diff --git a/drivers/net/ethernet/microchip/lan743x_ptp.h b/drivers/net/ethernet/microchip/lan743x_ptp.h index e26d4eff7133..0d29914cd460 100644 --- a/drivers/net/ethernet/microchip/lan743x_ptp.h +++ b/drivers/net/ethernet/microchip/lan743x_ptp.h @@ -21,6 +21,7 @@ #define LAN743X_PTP_N_EXTTS 4 #define LAN743X_PTP_N_PPS 0 #define PCI11X1X_PTP_IO_MAX_CHANNELS 8 +#define PTP_CMD_CTL_TIMEOUT_CNT 50 struct lan743x_adapter; From 66bba1fd5bad548c03f7e42669a59f3f4d8211cc Mon Sep 17 00:00:00 2001 From: Alexey Kodanev Date: Mon, 16 Jun 2025 11:37:43 +0000 Subject: [PATCH 662/971] net: lan743x: fix potential out-of-bounds write in lan743x_ptp_io_event_clock_get() [ Upstream commit e353b0854d3a1a31cb061df8d022fbfea53a0f24 ] Before calling lan743x_ptp_io_event_clock_get(), the 'channel' value is checked against the maximum value of PCI11X1X_PTP_IO_MAX_CHANNELS(8). This seems correct and aligns with the PTP interrupt status register (PTP_INT_STS) specifications. However, lan743x_ptp_io_event_clock_get() writes to ptp->extts[] with only LAN743X_PTP_N_EXTTS(4) elements, using channel as an index: lan743x_ptp_io_event_clock_get(..., u8 channel,...) { ... /* Update Local timestamp */ extts = &ptp->extts[channel]; extts->ts.tv_sec = sec; ... } To avoid an out-of-bounds write and utilize all the supported GPIO inputs, set LAN743X_PTP_N_EXTTS to 8. Detected using the static analysis tool - Svace. Fixes: 60942c397af6 ("net: lan743x: Add support for PTP-IO Event Input External Timestamp (extts)") Signed-off-by: Alexey Kodanev Reviewed-by: Jacob Keller Acked-by: Rengarajan S Link: https://patch.msgid.link/20250616113743.36284-1-aleksei.kodanev@bell-sw.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- drivers/net/ethernet/microchip/lan743x_ptp.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/microchip/lan743x_ptp.h b/drivers/net/ethernet/microchip/lan743x_ptp.h index 0d29914cd460..225e8232474d 100644 --- a/drivers/net/ethernet/microchip/lan743x_ptp.h +++ b/drivers/net/ethernet/microchip/lan743x_ptp.h @@ -18,9 +18,9 @@ */ #define LAN743X_PTP_N_EVENT_CHAN 2 #define LAN743X_PTP_N_PEROUT LAN743X_PTP_N_EVENT_CHAN -#define LAN743X_PTP_N_EXTTS 4 -#define LAN743X_PTP_N_PPS 0 #define PCI11X1X_PTP_IO_MAX_CHANNELS 8 +#define LAN743X_PTP_N_EXTTS PCI11X1X_PTP_IO_MAX_CHANNELS +#define LAN743X_PTP_N_PPS 0 #define PTP_CMD_CTL_TIMEOUT_CNT 50 struct lan743x_adapter; From 3162d8235c8c4d585525cee8a59d1c180940a968 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Thu, 19 Jun 2025 12:10:31 +1000 Subject: [PATCH 663/971] ublk: santizize the arguments from userspace when adding a device [ Upstream commit 8c8472855884355caf3d8e0c50adf825f83454b2 ] Sanity check the values for queue depth and number of queues we get from userspace when adding a device. Signed-off-by: Ronnie Sahlberg Reviewed-by: Ming Lei Fixes: 71f28f3136af ("ublk_drv: add io_uring based userspace block driver") Fixes: 62fe99cef94a ("ublk: add read()/write() support for ublk char device") Link: https://lore.kernel.org/r/20250619021031.181340-1-ronniesahlberg@gmail.com Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- drivers/block/ublk_drv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index 95095500f93a..df3e5aab4b5a 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -2323,6 +2323,9 @@ static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd) if (copy_from_user(&info, argp, sizeof(info))) return -EFAULT; + if (info.queue_depth > UBLK_MAX_QUEUE_DEPTH || info.nr_hw_queues > UBLK_MAX_NR_QUEUES) + return -EINVAL; + if (capable(CAP_SYS_ADMIN)) info.flags &= ~UBLK_F_UNPRIVILEGED_DEV; else if (!(info.flags & UBLK_F_UNPRIVILEGED_DEV)) From bde8833eb075ba8e8674de88e32de6b669966451 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Tue, 17 Jun 2025 15:40:42 -0700 Subject: [PATCH 664/971] calipso: Fix null-ptr-deref in calipso_req_{set,del}attr(). [ Upstream commit 10876da918fa1aec0227fb4c67647513447f53a9 ] syzkaller reported a null-ptr-deref in sock_omalloc() while allocating a CALIPSO option. [0] The NULL is of struct sock, which was fetched by sk_to_full_sk() in calipso_req_setattr(). Since commit a1a5344ddbe8 ("tcp: avoid two atomic ops for syncookies"), reqsk->rsk_listener could be NULL when SYN Cookie is returned to its client, as hinted by the leading SYN Cookie log. Here are 3 options to fix the bug: 1) Return 0 in calipso_req_setattr() 2) Return an error in calipso_req_setattr() 3) Alaways set rsk_listener 1) is no go as it bypasses LSM, but 2) effectively disables SYN Cookie for CALIPSO. 3) is also no go as there have been many efforts to reduce atomic ops and make TCP robust against DDoS. See also commit 3b24d854cb35 ("tcp/dccp: do not touch listener sk_refcnt under synflood"). As of the blamed commit, SYN Cookie already did not need refcounting, and no one has stumbled on the bug for 9 years, so no CALIPSO user will care about SYN Cookie. Let's return an error in calipso_req_setattr() and calipso_req_delattr() in the SYN Cookie case. This can be reproduced by [1] on Fedora and now connect() of nc times out. [0]: TCP: request_sock_TCPv6: Possible SYN flooding on port [::]:20002. Sending cookies. Oops: general protection fault, probably for non-canonical address 0xdffffc0000000006: 0000 [#1] PREEMPT SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000030-0x0000000000000037] CPU: 3 UID: 0 PID: 12262 Comm: syz.1.2611 Not tainted 6.14.0 #2 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014 RIP: 0010:read_pnet include/net/net_namespace.h:406 [inline] RIP: 0010:sock_net include/net/sock.h:655 [inline] RIP: 0010:sock_kmalloc+0x35/0x170 net/core/sock.c:2806 Code: 89 d5 41 54 55 89 f5 53 48 89 fb e8 25 e3 c6 fd e8 f0 91 e3 00 48 8d 7b 30 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 26 01 00 00 48 b8 00 00 00 00 00 fc ff df 4c 8b RSP: 0018:ffff88811af89038 EFLAGS: 00010216 RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffff888105266400 RDX: 0000000000000006 RSI: ffff88800c890000 RDI: 0000000000000030 RBP: 0000000000000050 R08: 0000000000000000 R09: ffff88810526640e R10: ffffed1020a4cc81 R11: ffff88810526640f R12: 0000000000000000 R13: 0000000000000820 R14: ffff888105266400 R15: 0000000000000050 FS: 00007f0653a07640(0000) GS:ffff88811af80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f863ba096f4 CR3: 00000000163c0005 CR4: 0000000000770ef0 PKRU: 80000000 Call Trace: ipv6_renew_options+0x279/0x950 net/ipv6/exthdrs.c:1288 calipso_req_setattr+0x181/0x340 net/ipv6/calipso.c:1204 calipso_req_setattr+0x56/0x80 net/netlabel/netlabel_calipso.c:597 netlbl_req_setattr+0x18a/0x440 net/netlabel/netlabel_kapi.c:1249 selinux_netlbl_inet_conn_request+0x1fb/0x320 security/selinux/netlabel.c:342 selinux_inet_conn_request+0x1eb/0x2c0 security/selinux/hooks.c:5551 security_inet_conn_request+0x50/0xa0 security/security.c:4945 tcp_v6_route_req+0x22c/0x550 net/ipv6/tcp_ipv6.c:825 tcp_conn_request+0xec8/0x2b70 net/ipv4/tcp_input.c:7275 tcp_v6_conn_request+0x1e3/0x440 net/ipv6/tcp_ipv6.c:1328 tcp_rcv_state_process+0xafa/0x52b0 net/ipv4/tcp_input.c:6781 tcp_v6_do_rcv+0x8a6/0x1a40 net/ipv6/tcp_ipv6.c:1667 tcp_v6_rcv+0x505e/0x5b50 net/ipv6/tcp_ipv6.c:1904 ip6_protocol_deliver_rcu+0x17c/0x1da0 net/ipv6/ip6_input.c:436 ip6_input_finish+0x103/0x180 net/ipv6/ip6_input.c:480 NF_HOOK include/linux/netfilter.h:314 [inline] NF_HOOK include/linux/netfilter.h:308 [inline] ip6_input+0x13c/0x6b0 net/ipv6/ip6_input.c:491 dst_input include/net/dst.h:469 [inline] ip6_rcv_finish net/ipv6/ip6_input.c:79 [inline] ip6_rcv_finish+0xb6/0x490 net/ipv6/ip6_input.c:69 NF_HOOK include/linux/netfilter.h:314 [inline] NF_HOOK include/linux/netfilter.h:308 [inline] ipv6_rcv+0xf9/0x490 net/ipv6/ip6_input.c:309 __netif_receive_skb_one_core+0x12e/0x1f0 net/core/dev.c:5896 __netif_receive_skb+0x1d/0x170 net/core/dev.c:6009 process_backlog+0x41e/0x13b0 net/core/dev.c:6357 __napi_poll+0xbd/0x710 net/core/dev.c:7191 napi_poll net/core/dev.c:7260 [inline] net_rx_action+0x9de/0xde0 net/core/dev.c:7382 handle_softirqs+0x19a/0x770 kernel/softirq.c:561 do_softirq.part.0+0x36/0x70 kernel/softirq.c:462 do_softirq arch/x86/include/asm/preempt.h:26 [inline] __local_bh_enable_ip+0xf1/0x110 kernel/softirq.c:389 local_bh_enable include/linux/bottom_half.h:33 [inline] rcu_read_unlock_bh include/linux/rcupdate.h:919 [inline] __dev_queue_xmit+0xc2a/0x3c40 net/core/dev.c:4679 dev_queue_xmit include/linux/netdevice.h:3313 [inline] neigh_hh_output include/net/neighbour.h:523 [inline] neigh_output include/net/neighbour.h:537 [inline] ip6_finish_output2+0xd69/0x1f80 net/ipv6/ip6_output.c:141 __ip6_finish_output net/ipv6/ip6_output.c:215 [inline] ip6_finish_output+0x5dc/0xd60 net/ipv6/ip6_output.c:226 NF_HOOK_COND include/linux/netfilter.h:303 [inline] ip6_output+0x24b/0x8d0 net/ipv6/ip6_output.c:247 dst_output include/net/dst.h:459 [inline] NF_HOOK include/linux/netfilter.h:314 [inline] NF_HOOK include/linux/netfilter.h:308 [inline] ip6_xmit+0xbbc/0x20d0 net/ipv6/ip6_output.c:366 inet6_csk_xmit+0x39a/0x720 net/ipv6/inet6_connection_sock.c:135 __tcp_transmit_skb+0x1a7b/0x3b40 net/ipv4/tcp_output.c:1471 tcp_transmit_skb net/ipv4/tcp_output.c:1489 [inline] tcp_send_syn_data net/ipv4/tcp_output.c:4059 [inline] tcp_connect+0x1c0c/0x4510 net/ipv4/tcp_output.c:4148 tcp_v6_connect+0x156c/0x2080 net/ipv6/tcp_ipv6.c:333 __inet_stream_connect+0x3a7/0xed0 net/ipv4/af_inet.c:677 tcp_sendmsg_fastopen+0x3e2/0x710 net/ipv4/tcp.c:1039 tcp_sendmsg_locked+0x1e82/0x3570 net/ipv4/tcp.c:1091 tcp_sendmsg+0x2f/0x50 net/ipv4/tcp.c:1358 inet6_sendmsg+0xb9/0x150 net/ipv6/af_inet6.c:659 sock_sendmsg_nosec net/socket.c:718 [inline] __sock_sendmsg+0xf4/0x2a0 net/socket.c:733 __sys_sendto+0x29a/0x390 net/socket.c:2187 __do_sys_sendto net/socket.c:2194 [inline] __se_sys_sendto net/socket.c:2190 [inline] __x64_sys_sendto+0xe1/0x1c0 net/socket.c:2190 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xc3/0x1d0 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f06553c47ed Code: 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f0653a06fc8 EFLAGS: 00000246 ORIG_RAX: 000000000000002c RAX: ffffffffffffffda RBX: 00007f0655605fa0 RCX: 00007f06553c47ed RDX: 0000000000000000 RSI: 0000000000000000 RDI: 000000000000000b RBP: 00007f065545db38 R08: 0000200000000140 R09: 000000000000001c R10: f7384d4ea84b01bd R11: 0000000000000246 R12: 0000000000000000 R13: 00007f0655605fac R14: 00007f0655606038 R15: 00007f06539e7000 Modules linked in: [1]: dnf install -y selinux-policy-targeted policycoreutils netlabel_tools procps-ng nmap-ncat mount -t selinuxfs none /sys/fs/selinux load_policy netlabelctl calipso add pass doi:1 netlabelctl map del default netlabelctl map add default address:::1 protocol:calipso,1 sysctl net.ipv4.tcp_syncookies=2 nc -l ::1 80 & nc ::1 80 Fixes: e1adea927080 ("calipso: Allow request sockets to be relabelled by the lsm.") Reported-by: syzkaller Reported-by: John Cheung Closes: https://lore.kernel.org/netdev/CAP=Rh=MvfhrGADy+-WJiftV2_WzMH4VEhEFmeT28qY+4yxNu4w@mail.gmail.com/ Signed-off-by: Kuniyuki Iwashima Acked-by: Paul Moore Link: https://patch.msgid.link/20250617224125.17299-1-kuni1840@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/ipv6/calipso.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/ipv6/calipso.c b/net/ipv6/calipso.c index c07e3da08d2a..24666291c54a 100644 --- a/net/ipv6/calipso.c +++ b/net/ipv6/calipso.c @@ -1210,6 +1210,10 @@ static int calipso_req_setattr(struct request_sock *req, struct ipv6_opt_hdr *old, *new; struct sock *sk = sk_to_full_sk(req_to_sk(req)); + /* sk is NULL for SYN+ACK w/ SYN Cookie */ + if (!sk) + return -ENOMEM; + if (req_inet->ipv6_opt && req_inet->ipv6_opt->hopopt) old = req_inet->ipv6_opt->hopopt; else @@ -1250,6 +1254,10 @@ static void calipso_req_delattr(struct request_sock *req) struct ipv6_txoptions *txopts; struct sock *sk = sk_to_full_sk(req_to_sk(req)); + /* sk is NULL for SYN+ACK w/ SYN Cookie */ + if (!sk) + return; + if (!req_inet->ipv6_opt || !req_inet->ipv6_opt->hopopt) return; From dffd03422ae6a459039c8602f410e6c0f4cbc6c8 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 18 Jun 2025 14:08:43 +0000 Subject: [PATCH 665/971] net: atm: add lec_mutex [ Upstream commit d13a3824bfd2b4774b671a75cf766a16637a0e67 ] syzbot found its way in net/atm/lec.c, and found an error path in lecd_attach() could leave a dangling pointer in dev_lec[]. Add a mutex to protect dev_lecp[] uses from lecd_attach(), lec_vcc_attach() and lec_mcast_attach(). Following patch will use this mutex for /proc/net/atm/lec. BUG: KASAN: slab-use-after-free in lecd_attach net/atm/lec.c:751 [inline] BUG: KASAN: slab-use-after-free in lane_ioctl+0x2224/0x23e0 net/atm/lec.c:1008 Read of size 8 at addr ffff88807c7b8e68 by task syz.1.17/6142 CPU: 1 UID: 0 PID: 6142 Comm: syz.1.17 Not tainted 6.16.0-rc1-syzkaller-00239-g08215f5486ec #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/07/2025 Call Trace: __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x116/0x1f0 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:408 [inline] print_report+0xcd/0x680 mm/kasan/report.c:521 kasan_report+0xe0/0x110 mm/kasan/report.c:634 lecd_attach net/atm/lec.c:751 [inline] lane_ioctl+0x2224/0x23e0 net/atm/lec.c:1008 do_vcc_ioctl+0x12c/0x930 net/atm/ioctl.c:159 sock_do_ioctl+0x118/0x280 net/socket.c:1190 sock_ioctl+0x227/0x6b0 net/socket.c:1311 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:907 [inline] __se_sys_ioctl fs/ioctl.c:893 [inline] __x64_sys_ioctl+0x18e/0x210 fs/ioctl.c:893 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcd/0x4c0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f Allocated by task 6132: kasan_save_stack+0x33/0x60 mm/kasan/common.c:47 kasan_save_track+0x14/0x30 mm/kasan/common.c:68 poison_kmalloc_redzone mm/kasan/common.c:377 [inline] __kasan_kmalloc+0xaa/0xb0 mm/kasan/common.c:394 kasan_kmalloc include/linux/kasan.h:260 [inline] __do_kmalloc_node mm/slub.c:4328 [inline] __kvmalloc_node_noprof+0x27b/0x620 mm/slub.c:5015 alloc_netdev_mqs+0xd2/0x1570 net/core/dev.c:11711 lecd_attach net/atm/lec.c:737 [inline] lane_ioctl+0x17db/0x23e0 net/atm/lec.c:1008 do_vcc_ioctl+0x12c/0x930 net/atm/ioctl.c:159 sock_do_ioctl+0x118/0x280 net/socket.c:1190 sock_ioctl+0x227/0x6b0 net/socket.c:1311 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:907 [inline] __se_sys_ioctl fs/ioctl.c:893 [inline] __x64_sys_ioctl+0x18e/0x210 fs/ioctl.c:893 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcd/0x4c0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 6132: kasan_save_stack+0x33/0x60 mm/kasan/common.c:47 kasan_save_track+0x14/0x30 mm/kasan/common.c:68 kasan_save_free_info+0x3b/0x60 mm/kasan/generic.c:576 poison_slab_object mm/kasan/common.c:247 [inline] __kasan_slab_free+0x51/0x70 mm/kasan/common.c:264 kasan_slab_free include/linux/kasan.h:233 [inline] slab_free_hook mm/slub.c:2381 [inline] slab_free mm/slub.c:4643 [inline] kfree+0x2b4/0x4d0 mm/slub.c:4842 free_netdev+0x6c5/0x910 net/core/dev.c:11892 lecd_attach net/atm/lec.c:744 [inline] lane_ioctl+0x1ce8/0x23e0 net/atm/lec.c:1008 do_vcc_ioctl+0x12c/0x930 net/atm/ioctl.c:159 sock_do_ioctl+0x118/0x280 net/socket.c:1190 sock_ioctl+0x227/0x6b0 net/socket.c:1311 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:907 [inline] __se_sys_ioctl fs/ioctl.c:893 [inline] __x64_sys_ioctl+0x18e/0x210 fs/ioctl.c:893 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: syzbot+8b64dec3affaed7b3af5@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/6852c6f6.050a0220.216029.0018.GAE@google.com/T/#u Signed-off-by: Eric Dumazet Link: https://patch.msgid.link/20250618140844.1686882-2-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/atm/lec.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/atm/lec.c b/net/atm/lec.c index ac3cfc1ae510..d4ac1488eca6 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c @@ -124,6 +124,7 @@ static unsigned char bus_mac[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; /* Device structures */ static struct net_device *dev_lec[MAX_LEC_ITF]; +static DEFINE_MUTEX(lec_mutex); #if IS_ENABLED(CONFIG_BRIDGE) static void lec_handle_bridge(struct sk_buff *skb, struct net_device *dev) @@ -685,6 +686,7 @@ static int lec_vcc_attach(struct atm_vcc *vcc, void __user *arg) int bytes_left; struct atmlec_ioc ioc_data; + lockdep_assert_held(&lec_mutex); /* Lecd must be up in this case */ bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmlec_ioc)); if (bytes_left != 0) @@ -710,6 +712,7 @@ static int lec_vcc_attach(struct atm_vcc *vcc, void __user *arg) static int lec_mcast_attach(struct atm_vcc *vcc, int arg) { + lockdep_assert_held(&lec_mutex); if (arg < 0 || arg >= MAX_LEC_ITF) return -EINVAL; arg = array_index_nospec(arg, MAX_LEC_ITF); @@ -725,6 +728,7 @@ static int lecd_attach(struct atm_vcc *vcc, int arg) int i; struct lec_priv *priv; + lockdep_assert_held(&lec_mutex); if (arg < 0) arg = 0; if (arg >= MAX_LEC_ITF) @@ -742,6 +746,7 @@ static int lecd_attach(struct atm_vcc *vcc, int arg) snprintf(dev_lec[i]->name, IFNAMSIZ, "lec%d", i); if (register_netdev(dev_lec[i])) { free_netdev(dev_lec[i]); + dev_lec[i] = NULL; return -EINVAL; } @@ -1003,6 +1008,7 @@ static int lane_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) return -ENOIOCTLCMD; } + mutex_lock(&lec_mutex); switch (cmd) { case ATMLEC_CTRL: err = lecd_attach(vcc, (int)arg); @@ -1017,6 +1023,7 @@ static int lane_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) break; } + mutex_unlock(&lec_mutex); return err; } From a5e3a144268899f1a8c445c8a3bfa15873ba85e8 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 18 Jun 2025 14:08:44 +0000 Subject: [PATCH 666/971] net: atm: fix /proc/net/atm/lec handling [ Upstream commit d03b79f459c7935cff830d98373474f440bd03ae ] /proc/net/atm/lec must ensure safety against dev_lec[] changes. It appears it had dev_put() calls without prior dev_hold(), leading to imbalance and UAF. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Eric Dumazet Acked-by: Francois Romieu # Minor atm contributor Link: https://patch.msgid.link/20250618140844.1686882-3-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/atm/lec.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/atm/lec.c b/net/atm/lec.c index d4ac1488eca6..b7fa48a9b720 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c @@ -909,7 +909,6 @@ static void *lec_itf_walk(struct lec_state *state, loff_t *l) v = (dev && netdev_priv(dev)) ? lec_priv_walk(state, l, netdev_priv(dev)) : NULL; if (!v && dev) { - dev_put(dev); /* Partial state reset for the next time we get called */ dev = NULL; } @@ -933,6 +932,7 @@ static void *lec_seq_start(struct seq_file *seq, loff_t *pos) { struct lec_state *state = seq->private; + mutex_lock(&lec_mutex); state->itf = 0; state->dev = NULL; state->locked = NULL; @@ -950,8 +950,9 @@ static void lec_seq_stop(struct seq_file *seq, void *v) if (state->dev) { spin_unlock_irqrestore(&state->locked->lec_arp_lock, state->flags); - dev_put(state->dev); + state->dev = NULL; } + mutex_unlock(&lec_mutex); } static void *lec_seq_next(struct seq_file *seq, void *v, loff_t *pos) From 6377977485f7f9bdb994e57c4b2cd55345ff87ed Mon Sep 17 00:00:00 2001 From: Avadhut Naik Date: Fri, 13 Jun 2025 00:51:35 +0000 Subject: [PATCH 667/971] EDAC/amd64: Correct number of UMCs for family 19h models 70h-7fh commit b2e673ae53ef4b943f68585207a5f21cfc9a0714 upstream. AMD's Family 19h-based Models 70h-7fh support 4 unified memory controllers (UMC) per processor die. The amd64_edac driver, however, assumes only 2 UMCs are supported since max_mcs variable for the models has not been explicitly set to 4. The same results in incomplete or incorrect memory information being logged to dmesg by the module during initialization in some instances. Fixes: 6c79e42169fe ("EDAC/amd64: Add support for ECC on family 19h model 60h-7Fh") Closes: https://lore.kernel.org/all/27dc093f-ce27-4c71-9e81-786150a040b6@reox.at/ Reported-by: reox Signed-off-by: Avadhut Naik Signed-off-by: Borislav Petkov (AMD) Cc: stable@kernel.org Link: https://lore.kernel.org/20250613005233.2330627-1-avadhut.naik@amd.com Signed-off-by: Greg Kroah-Hartman --- drivers/edac/amd64_edac.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 9cd86390a167..10119cf27ffd 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -4130,6 +4130,7 @@ static int per_family_init(struct amd64_pvt *pvt) break; case 0x70 ... 0x7f: pvt->ctl_name = "F19h_M70h"; + pvt->max_mcs = 4; pvt->flags.zn_regs_v2 = 1; break; case 0xa0 ... 0xaf: From aaaa689aa29d96b74f8aaddb51bd1aa4658020bd Mon Sep 17 00:00:00 2001 From: Akhil R Date: Tue, 3 Jun 2025 21:00:20 +0530 Subject: [PATCH 668/971] dt-bindings: i2c: nvidia,tegra20-i2c: Specify the required properties MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 903cc7096db22f889d48e2cee8840709ce04fdac upstream. Specify the properties which are essential and which are not for the Tegra I2C driver to function correctly. This was not added correctly when the TXT binding was converted to yaml. All the existing DT nodes have these properties already and hence this does not break the ABI. dmas and dma-names which were specified as a must in the TXT binding is now made optional since the driver can work in PIO mode if dmas are missing. Fixes: f10a9b722f80 ("dt-bindings: i2c: tegra: Convert to json-schema”) Signed-off-by: Akhil R Cc: # v5.17+ Reviewed-by: Krzysztof Kozlowski Signed-off-by: Andi Shyti Link: https://lore.kernel.org/r/20250603153022.39434-1-akhilrajeev@nvidia.com Signed-off-by: Greg Kroah-Hartman --- .../bindings/i2c/nvidia,tegra20-i2c.yaml | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.yaml b/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.yaml index 424a4fc218b6..2cb311ddd912 100644 --- a/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.yaml +++ b/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.yaml @@ -103,7 +103,10 @@ properties: resets: items: - - description: module reset + - description: + Module reset. This property is optional for controllers in Tegra194, + Tegra234 etc where an internal software reset is available as an + alternative. reset-names: items: @@ -119,6 +122,13 @@ properties: - const: rx - const: tx +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + allOf: - $ref: /schemas/i2c/i2c-controller.yaml - if: @@ -172,6 +182,18 @@ allOf: items: - description: phandle to the VENC power domain + - if: + not: + properties: + compatible: + contains: + enum: + - nvidia,tegra194-i2c + then: + required: + - resets + - reset-names + unevaluatedProperties: false examples: From b8ced2b9a23a1a2c1e0ed8d0d02512e51bdf38da Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Wed, 20 Nov 2024 08:01:54 -0800 Subject: [PATCH 669/971] smb: Log an error when close_all_cached_dirs fails commit a2182743a8b4969481f64aec4908ff162e8a206c upstream. Under low-memory conditions, close_all_cached_dirs() can't move the dentries to a separate list to dput() them once the locks are dropped. This will result in a "Dentry still in use" error, so add an error message that makes it clear this is what happened: [ 495.281119] CIFS: VFS: \\otters.example.com\share Out of memory while dropping dentries [ 495.281595] ------------[ cut here ]------------ [ 495.281887] BUG: Dentry ffff888115531138{i=78,n=/} still in use (2) [unmount of cifs cifs] [ 495.282391] WARNING: CPU: 1 PID: 2329 at fs/dcache.c:1536 umount_check+0xc8/0xf0 Also, bail out of looping through all tcons as soon as a single allocation fails, since we're already in trouble, and kmalloc() attempts for subseqeuent tcons are likely to fail just like the first one did. Signed-off-by: Paul Aurich Acked-by: Bharath SM Suggested-by: Ruben Devos Cc: stable@vger.kernel.org Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/smb/client/cached_dir.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c index 749794667295..d64742ba371a 100644 --- a/fs/smb/client/cached_dir.c +++ b/fs/smb/client/cached_dir.c @@ -484,8 +484,17 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb) spin_lock(&cfids->cfid_list_lock); list_for_each_entry(cfid, &cfids->entries, entry) { tmp_list = kmalloc(sizeof(*tmp_list), GFP_ATOMIC); - if (tmp_list == NULL) - break; + if (tmp_list == NULL) { + /* + * If the malloc() fails, we won't drop all + * dentries, and unmounting is likely to trigger + * a 'Dentry still in use' error. + */ + cifs_tcon_dbg(VFS, "Out of memory while dropping dentries\n"); + spin_unlock(&cfids->cfid_list_lock); + spin_unlock(&cifs_sb->tlink_tree_lock); + goto done; + } spin_lock(&cfid->fid_lock); tmp_list->dentry = cfid->dentry; cfid->dentry = NULL; @@ -497,6 +506,7 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb) } spin_unlock(&cifs_sb->tlink_tree_lock); +done: list_for_each_entry_safe(tmp_list, q, &entry, entry) { list_del(&tmp_list->entry); dput(tmp_list->dentry); From cfa7fa02078db9849d8e8c642fec78fbb8c99903 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Thu, 13 Jun 2024 14:33:16 -0700 Subject: [PATCH 670/971] net: make for_each_netdev_dump() a little more bug-proof commit f22b4b55edb507a2b30981e133b66b642be4d13f upstream. I find the behavior of xa_for_each_start() slightly counter-intuitive. It doesn't end the iteration by making the index point after the last element. IOW calling xa_for_each_start() again after it "finished" will run the body of the loop for the last valid element, instead of doing nothing. This works fine for netlink dumps if they terminate correctly (i.e. coalesce or carefully handle NLM_DONE), but as we keep getting reminded legacy dumps are unlikely to go away. Fixing this generically at the xa_for_each_start() level seems hard - there is no index reserved for "end of iteration". ifindexes are 31b wide, tho, and iterator is ulong so for for_each_netdev_dump() it's safe to go to the next element. Signed-off-by: Jakub Kicinski Reviewed-by: Przemek Kitszel Signed-off-by: David S. Miller [ The mctp RTM_GETADDR rework backport of acab78ae12c7 ("net: mctp: Don't access ifa_index when missing") pulled 2d45eeb7d5d7 ("mctp: no longer rely on net->dev_index_head[]") as a dependency. However, that change relies on this backport for correct behaviour of for_each_netdev_dump(). Jakub mentions[1] that nothing should be relying on the old behaviour of for_each_netdev_dump(), hence the backport. [1]: https://lore.kernel.org/netdev/20250609083749.741c27f5@kernel.org/ ] Signed-off-by: Jeremy Kerr Signed-off-by: Greg Kroah-Hartman --- include/linux/netdevice.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 0b0a172337db..030d9de2ba2d 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -3036,7 +3036,8 @@ extern rwlock_t dev_base_lock; /* Device list lock */ #define net_device_entry(lh) list_entry(lh, struct net_device, dev_list) #define for_each_netdev_dump(net, d, ifindex) \ - xa_for_each_start(&(net)->dev_by_index, (ifindex), (d), (ifindex)) + for (; (d = xa_find(&(net)->dev_by_index, &ifindex, \ + ULONG_MAX, XA_PRESENT)); ifindex++) static inline struct net_device *next_net_device(struct net_device *dev) { From e9a011fc6b04a31ce6bf3e6fef48b81564f8ec53 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Thu, 16 Jan 2025 20:22:49 +0200 Subject: [PATCH 671/971] serial: sh-sci: Increment the runtime usage counter for the earlycon device commit 651dee03696e1dfde6d9a7e8664bbdcd9a10ea7f upstream. In the sh-sci driver, serial ports are mapped to the sci_ports[] array, with earlycon mapped at index zero. The uart_add_one_port() function eventually calls __device_attach(), which, in turn, calls pm_request_idle(). The identified code path is as follows: uart_add_one_port() -> serial_ctrl_register_port() -> serial_core_register_port() -> serial_core_port_device_add() -> serial_base_port_add() -> device_add() -> bus_probe_device() -> device_initial_probe() -> __device_attach() -> // ... if (dev->p->dead) { // ... } else if (dev->driver) { // ... } else { // ... pm_request_idle(dev); // ... } The earlycon device clocks are enabled by the bootloader. However, the pm_request_idle() call in __device_attach() disables the SCI port clocks while earlycon is still active. The earlycon write function, serial_console_write(), calls sci_poll_put_char() via serial_console_putchar(). If the SCI port clocks are disabled, writing to earlycon may sometimes cause the SR.TDFE bit to remain unset indefinitely, causing the while loop in sci_poll_put_char() to never exit. On single-core SoCs, this can result in the system being blocked during boot when this issue occurs. To resolve this, increment the runtime PM usage counter for the earlycon SCI device before registering the UART port. Fixes: 0b0cced19ab1 ("serial: sh-sci: Add CONFIG_SERIAL_EARLYCON support") Cc: stable@vger.kernel.org Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20250116182249.3828577-6-claudiu.beznea.uj@bp.renesas.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index be7e57e1d1e3..dab5658d9d54 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -3424,6 +3424,22 @@ static int sci_probe_single(struct platform_device *dev, } if (sci_uart_earlycon && sci_ports[0].port.mapbase == sci_res->start) { + /* + * In case: + * - this is the earlycon port (mapped on index 0 in sci_ports[]) and + * - it now maps to an alias other than zero and + * - the earlycon is still alive (e.g., "earlycon keep_bootcon" is + * available in bootargs) + * + * we need to avoid disabling clocks and PM domains through the runtime + * PM APIs called in __device_attach(). For this, increment the runtime + * PM reference counter (the clocks and PM domains were already enabled + * by the bootloader). Otherwise the earlycon may access the HW when it + * has no clocks enabled leading to failures (infinite loop in + * sci_poll_put_char()). + */ + pm_runtime_get_noresume(&dev->dev); + /* * Skip cleanup the sci_port[0] in early_console_exit(), this * port is the same as the earlycon one. From 2f38986e93d31e4a53321df042c3bab0345b5a2f Mon Sep 17 00:00:00 2001 From: Renato Caldas Date: Sat, 2 Nov 2024 18:31:16 +0000 Subject: [PATCH 672/971] platform/x86: ideapad-laptop: add missing Ideapad Pro 5 fn keys commit 36e66be874a7ea9d28fb9757629899a8449b8748 upstream. The scancodes for the Mic Mute and Airplane keys on the Ideapad Pro 5 (14AHP9 at least, probably the other variants too) are different and were not being picked up by the driver. This adds them to the keymap. Apart from what is already supported, the remaining fn keys are unfortunately producing windows-specific key-combos. Signed-off-by: Renato Caldas Link: https://lore.kernel.org/r/20241102183116.30142-1-renato@calgera.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede Signed-off-by: WangYuli Signed-off-by: Greg Kroah-Hartman --- drivers/platform/x86/ideapad-laptop.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 88eefccb6ed2..50013af0537c 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -1101,6 +1101,9 @@ static const struct key_entry ideapad_keymap[] = { { KE_KEY, 0x27 | IDEAPAD_WMI_KEY, { KEY_HELP } }, /* Refresh Rate Toggle */ { KE_KEY, 0x0a | IDEAPAD_WMI_KEY, { KEY_DISPLAYTOGGLE } }, + /* Specific to some newer models */ + { KE_KEY, 0x3e | IDEAPAD_WMI_KEY, { KEY_MICMUTE } }, + { KE_KEY, 0x3f | IDEAPAD_WMI_KEY, { KEY_RFKILL } }, { KE_END }, }; From 94ec33e9600be12c3937e918d57d0818228247e7 Mon Sep 17 00:00:00 2001 From: Colin Foster Date: Fri, 31 May 2024 13:38:17 -0500 Subject: [PATCH 673/971] ARM: dts: am335x-bone-common: Increase MDIO reset deassert time commit b9bf5612610aa7e38d58fee16f489814db251c01 upstream. Prior to commit df16c1c51d81 ("net: phy: mdio_device: Reset device only when necessary") MDIO reset deasserts were performed twice during boot. Now that the second deassert is no longer performed, device probe failures happen due to the change in timing with the following error message: SMSC LAN8710/LAN8720: probe of 4a101000.mdio:00 failed with error -5 Restore the original effective timing, which resolves the probe failures. Signed-off-by: Colin Foster Link: https://lore.kernel.org/r/20240531183817.2698445-1-colin.foster@in-advantage.com Signed-off-by: Kevin Hilman Signed-off-by: Nobuhiro Iwamatsu (CIP) Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi b/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi index 96451c8a815c..4867ff28c97e 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi +++ b/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi @@ -385,7 +385,7 @@ /* Support GPIO reset on revision C3 boards */ reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; reset-assert-us = <300>; - reset-deassert-us = <6500>; + reset-deassert-us = <13000>; }; }; From eb74c6f1b2096b8cbc829796e7b027c1185c01b9 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 31 Oct 2024 10:29:51 +0100 Subject: [PATCH 674/971] ARM: dts: am335x-bone-common: Increase MDIO reset deassert delay to 50ms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 929d8490f8790164f5f63671c1c58d6c50411cb2 upstream. Commit b9bf5612610aa7e3 ("ARM: dts: am335x-bone-common: Increase MDIO reset deassert time") already increased the MDIO reset deassert delay from 6.5 to 13 ms, but this may still cause Ethernet PHY probe failures: SMSC LAN8710/LAN8720 4a101000.mdio:00: probe with driver SMSC LAN8710/LAN8720 failed with error -5 On BeagleBone Black Rev. C3, ETH_RESETn is controlled by an open-drain AND gate. It is pulled high by a 10K resistor, and has a 4.7µF capacitor to ground, giving an RC time constant of 47ms. As it takes 0.7RC to charge the capacitor above the threshold voltage of a CMOS input (VDD/2), the delay should be at least 33ms. Considering the typical tolerance of 20% on capacitors, 40ms would be safer. Add an additional safety margin and settle for 50ms. Signed-off-by: Geert Uytterhoeven Reviewed-by: Roger Quadros Link: https://lore.kernel.org/r/9002a58daa1b2983f39815b748ee9d2f8dcc4829.1730366936.git.geert+renesas@glider.be Signed-off-by: Kevin Hilman Signed-off-by: Nobuhiro Iwamatsu (CIP) Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi b/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi index 4867ff28c97e..27e73e745e25 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi +++ b/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi @@ -385,7 +385,7 @@ /* Support GPIO reset on revision C3 boards */ reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; reset-assert-us = <300>; - reset-deassert-us = <13000>; + reset-deassert-us = <50000>; }; }; From cc77844d61f7dd3be4997d1335ede2bb3d96d7d7 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Thu, 5 Jun 2025 13:53:41 +0100 Subject: [PATCH 675/971] Revert "cpufreq: tegra186: Share policy per cluster" This reverts commit ac64f0e893ff370c4d3426c83c1bd0acae75bcf4 which is upstream commit be4ae8c19492cd6d5de61ccb34ffb3f5ede5eec8. This commit is causing a suspend regression on Tegra186 Jetson TX2 with Linux v6.12.y kernels. This is not seen with Linux v6.15 that includes this change but indicates that there are there changes missing. Therefore, revert this change. Fixes: ac64f0e893ff ("cpufreq: tegra186: Share policy per cluster") Link: https://lore.kernel.org/linux-tegra/bf1dabf7-0337-40e9-8b8e-4e93a0ffd4cc@nvidia.com/ Signed-off-by: Jon Hunter Signed-off-by: Greg Kroah-Hartman --- drivers/cpufreq/tegra186-cpufreq.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/cpufreq/tegra186-cpufreq.c b/drivers/cpufreq/tegra186-cpufreq.c index 4e5b6f9a56d1..7b8fcfa55038 100644 --- a/drivers/cpufreq/tegra186-cpufreq.c +++ b/drivers/cpufreq/tegra186-cpufreq.c @@ -73,18 +73,11 @@ static int tegra186_cpufreq_init(struct cpufreq_policy *policy) { struct tegra186_cpufreq_data *data = cpufreq_get_driver_data(); unsigned int cluster = data->cpus[policy->cpu].bpmp_cluster_id; - u32 cpu; policy->freq_table = data->clusters[cluster].table; policy->cpuinfo.transition_latency = 300 * 1000; policy->driver_data = NULL; - /* set same policy for all cpus in a cluster */ - for (cpu = 0; cpu < ARRAY_SIZE(tegra186_cpus); cpu++) { - if (data->cpus[cpu].bpmp_cluster_id == cluster) - cpumask_set_cpu(cpu, policy->cpus); - } - return 0; } From 7b47919aff637ece151dd2189d1f6e06cb07d6bf Mon Sep 17 00:00:00 2001 From: zhangjian Date: Thu, 19 Jun 2025 09:18:29 +0800 Subject: [PATCH 676/971] smb: client: fix first command failure during re-negotiation commit 34331d7beed7576acfc98e991c39738b96162499 upstream. after fabc4ed200f9, server_unresponsive add a condition to check whether client need to reconnect depending on server->lstrp. When client failed to reconnect for some time and abort connection, server->lstrp is updated for the last time. In the following scene, server->lstrp is too old. This cause next command failure in re-negotiation rather than waiting for re-negotiation done. 1. mount -t cifs -o username=Everyone,echo_internal=10 //$server_ip/export /mnt 2. ssh $server_ip "echo b > /proc/sysrq-trigger &" 3. ls /mnt 4. sleep 21s 5. ssh $server_ip "service firewalld stop" 6. ls # return EHOSTDOWN If the interval between 5 and 6 is too small, 6 may trigger sending negotiation request. Before backgrounding cifsd thread try to receive negotiation response from server in cifs_readv_from_socket, server_unresponsive may trigger cifs_reconnect which cause 6 to be failed: ls thread ---------------- smb2_negotiate server->tcpStatus = CifsInNegotiate compound_send_recv wait_for_compound_request cifsd thread ---------------- cifs_readv_from_socket server_unresponsive server->tcpStatus == CifsInNegotiate && jiffies > server->lstrp + 20s cifs_reconnect cifs_abort_connection: mid_state = MID_RETRY_NEEDED ls thread ---------------- cifs_sync_mid_result return EAGAIN smb2_negotiate return EHOSTDOWN Though server->lstrp means last server response time, it is updated in cifs_abort_connection and cifs_get_tcp_session. We can also update server->lstrp before switching into CifsInNegotiate state to avoid failure in 6. Fixes: 7ccc1465465d ("smb: client: fix hang in wait_for_response() for negproto") Acked-by: Paulo Alcantara (Red Hat) Acked-by: Meetakshi Setiya Signed-off-by: zhangjian Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/smb/client/connect.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c index ed88ec0f2533..8fa5fe0a8c5c 100644 --- a/fs/smb/client/connect.c +++ b/fs/smb/client/connect.c @@ -3982,6 +3982,7 @@ retry: return 0; } + server->lstrp = jiffies; server->tcpStatus = CifsInNegotiate; spin_unlock(&server->srv_lock); From d7094ad351042965e1f2eb1fd5d1a54238110673 Mon Sep 17 00:00:00 2001 From: Yao Zi Date: Thu, 5 Jun 2025 20:34:46 +0800 Subject: [PATCH 677/971] platform/loongarch: laptop: Add backlight power control support commit 53c762b47f726e4079a1f06f684bce2fc0d56fba upstream. loongson_laptop_turn_{on,off}_backlight() are designed for controlling the power of the backlight, but they aren't really used in the driver previously. Unify these two functions since they only differ in arguments passed to ACPI method, and wire up loongson_laptop_backlight_update() to update the power state of the backlight as well. Tested on the TongFang L860-T2 Loongson-3A5000 laptop. Cc: stable@vger.kernel.org Fixes: 6246ed09111f ("LoongArch: Add ACPI-based generic laptop driver") Signed-off-by: Yao Zi Signed-off-by: Huacai Chen Signed-off-by: Greg Kroah-Hartman --- drivers/platform/loongarch/loongson-laptop.c | 73 ++++++++++---------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/drivers/platform/loongarch/loongson-laptop.c b/drivers/platform/loongarch/loongson-laptop.c index fe4fec2d4f94..5fcfa3a7970b 100644 --- a/drivers/platform/loongarch/loongson-laptop.c +++ b/drivers/platform/loongarch/loongson-laptop.c @@ -56,8 +56,7 @@ static struct input_dev *generic_inputdev; static acpi_handle hotkey_handle; static struct key_entry hotkey_keycode_map[GENERIC_HOTKEY_MAP_MAX]; -int loongson_laptop_turn_on_backlight(void); -int loongson_laptop_turn_off_backlight(void); +static bool bl_powered; static int loongson_laptop_backlight_update(struct backlight_device *bd); /* 2. ACPI Helpers and device model */ @@ -354,16 +353,42 @@ static int ec_backlight_level(u8 level) return level; } +static int ec_backlight_set_power(bool state) +{ + int status; + union acpi_object arg0 = { ACPI_TYPE_INTEGER }; + struct acpi_object_list args = { 1, &arg0 }; + + arg0.integer.value = state; + status = acpi_evaluate_object(NULL, "\\BLSW", &args, NULL); + if (ACPI_FAILURE(status)) { + pr_info("Loongson lvds error: 0x%x\n", status); + return -EIO; + } + + return 0; +} + static int loongson_laptop_backlight_update(struct backlight_device *bd) { - int lvl = ec_backlight_level(bd->props.brightness); + bool target_powered = !backlight_is_blank(bd); + int ret = 0, lvl = ec_backlight_level(bd->props.brightness); if (lvl < 0) return -EIO; + if (ec_set_brightness(lvl)) return -EIO; - return 0; + if (target_powered != bl_powered) { + ret = ec_backlight_set_power(target_powered); + if (ret < 0) + return ret; + + bl_powered = target_powered; + } + + return ret; } static int loongson_laptop_get_brightness(struct backlight_device *bd) @@ -384,7 +409,7 @@ static const struct backlight_ops backlight_laptop_ops = { static int laptop_backlight_register(void) { - int status = 0; + int status = 0, ret; struct backlight_properties props; memset(&props, 0, sizeof(props)); @@ -392,44 +417,20 @@ static int laptop_backlight_register(void) if (!acpi_evalf(hotkey_handle, &status, "ECLL", "d")) return -EIO; + ret = ec_backlight_set_power(true); + if (ret) + return ret; + + bl_powered = true; + props.max_brightness = status; props.brightness = ec_get_brightness(); + props.power = FB_BLANK_UNBLANK; props.type = BACKLIGHT_PLATFORM; backlight_device_register("loongson_laptop", NULL, NULL, &backlight_laptop_ops, &props); - return 0; -} - -int loongson_laptop_turn_on_backlight(void) -{ - int status; - union acpi_object arg0 = { ACPI_TYPE_INTEGER }; - struct acpi_object_list args = { 1, &arg0 }; - - arg0.integer.value = 1; - status = acpi_evaluate_object(NULL, "\\BLSW", &args, NULL); - if (ACPI_FAILURE(status)) { - pr_info("Loongson lvds error: 0x%x\n", status); - return -ENODEV; - } - - return 0; -} - -int loongson_laptop_turn_off_backlight(void) -{ - int status; - union acpi_object arg0 = { ACPI_TYPE_INTEGER }; - struct acpi_object_list args = { 1, &arg0 }; - - arg0.integer.value = 0; - status = acpi_evaluate_object(NULL, "\\BLSW", &args, NULL); - if (ACPI_FAILURE(status)) { - pr_info("Loongson lvds error: 0x%x\n", status); - return -ENODEV; - } return 0; } From 4ca4f418b76184c820666ed4f87cfd0844633086 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 19 May 2025 18:07:11 +0200 Subject: [PATCH 678/971] s390/pci: Fix __pcilg_mio_inuser() inline assembly commit c4abe6234246c75cdc43326415d9cff88b7cf06c upstream. Use "a" constraint for the shift operand of the __pcilg_mio_inuser() inline assembly. The used "d" constraint allows the compiler to use any general purpose register for the shift operand, including register zero. If register zero is used this my result in incorrect code generation: 8f6: a7 0a ff f8 ahi %r0,-8 8fa: eb 32 00 00 00 0c srlg %r3,%r2,0 <---- If register zero is selected to contain the shift value, the srlg instruction ignores the contents of the register and always shifts zero bits. Therefore use the "a" constraint which does not permit to select register zero. Fixes: f058599e22d5 ("s390/pci: Fix s390_mmio_read/write with MIO") Cc: stable@vger.kernel.org Reported-by: Niklas Schnelle Reviewed-by: Niklas Schnelle Signed-off-by: Heiko Carstens Signed-off-by: Niklas Schnelle Signed-off-by: Greg Kroah-Hartman --- arch/s390/pci/pci_mmio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/pci/pci_mmio.c b/arch/s390/pci/pci_mmio.c index a90499c087f0..2ee7b5a5016c 100644 --- a/arch/s390/pci/pci_mmio.c +++ b/arch/s390/pci/pci_mmio.c @@ -223,7 +223,7 @@ static inline int __pcilg_mio_inuser( [ioaddr_len] "+&d" (ioaddr_len.pair), [cc] "+d" (cc), [val] "=d" (val), [dst] "+a" (dst), [cnt] "+d" (cnt), [tmp] "=d" (tmp), - [shift] "+d" (shift) + [shift] "+a" (shift) :: "cc", "memory"); /* did we write everything to the user space buffer? */ From 2ee6044a693735396bb47eeaba1ac3ae26c1c99b Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 5 Jun 2025 12:31:45 +0200 Subject: [PATCH 679/971] perf: Fix sample vs do_exit() [ Upstream commit 4f6fc782128355931527cefe3eb45338abd8ab39 ] Baisheng Gao reported an ARM64 crash, which Mark decoded as being a synchronous external abort -- most likely due to trying to access MMIO in bad ways. The crash further shows perf trying to do a user stack sample while in exit_mmap()'s tlb_finish_mmu() -- i.e. while tearing down the address space it is trying to access. It turns out that we stop perf after we tear down the userspace mm; a receipie for disaster, since perf likes to access userspace for various reasons. Flip this order by moving up where we stop perf in do_exit(). Additionally, harden PERF_SAMPLE_CALLCHAIN and PERF_SAMPLE_STACK_USER to abort when the current task does not have an mm (exit_mm() makes sure to set current->mm = NULL; before commencing with the actual teardown). Such that CPU wide events don't trip on this same problem. Fixes: c5ebcedb566e ("perf: Add ability to attach user stack dump to sample") Reported-by: Baisheng Gao Suggested-by: Mark Rutland Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/20250605110815.GQ39944@noisy.programming.kicks-ass.net Signed-off-by: Sasha Levin --- kernel/events/core.c | 7 +++++++ kernel/exit.c | 17 +++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 563f39518f7f..90577a7a3a51 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6987,6 +6987,10 @@ perf_sample_ustack_size(u16 stack_size, u16 header_size, if (!regs) return 0; + /* No mm, no stack, no dump. */ + if (!current->mm) + return 0; + /* * Check if we fit in with the requested stack size into the: * - TASK_SIZE @@ -7685,6 +7689,9 @@ perf_callchain(struct perf_event *event, struct pt_regs *regs) const u32 max_stack = event->attr.sample_max_stack; struct perf_callchain_entry *callchain; + if (!current->mm) + user = false; + if (!kernel && !user) return &__empty_callchain; diff --git a/kernel/exit.c b/kernel/exit.c index 3540b2c9b1b6..03a1dd32e6ff 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -858,6 +858,15 @@ void __noreturn do_exit(long code) tsk->exit_code = code; taskstats_exit(tsk, group_dead); + /* + * Since sampling can touch ->mm, make sure to stop everything before we + * tear it down. + * + * Also flushes inherited counters to the parent - before the parent + * gets woken up by child-exit notifications. + */ + perf_event_exit_task(tsk); + exit_mm(); if (group_dead) @@ -874,14 +883,6 @@ void __noreturn do_exit(long code) exit_task_work(tsk); exit_thread(tsk); - /* - * Flush inherited counters to the parent - before the parent - * gets woken up by child-exit notifications. - * - * because of cgroup mode, must be called before cgroup_exit() - */ - perf_event_exit_task(tsk); - sched_autogroup_exit_task(tsk); cgroup_exit(tsk); From bddec730501b11c530b1ae84a70f1012264824b4 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 5 Jun 2025 12:37:11 +0200 Subject: [PATCH 680/971] perf: Fix cgroup state vs ERROR [ Upstream commit 61988e36dc5457cdff7ae7927e8d9ad1419ee998 ] While chasing down a missing perf_cgroup_event_disable() elsewhere, Leo Yan found that both perf_put_aux_event() and perf_remove_sibling_event() were also missing one. Specifically, the rule is that events that switch to OFF,ERROR need to call perf_cgroup_event_disable(). Unify the disable paths to ensure this. Fixes: ab43762ef010 ("perf: Allow normal events to output AUX data") Fixes: 9f0c4fa111dc ("perf/core: Add a new PERF_EV_CAP_SIBLING event capability") Reported-by: Leo Yan Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/20250605123343.GD35970@noisy.programming.kicks-ass.net Signed-off-by: Sasha Levin --- kernel/events/core.c | 51 ++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 90577a7a3a51..e9e785542b9f 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -2067,8 +2067,9 @@ perf_aux_output_match(struct perf_event *event, struct perf_event *aux_event) } static void put_event(struct perf_event *event); -static void event_sched_out(struct perf_event *event, - struct perf_event_context *ctx); +static void __event_disable(struct perf_event *event, + struct perf_event_context *ctx, + enum perf_event_state state); static void perf_put_aux_event(struct perf_event *event) { @@ -2101,8 +2102,7 @@ static void perf_put_aux_event(struct perf_event *event) * state so that we don't try to schedule it again. Note * that perf_event_enable() will clear the ERROR status. */ - event_sched_out(iter, ctx); - perf_event_set_state(event, PERF_EVENT_STATE_ERROR); + __event_disable(iter, ctx, PERF_EVENT_STATE_ERROR); } } @@ -2156,18 +2156,6 @@ static inline struct list_head *get_event_list(struct perf_event *event) &event->pmu_ctx->flexible_active; } -/* - * Events that have PERF_EV_CAP_SIBLING require being part of a group and - * cannot exist on their own, schedule them out and move them into the ERROR - * state. Also see _perf_event_enable(), it will not be able to recover - * this ERROR state. - */ -static inline void perf_remove_sibling_event(struct perf_event *event) -{ - event_sched_out(event, event->ctx); - perf_event_set_state(event, PERF_EVENT_STATE_ERROR); -} - static void perf_group_detach(struct perf_event *event) { struct perf_event *leader = event->group_leader; @@ -2203,8 +2191,15 @@ static void perf_group_detach(struct perf_event *event) */ list_for_each_entry_safe(sibling, tmp, &event->sibling_list, sibling_list) { + /* + * Events that have PERF_EV_CAP_SIBLING require being part of + * a group and cannot exist on their own, schedule them out + * and move them into the ERROR state. Also see + * _perf_event_enable(), it will not be able to recover this + * ERROR state. + */ if (sibling->event_caps & PERF_EV_CAP_SIBLING) - perf_remove_sibling_event(sibling); + __event_disable(sibling, ctx, PERF_EVENT_STATE_ERROR); sibling->group_leader = sibling; list_del_init(&sibling->sibling_list); @@ -2437,6 +2432,15 @@ static void perf_remove_from_context(struct perf_event *event, unsigned long fla event_function_call(event, __perf_remove_from_context, (void *)flags); } +static void __event_disable(struct perf_event *event, + struct perf_event_context *ctx, + enum perf_event_state state) +{ + event_sched_out(event, ctx); + perf_cgroup_event_disable(event, ctx); + perf_event_set_state(event, state); +} + /* * Cross CPU call to disable a performance event */ @@ -2455,13 +2459,18 @@ static void __perf_event_disable(struct perf_event *event, perf_pmu_disable(event->pmu_ctx->pmu); + /* + * When disabling a group leader, the whole group becomes ineligible + * to run, so schedule out the full group. + */ if (event == event->group_leader) group_sched_out(event, ctx); - else - event_sched_out(event, ctx); - perf_event_set_state(event, PERF_EVENT_STATE_OFF); - perf_cgroup_event_disable(event, ctx); + /* + * But only mark the leader OFF; the siblings will remain + * INACTIVE. + */ + __event_disable(event, ctx, PERF_EVENT_STATE_OFF); perf_pmu_enable(event->pmu_ctx->pmu); } From 7c631e5cd38ed3067240ab70e6390dd8dde39284 Mon Sep 17 00:00:00 2001 From: Luo Gengkun Date: Wed, 4 Jun 2025 03:39:24 +0000 Subject: [PATCH 681/971] perf/core: Fix WARN in perf_cgroup_switch() [ Upstream commit 3172fb986666dfb71bf483b6d3539e1e587fa197 ] There may be concurrency between perf_cgroup_switch and perf_cgroup_event_disable. Consider the following scenario: after a new perf cgroup event is created on CPU0, the new event may not trigger a reprogramming, causing ctx->is_active to be 0. In this case, when CPU1 disables this perf event, it executes __perf_remove_from_context-> list _del_event->perf_cgroup_event_disable on CPU1, which causes a race with perf_cgroup_switch running on CPU0. The following describes the details of this concurrency scenario: CPU0 CPU1 perf_cgroup_switch: ... # cpuctx->cgrp is not NULL here if (READ_ONCE(cpuctx->cgrp) == NULL) return; perf_remove_from_context: ... raw_spin_lock_irq(&ctx->lock); ... # ctx->is_active == 0 because reprogramm is not # tigger, so CPU1 can do __perf_remove_from_context # for CPU0 __perf_remove_from_context: perf_cgroup_event_disable: ... if (--ctx->nr_cgroups) ... # this warning will happened because CPU1 changed # ctx.nr_cgroups to 0. WARN_ON_ONCE(cpuctx->ctx.nr_cgroups == 0); [peterz: use guard instead of goto unlock] Fixes: db4a835601b7 ("perf/core: Set cgroup in CPU contexts for new cgroup events") Signed-off-by: Luo Gengkun Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/20250604033924.3914647-3-luogengkun@huaweicloud.com Signed-off-by: Sasha Levin --- kernel/events/core.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index e9e785542b9f..873b17545717 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -171,6 +171,19 @@ static void perf_ctx_unlock(struct perf_cpu_context *cpuctx, raw_spin_unlock(&cpuctx->ctx.lock); } +typedef struct { + struct perf_cpu_context *cpuctx; + struct perf_event_context *ctx; +} class_perf_ctx_lock_t; + +static inline void class_perf_ctx_lock_destructor(class_perf_ctx_lock_t *_T) +{ perf_ctx_unlock(_T->cpuctx, _T->ctx); } + +static inline class_perf_ctx_lock_t +class_perf_ctx_lock_constructor(struct perf_cpu_context *cpuctx, + struct perf_event_context *ctx) +{ perf_ctx_lock(cpuctx, ctx); return (class_perf_ctx_lock_t){ cpuctx, ctx }; } + #define TASK_TOMBSTONE ((void *)-1L) static bool is_kernel_event(struct perf_event *event) @@ -866,7 +879,13 @@ static void perf_cgroup_switch(struct task_struct *task) if (READ_ONCE(cpuctx->cgrp) == cgrp) return; - perf_ctx_lock(cpuctx, cpuctx->task_ctx); + guard(perf_ctx_lock)(cpuctx, cpuctx->task_ctx); + /* + * Re-check, could've raced vs perf_remove_from_context(). + */ + if (READ_ONCE(cpuctx->cgrp) == NULL) + return; + perf_ctx_disable(&cpuctx->ctx, true); ctx_sched_out(&cpuctx->ctx, EVENT_ALL|EVENT_CGROUP); @@ -884,7 +903,6 @@ static void perf_cgroup_switch(struct task_struct *task) ctx_sched_in(&cpuctx->ctx, EVENT_ALL|EVENT_CGROUP); perf_ctx_enable(&cpuctx->ctx, true); - perf_ctx_unlock(cpuctx, cpuctx->task_ctx); } static int perf_cgroup_ensure_storage(struct perf_event *event, From 21da6d3561f373898349ca7167c9811c020da695 Mon Sep 17 00:00:00 2001 From: Tengda Wu Date: Wed, 4 Jun 2025 00:55:33 +0000 Subject: [PATCH 682/971] arm64/ptrace: Fix stack-out-of-bounds read in regs_get_kernel_stack_nth() [ Upstream commit 39dfc971e42d886e7df01371cd1bef505076d84c ] KASAN reports a stack-out-of-bounds read in regs_get_kernel_stack_nth(). Call Trace: [ 97.283505] BUG: KASAN: stack-out-of-bounds in regs_get_kernel_stack_nth+0xa8/0xc8 [ 97.284677] Read of size 8 at addr ffff800089277c10 by task 1.sh/2550 [ 97.285732] [ 97.286067] CPU: 7 PID: 2550 Comm: 1.sh Not tainted 6.6.0+ #11 [ 97.287032] Hardware name: linux,dummy-virt (DT) [ 97.287815] Call trace: [ 97.288279] dump_backtrace+0xa0/0x128 [ 97.288946] show_stack+0x20/0x38 [ 97.289551] dump_stack_lvl+0x78/0xc8 [ 97.290203] print_address_description.constprop.0+0x84/0x3c8 [ 97.291159] print_report+0xb0/0x280 [ 97.291792] kasan_report+0x84/0xd0 [ 97.292421] __asan_load8+0x9c/0xc0 [ 97.293042] regs_get_kernel_stack_nth+0xa8/0xc8 [ 97.293835] process_fetch_insn+0x770/0xa30 [ 97.294562] kprobe_trace_func+0x254/0x3b0 [ 97.295271] kprobe_dispatcher+0x98/0xe0 [ 97.295955] kprobe_breakpoint_handler+0x1b0/0x210 [ 97.296774] call_break_hook+0xc4/0x100 [ 97.297451] brk_handler+0x24/0x78 [ 97.298073] do_debug_exception+0xac/0x178 [ 97.298785] el1_dbg+0x70/0x90 [ 97.299344] el1h_64_sync_handler+0xcc/0xe8 [ 97.300066] el1h_64_sync+0x78/0x80 [ 97.300699] kernel_clone+0x0/0x500 [ 97.301331] __arm64_sys_clone+0x70/0x90 [ 97.302084] invoke_syscall+0x68/0x198 [ 97.302746] el0_svc_common.constprop.0+0x11c/0x150 [ 97.303569] do_el0_svc+0x38/0x50 [ 97.304164] el0_svc+0x44/0x1d8 [ 97.304749] el0t_64_sync_handler+0x100/0x130 [ 97.305500] el0t_64_sync+0x188/0x190 [ 97.306151] [ 97.306475] The buggy address belongs to stack of task 1.sh/2550 [ 97.307461] and is located at offset 0 in frame: [ 97.308257] __se_sys_clone+0x0/0x138 [ 97.308910] [ 97.309241] This frame has 1 object: [ 97.309873] [48, 184) 'args' [ 97.309876] [ 97.310749] The buggy address belongs to the virtual mapping at [ 97.310749] [ffff800089270000, ffff800089279000) created by: [ 97.310749] dup_task_struct+0xc0/0x2e8 [ 97.313347] [ 97.313674] The buggy address belongs to the physical page: [ 97.314604] page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x14f69a [ 97.315885] flags: 0x15ffffe00000000(node=1|zone=2|lastcpupid=0xfffff) [ 97.316957] raw: 015ffffe00000000 0000000000000000 dead000000000122 0000000000000000 [ 97.318207] raw: 0000000000000000 0000000000000000 00000001ffffffff 0000000000000000 [ 97.319445] page dumped because: kasan: bad access detected [ 97.320371] [ 97.320694] Memory state around the buggy address: [ 97.321511] ffff800089277b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 97.322681] ffff800089277b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 97.323846] >ffff800089277c00: 00 00 f1 f1 f1 f1 f1 f1 00 00 00 00 00 00 00 00 [ 97.325023] ^ [ 97.325683] ffff800089277c80: 00 00 00 00 00 00 00 00 00 f3 f3 f3 f3 f3 f3 f3 [ 97.326856] ffff800089277d00: f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 This issue seems to be related to the behavior of some gcc compilers and was also fixed on the s390 architecture before: commit d93a855c31b7 ("s390/ptrace: Avoid KASAN false positives in regs_get_kernel_stack_nth()") As described in that commit, regs_get_kernel_stack_nth() has confirmed that `addr` is on the stack, so reading the value at `*addr` should be allowed. Use READ_ONCE_NOCHECK() helper to silence the KASAN check for this case. Fixes: 0a8ea52c3eb1 ("arm64: Add HAVE_REGS_AND_STACK_ACCESS_API feature") Signed-off-by: Tengda Wu Link: https://lore.kernel.org/r/20250604005533.1278992-1-wutengda@huaweicloud.com [will: Use '*addr' as the argument to READ_ONCE_NOCHECK()] Signed-off-by: Will Deacon Signed-off-by: Sasha Levin --- arch/arm64/kernel/ptrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index a26293e0cc55..c30f5a70bd18 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -139,7 +139,7 @@ unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n) addr += n; if (regs_within_kernel_stack(regs, (unsigned long)addr)) - return *addr; + return READ_ONCE_NOCHECK(*addr); else return 0; } From a77d0a14ed4740fb4d9fe089dc1176a2eab012ff Mon Sep 17 00:00:00 2001 From: Vitaliy Shevtsov Date: Thu, 12 Jun 2025 21:35:18 +0500 Subject: [PATCH 683/971] scsi: elx: efct: Fix memory leak in efct_hw_parse_filter() [ Upstream commit 2a8a5a5dd06eef580f9818567773fd75057cb875 ] strsep() modifies the address of the pointer passed to it so that it no longer points to the original address. This means kfree() gets the wrong pointer. Fix this by passing unmodified pointer returned from kstrdup() to kfree(). Found by Linux Verification Center (linuxtesting.org) with Svace. Fixes: 4df84e846624 ("scsi: elx: efct: Driver initialization routines") Signed-off-by: Vitaliy Shevtsov Link: https://lore.kernel.org/r/20250612163616.24298-1-v.shevtsov@mt-integration.ru Reviewed-by: Daniel Wagner Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/elx/efct/efct_hw.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/elx/efct/efct_hw.c b/drivers/scsi/elx/efct/efct_hw.c index 5a5525054d71..5b079b8b7a08 100644 --- a/drivers/scsi/elx/efct/efct_hw.c +++ b/drivers/scsi/elx/efct/efct_hw.c @@ -1120,7 +1120,7 @@ int efct_hw_parse_filter(struct efct_hw *hw, void *value) { int rc = 0; - char *p = NULL; + char *p = NULL, *pp = NULL; char *token; u32 idx = 0; @@ -1132,6 +1132,7 @@ efct_hw_parse_filter(struct efct_hw *hw, void *value) efc_log_err(hw->os, "p is NULL\n"); return -ENOMEM; } + pp = p; idx = 0; while ((token = strsep(&p, ",")) && *token) { @@ -1144,7 +1145,7 @@ efct_hw_parse_filter(struct efct_hw *hw, void *value) if (idx == ARRAY_SIZE(hw->config.filter_def)) break; } - kfree(p); + kfree(pp); return rc; } From e20f0f44ec5942b88c26fd284fc15b78d3d57706 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Thu, 5 Jun 2025 11:44:46 +0530 Subject: [PATCH 684/971] RISC-V: KVM: Fix the size parameter check in SBI SFENCE calls [ Upstream commit 6aba0cb5bba6141158d5449f2cf53187b7f755f9 ] As-per the SBI specification, an SBI remote fence operation applies to the entire address space if either: 1) start_addr and size are both 0 2) size is equal to 2^XLEN-1 >From the above, only #1 is checked by SBI SFENCE calls so fix the size parameter check in SBI SFENCE calls to cover #2 as well. Fixes: 13acfec2dbcc ("RISC-V: KVM: Add remote HFENCE functions based on VCPU requests") Reviewed-by: Atish Patra Signed-off-by: Anup Patel Link: https://lore.kernel.org/r/20250605061458.196003-2-apatel@ventanamicro.com Signed-off-by: Anup Patel Signed-off-by: Sasha Levin --- arch/riscv/kvm/vcpu_sbi_replace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/riscv/kvm/vcpu_sbi_replace.c b/arch/riscv/kvm/vcpu_sbi_replace.c index 87ec68ed52d7..960836e0cac7 100644 --- a/arch/riscv/kvm/vcpu_sbi_replace.c +++ b/arch/riscv/kvm/vcpu_sbi_replace.c @@ -103,7 +103,7 @@ static int kvm_sbi_ext_rfence_handler(struct kvm_vcpu *vcpu, struct kvm_run *run kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_FENCE_I_SENT); break; case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA: - if (cp->a2 == 0 && cp->a3 == 0) + if ((cp->a2 == 0 && cp->a3 == 0) || cp->a3 == -1UL) kvm_riscv_hfence_vvma_all(vcpu->kvm, hbase, hmask); else kvm_riscv_hfence_vvma_gva(vcpu->kvm, hbase, hmask, @@ -111,7 +111,7 @@ static int kvm_sbi_ext_rfence_handler(struct kvm_vcpu *vcpu, struct kvm_run *run kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_HFENCE_VVMA_SENT); break; case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID: - if (cp->a2 == 0 && cp->a3 == 0) + if ((cp->a2 == 0 && cp->a3 == 0) || cp->a3 == -1UL) kvm_riscv_hfence_vvma_asid_all(vcpu->kvm, hbase, hmask, cp->a4); else From 2a673aca82fee63685a61eefb7437f2f109d953e Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Thu, 5 Jun 2025 11:44:47 +0530 Subject: [PATCH 685/971] RISC-V: KVM: Don't treat SBI HFENCE calls as NOPs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 2e7be162996640bbe3b6da694cc064c511b8a5d9 ] The SBI specification clearly states that SBI HFENCE calls should return SBI_ERR_NOT_SUPPORTED when one of the target hart doesn’t support hypervisor extension (aka nested virtualization in-case of KVM RISC-V). Fixes: c7fa3c48de86 ("RISC-V: KVM: Treat SBI HFENCE calls as NOPs") Reviewed-by: Atish Patra Signed-off-by: Anup Patel Link: https://lore.kernel.org/r/20250605061458.196003-3-apatel@ventanamicro.com Signed-off-by: Anup Patel Signed-off-by: Sasha Levin --- arch/riscv/kvm/vcpu_sbi_replace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/riscv/kvm/vcpu_sbi_replace.c b/arch/riscv/kvm/vcpu_sbi_replace.c index 960836e0cac7..36f5386c60db 100644 --- a/arch/riscv/kvm/vcpu_sbi_replace.c +++ b/arch/riscv/kvm/vcpu_sbi_replace.c @@ -127,9 +127,9 @@ static int kvm_sbi_ext_rfence_handler(struct kvm_vcpu *vcpu, struct kvm_run *run case SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID: /* * Until nested virtualization is implemented, the - * SBI HFENCE calls should be treated as NOPs + * SBI HFENCE calls should return not supported + * hence fallthrough. */ - break; default: retdata->err_val = SBI_ERR_NOT_SUPPORTED; } From f6071c3cfe3a299c9d2ce2b1a7d34fee35a5c98b Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Fri, 13 Jun 2025 17:41:05 -0700 Subject: [PATCH 686/971] perf evsel: Missed close() when probing hybrid core PMUs [ Upstream commit ebec62bc7ec435b475722a5467d67c720a1ad79f ] Add missing close() to avoid leaking perf events. In past perfs this mattered little as the function was just used by 'perf list'. As the function is now used to detect hybrid PMUs leaking the perf event is somewhat more painful. Fixes: b41f1cec91c37eee ("perf list: Skip unsupported events") Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ingo Molnar Cc: Jiapeng Chong Cc: Jiri Olsa Cc: Kan Liang Cc: Mark Rutland Cc: Michael Petlan Cc: Namhyung Kim Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Tiezhu Yang Link: https://lore.kernel.org/r/20250614004108.1650988-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/util/print-events.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c index 9bee082194d5..fb11a967c450 100644 --- a/tools/perf/util/print-events.c +++ b/tools/perf/util/print-events.c @@ -271,6 +271,7 @@ bool is_event_supported(u8 type, u64 config) ret = evsel__open(evsel, NULL, tmap) >= 0; } + evsel__close(evsel); evsel__delete(evsel); } From 6b4311f78a133fc3d6a4bedba0881ea399447d3a Mon Sep 17 00:00:00 2001 From: David Thompson Date: Fri, 13 Jun 2025 16:34:43 +0000 Subject: [PATCH 687/971] gpio: mlxbf3: only get IRQ for device instance 0 [ Upstream commit 10af0273a35ab4513ca1546644b8c853044da134 ] The gpio-mlxbf3 driver interfaces with two GPIO controllers, device instance 0 and 1. There is a single IRQ resource shared between the two controllers, and it is found in the ACPI table for device instance 0. The driver should not attempt to get an IRQ resource when probing device instance 1, otherwise the following error is logged: mlxbf3_gpio MLNXBF33:01: error -ENXIO: IRQ index 0 not found Signed-off-by: David Thompson Reviewed-by: Shravan Kumar Ramani Fixes: cd33f216d241 ("gpio: mlxbf3: Add gpio driver support") Link: https://lore.kernel.org/r/20250613163443.1065217-1-davthompson@nvidia.com Signed-off-by: Bartosz Golaszewski Signed-off-by: Sasha Levin --- drivers/gpio/gpio-mlxbf3.c | 52 +++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/drivers/gpio/gpio-mlxbf3.c b/drivers/gpio/gpio-mlxbf3.c index 10ea71273c89..9875e34bde72 100644 --- a/drivers/gpio/gpio-mlxbf3.c +++ b/drivers/gpio/gpio-mlxbf3.c @@ -190,7 +190,9 @@ static int mlxbf3_gpio_probe(struct platform_device *pdev) struct mlxbf3_gpio_context *gs; struct gpio_irq_chip *girq; struct gpio_chip *gc; + char *colon_ptr; int ret, irq; + long num; gs = devm_kzalloc(dev, sizeof(*gs), GFP_KERNEL); if (!gs) @@ -227,25 +229,39 @@ static int mlxbf3_gpio_probe(struct platform_device *pdev) gc->owner = THIS_MODULE; gc->add_pin_ranges = mlxbf3_gpio_add_pin_ranges; - irq = platform_get_irq(pdev, 0); - if (irq >= 0) { - girq = &gs->gc.irq; - gpio_irq_chip_set_chip(girq, &gpio_mlxbf3_irqchip); - girq->default_type = IRQ_TYPE_NONE; - /* This will let us handle the parent IRQ in the driver */ - girq->num_parents = 0; - girq->parents = NULL; - girq->parent_handler = NULL; - girq->handler = handle_bad_irq; + colon_ptr = strchr(dev_name(dev), ':'); + if (!colon_ptr) { + dev_err(dev, "invalid device name format\n"); + return -EINVAL; + } - /* - * Directly request the irq here instead of passing - * a flow-handler because the irq is shared. - */ - ret = devm_request_irq(dev, irq, mlxbf3_gpio_irq_handler, - IRQF_SHARED, dev_name(dev), gs); - if (ret) - return dev_err_probe(dev, ret, "failed to request IRQ"); + ret = kstrtol(++colon_ptr, 16, &num); + if (ret) { + dev_err(dev, "invalid device instance\n"); + return ret; + } + + if (!num) { + irq = platform_get_irq(pdev, 0); + if (irq >= 0) { + girq = &gs->gc.irq; + gpio_irq_chip_set_chip(girq, &gpio_mlxbf3_irqchip); + girq->default_type = IRQ_TYPE_NONE; + /* This will let us handle the parent IRQ in the driver */ + girq->num_parents = 0; + girq->parents = NULL; + girq->parent_handler = NULL; + girq->handler = handle_bad_irq; + + /* + * Directly request the irq here instead of passing + * a flow-handler because the irq is shared. + */ + ret = devm_request_irq(dev, irq, mlxbf3_gpio_irq_handler, + IRQF_SHARED, dev_name(dev), gs); + if (ret) + return dev_err_probe(dev, ret, "failed to request IRQ"); + } } platform_set_drvdata(pdev, gs); From 218c3629fb8f2de93164bce03f1141175b0c87a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sun, 8 Jun 2025 16:10:33 +0200 Subject: [PATCH 688/971] cifs: Remove duplicate fattr->cf_dtype assignment from wsl_to_fattr() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 840738eae94864993a735ab677b9795bb8f3b961 ] Commit 8bd25b61c5a5 ("smb: client: set correct d_type for reparse DFS/DFSR and mount point") deduplicated assignment of fattr->cf_dtype member from all places to end of the function cifs_reparse_point_to_fattr(). The only one missing place which was not deduplicated is wsl_to_fattr(). Fix it. Fixes: 8bd25b61c5a5 ("smb: client: set correct d_type for reparse DFS/DFSR and mount point") Signed-off-by: Pali Rohár Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/smb/client/reparse.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c index b6556fe3dfa1..4d45c31336df 100644 --- a/fs/smb/client/reparse.c +++ b/fs/smb/client/reparse.c @@ -738,7 +738,6 @@ out: if (!have_xattr_dev && (tag == IO_REPARSE_TAG_LX_CHR || tag == IO_REPARSE_TAG_LX_BLK)) return false; - fattr->cf_dtype = S_DT(fattr->cf_mode); return true; } From 3f5b4c104b7d3267d015daf9d9681c5fe3b01224 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 27 Jun 2025 11:09:04 +0100 Subject: [PATCH 689/971] Linux 6.6.95 Link: https://lore.kernel.org/r/20250623130626.910356556@linuxfoundation.org Tested-by: Peter Schneider Tested-by: Florian Fainelli Tested-by: Ron Economos Tested-by: Mark Brown Link: https://lore.kernel.org/r/20250624121409.093630364@linuxfoundation.org Tested-by: Peter Schneider Tested-by: Florian Fainelli Tested-by: Jon Hunter Tested-by: Linux Kernel Functional Testing Tested-by: Harshit Mogalapalli Tested-by: Mark Brown Tested-by: Miguel Ojeda Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9625d9072c77..679dff5e165c 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 6 PATCHLEVEL = 6 -SUBLEVEL = 94 +SUBLEVEL = 95 EXTRAVERSION = NAME = Pinguïn Aangedreven From 7ebf0f8ffd9e177fc8c912d31b9b5a2edbaf9f1f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Jul 2025 06:43:21 +0000 Subject: [PATCH 690/971] Revert "coredump: hand a pidfd to the usermode coredump helper" This reverts commit cdb61a705f5f3ca2453130daab925e021bda814e which is commit b5325b2a270fcaf7b2a9a0f23d422ca8a5a8bdea upstream. It breaks the Android kernel abi and can be brought back in the future in an abi-safe way if it is really needed. Bug: 161946584 Change-Id: I9ab9c7ee427a717644d3bce8f6a6b89839658be1 Signed-off-by: Greg Kroah-Hartman --- fs/coredump.c | 78 ++++------------------------------------ include/linux/coredump.h | 1 - 2 files changed, 7 insertions(+), 72 deletions(-) diff --git a/fs/coredump.c b/fs/coredump.c index d3a4f5dc2e36..f342f352b478 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include @@ -57,13 +56,6 @@ static bool dump_vma_snapshot(struct coredump_params *cprm); static void free_vma_snapshot(struct coredump_params *cprm); -/* - * File descriptor number for the pidfd for the thread-group leader of - * the coredumping task installed into the usermode helper's file - * descriptor table. - */ -#define COREDUMP_PIDFD_NUMBER 3 - static int core_uses_pid; static unsigned int core_pipe_limit; static char core_pattern[CORENAME_MAX_SIZE] = "core"; @@ -340,27 +332,6 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm, case 'C': err = cn_printf(cn, "%d", cprm->cpu); break; - /* pidfd number */ - case 'F': { - /* - * Installing a pidfd only makes sense if - * we actually spawn a usermode helper. - */ - if (!ispipe) - break; - - /* - * Note that we'll install a pidfd for the - * thread-group leader. We know that task - * linkage hasn't been removed yet and even if - * this @current isn't the actual thread-group - * leader we know that the thread-group leader - * cannot be reaped until @current has exited. - */ - cprm->pid = task_tgid(current); - err = cn_printf(cn, "%d", COREDUMP_PIDFD_NUMBER); - break; - } default: break; } @@ -517,7 +488,7 @@ static void wait_for_dump_helpers(struct file *file) } /* - * umh_coredump_setup + * umh_pipe_setup * helper function to customize the process used * to collect the core in userspace. Specifically * it sets up a pipe and installs it as fd 0 (stdin) @@ -527,62 +498,27 @@ static void wait_for_dump_helpers(struct file *file) * is a special value that we use to trap recursive * core dumps */ -static int umh_coredump_setup(struct subprocess_info *info, struct cred *new) +static int umh_pipe_setup(struct subprocess_info *info, struct cred *new) { struct file *files[2]; - struct file *pidfs_file = NULL; struct coredump_params *cp = (struct coredump_params *)info->data; int err; - if (cp->pid) { - int fd; - - fd = pidfd_prepare(cp->pid, 0, &pidfs_file); - if (fd < 0) - return fd; - - /* - * We don't care about the fd. We also cannot simply - * replace it below because dup2() will refuse to close - * this file descriptor if its in a larval state. So - * close it! - */ - put_unused_fd(fd); - - /* - * Usermode helpers are childen of either - * system_unbound_wq or of kthreadd. So we know that - * we're starting off with a clean file descriptor - * table. So we should always be able to use - * COREDUMP_PIDFD_NUMBER as our file descriptor value. - */ - err = replace_fd(COREDUMP_PIDFD_NUMBER, pidfs_file, 0); - if (err < 0) - goto out_fail; - - pidfs_file = NULL; - } - err = create_pipe_files(files, 0); if (err) - goto out_fail; + return err; cp->file = files[1]; err = replace_fd(0, files[0], 0); fput(files[0]); if (err < 0) - goto out_fail; + return err; /* and disallow core files too */ current->signal->rlim[RLIMIT_CORE] = (struct rlimit){1, 1}; - err = 0; - -out_fail: - if (pidfs_file) - fput(pidfs_file); - return err; + return 0; } void do_coredump(const kernel_siginfo_t *siginfo) @@ -658,7 +594,7 @@ void do_coredump(const kernel_siginfo_t *siginfo) } if (cprm.limit == 1) { - /* See umh_coredump_setup() which sets RLIMIT_CORE = 1. + /* See umh_pipe_setup() which sets RLIMIT_CORE = 1. * * Normally core limits are irrelevant to pipes, since * we're not writing to the file system, but we use @@ -703,7 +639,7 @@ void do_coredump(const kernel_siginfo_t *siginfo) retval = -ENOMEM; sub_info = call_usermodehelper_setup(helper_argv[0], helper_argv, NULL, GFP_KERNEL, - umh_coredump_setup, NULL, &cprm); + umh_pipe_setup, NULL, &cprm); if (sub_info) retval = call_usermodehelper_exec(sub_info, UMH_WAIT_EXEC); diff --git a/include/linux/coredump.h b/include/linux/coredump.h index c1b4c8c70cae..d3eba4360150 100644 --- a/include/linux/coredump.h +++ b/include/linux/coredump.h @@ -28,7 +28,6 @@ struct coredump_params { int vma_count; size_t vma_data_size; struct core_vma_metadata *vma_meta; - struct pid *pid; }; /* From 2ed4312ac372f24da256eee4ca4326f65bb630ec Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 3 Jul 2025 09:13:54 +0000 Subject: [PATCH 691/971] Revert "usb: typec: ucsi: fix Clang -Wsign-conversion warning" This reverts commit b63f23fb0ad28987e177587a6bbd9436e03a29a8 which is commit f4239ace2dd8606f6824757f192965a95746da05 upstream. It breaks the Android kernel abi and can be brought back in the future in an abi-safe way if it is really needed. Bug: 161946584 Change-Id: I24f111caa0ab721abfae8d993c6662ec25b85b55 Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/ucsi/ucsi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h index b7877ef63fb7..abfcfa1887c8 100644 --- a/drivers/usb/typec/ucsi/ucsi.h +++ b/drivers/usb/typec/ucsi/ucsi.h @@ -298,7 +298,7 @@ struct ucsi_debugfs_entry { u64 low; u64 high; } response; - int status; + u32 status; struct dentry *dentry; }; From 6a12f866df4fa7292c53bf4d5be6b0bd06ba39e2 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 3 Jul 2025 09:14:46 +0000 Subject: [PATCH 692/971] Revert "Bluetooth: MGMT: Protect mgmt_pending list with its own lock" This reverts commit bdd56875c6926d8009914f427df71797693e90d4 which is commit 6fe26f694c824b8a4dbf50c635bee1302e3f099c upstream. It breaks the Android kernel abi and can be brought back in the future in an abi-safe way if it is really needed. Bug: 161946584 Change-Id: Icc2f278181cb94ad70d566cc655c8034e24c9156 Signed-off-by: Greg Kroah-Hartman --- include/net/bluetooth/hci_core.h | 1 - net/bluetooth/hci_core.c | 1 - net/bluetooth/mgmt.c | 101 ++++++++++++++++--------------- net/bluetooth/mgmt_util.c | 32 ++-------- net/bluetooth/mgmt_util.h | 4 +- 5 files changed, 59 insertions(+), 80 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index cf20adc689da..46f40cb391c6 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -573,7 +573,6 @@ struct hci_dev { struct hci_conn_hash conn_hash; struct list_head mesh_pending; - struct mutex mgmt_pending_lock; struct list_head mgmt_pending; struct list_head reject_list; struct list_head accept_list; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 32f7bd0e8916..023ad47a385b 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2490,7 +2490,6 @@ struct hci_dev *hci_alloc_dev_priv(int sizeof_priv) mutex_init(&hdev->lock); mutex_init(&hdev->req_lock); - mutex_init(&hdev->mgmt_pending_lock); ida_init(&hdev->unset_handle_ida); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 853d217cabc9..cf1b2fff928d 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1433,17 +1433,22 @@ static void settings_rsp(struct mgmt_pending_cmd *cmd, void *data) send_settings_rsp(cmd->sk, cmd->opcode, match->hdev); + list_del(&cmd->list); + if (match->sk == NULL) { match->sk = cmd->sk; sock_hold(match->sk); } + + mgmt_pending_free(cmd); } static void cmd_status_rsp(struct mgmt_pending_cmd *cmd, void *data) { u8 *status = data; - mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, *status); + mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, *status); + mgmt_pending_remove(cmd); } static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data) @@ -1457,6 +1462,8 @@ static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data) if (cmd->cmd_complete) { cmd->cmd_complete(cmd, match->mgmt_status); + mgmt_pending_remove(cmd); + return; } @@ -1465,13 +1472,13 @@ static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data) static int generic_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status) { - return mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, + return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, cmd->param, cmd->param_len); } static int addr_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status) { - return mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, + return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, cmd->param, sizeof(struct mgmt_addr_info)); } @@ -1511,7 +1518,7 @@ static void mgmt_set_discoverable_complete(struct hci_dev *hdev, void *data, if (err) { u8 mgmt_err = mgmt_status(err); - mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err); + mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE); goto done; } @@ -1686,7 +1693,7 @@ static void mgmt_set_connectable_complete(struct hci_dev *hdev, void *data, if (err) { u8 mgmt_err = mgmt_status(err); - mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err); + mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); goto done; } @@ -1923,8 +1930,8 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err) new_settings(hdev, NULL); } - mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, true, - cmd_status_rsp, &mgmt_err); + mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, cmd_status_rsp, + &mgmt_err); return; } @@ -1934,7 +1941,7 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err) changed = hci_dev_test_and_clear_flag(hdev, HCI_SSP_ENABLED); } - mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, true, settings_rsp, &match); + mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, settings_rsp, &match); if (changed) new_settings(hdev, match.sk); @@ -2054,12 +2061,12 @@ static void set_le_complete(struct hci_dev *hdev, void *data, int err) bt_dev_dbg(hdev, "err %d", err); if (status) { - mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, true, cmd_status_rsp, - &status); + mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, cmd_status_rsp, + &status); return; } - mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, true, settings_rsp, &match); + mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, settings_rsp, &match); new_settings(hdev, match.sk); @@ -2118,7 +2125,7 @@ static void set_mesh_complete(struct hci_dev *hdev, void *data, int err) struct sock *sk = cmd->sk; if (status) { - mgmt_pending_foreach(MGMT_OP_SET_MESH_RECEIVER, hdev, true, + mgmt_pending_foreach(MGMT_OP_SET_MESH_RECEIVER, hdev, cmd_status_rsp, &status); return; } @@ -2559,7 +2566,7 @@ static void mgmt_class_complete(struct hci_dev *hdev, void *data, int err) bt_dev_dbg(hdev, "err %d", err); - mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, + mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err), hdev->dev_class, 3); mgmt_pending_free(cmd); @@ -3347,7 +3354,7 @@ static int pairing_complete(struct mgmt_pending_cmd *cmd, u8 status) bacpy(&rp.addr.bdaddr, &conn->dst); rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type); - err = mgmt_cmd_complete(cmd->sk, cmd->hdev->id, MGMT_OP_PAIR_DEVICE, + err = mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, status, &rp, sizeof(rp)); /* So we don't get further callbacks for this connection */ @@ -5236,7 +5243,7 @@ static void mgmt_add_adv_patterns_monitor_complete(struct hci_dev *hdev, hci_update_passive_scan(hdev); } - mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, + mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(status), &rp, sizeof(rp)); mgmt_pending_remove(cmd); @@ -5451,7 +5458,7 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev, hci_update_passive_scan(hdev); } - mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, + mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(status), &rp, sizeof(rp)); mgmt_pending_free(cmd); @@ -5850,7 +5857,7 @@ static void start_discovery_complete(struct hci_dev *hdev, void *data, int err) cmd != pending_find(MGMT_OP_START_SERVICE_DISCOVERY, hdev)) return; - mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err), + mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err), cmd->param, 1); mgmt_pending_remove(cmd); @@ -6088,7 +6095,7 @@ static void stop_discovery_complete(struct hci_dev *hdev, void *data, int err) bt_dev_dbg(hdev, "err %d", err); - mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err), + mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err), cmd->param, 1); mgmt_pending_remove(cmd); @@ -6313,7 +6320,7 @@ static void set_advertising_complete(struct hci_dev *hdev, void *data, int err) u8 status = mgmt_status(err); if (status) { - mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, true, + mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, cmd_status_rsp, &status); return; } @@ -6323,7 +6330,7 @@ static void set_advertising_complete(struct hci_dev *hdev, void *data, int err) else hci_dev_clear_flag(hdev, HCI_ADVERTISING); - mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, true, settings_rsp, + mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, settings_rsp, &match); new_settings(hdev, match.sk); @@ -6667,7 +6674,7 @@ static void set_bredr_complete(struct hci_dev *hdev, void *data, int err) */ hci_dev_clear_flag(hdev, HCI_BREDR_ENABLED); - mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err); + mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); } else { send_settings_rsp(cmd->sk, MGMT_OP_SET_BREDR, hdev); new_settings(hdev, cmd->sk); @@ -6804,7 +6811,7 @@ static void set_secure_conn_complete(struct hci_dev *hdev, void *data, int err) if (err) { u8 mgmt_err = mgmt_status(err); - mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err); + mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); goto done; } @@ -7251,7 +7258,7 @@ static void get_conn_info_complete(struct hci_dev *hdev, void *data, int err) rp.max_tx_power = HCI_TX_POWER_INVALID; } - mgmt_cmd_complete(cmd->sk, cmd->hdev->id, MGMT_OP_GET_CONN_INFO, status, + mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_GET_CONN_INFO, status, &rp, sizeof(rp)); mgmt_pending_free(cmd); @@ -7411,7 +7418,7 @@ static void get_clock_info_complete(struct hci_dev *hdev, void *data, int err) } complete: - mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, &rp, + mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, &rp, sizeof(rp)); mgmt_pending_free(cmd); @@ -8615,10 +8622,10 @@ static void add_advertising_complete(struct hci_dev *hdev, void *data, int err) rp.instance = cp->instance; if (err) - mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, + mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err)); else - mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, + mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err), &rp, sizeof(rp)); add_adv_complete(hdev, cmd->sk, cp->instance, err); @@ -8806,10 +8813,10 @@ static void add_ext_adv_params_complete(struct hci_dev *hdev, void *data, hci_remove_adv_instance(hdev, cp->instance); - mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, + mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err)); } else { - mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, + mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err), &rp, sizeof(rp)); } @@ -8957,10 +8964,10 @@ static void add_ext_adv_data_complete(struct hci_dev *hdev, void *data, int err) rp.instance = cp->instance; if (err) - mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, + mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err)); else - mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, + mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err), &rp, sizeof(rp)); mgmt_pending_free(cmd); @@ -9119,10 +9126,10 @@ static void remove_advertising_complete(struct hci_dev *hdev, void *data, rp.instance = cp->instance; if (err) - mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, + mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err)); else - mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, + mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, MGMT_STATUS_SUCCESS, &rp, sizeof(rp)); mgmt_pending_free(cmd); @@ -9393,7 +9400,7 @@ void mgmt_index_removed(struct hci_dev *hdev) if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) return; - mgmt_pending_foreach(0, hdev, true, cmd_complete_rsp, &match); + mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match); if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { mgmt_index_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev, NULL, 0, @@ -9431,8 +9438,7 @@ void mgmt_power_on(struct hci_dev *hdev, int err) hci_update_passive_scan(hdev); } - mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, true, settings_rsp, - &match); + mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); new_settings(hdev, match.sk); @@ -9447,8 +9453,7 @@ void __mgmt_power_off(struct hci_dev *hdev) struct cmd_lookup match = { NULL, hdev }; u8 zero_cod[] = { 0, 0, 0 }; - mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, true, settings_rsp, - &match); + mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); /* If the power off is because of hdev unregistration let * use the appropriate INVALID_INDEX status. Otherwise use @@ -9462,7 +9467,7 @@ void __mgmt_power_off(struct hci_dev *hdev) else match.mgmt_status = MGMT_STATUS_NOT_POWERED; - mgmt_pending_foreach(0, hdev, true, cmd_complete_rsp, &match); + mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match); if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0) { mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, @@ -9703,6 +9708,7 @@ static void unpair_device_rsp(struct mgmt_pending_cmd *cmd, void *data) device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, cmd->sk); cmd->cmd_complete(cmd, 0); + mgmt_pending_remove(cmd); } bool mgmt_powering_down(struct hci_dev *hdev) @@ -9755,8 +9761,8 @@ void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, struct mgmt_cp_disconnect *cp; struct mgmt_pending_cmd *cmd; - mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, true, - unpair_device_rsp, hdev); + mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp, + hdev); cmd = pending_find(MGMT_OP_DISCONNECT, hdev); if (!cmd) @@ -9949,7 +9955,7 @@ void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status) if (status) { u8 mgmt_err = mgmt_status(status); - mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, true, + mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, cmd_status_rsp, &mgmt_err); return; } @@ -9959,8 +9965,8 @@ void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status) else changed = hci_dev_test_and_clear_flag(hdev, HCI_LINK_SECURITY); - mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, true, - settings_rsp, &match); + mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, settings_rsp, + &match); if (changed) new_settings(hdev, match.sk); @@ -9984,12 +9990,9 @@ void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, { struct cmd_lookup match = { NULL, hdev, mgmt_status(status) }; - mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, false, sk_lookup, - &match); - mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, false, sk_lookup, - &match); - mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, false, sk_lookup, - &match); + mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, sk_lookup, &match); + mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, sk_lookup, &match); + mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, sk_lookup, &match); if (!status) { mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, dev_class, diff --git a/net/bluetooth/mgmt_util.c b/net/bluetooth/mgmt_util.c index 4ba500c377a4..dba6a0d66500 100644 --- a/net/bluetooth/mgmt_util.c +++ b/net/bluetooth/mgmt_util.c @@ -217,47 +217,30 @@ int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode, struct hci_dev *hdev) { - struct mgmt_pending_cmd *cmd, *tmp; + struct mgmt_pending_cmd *cmd; - mutex_lock(&hdev->mgmt_pending_lock); - - list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) { + list_for_each_entry(cmd, &hdev->mgmt_pending, list) { if (hci_sock_get_channel(cmd->sk) != channel) continue; - - if (cmd->opcode == opcode) { - mutex_unlock(&hdev->mgmt_pending_lock); + if (cmd->opcode == opcode) return cmd; - } } - mutex_unlock(&hdev->mgmt_pending_lock); - return NULL; } -void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, bool remove, +void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, void (*cb)(struct mgmt_pending_cmd *cmd, void *data), void *data) { struct mgmt_pending_cmd *cmd, *tmp; - mutex_lock(&hdev->mgmt_pending_lock); - list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) { if (opcode > 0 && cmd->opcode != opcode) continue; - if (remove) - list_del(&cmd->list); - cb(cmd, data); - - if (remove) - mgmt_pending_free(cmd); } - - mutex_unlock(&hdev->mgmt_pending_lock); } struct mgmt_pending_cmd *mgmt_pending_new(struct sock *sk, u16 opcode, @@ -271,7 +254,7 @@ struct mgmt_pending_cmd *mgmt_pending_new(struct sock *sk, u16 opcode, return NULL; cmd->opcode = opcode; - cmd->hdev = hdev; + cmd->index = hdev->id; cmd->param = kmemdup(data, len, GFP_KERNEL); if (!cmd->param) { @@ -297,9 +280,7 @@ struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, if (!cmd) return NULL; - mutex_lock(&hdev->mgmt_pending_lock); list_add_tail(&cmd->list, &hdev->mgmt_pending); - mutex_unlock(&hdev->mgmt_pending_lock); return cmd; } @@ -313,10 +294,7 @@ void mgmt_pending_free(struct mgmt_pending_cmd *cmd) void mgmt_pending_remove(struct mgmt_pending_cmd *cmd) { - mutex_lock(&cmd->hdev->mgmt_pending_lock); list_del(&cmd->list); - mutex_unlock(&cmd->hdev->mgmt_pending_lock); - mgmt_pending_free(cmd); } diff --git a/net/bluetooth/mgmt_util.h b/net/bluetooth/mgmt_util.h index 024e51dd6937..f2ba994ab1d8 100644 --- a/net/bluetooth/mgmt_util.h +++ b/net/bluetooth/mgmt_util.h @@ -33,7 +33,7 @@ struct mgmt_mesh_tx { struct mgmt_pending_cmd { struct list_head list; u16 opcode; - struct hci_dev *hdev; + int index; void *param; size_t param_len; struct sock *sk; @@ -54,7 +54,7 @@ int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode, struct hci_dev *hdev); -void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, bool remove, +void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, void (*cb)(struct mgmt_pending_cmd *cmd, void *data), void *data); struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, From 4a6499ffc84ca1b661b7292745297ce10a5ef4ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sat, 2 Nov 2024 17:58:31 +0100 Subject: [PATCH 693/971] 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 [ Upstream commit 89381c72d52094988e11d23ef24a00066a0fa458 ] [MS-CIFS] specification in section 2.2.4.53.1 where is described SMB_COM_SESSION_SETUP_ANDX Request, for SessionKey field says: The client MUST set this field to be equal to the SessionKey field in the SMB_COM_NEGOTIATE Response for this SMB connection. Linux SMB client currently set this field to zero. This is working fine against Windows NT SMB servers thanks to [MS-CIFS] product behavior <94>: Windows NT Server ignores the client's SessionKey. For compatibility with [MS-CIFS], set this SessionKey field in Session Setup Request to value retrieved from Negotiate response. Signed-off-by: Pali Rohár Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/smb/client/cifsglob.h | 1 + fs/smb/client/cifspdu.h | 6 +++--- fs/smb/client/cifssmb.c | 1 + fs/smb/client/sess.c | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 6a4ed99e162c..c7da6bf2f44b 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 ca33f6cd6a80..763178b77454 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 c36ab20050c1..db35e68e8a58 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 8959206a0353..81ac4196bb74 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 */ From 0e7f0e6e14badce275cbe16264405693881cea29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 31 Dec 2024 16:06:22 +0100 Subject: [PATCH 694/971] 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 [ Upstream commit a3e771afbb3bce91c8296828304903e7348003fe ] For TRANS2 QUERY_PATH_INFO request when the path does not exist, the Windows NT SMB server returns error response STATUS_OBJECT_NAME_NOT_FOUND or ERRDOS/ERRbadfile without the SMBFLG_RESPONSE flag set. Similarly it returns STATUS_DELETE_PENDING when the file is being deleted. And looks like that any error response from TRANS2 QUERY_PATH_INFO does not have SMBFLG_RESPONSE flag set. So relax check in check_smb_hdr() for detecting if the packet is response for this special case. This change fixes stat() operation against Windows NT SMB servers and also all operations which depends on -ENOENT result from stat like creat() or mkdir(). Signed-off-by: Pali Rohár Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/smb/client/misc.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c index 65d4b72b4d51..9e8e0a01ae8e 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; From 670c1c546cdaabf5fbf90cd50ea99e522825d085 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sun, 6 Oct 2024 19:24:29 +0200 Subject: [PATCH 695/971] 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 [ 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 Signed-off-by: Steve French Signed-off-by: Sasha Levin --- 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 81ac4196bb74..c351da8c3e2e 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; From cad6f283f6a6589e83f77cbc85b950ca6003043b Mon Sep 17 00:00:00 2001 From: Han Young Date: Sun, 4 May 2025 20:57:04 +0800 Subject: [PATCH 696/971] NFSv4: Always set NLINK even if the server doesn't support it [ Upstream commit 3a3065352f73381d3a1aa0ccab44aec3a5a9b365 ] fattr4_numlinks is a recommended attribute, so the client should emulate it even if the server doesn't support it. In decode_attr_nlink function in nfs4xdr.c, nlink is initialized to 1. However, this default value isn't set to the inode due to the check in nfs_fhget. So if the server doesn't support numlinks, inode's nlink will be zero, the mount will fail with error "Stale file handle". Set the nlink to 1 if the server doesn't support it. Signed-off-by: Han Young Signed-off-by: Anna Schumaker Signed-off-by: Sasha Levin --- fs/nfs/inode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 06230baaa554..419d98cf9e29 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) From 7d03b140af33044453e1f0f162bc63d82a25ac7b Mon Sep 17 00:00:00 2001 From: Olga Kornievskaia Date: Fri, 25 Apr 2025 14:09:21 -0400 Subject: [PATCH 697/971] NFSv4.2: fix listxattr to return selinux security label [ Upstream commit 243fea134633ba3d64aceb4c16129c59541ea2c6 ] Currently, when NFS is queried for all the labels present on the file via a command example "getfattr -d -m . /mnt/testfile", it does not return the security label. Yet when asked specifically for the label (getfattr -n security.selinux) it will be returned. Include the security label when all attributes are queried. Signed-off-by: Olga Kornievskaia Signed-off-by: Anna Schumaker Signed-off-by: Sasha Levin --- fs/nfs/nfs4proc.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 1b94a55215e7..97a009e007f9 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; + } - error += error2 + error3; + error4 = security_inode_listsecurity(d_inode(dentry), list, left); + if (error4 < 0) + return error4; + + error += error2 + error3 + error4; if (size && error > size) return -ERANGE; return error; From 35cda8619d97f3b69fee46cf642fb5d22fa90da2 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 11 Apr 2025 21:14:10 +0800 Subject: [PATCH 698/971] mailbox: Not protect module_put with spin_lock_irqsave [ Upstream commit dddbd233e67e792bb0a3f9694a4707e6be29b2c6 ] &chan->lock is not supposed to protect 'chan->mbox'. And in __mbox_bind_client, try_module_get is also not protected by &chan->lock. So move module_put out of the lock protected region. Signed-off-by: Peng Fan Signed-off-by: Jassi Brar Signed-off-by: Sasha Levin --- drivers/mailbox/mailbox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c index f13d705f7861..cb59b4dbad62 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); From f0ba7e6d06f24b5586781324f1efee550df4f8f9 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 6 Apr 2025 21:50:11 +0200 Subject: [PATCH 699/971] mfd: max14577: Fix wakeup source leaks on device unbind [ Upstream commit d905d06e64b0eb3da43af6186c132f5282197998 ] Device can be unbound, so driver must also release memory for the wakeup source. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250406-mfd-device-wakekup-leak-v1-3-318e14bdba0a@linaro.org Signed-off-by: Lee Jones Signed-off-by: Sasha Levin --- drivers/mfd/max14577.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c index 1f4f5002595c..17672eeb1732 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) From c3616dfddf1d484839ea853a25063ab7452e44e9 Mon Sep 17 00:00:00 2001 From: Nikhil Jha Date: Wed, 19 Mar 2025 13:02:40 -0400 Subject: [PATCH 700/971] sunrpc: don't immediately retransmit on seqno miss [ 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 Acked-by: Chuck Lever Signed-off-by: Anna Schumaker Signed-off-by: Sasha Levin --- 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 4ffb2bcaf364..63756607f632 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -2733,8 +2733,13 @@ out_verifier: 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; } From a13b2634dd66191d220d17e2ded95429f0faf4f2 Mon Sep 17 00:00:00 2001 From: Sven Schwermer Date: Fri, 4 Apr 2025 20:40:36 +0200 Subject: [PATCH 701/971] leds: multicolor: Fix intensity setting while SW blinking [ Upstream commit e35ca991a777ef513040cbb36bc8245a031a2633 ] When writing to the multi_intensity file, don't unconditionally call led_set_brightness. By only doing this if blinking is inactive we prevent blinking from stopping if the blinking is in its off phase while the file is written. Instead, if blinking is active, the changed intensity values are applied upon the next blink. This is consistent with changing the brightness on monochrome LEDs with active blinking. Suggested-by: Jacek Anaszewski Acked-by: Jacek Anaszewski Acked-by: Pavel Machek Reviewed-by: Tobias Deiminger Tested-by: Sven Schuchmann Signed-off-by: Sven Schwermer Link: https://lore.kernel.org/r/20250404184043.227116-1-sven@svenschwermer.de Signed-off-by: Lee Jones Signed-off-by: Sasha Levin --- drivers/leds/led-class-multicolor.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/leds/led-class-multicolor.c b/drivers/leds/led-class-multicolor.c index ec62a4811613..e0785935f4ba 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); From 96715eb1a12097a1a89f7a8912c9597385de63aa Mon Sep 17 00:00:00 2001 From: Guang Yuan Wu Date: Fri, 2 May 2025 04:04:21 +0000 Subject: [PATCH 702/971] fuse: fix race between concurrent setattrs from multiple nodes [ 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 Reviewed-by: Bernd Schubert Signed-off-by: Miklos Szeredi Signed-off-by: Sasha Levin --- fs/fuse/dir.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 82951a535d2d..0b84284ece98 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)); From 9d90ab45d3d393532b7fa62d6a6b7ebbde9cf5fc Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Fri, 9 May 2025 17:06:58 +0200 Subject: [PATCH 703/971] cxl/region: Add a dev_err() on missing target list entries [ 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 Reviewed-by: Gregory Price Reviewed-by: Jonathan Cameron Reviewed-by: Dave Jiang Reviewed-by: Dan Williams Reviewed-by: Alison Schofield Reviewed-by: "Fabio M. De Francesco" Tested-by: Gregory Price Acked-by: Dan Williams Link: https://patch.msgid.link/20250509150700.2817697-14-rrichter@amd.com Signed-off-by: Dave Jiang Signed-off-by: Sasha Levin --- 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 d7f7f88009d7..1728cae1e840 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; } From 2d8b3898caf5b4875e7319cd4d71b14c46bc0923 Mon Sep 17 00:00:00 2001 From: Scott Mayhew Date: Wed, 16 Apr 2025 11:23:38 -0400 Subject: [PATCH 704/971] NFSv4: xattr handlers should check for absent nfs filehandles [ Upstream commit 6e9a2f8dbe93c8004c2af2c0158888628b7ca034 ] The nfs inodes for referral anchors that have not yet been followed have their filehandles zeroed out. Attempting to call getxattr() on one of these will cause the nfs client to send a GETATTR to the nfs server with the preceding PUTFH sans filehandle. The server will reply NFS4ERR_NOFILEHANDLE, leading to -EIO being returned to the application. For example: $ strace -e trace=getxattr getfattr -n system.nfs4_acl /mnt/t/ref getxattr("/mnt/t/ref", "system.nfs4_acl", NULL, 0) = -1 EIO (Input/output error) /mnt/t/ref: system.nfs4_acl: Input/output error +++ exited with 1 +++ Have the xattr handlers return -ENODATA instead. Signed-off-by: Scott Mayhew Signed-off-by: Anna Schumaker Signed-off-by: Sasha Levin --- fs/nfs/nfs4proc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 97a009e007f9..3085a2faab2d 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); From ad804e3648d3d4fddb5c6cd0b1272f0294bdf300 Mon Sep 17 00:00:00 2001 From: Alexis Czezar Torreno Date: Mon, 7 Apr 2025 11:47:24 +0800 Subject: [PATCH 705/971] hwmon: (pmbus/max34440) Fix support for max34451 [ Upstream commit 19932f844f3f51646f762f3eac4744ec3a405064 ] The max344** family has an issue with some PMBUS address being switched. This includes max34451 however version MAX34451-NA6 and later has this issue fixed and this commit supports that update. Signed-off-by: Alexis Czezar Torreno Link: https://lore.kernel.org/r/20250407-dev_adpm12160-v3-1-9cd3095445c8@analog.com Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin --- drivers/hwmon/pmbus/max34440.c | 48 +++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/drivers/hwmon/pmbus/max34440.c b/drivers/hwmon/pmbus/max34440.c index fe7f6b1b0985..e14be8ebaad3 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); From f72093f270ea1cc8915ee05d9b6440459f7e163b Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Tue, 27 May 2025 11:23:01 +0900 Subject: [PATCH 706/971] ksmbd: allow a filename to contain special characters on SMB3.1.1 posix extension [ Upstream commit dc3e0f17f74558e8a2fce00608855f050de10230 ] If client send SMB2_CREATE_POSIX_CONTEXT to ksmbd, Allow a filename to contain special characters. Reported-by: Philipp Kerling Signed-off-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/smb/server/smb2pdu.c | 53 +++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index d8325504a162..b851cd7d19b4 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)) { From efe5db9d98b1f94ca3dffc9210439beb42d56a6d Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Wed, 21 May 2025 09:02:29 +0900 Subject: [PATCH 707/971] ksmbd: provide zero as a unique ID to the Mac client [ 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 Signed-off-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Sasha Levin --- 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 4fdd76ce53b9..dc07c6eb8c19 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 b851cd7d19b4..185f7e0744f8 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 25cc81aac350..2821e6c8298f 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]; From c765f592adc719cd2b925b0f30d65207a7e8f8f5 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Sat, 8 Mar 2025 13:45:06 +0900 Subject: [PATCH 708/971] rust: module: place cleanup_module() in .exit.text section [ Upstream commit 249c3a0e53acefc2b06d3b3e1fc28fb2081f878d ] Place cleanup_module() in .exit.text section. Currently, cleanup_module() is likely placed in the .text section. It's inconsistent with the layout of C modules, where cleanup_module() is placed in .exit.text. [ Boqun asked for an example of how the section changed to be put in the log. Tomonori provided the following examples: C module: $ objdump -t ~/build/x86/drivers/block/loop.o|grep clean 0000000000000000 l O .exit.data 0000000000000008 __UNIQUE_ID___addressable_cleanup_module412 0000000000000000 g F .exit.text 000000000000009c cleanup_module Rust module without this patch: $ objdump -t ~/build/x86/samples/rust/rust_minimal.o|grep clean 00000000000002b0 g F .text 00000000000000c6 cleanup_module 0000000000000000 g O .exit.data 0000000000000008 _R...___UNIQUE_ID___addressable_cleanup_module Rust module with this patch: $ objdump -t ~/build/x86/samples/rust/rust_minimal.o|grep clean 0000000000000000 g F .exit.text 00000000000000c6 cleanup_module 0000000000000000 g O .exit.data 0000000000000008 _R...___UNIQUE_ID___addressable_cleanup_module - Miguel ] Signed-off-by: FUJITA Tomonori Acked-by: Jarkko Sakkinen Link: https://lore.kernel.org/r/20250308044506.14458-1-fujita.tomonori@gmail.com Signed-off-by: Miguel Ojeda Signed-off-by: Sasha Levin --- rust/macros/module.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/rust/macros/module.rs b/rust/macros/module.rs index 7dee348ef0cc..7614a7198ce2 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 From e0051a3daa8b2cb318b03b2f9317c3e40855847a Mon Sep 17 00:00:00 2001 From: Yi Sun Date: Fri, 9 May 2025 08:03:04 +0800 Subject: [PATCH 709/971] dmaengine: idxd: Check availability of workqueue allocated by idxd wq driver before using [ 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 Reviewed-by: Dave Jiang Reviewed-by: Anil S Keshavamurthy Link: https://lore.kernel.org/r/20250509000304.1402863-1-yi.sun@intel.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- 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 7e3a67f9f0a6..aa39fcd389a9 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); } From 7d942dbcd15553b28ef7d1534b24cf142c7e560e Mon Sep 17 00:00:00 2001 From: Thomas Gessler Date: Wed, 7 May 2025 20:21:01 +0200 Subject: [PATCH 710/971] dmaengine: xilinx_dma: Set dma_device directions [ Upstream commit 7e01511443c30a55a5ae78d3debd46d4d872517e ] Coalesce the direction bits from the enabled TX and/or RX channels into the directions bit mask of dma_device. Without this mask set, dma_get_slave_caps() in the DMAEngine fails, which prevents the driver from being used with an IIO DMAEngine buffer. Signed-off-by: Thomas Gessler Reviewed-by: Suraj Gupta Tested-by: Folker Schwesinger Link: https://lore.kernel.org/r/20250507182101.909010-1-thomas.gessler@brueckmann-gmbh.de Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/dma/xilinx/xilinx_dma.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index 0a3b2e22f23d..14c4c5031b55 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) From 969c9646f0d0fd3c93c2276aa40539e045473b2c Mon Sep 17 00:00:00 2001 From: Wenbin Yao Date: Tue, 22 Apr 2025 18:36:23 +0800 Subject: [PATCH 711/971] PCI: dwc: Make link training more robust by setting PORT_LOGIC_LINK_WIDTH to one lane [ 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 Signed-off-by: Qiang Yu Signed-off-by: Wenbin Yao [mani: subject change] Signed-off-by: Manivannan Sadhasivam [bhelgaas: update PCIe spec citation, format quote] Signed-off-by: Bjorn Helgaas Tested-by: Niklas Cassel Link: https://patch.msgid.link/20250422103623.462277-1-quic_wenbyao@quicinc.com Signed-off-by: Sasha Levin --- 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 2b60d20dfdf5..717af1b757f0 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); From aaef4f1f44b395d3d76ac1b833d4acdb67f77fea Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Tue, 1 Apr 2025 10:17:08 +0100 Subject: [PATCH 712/971] PCI: apple: Fix missing OF node reference in apple_pcie_setup_port [ Upstream commit 7fa9fbf39116b061f8a41cd84f1884c545f322c4 ] In the success path, we hang onto a reference to the node, so make sure to grab one. The caller iterator puts our borrowed reference when we return. Signed-off-by: Hector Martin Signed-off-by: Alyssa Rosenzweig Signed-off-by: Marc Zyngier Signed-off-by: Manivannan Sadhasivam Tested-by: Janne Grunau Reviewed-by: Rob Herring (Arm) Reviewed-by: Manivannan Sadhasivam Acked-by: Alyssa Rosenzweig Link: https://patch.msgid.link/20250401091713.2765724-9-maz@kernel.org Signed-off-by: Sasha Levin --- drivers/pci/controller/pcie-apple.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c index 7e6bd63a6425..08b7070f05d8 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); From 2fb2470bc6835d1a812312dd94da61b186764b6f Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Sat, 24 May 2025 14:13:10 +0800 Subject: [PATCH 713/971] md/md-bitmap: fix dm-raid max_write_behind setting [ Upstream commit 2afe17794cfed5f80295b1b9facd66e6f65e5002 ] It's supposed to be COUNTER_MAX / 2, not COUNTER_MAX. Link: https://lore.kernel.org/linux-raid/20250524061320.370630-14-yukuai1@huaweicloud.com Signed-off-by: Yu Kuai Reviewed-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Signed-off-by: Sasha Levin --- drivers/md/md-bitmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 8317e07b326d..21decb97bc05 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; From 9d578589e3ec6ce2cc6281eac64fe9bdc97fe2a5 Mon Sep 17 00:00:00 2001 From: Yifan Zhang Date: Wed, 21 May 2025 18:06:28 +0800 Subject: [PATCH 714/971] amd/amdkfd: fix a kfd_process ref leak [ Upstream commit 90237b16ec1d7afa16e2173cc9a664377214cdd9 ] This patch is to fix a kfd_prcess ref leak. Signed-off-by: Yifan Zhang Reviewed-by: Philip Yang Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/amdkfd/kfd_events.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index 0f58be65132f..2b07c0000df6 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; } From 553f560e0a74a7008ad9dba05c3fd05da296befb Mon Sep 17 00:00:00 2001 From: Linggang Zeng Date: Tue, 27 May 2025 13:15:59 +0800 Subject: [PATCH 715/971] bcache: fix NULL pointer in cache_set_flush() [ Upstream commit 1e46ed947ec658f89f1a910d880cd05e42d3763e ] 1. LINE#1794 - LINE#1887 is some codes about function of bch_cache_set_alloc(). 2. LINE#2078 - LINE#2142 is some codes about function of register_cache_set(). 3. register_cache_set() will call bch_cache_set_alloc() in LINE#2098. 1794 struct cache_set *bch_cache_set_alloc(struct cache_sb *sb) 1795 { ... 1860 if (!(c->devices = kcalloc(c->nr_uuids, sizeof(void *), GFP_KERNEL)) || 1861 mempool_init_slab_pool(&c->search, 32, bch_search_cache) || 1862 mempool_init_kmalloc_pool(&c->bio_meta, 2, 1863 sizeof(struct bbio) + sizeof(struct bio_vec) * 1864 bucket_pages(c)) || 1865 mempool_init_kmalloc_pool(&c->fill_iter, 1, iter_size) || 1866 bioset_init(&c->bio_split, 4, offsetof(struct bbio, bio), 1867 BIOSET_NEED_BVECS|BIOSET_NEED_RESCUER) || 1868 !(c->uuids = alloc_bucket_pages(GFP_KERNEL, c)) || 1869 !(c->moving_gc_wq = alloc_workqueue("bcache_gc", 1870 WQ_MEM_RECLAIM, 0)) || 1871 bch_journal_alloc(c) || 1872 bch_btree_cache_alloc(c) || 1873 bch_open_buckets_alloc(c) || 1874 bch_bset_sort_state_init(&c->sort, ilog2(c->btree_pages))) 1875 goto err; ^^^^^^^^ 1876 ... 1883 return c; 1884 err: 1885 bch_cache_set_unregister(c); ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1886 return NULL; 1887 } ... 2078 static const char *register_cache_set(struct cache *ca) 2079 { ... 2098 c = bch_cache_set_alloc(&ca->sb); 2099 if (!c) 2100 return err; ^^^^^^^^^^ ... 2128 ca->set = c; 2129 ca->set->cache[ca->sb.nr_this_dev] = ca; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... 2138 return NULL; 2139 err: 2140 bch_cache_set_unregister(c); 2141 return err; 2142 } (1) If LINE#1860 - LINE#1874 is true, then do 'goto err'(LINE#1875) and call bch_cache_set_unregister()(LINE#1885). (2) As (1) return NULL(LINE#1886), LINE#2098 - LINE#2100 would return. (3) As (2) has returned, LINE#2128 - LINE#2129 would do *not* give the value to c->cache[], it means that c->cache[] is NULL. LINE#1624 - LINE#1665 is some codes about function of cache_set_flush(). As (1), in LINE#1885 call bch_cache_set_unregister() ---> bch_cache_set_stop() ---> closure_queue() -.-> cache_set_flush() (as below LINE#1624) 1624 static void cache_set_flush(struct closure *cl) 1625 { ... 1654 for_each_cache(ca, c, i) 1655 if (ca->alloc_thread) ^^ 1656 kthread_stop(ca->alloc_thread); ... 1665 } (4) In LINE#1655 ca is NULL(see (3)) in cache_set_flush() then the kernel crash occurred as below: [ 846.712887] bcache: register_cache() error drbd6: cannot allocate memory [ 846.713242] bcache: register_bcache() error : failed to register device [ 846.713336] bcache: cache_set_free() Cache set 2f84bdc1-498a-4f2f-98a7-01946bf54287 unregistered [ 846.713768] BUG: unable to handle kernel NULL pointer dereference at 00000000000009f8 [ 846.714790] PGD 0 P4D 0 [ 846.715129] Oops: 0000 [#1] SMP PTI [ 846.715472] CPU: 19 PID: 5057 Comm: kworker/19:16 Kdump: loaded Tainted: G OE --------- - - 4.18.0-147.5.1.el8_1.5es.3.x86_64 #1 [ 846.716082] Hardware name: ESPAN GI-25212/X11DPL-i, BIOS 2.1 06/15/2018 [ 846.716451] Workqueue: events cache_set_flush [bcache] [ 846.716808] RIP: 0010:cache_set_flush+0xc9/0x1b0 [bcache] [ 846.717155] Code: 00 4c 89 a5 b0 03 00 00 48 8b 85 68 f6 ff ff a8 08 0f 84 88 00 00 00 31 db 66 83 bd 3c f7 ff ff 00 48 8b 85 48 ff ff ff 74 28 <48> 8b b8 f8 09 00 00 48 85 ff 74 05 e8 b6 58 a2 e1 0f b7 95 3c f7 [ 846.718026] RSP: 0018:ffffb56dcf85fe70 EFLAGS: 00010202 [ 846.718372] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000 [ 846.718725] RDX: 0000000000000001 RSI: 0000000040000001 RDI: 0000000000000000 [ 846.719076] RBP: ffffa0ccc0f20df8 R08: ffffa0ce1fedb118 R09: 000073746e657665 [ 846.719428] R10: 8080808080808080 R11: 0000000000000000 R12: ffffa0ce1fee8700 [ 846.719779] R13: ffffa0ccc0f211a8 R14: ffffa0cd1b902840 R15: ffffa0ccc0f20e00 [ 846.720132] FS: 0000000000000000(0000) GS:ffffa0ce1fec0000(0000) knlGS:0000000000000000 [ 846.720726] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 846.721073] CR2: 00000000000009f8 CR3: 00000008ba00a005 CR4: 00000000007606e0 [ 846.721426] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 846.721778] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 846.722131] PKRU: 55555554 [ 846.722467] Call Trace: [ 846.722814] process_one_work+0x1a7/0x3b0 [ 846.723157] worker_thread+0x30/0x390 [ 846.723501] ? create_worker+0x1a0/0x1a0 [ 846.723844] kthread+0x112/0x130 [ 846.724184] ? kthread_flush_work_fn+0x10/0x10 [ 846.724535] ret_from_fork+0x35/0x40 Now, check whether that ca is NULL in LINE#1655 to fix the issue. Signed-off-by: Linggang Zeng Signed-off-by: Mingzhe Zou Signed-off-by: Coly Li Link: https://lore.kernel.org/r/20250527051601.74407-2-colyli@kernel.org Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- drivers/md/bcache/super.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index 8440b56e385d..b9dfebaa9eae 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) { From c5734f9bab6f0d40577ad0633af4090a5fda2407 Mon Sep 17 00:00:00 2001 From: "Lin.Cao" Date: Thu, 15 May 2025 10:07:13 +0800 Subject: [PATCH 716/971] drm/scheduler: signal scheduled fence when kill job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ 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 Reviewed-by: Philipp Stanner Signed-off-by: Christian König Link: https://lore.kernel.org/r/20250515020713.1110476-1-lincao12@amd.com Signed-off-by: Sasha Levin --- 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 53130a50584c..eed3b8bed9e4 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); From 462215a2a3f42f468cc137912dbcd23edbdeb4d6 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 13 Apr 2025 11:34:41 +0100 Subject: [PATCH 717/971] iio: pressure: zpa2326: Use aligned_s64 for the timestamp [ Upstream commit 886a446b76afddfad307488e95e87f23a08ffd51 ] On x86_32 s64 fields are only 32-bit aligned. Hence force the alignment of the field and padding in the structure by using aligned_s64 instead. Reviewed-by: David Lechner Link: https://patch.msgid.link/20250413103443.2420727-19-jic23@kernel.org Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- drivers/iio/pressure/zpa2326.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c index ef1d0349f424..a1c694199c98 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; From 265ca1741075c8d17dae94b25c8439188be66b0a Mon Sep 17 00:00:00 2001 From: Sami Tolvanen Date: Wed, 26 Mar 2025 19:05:00 +0000 Subject: [PATCH 718/971] um: Add cmpxchg8b_emu and checksum functions to asm-prototypes.h [ Upstream commit 674d03f6bd6b0f8327f1a4920ff5893557facfbd ] With CONFIG_GENDWARFKSYMS, um builds fail due to missing prototypes in asm/asm-prototypes.h. Add declarations for cmpxchg8b_emu and the exported checksum functions, including csum_partial_copy_generic as it's also exported. Cc: Masahiro Yamada Cc: linux-kbuild@vger.kernel.org Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202503251216.lE4t9Ikj-lkp@intel.com/ Signed-off-by: Sami Tolvanen Link: https://patch.msgid.link/20250326190500.847236-2-samitolvanen@google.com Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- arch/um/include/asm/asm-prototypes.h | 5 +++++ arch/x86/um/asm/checksum.h | 3 +++ 2 files changed, 8 insertions(+) diff --git a/arch/um/include/asm/asm-prototypes.h b/arch/um/include/asm/asm-prototypes.h index 5898a26daa0d..408b31d59127 100644 --- a/arch/um/include/asm/asm-prototypes.h +++ b/arch/um/include/asm/asm-prototypes.h @@ -1 +1,6 @@ #include +#include + +#ifdef CONFIG_UML_X86 +extern void cmpxchg8b_emu(void); +#endif diff --git a/arch/x86/um/asm/checksum.h b/arch/x86/um/asm/checksum.h index b07824500363..ddc144657efa 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 From 8dbc01f09cadb8b5ef7fc4fc9b4cceca5fbb7c92 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Tue, 8 Apr 2025 09:45:24 +0200 Subject: [PATCH 719/971] um: use proper care when taking mmap lock during segfault [ Upstream commit 6767e8784cd2e8b386a62330ea6864949d983a3e ] Segfaults can occur at times where the mmap lock cannot be taken. If that happens the segfault handler may not be able to take the mmap lock. Fix the code to use the same approach as most other architectures. Unfortunately, this requires copying code from mm/memory.c and modifying it slightly as UML does not have exception tables. Signed-off-by: Benjamin Berg Link: https://patch.msgid.link/20250408074524.300153-2-benjamin@sipsolutions.net Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- arch/um/kernel/trap.c | 129 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 117 insertions(+), 12 deletions(-) diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 6d8ae86ae978..c16b80011ada 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -17,6 +17,122 @@ #include #include +/* + * NOTE: UML does not have exception tables. As such, this is almost a copy + * of the code in mm/memory.c, only adjusting the logic to simply check whether + * we are coming from the kernel instead of doing an additional lookup in the + * exception table. + * We can do this simplification because we never get here if the exception was + * fixable. + */ +static inline bool get_mmap_lock_carefully(struct mm_struct *mm, bool is_user) +{ + if (likely(mmap_read_trylock(mm))) + return true; + + if (!is_user) + return false; + + return !mmap_read_lock_killable(mm); +} + +static inline bool mmap_upgrade_trylock(struct mm_struct *mm) +{ + /* + * We don't have this operation yet. + * + * It should be easy enough to do: it's basically a + * atomic_long_try_cmpxchg_acquire() + * from RWSEM_READER_BIAS -> RWSEM_WRITER_LOCKED, but + * it also needs the proper lockdep magic etc. + */ + return false; +} + +static inline bool upgrade_mmap_lock_carefully(struct mm_struct *mm, bool is_user) +{ + mmap_read_unlock(mm); + if (!is_user) + return false; + + return !mmap_write_lock_killable(mm); +} + +/* + * Helper for page fault handling. + * + * This is kind of equivalend to "mmap_read_lock()" followed + * by "find_extend_vma()", except it's a lot more careful about + * the locking (and will drop the lock on failure). + * + * For example, if we have a kernel bug that causes a page + * fault, we don't want to just use mmap_read_lock() to get + * the mm lock, because that would deadlock if the bug were + * to happen while we're holding the mm lock for writing. + * + * So this checks the exception tables on kernel faults in + * order to only do this all for instructions that are actually + * expected to fault. + * + * We can also actually take the mm lock for writing if we + * need to extend the vma, which helps the VM layer a lot. + */ +static struct vm_area_struct * +um_lock_mm_and_find_vma(struct mm_struct *mm, + unsigned long addr, bool is_user) +{ + struct vm_area_struct *vma; + + if (!get_mmap_lock_carefully(mm, is_user)) + return NULL; + + vma = find_vma(mm, addr); + if (likely(vma && (vma->vm_start <= addr))) + return vma; + + /* + * Well, dang. We might still be successful, but only + * if we can extend a vma to do so. + */ + if (!vma || !(vma->vm_flags & VM_GROWSDOWN)) { + mmap_read_unlock(mm); + return NULL; + } + + /* + * We can try to upgrade the mmap lock atomically, + * in which case we can continue to use the vma + * we already looked up. + * + * Otherwise we'll have to drop the mmap lock and + * re-take it, and also look up the vma again, + * re-checking it. + */ + if (!mmap_upgrade_trylock(mm)) { + if (!upgrade_mmap_lock_carefully(mm, is_user)) + return NULL; + + vma = find_vma(mm, addr); + if (!vma) + goto fail; + if (vma->vm_start <= addr) + goto success; + if (!(vma->vm_flags & VM_GROWSDOWN)) + goto fail; + } + + if (expand_stack_locked(vma, addr)) + goto fail; + +success: + mmap_write_downgrade(mm); + return vma; + +fail: + mmap_write_unlock(mm); + return NULL; +} + /* * Note this is constrained to return 0, -EFAULT, -EACCES, -ENOMEM by * segv(). @@ -43,21 +159,10 @@ int handle_page_fault(unsigned long address, unsigned long ip, if (is_user) flags |= FAULT_FLAG_USER; retry: - mmap_read_lock(mm); - vma = find_vma(mm, address); - if (!vma) - goto out; - if (vma->vm_start <= address) - goto good_area; - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto out; - if (is_user && !ARCH_IS_STACKGROW(address)) - goto out; - vma = expand_stack(mm, address); + vma = um_lock_mm_and_find_vma(mm, address, is_user); if (!vma) goto out_nosemaphore; -good_area: *code_out = SEGV_ACCERR; if (is_write) { if (!(vma->vm_flags & VM_WRITE)) From 8217fa7d92f0bdcfc61c20ba9fa2b6ae50970110 Mon Sep 17 00:00:00 2001 From: James Clark Date: Tue, 25 Mar 2025 11:58:47 +0000 Subject: [PATCH 720/971] coresight: Only check bottom two claim bits [ Upstream commit a4e65842e1142aa18ef36113fbd81d614eaefe5a ] The use of the whole register and == could break the claim mechanism if any of the other bits are used in the future. The referenced doc "PSCI - ARM DEN 0022D" also says to only read and clear the bottom two bits. Use FIELD_GET() to extract only the relevant part. Reviewed-by: Leo Yan Reviewed-by: Yeoreum Yun Signed-off-by: James Clark Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20250325-james-coresight-claim-tags-v4-2-dfbd3822b2e5@linaro.org Signed-off-by: Sasha Levin --- drivers/hwtracing/coresight/coresight-core.c | 3 ++- drivers/hwtracing/coresight/coresight-priv.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index 783e259c3761..3b57851869ea 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 30c051055e54..b758a42ed8c7 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 From 41732f9febdccb4f9b87c13cb915d717d68ccafd Mon Sep 17 00:00:00 2001 From: Michael Grzeschik Date: Thu, 17 Apr 2025 19:40:17 +0200 Subject: [PATCH 721/971] usb: dwc2: also exit clock_gating when stopping udc while suspended [ Upstream commit af076a41f8a28faf9ceb9dd2d88aef2c202ef39a ] It is possible that the gadget will be disabled, while the udc is suspended. When enabling the udc in that case, the clock gating will not be enabled again. Leaving the phy unclocked. Even when the udc is not enabled, connecting this powered but not clocked phy leads to enumeration errors on the host side. To ensure that the clock gating will be in an valid state, we ensure that the clock gating will be enabled before stopping the udc. Signed-off-by: Michael Grzeschik Acked-by: Minas Harutyunyan Link: https://lore.kernel.org/r/20250417-dwc2_clock_gating-v1-1-8ea7c4d53d73@pengutronix.de Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/dwc2/gadget.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index ce20c06a9025..c0db3c52831a 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]) From 1063c586a35cbc03c274c39e521492d64fa16f25 Mon Sep 17 00:00:00 2001 From: Purva Yeshi Date: Thu, 10 Apr 2025 22:34:08 +0530 Subject: [PATCH 722/971] iio: adc: ad_sigma_delta: Fix use of uninitialized status_pos [ Upstream commit e5cdb098a3cb165d52282ffc3a6448642953ea13 ] Fix Smatch-detected issue: drivers/iio/adc/ad_sigma_delta.c:604 ad_sd_trigger_handler() error: uninitialized symbol 'status_pos'. The variable `status_pos` was only initialized in specific switch cases (1, 2, 3, 4), which could leave it uninitialized if `reg_size` had an unexpected value. Fix by adding a default case to the switch block to catch unexpected values of `reg_size`. Use `dev_err_ratelimited()` for error logging and `goto irq_handled` instead of returning early. Signed-off-by: Purva Yeshi Link: https://patch.msgid.link/20250410170408.8585-1-purvayeshi550@gmail.com Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- drivers/iio/adc/ad_sigma_delta.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c index 7e2192870743..533667eefe41 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; } /* From a8d1b4f219e8833130927f19d1c8bfbf49215ce4 Mon Sep 17 00:00:00 2001 From: Chenyuan Yang Date: Mon, 10 Mar 2025 20:05:11 -0500 Subject: [PATCH 723/971] misc: tps6594-pfsm: Add NULL pointer check in tps6594_pfsm_probe() [ 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 Link: https://lore.kernel.org/r/20250311010511.1028269-1-chenyuan0y@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- 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 88dcac814892..71fbe31542e5 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; From a33f507f36d5881f602dab581ab0f8d22b49762c Mon Sep 17 00:00:00 2001 From: Chen Yufeng Date: Tue, 15 Apr 2025 14:58:57 +0800 Subject: [PATCH 724/971] usb: potential integer overflow in usbg_make_tpg() [ Upstream commit 153874010354d050f62f8ae25cbb960c17633dc5 ] The variable tpgt in usbg_make_tpg() is defined as unsigned long and is assigned to tpgt->tport_tpgt, which is defined as u16. This may cause an integer overflow when tpgt is greater than USHRT_MAX (65535). I haven't tried to trigger it myself, but it is possible to trigger it by calling usbg_make_tpg() with a large value for tpgt. I modified the type of tpgt to match tpgt->tport_tpgt and adjusted the relevant code accordingly. This patch is similar to commit 59c816c1f24d ("vhost/scsi: potential memory corruption"). Signed-off-by: Chen Yufeng Link: https://lore.kernel.org/r/20250415065857.1619-1-chenyufeng@iie.ac.cn Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/gadget/function/f_tcm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index a7cd0a06879e..5d0d89495395 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); From 8e958d10dd0ce5ae674cce460db5c9ca3f25243b Mon Sep 17 00:00:00 2001 From: Jakub Lewalski Date: Mon, 31 Mar 2025 18:06:19 +0200 Subject: [PATCH 725/971] tty: serial: uartlite: register uart driver in init [ Upstream commit 6bd697b5fc39fd24e2aa418c7b7d14469f550a93 ] When two instances of uart devices are probing, a concurrency race can occur. If one thread calls uart_register_driver function, which first allocates and assigns memory to 'uart_state' member of uart_driver structure, the other instance can bypass uart driver registration and call ulite_assign. This calls uart_add_one_port, which expects the uart driver to be fully initialized. This leads to a kernel panic due to a null pointer dereference: [ 8.143581] BUG: kernel NULL pointer dereference, address: 00000000000002b8 [ 8.156982] #PF: supervisor write access in kernel mode [ 8.156984] #PF: error_code(0x0002) - not-present page [ 8.156986] PGD 0 P4D 0 ... [ 8.180668] RIP: 0010:mutex_lock+0x19/0x30 [ 8.188624] Call Trace: [ 8.188629] ? __die_body.cold+0x1a/0x1f [ 8.195260] ? page_fault_oops+0x15c/0x290 [ 8.209183] ? __irq_resolve_mapping+0x47/0x80 [ 8.209187] ? exc_page_fault+0x64/0x140 [ 8.209190] ? asm_exc_page_fault+0x22/0x30 [ 8.209196] ? mutex_lock+0x19/0x30 [ 8.223116] uart_add_one_port+0x60/0x440 [ 8.223122] ? proc_tty_register_driver+0x43/0x50 [ 8.223126] ? tty_register_driver+0x1ca/0x1e0 [ 8.246250] ulite_probe+0x357/0x4b0 [uartlite] To prevent it, move uart driver registration in to init function. This will ensure that uart_driver is always registered when probe function is called. Signed-off-by: Jakub Lewalski Signed-off-by: Elodie Decerle Link: https://lore.kernel.org/r/20250331160732.2042-1-elodie.decerle@nokia.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/tty/serial/uartlite.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index b225a78f6175..9f39bafa7fa9 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c @@ -872,16 +872,6 @@ of_err: 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); From 0aaf810416c98766e19105c914ea2432d2556df5 Mon Sep 17 00:00:00 2001 From: Chance Yang Date: Fri, 11 Apr 2025 16:33:26 +0800 Subject: [PATCH 726/971] usb: common: usb-conn-gpio: use a unique name for usb connector device [ Upstream commit d4e5b10c55627e2f3fc9e5b337a28b4e2f02a55e ] The current implementation of the usb-conn-gpio driver uses a fixed "usb-charger" name for all USB connector devices. This causes conflicts in the power supply subsystem when multiple USB connectors are present, as duplicate names are not allowed. Use IDA to manage unique IDs for naming usb connectors (e.g., usb-charger-0, usb-charger-1). Signed-off-by: Chance Yang Link: https://lore.kernel.org/r/20250411-work-next-v3-1-7cd9aa80190c@kneron.us Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/common/usb-conn-gpio.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/usb/common/usb-conn-gpio.c b/drivers/usb/common/usb-conn-gpio.c index 501e8bc9738e..1096a884c8d7 100644 --- a/drivers/usb/common/usb-conn-gpio.c +++ b/drivers/usb/common/usb-conn-gpio.c @@ -20,6 +20,9 @@ #include #include #include +#include + +static DEFINE_IDA(usb_conn_ida); #define USB_GPIO_DEB_MS 20 /* ms */ #define USB_GPIO_DEB_US ((USB_GPIO_DEB_MS) * 1000) /* us */ @@ -29,6 +32,7 @@ struct usb_conn_info { struct device *dev; + int conn_id; /* store the IDA-allocated ID */ struct usb_role_switch *role_sw; enum usb_role last_role; struct regulator *vbus; @@ -160,7 +164,17 @@ static int usb_conn_psy_register(struct usb_conn_info *info) .of_node = dev->of_node, }; - desc->name = "usb-charger"; + info->conn_id = ida_alloc(&usb_conn_ida, GFP_KERNEL); + if (info->conn_id < 0) + return info->conn_id; + + desc->name = devm_kasprintf(dev, GFP_KERNEL, "usb-charger-%d", + info->conn_id); + if (!desc->name) { + ida_free(&usb_conn_ida, info->conn_id); + return -ENOMEM; + } + desc->properties = usb_charger_properties; desc->num_properties = ARRAY_SIZE(usb_charger_properties); desc->get_property = usb_charger_get_property; @@ -168,8 +182,10 @@ static int usb_conn_psy_register(struct usb_conn_info *info) cfg.drv_data = info; info->charger = devm_power_supply_register(dev, desc, &cfg); - if (IS_ERR(info->charger)) - dev_err(dev, "Unable to register charger\n"); + if (IS_ERR(info->charger)) { + dev_err(dev, "Unable to register charger %d\n", info->conn_id); + ida_free(&usb_conn_ida, info->conn_id); + } return PTR_ERR_OR_ZERO(info->charger); } @@ -277,6 +293,9 @@ static 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); From 433cb3e70dc95bd0641a7b4982ef07e79c14a4c9 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 21 Mar 2025 18:49:49 +0200 Subject: [PATCH 727/971] 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 [ Upstream commit 82fe5107fa3d21d6c3fba091c9dbc50495588630 ] When creating a device path in the driver the snprintf() takes up to 16 characters long argument along with the additional up to 12 characters for the signed integer (as it can't see the actual limits) and tries to pack this into 16 bytes array. GCC complains about that when build with `make W=1`: drivers/usb/core/usb.c:705:25: note: ‘snprintf’ output between 3 and 28 bytes into a destination of size 16 Since everything works until now, let's just check for the potential buffer overflow and bail out. It is most likely a never happen situation, but at least it makes GCC happy. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20250321164949.423957-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/core/usb.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 2a938cf47ccd..da6d5e5f79e7 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); From 00626325dba74c24bf81dd95bd447fc09902a2f1 Mon Sep 17 00:00:00 2001 From: Robert Hodaszi Date: Thu, 3 Apr 2025 16:40:04 +0200 Subject: [PATCH 728/971] usb: cdc-wdm: avoid setting WDM_READ for ZLP-s [ Upstream commit 387602d8a75574fafb451b7a8215e78dfd67ee63 ] Don't set WDM_READ flag in wdm_in_callback() for ZLP-s, otherwise when userspace tries to poll for available data, it might - incorrectly - believe there is something available, and when it tries to non-blocking read it, it might get stuck in the read loop. For example this is what glib does for non-blocking read (briefly): 1. poll() 2. if poll returns with non-zero, starts a read data loop: a. loop on poll() (EINTR disabled) b. if revents was set, reads data I. if read returns with EINTR or EAGAIN, goto 2.a. II. otherwise return with data So if ZLP sets WDM_READ (#1), we expect data, and try to read it (#2). But as that was a ZLP, and we are doing non-blocking read, wdm_read() returns with EAGAIN (#2.b.I), so loop again, and try to read again (#2.a.). With glib, we might stuck in this loop forever, as EINTR is disabled (#2.a). Signed-off-by: Robert Hodaszi Acked-by: Oliver Neukum Link: https://lore.kernel.org/r/20250403144004.3889125-1-robert.hodaszi@digi.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/class/cdc-wdm.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 559c121f0923..600ad9412c14 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 @@ retry: 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); } From 8851e40587013db00b71d4aeaae30f5fd59b0eec Mon Sep 17 00:00:00 2001 From: Jos Wang Date: Sun, 9 Feb 2025 15:19:26 +0800 Subject: [PATCH 729/971] 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 [ Upstream commit b4b38ffb38c91afd4dc387608db26f6fc34ed40b ] Although some Type-C DRD devices that do not support the DP Sink function (such as Huawei Mate 40Pro), the Source Port initiates Enter Mode CMD, but the device responds to Enter Mode ACK, the Source port then initiates DP Status Update CMD, and the device responds to DP Status Update NAK. As PD2.0 spec ("6.4.4.3.4 Enter Mode Command"),A DR_Swap Message Shall Not be sent during Modal Operation between the Port Partners. At this time, the source port initiates DR_Swap message through the "echo device > /sys/class/typec/port0/data_role" command to switch the data role from host to device. The device will initiate a Hard Reset for recovery, resulting in the failure of data role swap. Therefore, when DP Status Update NAK is received, Exit Mode CMD is initiated to exit the currently entered DP altmode. Signed-off-by: Jos Wang Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20250209071926.69625-1-joswang1221@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/typec/altmodes/displayport.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c index ccff838ab89e..5f6fc5b79212 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); From 23fe269bfab3786f2bbc386dcf2fd1cf9138e382 Mon Sep 17 00:00:00 2001 From: Michael Grzeschik Date: Fri, 4 Apr 2025 00:21:01 +0200 Subject: [PATCH 730/971] usb: typec: mux: do not return on EOPNOTSUPP in {mux, switch}_set [ Upstream commit 0f7bbef1794dc87141897f804e5871a293aa174b ] Since the typec connectors can have many muxes or switches for different lanes (sbu, usb2, usb3) going into different modal states (usb2, usb3, audio, debug) all of them will be called on typec_switch_set and typec_mux_set. But not all of them will be handling the expected mode. If one of the mux or switch will come back with EOPTNOSUPP this is no reason to stop running through the next ones. Therefor we skip this particular error value and continue calling the next. Signed-off-by: Michael Grzeschik Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20250404-ml-topic-typec-mux-v1-1-22c0526381ba@pengutronix.de Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/typec/mux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c index 80dd91938d96..a5b2a6f9c579 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; } From b8cd384c53ae9682753f3a4b3ad9d53610c230f8 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Fri, 30 May 2025 16:13:09 +0200 Subject: [PATCH 731/971] 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 [ Upstream commit 3f100f524e75586537e337b34d18c8d604b398e7 ] For the classic snd_hda_intel driver, codec->card and bus->card point to the exact same thing. When snd_card_diconnect() fires, bus->shutdown is set thanks to azx_dev_disconnect(). card->shutdown is already set when that happens but both provide basically the same functionality. For the DSP snd_soc_avs driver where multiple codecs are located on multiple cards, bus->shutdown 'shortcut' is not sufficient. One codec card may be unregistered while other codecs are still operational. Proper check in form of card->shutdown must be used to verify whether the codec's card is being shut down. Reviewed-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250530141309.2943404-1-cezary.rojewski@intel.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/pci/hda/hda_bind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c index b7ca2a83fbb0..95786bdadfe6 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 */ From 789a3f63bd601e14e8e52e2458a8d6f8226b4284 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Thu, 29 May 2025 11:08:13 +0530 Subject: [PATCH 732/971] ALSA: hda: Add new pci id for AMD GPU display HD audio controller [ Upstream commit ab72bfce7647522e01a181e3600c3d14ff5c143e ] Add new pci id for AMD GPU display HD audio controller(device id- 0xab40). Signed-off-by: Vijendar Mukunda Reviewed-by: Alex Deucher Link: https://patch.msgid.link/20250529053838.2350071-1-Vijendar.Mukunda@amd.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/pci/hda/hda_intel.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 3cd5b7da8e15..059693e03fd9 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, From f3465bb320500b52bb10a40c70404fc4b7ee537e Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Tue, 27 May 2025 12:26:56 -0500 Subject: [PATCH 733/971] ALSA: usb-audio: Add a quirk for Lenovo Thinkpad Thunderbolt 3 dock [ Upstream commit 4919353c7789b8047e06a9b2b943f775a8f72883 ] The audio controller in the Lenovo Thinkpad Thunderbolt 3 dock doesn't support reading the sampling rate. Add a quirk for it. Suggested-by: Takashi Iwai Signed-off-by: Mario Limonciello Link: https://patch.msgid.link/20250527172657.1972565-1-superm1@kernel.org Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/usb/quirks.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 0b8b20550ab3..f19c808444c9 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 */ From acc1d4cc47f185e7c0669a69c7a0cc56f10cb3ef Mon Sep 17 00:00:00 2001 From: Dmitry Kandybka Date: Tue, 22 Apr 2025 12:32:04 +0300 Subject: [PATCH 734/971] ceph: fix possible integer overflow in ceph_zero_objects() [ Upstream commit 0abd87942e0c93964e93224836944712feba1d91 ] In 'ceph_zero_objects', promote 'object_size' to 'u64' to avoid possible integer overflow. Compile tested only. Found by Linux Verification Center (linuxtesting.org) with SVACE. Signed-off-by: Dmitry Kandybka Reviewed-by: Viacheslav Dubeyko Signed-off-by: Ilya Dryomov Signed-off-by: Sasha Levin --- fs/ceph/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ceph/file.c b/fs/ceph/file.c index a03b11cf7887..e12657b4c3e0 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 */ From d120737a6da7498bcdeb7785b1eeac544a357762 Mon Sep 17 00:00:00 2001 From: Ziqi Chen Date: Thu, 22 May 2025 16:12:28 +0800 Subject: [PATCH 735/971] scsi: ufs: core: Don't perform UFS clkscaling during host async scan [ 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 Signed-off-by: Can Guo Signed-off-by: Ziqi Chen Link: https://lore.kernel.org/r/20250522081233.2358565-1-quic_ziqichen@quicinc.com Suggested-by: Bart Van Assche Reviewed-by: Bart Van Assche Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- 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 9dabc03675b0..412931cf240f 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); } From 2cbeb47ea983cb79ca6464c5fd1abcb1372a7532 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 21 Apr 2025 16:15:19 -0700 Subject: [PATCH 736/971] ovl: Check for NULL d_inode() in ovl_dentry_upper() [ Upstream commit 8a39f1c870e9d6fbac5638f3a42a6a6363829c49 ] In ovl_path_type() and ovl_is_metacopy_dentry() GCC notices that it is possible for OVL_E() to return NULL (which implies that d_inode(dentry) may be NULL). This would result in out of bounds reads via container_of(), seen with GCC 15's -Warray-bounds -fdiagnostics-details. For example: In file included from arch/x86/include/generated/asm/rwonce.h:1, from include/linux/compiler.h:339, from include/linux/export.h:5, from include/linux/linkage.h:7, from include/linux/fs.h:5, from fs/overlayfs/util.c:7: In function 'ovl_upperdentry_dereference', inlined from 'ovl_dentry_upper' at ../fs/overlayfs/util.c:305:9, inlined from 'ovl_path_type' at ../fs/overlayfs/util.c:216:6: include/asm-generic/rwonce.h:44:26: error: array subscript 0 is outside array bounds of 'struct inode[7486503276667837]' [-Werror=array-bounds=] 44 | #define __READ_ONCE(x) (*(const volatile __unqual_scalar_typeof(x) *)&(x)) | ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/asm-generic/rwonce.h:50:9: note: in expansion of macro '__READ_ONCE' 50 | __READ_ONCE(x); \ | ^~~~~~~~~~~ fs/overlayfs/ovl_entry.h:195:16: note: in expansion of macro 'READ_ONCE' 195 | return READ_ONCE(oi->__upperdentry); | ^~~~~~~~~ 'ovl_path_type': event 1 185 | return inode ? OVL_I(inode)->oe : NULL; 'ovl_path_type': event 2 Avoid this by allowing ovl_dentry_upper() to return NULL if d_inode() is NULL, as that means the problematic dereferencing can never be reached. Note that this fixes the over-eager compiler warning in an effort to being able to enable -Warray-bounds globally. There is no known behavioral bug here. Suggested-by: Amir Goldstein Signed-off-by: Kees Cook Signed-off-by: Miklos Szeredi Signed-off-by: Sasha Levin --- fs/overlayfs/util.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 0bf3ffcd072f..0da1cd01d01c 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) From fc97a116dc4929905538bc0bd3af7faa51192957 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Sat, 7 Jun 2025 09:18:43 +0930 Subject: [PATCH 737/971] btrfs: handle csum tree error with rescue=ibadroots correctly [ Upstream commit 547e836661554dcfa15c212a3821664e85b4191a ] [BUG] There is syzbot based reproducer that can crash the kernel, with the following call trace: (With some debug output added) DEBUG: rescue=ibadroots parsed BTRFS: device fsid 14d642db-7b15-43e4-81e6-4b8fac6a25f8 devid 1 transid 8 /dev/loop0 (7:0) scanned by repro (1010) BTRFS info (device loop0): first mount of filesystem 14d642db-7b15-43e4-81e6-4b8fac6a25f8 BTRFS info (device loop0): using blake2b (blake2b-256-generic) checksum algorithm BTRFS info (device loop0): using free-space-tree BTRFS warning (device loop0): checksum verify failed on logical 5312512 mirror 1 wanted 0xb043382657aede36608fd3386d6b001692ff406164733d94e2d9a180412c6003 found 0x810ceb2bacb7f0f9eb2bf3b2b15c02af867cb35ad450898169f3b1f0bd818651 level 0 DEBUG: read tree root path failed for tree csum, ret=-5 BTRFS warning (device loop0): checksum verify failed on logical 5328896 mirror 1 wanted 0x51be4e8b303da58e6340226815b70e3a93592dac3f30dd510c7517454de8567a found 0x51be4e8b303da58e634022a315b70e3a93592dac3f30dd510c7517454de8567a level 0 BTRFS warning (device loop0): checksum verify failed on logical 5292032 mirror 1 wanted 0x1924ccd683be9efc2fa98582ef58760e3848e9043db8649ee382681e220cdee4 found 0x0cb6184f6e8799d9f8cb335dccd1d1832da1071d12290dab3b85b587ecacca6e level 0 process 'repro' launched './file2' with NULL argv: empty string added DEBUG: no csum root, idatacsums=0 ibadroots=134217728 Oops: general protection fault, probably for non-canonical address 0xdffffc0000000041: 0000 [#1] SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000208-0x000000000000020f] CPU: 5 UID: 0 PID: 1010 Comm: repro Tainted: G OE 6.15.0-custom+ #249 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS unknown 02/02/2022 RIP: 0010:btrfs_lookup_csum+0x93/0x3d0 [btrfs] Call Trace: btrfs_lookup_bio_sums+0x47a/0xdf0 [btrfs] btrfs_submit_bbio+0x43e/0x1a80 [btrfs] submit_one_bio+0xde/0x160 [btrfs] btrfs_readahead+0x498/0x6a0 [btrfs] read_pages+0x1c3/0xb20 page_cache_ra_order+0x4b5/0xc20 filemap_get_pages+0x2d3/0x19e0 filemap_read+0x314/0xde0 __kernel_read+0x35b/0x900 bprm_execve+0x62e/0x1140 do_execveat_common.isra.0+0x3fc/0x520 __x64_sys_execveat+0xdc/0x130 do_syscall_64+0x54/0x1d0 entry_SYSCALL_64_after_hwframe+0x76/0x7e ---[ end trace 0000000000000000 ]--- [CAUSE] Firstly the fs has a corrupted csum tree root, thus to mount the fs we have to go "ro,rescue=ibadroots" mount option. Normally with that mount option, a bad csum tree root should set BTRFS_FS_STATE_NO_DATA_CSUMS flag, so that any future data read will ignore csum search. But in this particular case, we have the following call trace that caused NULL csum root, but not setting BTRFS_FS_STATE_NO_DATA_CSUMS: load_global_roots_objectid(): ret = btrfs_search_slot(); /* Succeeded */ btrfs_item_key_to_cpu() found = true; /* We found the root item for csum tree. */ root = read_tree_root_path(); if (IS_ERR(root)) { if (!btrfs_test_opt(fs_info, IGNOREBADROOTS)) /* * Since we have rescue=ibadroots mount option, * @ret is still 0. */ break; if (!found || ret) { /* @found is true, @ret is 0, error handling for csum * tree is skipped. */ } This means we completely skipped to set BTRFS_FS_STATE_NO_DATA_CSUMS if the csum tree is corrupted, which results unexpected later csum lookup. [FIX] If read_tree_root_path() failed, always populate @ret to the error number. As at the end of the function, we need @ret to determine if we need to do the extra error handling for csum tree. Fixes: abed4aaae4f7 ("btrfs: track the csum, extent, and free space trees in a rb tree") Reported-by: Zhiyu Zhang Reported-by: Longxing Li Reviewed-by: David Sterba Signed-off-by: Qu Wenruo Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/disk-io.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 34a30d61b470..bb5f7911d473 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); From 7747d3f9a50652aac80725d11ebaa16d7d6329b3 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Thu, 20 Feb 2025 10:31:19 -0600 Subject: [PATCH 738/971] fs/jfs: consolidate sanity checking in dbMount [ Upstream commit 0d250b1c52484d489e31df2cf9118b7c4bd49d31 ] Sanity checks have been added to dbMount as individual if clauses with identical error handling. Move these all into one clause. Signed-off-by: Dave Kleikamp Stable-dep-of: 37bfb464ddca ("jfs: validate AG parameters in dbMount() to prevent crashes") Signed-off-by: Sasha Levin --- fs/jfs/jfs_dmap.c | 37 +++++++++---------------------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index 0e1019382cf5..26e89d0c69b6 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; } From 0c40fa81f850556e9aa0185fede9ef1112db7b39 Mon Sep 17 00:00:00 2001 From: Vasiliy Kovalev Date: Mon, 10 Mar 2025 11:56:02 +0300 Subject: [PATCH 739/971] jfs: validate AG parameters in dbMount() to prevent crashes [ Upstream commit 37bfb464ddca87f203071b5bd562cd91ddc0b40a ] Validate db_agheight, db_agwidth, and db_agstart in dbMount to catch corrupted metadata early and avoid undefined behavior in dbAllocAG. Limits are derived from L2LPERCTL, LPERCTL/MAXAG, and CTLTREESIZE: - agheight: 0 to L2LPERCTL/2 (0 to 5) ensures shift (L2LPERCTL - 2*agheight) >= 0. - agwidth: 1 to min(LPERCTL/MAXAG, 2^(L2LPERCTL - 2*agheight)) ensures agperlev >= 1. - Ranges: 1-8 (agheight 0-3), 1-4 (agheight 4), 1 (agheight 5). - LPERCTL/MAXAG = 1024/128 = 8 limits leaves per AG; 2^(10 - 2*agheight) prevents division to 0. - agstart: 0 to CTLTREESIZE-1 - agwidth*(MAXAG-1) keeps ti within stree (size 1365). - Ranges: 0-1237 (agwidth 1), 0-348 (agwidth 8). UBSAN: shift-out-of-bounds in fs/jfs/jfs_dmap.c:1400:9 shift exponent -335544310 is negative CPU: 0 UID: 0 PID: 5822 Comm: syz-executor130 Not tainted 6.14.0-rc5-syzkaller #0 Hardware name: Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2025 Call Trace: __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120 ubsan_epilogue lib/ubsan.c:231 [inline] __ubsan_handle_shift_out_of_bounds+0x3c8/0x420 lib/ubsan.c:468 dbAllocAG+0x1087/0x10b0 fs/jfs/jfs_dmap.c:1400 dbDiscardAG+0x352/0xa20 fs/jfs/jfs_dmap.c:1613 jfs_ioc_trim+0x45a/0x6b0 fs/jfs/jfs_discard.c:105 jfs_ioctl+0x2cd/0x3e0 fs/jfs/ioctl.c:131 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:906 [inline] __se_sys_ioctl+0xf5/0x170 fs/ioctl.c:892 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f Found by Linux Verification Center (linuxtesting.org) with Syzkaller. Cc: stable@vger.kernel.org Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: syzbot+fe8264911355151c487f@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=fe8264911355151c487f Signed-off-by: Vasiliy Kovalev Signed-off-by: Dave Kleikamp Signed-off-by: Sasha Levin --- fs/jfs/jfs_dmap.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index 26e89d0c69b6..35e063c9f3a4 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) { From 99d69684228747b5f092ba593c769b5ef8de5d11 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 12 Jun 2024 18:15:17 +0200 Subject: [PATCH 740/971] ASoC: codecs: wcd9335: Handle nicer probe deferral and simplify with dev_err_probe() [ Upstream commit 4a03b5dbad466c902d522f3405daa4e5d80578c5 ] wcd9335_parse_dt() function is called only from probe(), so printing errors on resource acquisition is discouraged, because it can pollute dmesg. Use dev_err_probe() to fix this and also make the code a bit simpler. Signed-off-by: Krzysztof Kozlowski Link: https://msgid.link/r/20240612-asoc-wcd9xxx-wide-cleanups-v1-4-0d15885b2a06@linaro.org Signed-off-by: Mark Brown Stable-dep-of: 9079db287fc3 ("ASoC: codecs: wcd9335: Fix missing free of regulator supplies") Signed-off-by: Sasha Levin --- sound/soc/codecs/wcd9335.c | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index a05b553e6472..6e172be34ac9 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) From 28b6ef1ab65da4f585ff370a0c24d3603c4761a7 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 24 Mar 2025 19:51:29 +0800 Subject: [PATCH 741/971] ASoC: codec: wcd9335: Convert to GPIO descriptors [ Upstream commit d5099bc1b56417733f4cccf10c61ee74dadd5562 ] of_gpio.h is deprecated, update the driver to use GPIO descriptors. - Use dev_gpiod_get to get GPIO descriptor. - Use gpiod_set_value to configure output value. With legacy of_gpio API, the driver set gpio value 0 to assert reset, and 1 to deassert reset. And the reset-gpios use GPIO_ACTIVE_LOW flag in DTS, so set GPIOD_OUT_LOW when get GPIO descriptors, and set value 1 means output low, set value 0 means output high with gpiod API. The in-tree DTS files have the right polarity set up already so we can expect this to "just work" Reviewed-by: Linus Walleij Signed-off-by: Peng Fan Link: https://patch.msgid.link/20250324-wcd-gpiod-v2-3-773f67ce3b56@nxp.com Reviewed-by: Bartosz Golaszewski Signed-off-by: Mark Brown Stable-dep-of: 9079db287fc3 ("ASoC: codecs: wcd9335: Fix missing free of regulator supplies") Signed-off-by: Sasha Levin --- sound/soc/codecs/wcd9335.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 6e172be34ac9..15f263087bb8 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include @@ -329,7 +329,7 @@ struct wcd9335_codec { int comp_enabled[COMPANDER_MAX]; int intr1; - int reset_gpio; + struct gpio_desc *reset_gpio; struct regulator_bulk_data supplies[WCD9335_MAX_SUPPLY]; unsigned int rx_port_value[WCD9335_RX_MAX]; @@ -5032,12 +5032,11 @@ static const struct regmap_irq_chip wcd9335_regmap_irq1_chip = { static int wcd9335_parse_dt(struct wcd9335_codec *wcd) { struct device *dev = wcd->dev; - struct device_node *np = dev->of_node; int ret; - wcd->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0); - if (wcd->reset_gpio < 0) - return dev_err_probe(dev, wcd->reset_gpio, "Reset GPIO missing from DT\n"); + wcd->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(wcd->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(wcd->reset_gpio), "Reset GPIO missing from DT\n"); wcd->mclk = devm_clk_get(dev, "mclk"); if (IS_ERR(wcd->mclk)) @@ -5080,9 +5079,9 @@ static int wcd9335_power_on_reset(struct wcd9335_codec *wcd) */ usleep_range(600, 650); - gpio_direction_output(wcd->reset_gpio, 0); + gpiod_set_value(wcd->reset_gpio, 1); msleep(20); - gpio_set_value(wcd->reset_gpio, 1); + gpiod_set_value(wcd->reset_gpio, 0); msleep(20); return 0; From 9830ef1803a5bc50b4a984a06cf23142cd46229d Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 26 May 2025 11:47:01 +0200 Subject: [PATCH 742/971] ASoC: codecs: wcd9335: Fix missing free of regulator supplies [ Upstream commit 9079db287fc3e38e040b0edeb0a25770bb679c8e ] Driver gets and enables all regulator supplies in probe path (wcd9335_parse_dt() and wcd9335_power_on_reset()), but does not cleanup in final error paths and in unbind (missing remove() callback). This leads to leaked memory and unbalanced regulator enable count during probe errors or unbind. Fix this by converting entire code into devm_regulator_bulk_get_enable() which also greatly simplifies the code. Fixes: 20aedafdf492 ("ASoC: wcd9335: add support to wcd9335 codec") Cc: stable@vger.kernel.org Signed-off-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20250526-b4-b4-asoc-wcd9395-vdd-px-fixes-v1-1-0b8a2993b7d3@linaro.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/wcd9335.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 15f263087bb8..8d5d186fd580 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. From 3bc5abf8e75a3d2cce8e0a1bfe2e4cb38df1a93a Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 13 May 2025 19:25:38 +0800 Subject: [PATCH 743/971] f2fs: don't over-report free space or inodes in statvfs [ Upstream commit a9201960623287927bf5776de3f70fb2fbde7e02 ] This fixes an analogus bug that was fixed in modern filesystems: a) xfs in commit 4b8d867ca6e2 ("xfs: don't over-report free space or inodes in statvfs") b) ext4 in commit f87d3af74193 ("ext4: don't over-report free space or inodes in statvfs") where statfs can report misleading / incorrect information where project quota is enabled, and the free space is less than the remaining quota. This commit will resolve a test failure in generic/762 which tests for this bug. generic/762 - output mismatch (see /share/git/fstests/results//generic/762.out.bad) # --- tests/generic/762.out 2025-04-15 10:21:53.371067071 +0800 # +++ /share/git/fstests/results//generic/762.out.bad 2025-05-13 16:13:37.000000000 +0800 # @@ -6,8 +6,10 @@ # root blocks2 is in range # dir blocks2 is in range # root bavail2 is in range # -dir bavail2 is in range # +dir bavail2 has value of 1539066 # +dir bavail2 is NOT in range 304734.87 .. 310891.13 # root blocks3 is in range # ... # (Run 'diff -u /share/git/fstests/tests/generic/762.out /share/git/fstests/results//generic/762.out.bad' to see the entire diff) HINT: You _MAY_ be missing kernel fix: XXXXXXXXXXXXXX xfs: don't over-report free space or inodes in statvfs Cc: stable@kernel.org Fixes: ddc34e328d06 ("f2fs: introduce f2fs_statfs_project") Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- fs/f2fs/super.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 702137eafaa6..b9913ab526fd 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); From ebba6cc0781c00566ab7a11d9307cd093a787881 Mon Sep 17 00:00:00 2001 From: Saurabh Sengar Date: Sat, 30 Mar 2024 01:51:57 -0700 Subject: [PATCH 744/971] Drivers: hv: vmbus: Add utility function for querying ring size [ Upstream commit e8c4bd6c6e6b7e7b416c42806981c2a81370001e ] Add a function to query for the preferred ring buffer size of VMBus device. This will allow the drivers (eg. UIO) to allocate the most optimized ring buffer size for devices. Signed-off-by: Saurabh Sengar Reviewed-by: Long Li Link: https://lore.kernel.org/r/1711788723-8593-2-git-send-email-ssengar@linux.microsoft.com Signed-off-by: Greg Kroah-Hartman Stable-dep-of: 0315fef2aff9 ("uio_hv_generic: Align ring size to system page") Signed-off-by: Sasha Levin --- drivers/hv/channel_mgmt.c | 15 ++++++++++++--- drivers/hv/hyperv_vmbus.h | 5 +++++ include/linux/hyperv.h | 2 ++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 2f4d09ce027a..3c6011a48dab 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 787b15068641..34b60009114a 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 b5bf5315ca8c..e4ad9760774e 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; From ca0198894bf980d930282c932bff5b0bbdceb484 Mon Sep 17 00:00:00 2001 From: Saurabh Sengar Date: Sat, 30 Mar 2024 01:51:58 -0700 Subject: [PATCH 745/971] uio_hv_generic: Query the ringbuffer size for device [ Upstream commit e566ed5b64177a0c07b677568f623ed31d23406d ] Query the ring buffer size from pre defined table per device and use that value for allocating the ring buffer for that device. Keep the size as current default which is 2 MB if the device doesn't have any preferred ring size. Signed-off-by: Saurabh Sengar Reviewed-by: Long Li Link: https://lore.kernel.org/r/1711788723-8593-3-git-send-email-ssengar@linux.microsoft.com Signed-off-by: Greg Kroah-Hartman Stable-dep-of: 0315fef2aff9 ("uio_hv_generic: Align ring size to system page") Signed-off-by: Sasha Levin --- drivers/uio/uio_hv_generic.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c index 2804a4f74975..031f6a8f1ebb 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; From df1d7e879eddc0e346727a47b649c5cab1820757 Mon Sep 17 00:00:00 2001 From: Long Li Date: Mon, 5 May 2025 17:56:35 -0700 Subject: [PATCH 746/971] uio_hv_generic: Align ring size to system page [ Upstream commit 0315fef2aff9f251ddef8a4b53db9187429c3553 ] Following the ring header, the ring data should align to system page boundary. Adjust the size if necessary. Cc: stable@vger.kernel.org Fixes: 95096f2fbd10 ("uio-hv-generic: new userspace i/o driver for VMBus") Signed-off-by: Long Li Reviewed-by: Michael Kelley Link: https://lore.kernel.org/r/1746492997-4599-4-git-send-email-longli@linuxonhyperv.com Signed-off-by: Wei Liu Message-ID: <1746492997-4599-4-git-send-email-longli@linuxonhyperv.com> Signed-off-by: Sasha Levin --- drivers/uio/uio_hv_generic.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c index 031f6a8f1ebb..17c1f85f2b7b 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; From b8704eef56c5caf840c7918d7627eac70c99c948 Mon Sep 17 00:00:00 2001 From: Zhang Zekun Date: Sat, 31 Aug 2024 12:04:12 +0800 Subject: [PATCH 747/971] 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 [ Upstream commit f60b4e06a945f25d463ae065c6e41c6e24faee0a ] The for_each_available_child_of_node_scoped() helper provides a scope-based clean-up functionality to put the device_node automatically, and as such, there is no need to call of_node_put() directly. Thus, use this helper to simplify the code. Signed-off-by: Zhang Zekun Reviewed-by: Jonathan Cameron Reviewed-by: Manivannan Sadhasivam Link: https://lore.kernel.org/r/20240831040413.126417-6-zhangzekun11@huawei.com [kwilczynski: commit log] Signed-off-by: Krzysztof Wilczyński Stable-dep-of: 751bec089c4e ("PCI: apple: Set only available ports up") Signed-off-by: Sasha Levin --- drivers/pci/controller/pcie-apple.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c index 08b7070f05d8..66f8854fc341 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; } } From 7bf946a284c321ef1154ae134f80a423f2e345b3 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Tue, 1 Apr 2025 10:17:01 +0100 Subject: [PATCH 748/971] PCI: apple: Set only available ports up [ Upstream commit 751bec089c4eed486578994abd2c5395f08d0302 ] Iterating over disabled ports results in of_irq_parse_raw() parsing the wrong "interrupt-map" entries, as it takes the status of the node into account. This became apparent after disabling unused PCIe ports in the Apple Silicon device trees instead of deleting them. Switching from for_each_child_of_node_scoped() to for_each_available_child_of_node_scoped() solves this issue. Fixes: 1e33888fbe44 ("PCI: apple: Add initial hardware bring-up") Fixes: a0189fdfb73d ("arm64: dts: apple: t8103: Disable unused PCIe ports") Signed-off-by: Janne Grunau Signed-off-by: Alyssa Rosenzweig Signed-off-by: Marc Zyngier Signed-off-by: Manivannan Sadhasivam Tested-by: Janne Grunau Reviewed-by: Rob Herring (Arm) Reviewed-by: Manivannan Sadhasivam Acked-by: Alyssa Rosenzweig Cc: stable@vger.kernel.org Link: https://lore.kernel.org/asahi/20230214-apple_dts_pcie_disable_unused-v1-0-5ea0d3ddcde3@jannau.net/ Link: https://lore.kernel.org/asahi/1ea2107a-bb86-8c22-0bbc-82c453ab08ce@linaro.org/ Link: https://patch.msgid.link/20250401091713.2765724-2-maz@kernel.org Signed-off-by: Sasha Levin --- drivers/pci/controller/pcie-apple.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c index 66f8854fc341..8dfea64a51e0 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); From 0b10b5ab7d1d09fbe34f173250fc369c3fb5b170 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Mon, 22 Jan 2024 12:03:34 +0100 Subject: [PATCH 749/971] tty: vt: make init parameter of consw::con_init() a bool [ Upstream commit dae3e6b6180f1a2394b984c596d39ed2c57d25fe ] The 'init' parameter of consw::con_init() is true for the first call of the hook on a particular console. So make the parameter a bool. And document the hook. Signed-off-by: "Jiri Slaby (SUSE)" Reviewed-by: Geert Uytterhoeven Cc: Helge Deller Cc: "James E.J. Bottomley" Cc: Daniel Vetter Cc: linux-fbdev@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linux-parisc@vger.kernel.org Tested-by: Helge Deller # parisc STI console Link: https://lore.kernel.org/r/20240122110401.7289-21-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover") Signed-off-by: Sasha Levin --- drivers/tty/vt/vt.c | 8 ++++---- drivers/video/console/dummycon.c | 2 +- drivers/video/console/mdacon.c | 2 +- drivers/video/console/newport_con.c | 2 +- drivers/video/console/sticon.c | 2 +- drivers/video/console/vgacon.c | 4 ++-- drivers/video/fbdev/core/fbcon.c | 2 +- include/linux/console.h | 4 +++- 8 files changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 6bd1a7785e88..83028ccf6e52 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 f1711b2f9ff0..9a19eb72a18b 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 ef29b321967f..c5b255c96879 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 e8e4f82cd4a1..12c64ef47087 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -324,7 +324,7 @@ out_unmap: 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 992a4fa431aa..0bfeabc3f7c7 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 c9ec89649b05..490e157aebdd 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 75996ef9992e..9f10a6e92e50 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 7de11c763eb3..4efe76ac56d7 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); From e9ba8c528b8f0d448890382d975074b20214b1b2 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Mon, 22 Jan 2024 12:03:35 +0100 Subject: [PATCH 750/971] tty: vt: sanitize arguments of consw::con_clear() [ Upstream commit 559f01a0ee6d924c6fec3eaf6a5b078b15e71070 ] In consw::con_clear(): * Height is always 1, so drop it. * Offsets and width are always unsigned values, so re-type them as such. This needs a new __fbcon_clear() in the fbcon code to still handle height which might not be 1 when called internally. Note that tests for negative count/width are left in place -- they are taken care of in the next patches. And document the hook. Signed-off-by: "Jiri Slaby (SUSE)" Cc: Helge Deller Cc: "James E.J. Bottomley" Cc: Daniel Vetter Cc: linux-fbdev@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linux-parisc@vger.kernel.org Tested-by: Helge Deller # parisc STI console Link: https://lore.kernel.org/r/20240122110401.7289-22-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover") Signed-off-by: Sasha Levin --- drivers/tty/vt/vt.c | 2 +- drivers/video/console/dummycon.c | 4 ++-- drivers/video/console/mdacon.c | 15 +++++--------- drivers/video/console/newport_con.c | 6 +++--- drivers/video/console/sticon.c | 8 ++++---- drivers/video/console/vgacon.c | 4 ++-- drivers/video/fbdev/core/fbcon.c | 32 +++++++++++++++++------------ include/linux/console.h | 5 +++-- 8 files changed, 39 insertions(+), 37 deletions(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 83028ccf6e52..a368c98c92be 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 9a19eb72a18b..6918014b0240 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 c5b255c96879..1ddbb6cd5b0c 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 12c64ef47087..55c6106b3507 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 0bfeabc3f7c7..d99c2a659bfd 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 490e157aebdd..5b5d1c9ef488 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 9f10a6e92e50..c14dbb09341f 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -1240,8 +1240,8 @@ finished: * 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 4efe76ac56d7..e06cee4923fe 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); From 8853bad7634fe941b9ff4e2de537b249bcf04ddd Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Mon, 22 Jan 2024 12:03:44 +0100 Subject: [PATCH 751/971] tty: vt: make consw::con_switch() return a bool [ Upstream commit 8d5cc8eed738e3202379722295c626cba0849785 ] The non-zero (true) return value from consw::con_switch() means a redraw is needed. So make this return type a bool explicitly instead of int. The latter might imply that -Eerrors are expected. They are not. And document the hook. Signed-off-by: "Jiri Slaby (SUSE)" Cc: Helge Deller Cc: "James E.J. Bottomley" Cc: Daniel Vetter Cc: linux-fbdev@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linux-parisc@vger.kernel.org Tested-by: Helge Deller # parisc STI console Link: https://lore.kernel.org/r/20240122110401.7289-31-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover") Signed-off-by: Sasha Levin --- drivers/tty/vt/vt.c | 2 +- drivers/video/console/dummycon.c | 4 ++-- drivers/video/console/mdacon.c | 4 ++-- drivers/video/console/newport_con.c | 4 ++-- drivers/video/console/sticon.c | 4 ++-- drivers/video/console/vgacon.c | 4 ++-- drivers/video/fbdev/core/fbcon.c | 6 +++--- include/linux/console.h | 4 +++- 8 files changed, 17 insertions(+), 15 deletions(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index a368c98c92be..c5ec7306aa71 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 6918014b0240..d701f2b51f5b 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 1ddbb6cd5b0c..26b41a8f36c8 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 55c6106b3507..63d96c4bbdcc 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 d99c2a659bfd..87900600eff1 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 5b5d1c9ef488..bbc362db40c5 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 c14dbb09341f..9d095fe03e18 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 e06cee4923fe..38571607065d 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); From b6b5bcae7aa5248d2c102991c93aea1cae5d4932 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 20 May 2025 09:14:00 +0200 Subject: [PATCH 752/971] dummycon: Trigger redraw when switching consoles with deferred takeover [ Upstream commit 03bcbbb3995ba5df43af9aba45334e35f2dfe27b ] Signal vt subsystem to redraw console when switching to dummycon with deferred takeover enabled. Makes the console switch to fbcon and displays the available output. With deferred takeover enabled, dummycon acts as the placeholder until the first output to the console happens. At that point, fbcon takes over. If the output happens while dummycon is not active, it cannot inform fbcon. This is the case if the vt subsystem runs in graphics mode. A typical graphical boot starts plymouth, a display manager and a compositor; all while leaving out dummycon. Switching to a text-mode console leaves the console with dummycon even if a getty terminal has been started. Returning true from dummycon's con_switch helper signals the vt subsystem to redraw the screen. If there's output available dummycon's con_putc{s} helpers trigger deferred takeover of fbcon, which sets a display mode and displays the output. If no output is available, dummycon remains active. v2: - make the comment slightly more verbose (Javier) Signed-off-by: Thomas Zimmermann Reported-by: Andrei Borzenkov Closes: https://bugzilla.suse.com/show_bug.cgi?id=1242191 Tested-by: Andrei Borzenkov Acked-by: Javier Martinez Canillas Fixes: 83d83bebf401 ("console/fbcon: Add support for deferred console takeover") Cc: Hans de Goede Cc: linux-fbdev@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: # v4.19+ Link: https://lore.kernel.org/r/20250520071418.8462-1-tzimmermann@suse.de Signed-off-by: Sasha Levin --- drivers/video/console/dummycon.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c index d701f2b51f5b..d99e1b3e4e5c 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 * From d19ae7b033b2b9741a7e5a6af6cd539bcb2600a9 Mon Sep 17 00:00:00 2001 From: Gergo Koteles Date: Thu, 25 Jul 2024 11:21:07 +0200 Subject: [PATCH 753/971] platform/x86: ideapad-laptop: introduce a generic notification chain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ 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 Link: https://lore.kernel.org/r/c5a43efae8a32bd034c3d19c0a686941347575a7.1721898747.git.soyer@irl.hu Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Stable-dep-of: 5808c3421695 ("platform/x86: ideapad-laptop: use usleep_range() for EC polling") Signed-off-by: Sasha Levin --- 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 50013af0537c..e21b4dcfe1dd 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 4498a96de597..3eb0dcd6bf7b 100644 --- a/drivers/platform/x86/ideapad-laptop.h +++ b/drivers/platform/x86/ideapad-laptop.h @@ -12,6 +12,11 @@ #include #include #include +#include + +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, From f8761b11f1c054c510d2e40784f3ee5ef94c12bf Mon Sep 17 00:00:00 2001 From: Gergo Koteles Date: Thu, 25 Jul 2024 11:21:08 +0200 Subject: [PATCH 754/971] 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 [ 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 Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/d980ab3ac32b5e554f456b0ff17279bfdbe2a203.1721898747.git.soyer@irl.hu Signed-off-by: Ilpo Järvinen Stable-dep-of: 5808c3421695 ("platform/x86: ideapad-laptop: use usleep_range() for EC polling") Signed-off-by: Sasha Levin --- 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 07eea525091b..1fd57eb86766 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 e21b4dcfe1dd..3d23c4f90842 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 3eb0dcd6bf7b..948cc61800a9 100644 --- a/drivers/platform/x86/ideapad-laptop.h +++ b/drivers/platform/x86/ideapad-laptop.h @@ -14,6 +14,10 @@ #include #include +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 ef2c267ab485..bd9f95404c7c 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 "); MODULE_DESCRIPTION("Lenovo Yoga Mode Control driver"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(IDEAPAD_LAPTOP); From 6e7af3d4f67fe8cde5c3a3c6a936af8103304040 Mon Sep 17 00:00:00 2001 From: Gergo Koteles Date: Thu, 25 Jul 2024 11:21:09 +0200 Subject: [PATCH 755/971] 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 [ 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 Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/57a48d2582b567f6c6fbcd3b379e17aee0fb5a94.1721898747.git.soyer@irl.hu Signed-off-by: Hans de Goede Stable-dep-of: 5808c3421695 ("platform/x86: ideapad-laptop: use usleep_range() for EC polling") Signed-off-by: Sasha Levin --- 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 3d23c4f90842..db8256cde34a 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -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 948cc61800a9..1e52f2aa0aac 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 -#include -#include #include 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_ */ From 47847495a6eac24bd98d2b7bd651c05849bcbf4b Mon Sep 17 00:00:00 2001 From: Rong Zhang Date: Mon, 26 May 2025 04:18:07 +0800 Subject: [PATCH 756/971] 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 [ 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 Tested-by: Eric Long Tested-by: Jianfei Zhang Tested-by: Mingcong Bai Tested-by: Minh Le Tested-by: Sicheng Zhu Signed-off-by: Rong Zhang Link: https://lore.kernel.org/r/20250525201833.37939-1-i@rong.moe Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin --- 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 db8256cde34a..e84fcb444d87 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -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) From b7904e2fccd0543d1862fb47d32274653145cb40 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Thu, 20 Jun 2024 13:56:13 -0700 Subject: [PATCH 757/971] af_unix: Define locking order for unix_table_double_lock(). [ 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 Reviewed-by: Kent Overstreet Signed-off-by: Paolo Abeni Stable-dep-of: 32ca245464e1 ("af_unix: Don't leave consecutive consumed OOB skbs.") Signed-off-by: Sasha Levin --- 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 236a2cd2bc93..4f839d687c1e 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]); } From fd3af69c14ed0611910ecae8d60dbb084af51a25 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Thu, 20 Jun 2024 13:56:14 -0700 Subject: [PATCH 758/971] af_unix: Define locking order for U_LOCK_SECOND in unix_state_double_lock(). [ 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 Reviewed-by: Kent Overstreet Signed-off-by: Paolo Abeni Stable-dep-of: 32ca245464e1 ("af_unix: Don't leave consecutive consumed OOB skbs.") Signed-off-by: Sasha Levin --- 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 4f839d687c1e..a6f0cc635f4d 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) From 0919388ac44f8a0d7e448d8f85b075417ce75281 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Thu, 20 Jun 2024 13:56:20 -0700 Subject: [PATCH 759/971] af_unix: Define locking order for U_RECVQ_LOCK_EMBRYO in unix_collect_skb(). [ 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 Signed-off-by: Paolo Abeni Stable-dep-of: 32ca245464e1 ("af_unix: Don't leave consecutive consumed OOB skbs.") Signed-off-by: Sasha Levin --- 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 a6f0cc635f4d..7546654f8273 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 23efb78fe9ef..06d94ad999e9 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); } From aabb458c33d974b4e494b5277a210a90d3ad9439 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Fri, 16 Aug 2024 16:39:21 -0700 Subject: [PATCH 760/971] af_unix: Don't call skb_get() for OOB skb. [ Upstream commit 8594d9b85c07f05e431bd07e895c2a3ad9b85d6f ] Since introduced, OOB skb holds an additional reference count with no special reason and caused many issues. Also, kfree_skb() and consume_skb() are used to decrement the count, which is confusing. Let's drop the unnecessary skb_get() in queue_oob() and corresponding kfree_skb(), consume_skb(), and skb_unref(). Now unix_sk(sk)->oob_skb is just a pointer to skb in the receive queue, so special handing is no longer needed in GC. Signed-off-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20240816233921.57800-1-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Stable-dep-of: 32ca245464e1 ("af_unix: Don't leave consecutive consumed OOB skbs.") Signed-off-by: Sasha Levin --- net/unix/af_unix.c | 27 +++++---------------------- net/unix/garbage.c | 16 ++-------------- 2 files changed, 7 insertions(+), 36 deletions(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 7546654f8273..3cfc78121422 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 06d94ad999e9..0068e758be4d 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); From fad0a2c16062ac7c606b93166a7ce9d265bab976 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 18 Jun 2025 21:13:55 -0700 Subject: [PATCH 761/971] af_unix: Don't leave consecutive consumed OOB skbs. [ Upstream commit 32ca245464e1479bfea8592b9db227fdc1641705 ] Jann Horn reported a use-after-free in unix_stream_read_generic(). The following sequences reproduce the issue: $ python3 from socket import * s1, s2 = socketpair(AF_UNIX, SOCK_STREAM) s1.send(b'x', MSG_OOB) s2.recv(1, MSG_OOB) # leave a consumed OOB skb s1.send(b'y', MSG_OOB) s2.recv(1, MSG_OOB) # leave a consumed OOB skb s1.send(b'z', MSG_OOB) s2.recv(1) # recv 'z' illegally s2.recv(1, MSG_OOB) # access 'z' skb (use-after-free) Even though a user reads OOB data, the skb holding the data stays on the recv queue to mark the OOB boundary and break the next recv(). After the last send() in the scenario above, the sk2's recv queue has 2 leading consumed OOB skbs and 1 real OOB skb. Then, the following happens during the next recv() without MSG_OOB 1. unix_stream_read_generic() peeks the first consumed OOB skb 2. manage_oob() returns the next consumed OOB skb 3. unix_stream_read_generic() fetches the next not-yet-consumed OOB skb 4. unix_stream_read_generic() reads and frees the OOB skb , and the last recv(MSG_OOB) triggers KASAN splat. The 3. above occurs because of the SO_PEEK_OFF code, which does not expect unix_skb_len(skb) to be 0, but this is true for such consumed OOB skbs. while (skip >= unix_skb_len(skb)) { skip -= unix_skb_len(skb); skb = skb_peek_next(skb, &sk->sk_receive_queue); ... } In addition to this use-after-free, there is another issue that ioctl(SIOCATMARK) does not function properly with consecutive consumed OOB skbs. So, nothing good comes out of such a situation. Instead of complicating manage_oob(), ioctl() handling, and the next ECONNRESET fix by introducing a loop for consecutive consumed OOB skbs, let's not leave such consecutive OOB unnecessarily. Now, while receiving an OOB skb in unix_stream_recv_urg(), if its previous skb is a consumed OOB skb, it is freed. [0]: BUG: KASAN: slab-use-after-free in unix_stream_read_actor (net/unix/af_unix.c:3027) Read of size 4 at addr ffff888106ef2904 by task python3/315 CPU: 2 UID: 0 PID: 315 Comm: python3 Not tainted 6.16.0-rc1-00407-gec315832f6f9 #8 PREEMPT(voluntary) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-4.fc42 04/01/2014 Call Trace: dump_stack_lvl (lib/dump_stack.c:122) print_report (mm/kasan/report.c:409 mm/kasan/report.c:521) kasan_report (mm/kasan/report.c:636) unix_stream_read_actor (net/unix/af_unix.c:3027) unix_stream_read_generic (net/unix/af_unix.c:2708 net/unix/af_unix.c:2847) unix_stream_recvmsg (net/unix/af_unix.c:3048) sock_recvmsg (net/socket.c:1063 (discriminator 20) net/socket.c:1085 (discriminator 20)) __sys_recvfrom (net/socket.c:2278) __x64_sys_recvfrom (net/socket.c:2291 (discriminator 1) net/socket.c:2287 (discriminator 1) net/socket.c:2287 (discriminator 1)) do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1)) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130) RIP: 0033:0x7f8911fcea06 Code: 5d e8 41 8b 93 08 03 00 00 59 5e 48 83 f8 fc 75 19 83 e2 39 83 fa 08 75 11 e8 26 ff ff ff 66 0f 1f 44 00 00 48 8b 45 10 0f 05 <48> 8b 5d f8 c9 c3 0f 1f 40 00 f3 0f 1e fa 55 48 89 e5 48 83 ec 08 RSP: 002b:00007fffdb0dccb0 EFLAGS: 00000202 ORIG_RAX: 000000000000002d RAX: ffffffffffffffda RBX: 00007fffdb0dcdc8 RCX: 00007f8911fcea06 RDX: 0000000000000001 RSI: 00007f8911a5e060 RDI: 0000000000000006 RBP: 00007fffdb0dccd0 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000202 R12: 00007f89119a7d20 R13: ffffffffc4653600 R14: 0000000000000000 R15: 0000000000000000 Allocated by task 315: kasan_save_stack (mm/kasan/common.c:48) kasan_save_track (mm/kasan/common.c:60 (discriminator 1) mm/kasan/common.c:69 (discriminator 1)) __kasan_slab_alloc (mm/kasan/common.c:348) kmem_cache_alloc_node_noprof (./include/linux/kasan.h:250 mm/slub.c:4148 mm/slub.c:4197 mm/slub.c:4249) __alloc_skb (net/core/skbuff.c:660 (discriminator 4)) alloc_skb_with_frags (./include/linux/skbuff.h:1336 net/core/skbuff.c:6668) sock_alloc_send_pskb (net/core/sock.c:2993) unix_stream_sendmsg (./include/net/sock.h:1847 net/unix/af_unix.c:2256 net/unix/af_unix.c:2418) __sys_sendto (net/socket.c:712 (discriminator 20) net/socket.c:727 (discriminator 20) net/socket.c:2226 (discriminator 20)) __x64_sys_sendto (net/socket.c:2233 (discriminator 1) net/socket.c:2229 (discriminator 1) net/socket.c:2229 (discriminator 1)) do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1)) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130) Freed by task 315: kasan_save_stack (mm/kasan/common.c:48) kasan_save_track (mm/kasan/common.c:60 (discriminator 1) mm/kasan/common.c:69 (discriminator 1)) kasan_save_free_info (mm/kasan/generic.c:579 (discriminator 1)) __kasan_slab_free (mm/kasan/common.c:271) kmem_cache_free (mm/slub.c:4643 (discriminator 3) mm/slub.c:4745 (discriminator 3)) unix_stream_read_generic (net/unix/af_unix.c:3010) unix_stream_recvmsg (net/unix/af_unix.c:3048) sock_recvmsg (net/socket.c:1063 (discriminator 20) net/socket.c:1085 (discriminator 20)) __sys_recvfrom (net/socket.c:2278) __x64_sys_recvfrom (net/socket.c:2291 (discriminator 1) net/socket.c:2287 (discriminator 1) net/socket.c:2287 (discriminator 1)) do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1)) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130) The buggy address belongs to the object at ffff888106ef28c0 which belongs to the cache skbuff_head_cache of size 224 The buggy address is located 68 bytes inside of freed 224-byte region [ffff888106ef28c0, ffff888106ef29a0) The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff888106ef3cc0 pfn:0x106ef2 head: order:1 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 flags: 0x200000000000040(head|node=0|zone=2) page_type: f5(slab) raw: 0200000000000040 ffff8881001d28c0 ffffea000422fe00 0000000000000004 raw: ffff888106ef3cc0 0000000080190010 00000000f5000000 0000000000000000 head: 0200000000000040 ffff8881001d28c0 ffffea000422fe00 0000000000000004 head: ffff888106ef3cc0 0000000080190010 00000000f5000000 0000000000000000 head: 0200000000000001 ffffea00041bbc81 00000000ffffffff 00000000ffffffff head: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff888106ef2800: 00 00 00 00 00 00 00 00 00 00 00 00 fc fc fc fc ffff888106ef2880: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb >ffff888106ef2900: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ^ ffff888106ef2980: fb fb fb fb fc fc fc fc fc fc fc fc fc fc fc fc ffff888106ef2a00: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb Fixes: 314001f0bf92 ("af_unix: Add OOB support") Reported-by: Jann Horn Signed-off-by: Kuniyuki Iwashima Reviewed-by: Jann Horn Link: https://patch.msgid.link/20250619041457.1132791-2-kuni1840@gmail.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- net/unix/af_unix.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 3cfc78121422..7604d399a778 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; From 4841060d2e7a1b6547c7f3e98d4cdc52f03d9aa3 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 22 May 2025 08:43:49 +0200 Subject: [PATCH 762/971] i2c: tiny-usb: disable zero-length read messages commit cbdb25ccf7566eee0c2b945e35cb98baf9ed0aa6 upstream. This driver passes the length of an i2c_msg directly to usb_control_msg(). If the message is now a read and of length 0, it violates the USB protocol and a warning will be printed. Enable the I2C_AQ_NO_ZERO_LEN_READ quirk for this adapter thus forbidding 0-length read messages altogether. Fixes: e8c76eed2ecd ("i2c: New i2c-tiny-usb bus driver") Signed-off-by: Wolfram Sang Cc: # v2.6.22+ Signed-off-by: Andi Shyti Link: https://lore.kernel.org/r/20250522064349.3823-2-wsa+renesas@sang-engineering.com Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-tiny-usb.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c index 1bffe36c40ad..d984b90b3527 100644 --- a/drivers/i2c/busses/i2c-tiny-usb.c +++ b/drivers/i2c/busses/i2c-tiny-usb.c @@ -140,6 +140,11 @@ out: return ret; } +/* prevent invalid 0-length usb_control_msg */ +static const struct i2c_adapter_quirks usb_quirks = { + .flags = I2C_AQ_NO_ZERO_LEN_READ, +}; + /* This is the actual algorithm we define */ static const struct i2c_algorithm usb_algorithm = { .master_xfer = usb_xfer, @@ -248,6 +253,7 @@ static int i2c_tiny_usb_probe(struct usb_interface *interface, /* setup i2c adapter description */ dev->adapter.owner = THIS_MODULE; dev->adapter.class = I2C_CLASS_HWMON; + dev->adapter.quirks = &usb_quirks; dev->adapter.algo = &usb_algorithm; dev->adapter.algo_data = dev; snprintf(dev->adapter.name, sizeof(dev->adapter.name), From c9036b6390afcd34c81cb64d3fb46a84c81abd4f Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 22 May 2025 08:42:35 +0200 Subject: [PATCH 763/971] i2c: robotfuzz-osif: disable zero-length read messages commit 56ad91c1aa9c18064348edf69308080b03c9dc48 upstream. This driver passes the length of an i2c_msg directly to usb_control_msg(). If the message is now a read and of length 0, it violates the USB protocol and a warning will be printed. Enable the I2C_AQ_NO_ZERO_LEN_READ quirk for this adapter thus forbidding 0-length read messages altogether. Fixes: 83e53a8f120f ("i2c: Add bus driver for for OSIF USB i2c device.") Signed-off-by: Wolfram Sang Cc: # v3.14+ Signed-off-by: Andi Shyti Link: https://lore.kernel.org/r/20250522064234.3721-2-wsa+renesas@sang-engineering.com Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-robotfuzz-osif.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/i2c/busses/i2c-robotfuzz-osif.c b/drivers/i2c/busses/i2c-robotfuzz-osif.c index 66dfa211e736..8e4cf9028b23 100644 --- a/drivers/i2c/busses/i2c-robotfuzz-osif.c +++ b/drivers/i2c/busses/i2c-robotfuzz-osif.c @@ -111,6 +111,11 @@ static u32 osif_func(struct i2c_adapter *adapter) return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; } +/* prevent invalid 0-length usb_control_msg */ +static const struct i2c_adapter_quirks osif_quirks = { + .flags = I2C_AQ_NO_ZERO_LEN_READ, +}; + static const struct i2c_algorithm osif_algorithm = { .master_xfer = osif_xfer, .functionality = osif_func, @@ -143,6 +148,7 @@ static int osif_probe(struct usb_interface *interface, priv->adapter.owner = THIS_MODULE; priv->adapter.class = I2C_CLASS_HWMON; + priv->adapter.quirks = &osif_quirks; priv->adapter.algo = &osif_algorithm; priv->adapter.algo_data = priv; snprintf(priv->adapter.name, sizeof(priv->adapter.name), From 490a43d07f1663d827e802720d30cbc0494e4f81 Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Thu, 19 Jun 2025 11:36:07 -0700 Subject: [PATCH 764/971] mm/damon/sysfs-schemes: free old damon_sysfs_scheme_filter->memcg_path on write commit 4f489fe6afb395dbc79840efa3c05440b760d883 upstream. memcg_path_store() assigns a newly allocated memory buffer to filter->memcg_path, without deallocating the previously allocated and assigned memory buffer. As a result, users can leak kernel memory by continuously writing a data to memcg_path DAMOS sysfs file. Fix the leak by deallocating the previously set memory buffer. Link: https://lkml.kernel.org/r/20250619183608.6647-2-sj@kernel.org Fixes: 7ee161f18b5d ("mm/damon/sysfs-schemes: implement filter directory") Signed-off-by: SeongJae Park Cc: Shuah Khan Cc: [6.3.x] Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- mm/damon/sysfs-schemes.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/damon/sysfs-schemes.c b/mm/damon/sysfs-schemes.c index 26c948f87489..19d661889cf7 100644 --- a/mm/damon/sysfs-schemes.c +++ b/mm/damon/sysfs-schemes.c @@ -376,6 +376,7 @@ static ssize_t memcg_path_store(struct kobject *kobj, return -ENOMEM; strscpy(path, buf, count + 1); + kfree(filter->memcg_path); filter->memcg_path = path; return count; } From db33aa6c5c936e581a1fe0151e3d26898199acdb Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Sun, 22 Jun 2025 00:30:01 +0200 Subject: [PATCH 765/971] ASoC: amd: yc: Add DMI quirk for Lenovo IdeaPad Slim 5 15 commit bf39286adc5e10ce3e32eb86ad316ae56f3b52a0 upstream. It's smaller brother has already received the patch to enable the microphone, now add it too to the DMI quirk table. Cc: stable@vger.kernel.org Signed-off-by: Oliver Schramm Link: https://patch.msgid.link/20250621223000.11817-2-oliver.schramm97@gmail.com Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index 9fdee74c28df..40e2b5a87916 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -353,6 +353,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "83J2"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83J3"), + } + }, { .driver_data = &acp6x_card, .matches = { From 88f3869649edbc4a13f6c2877091f81cd5a50f05 Mon Sep 17 00:00:00 2001 From: Fedor Pchelkin Date: Wed, 11 Jun 2025 22:20:10 +0300 Subject: [PATCH 766/971] s390/pkey: Prevent overflow in size calculation for memdup_user() commit 7360ee47599af91a1d5f4e74d635d9408a54e489 upstream. Number of apqn target list entries contained in 'nr_apqns' variable is determined by userspace via an ioctl call so the result of the product in calculation of size passed to memdup_user() may overflow. In this case the actual size of the allocated area and the value describing it won't be in sync leading to various types of unpredictable behaviour later. Use a proper memdup_array_user() helper which returns an error if an overflow is detected. Note that it is different from when nr_apqns is initially zero - that case is considered valid and should be handled in subsequent pkey_handler implementations. Found by Linux Verification Center (linuxtesting.org). Fixes: f2bbc96e7cfa ("s390/pkey: add CCA AES cipher key support") Cc: stable@vger.kernel.org Signed-off-by: Fedor Pchelkin Reviewed-by: Holger Dengler Reviewed-by: Heiko Carstens Link: https://lore.kernel.org/r/20250611192011.206057-1-pchelkin@ispras.ru Signed-off-by: Alexander Gordeev Signed-off-by: Greg Kroah-Hartman --- drivers/s390/crypto/pkey_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c index 70fcb5c40cfe..21fc6151af79 100644 --- a/drivers/s390/crypto/pkey_api.c +++ b/drivers/s390/crypto/pkey_api.c @@ -1333,7 +1333,7 @@ static void *_copy_apqns_from_user(void __user *uapqns, size_t nr_apqns) if (!uapqns || nr_apqns == 0) return NULL; - return memdup_user(uapqns, nr_apqns * sizeof(struct pkey_apqn)); + return memdup_array_user(uapqns, nr_apqns, sizeof(struct pkey_apqn)); } static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, From 64a99eff8dcf1f951a544e6058341b2b19a8fdbd Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Thu, 19 Jun 2025 21:26:55 +0800 Subject: [PATCH 767/971] lib/group_cpus: fix NULL pointer dereference from group_cpus_evenly() commit df831e97739405ecbaddb85516bc7d4d1c933d6b upstream. While testing null_blk with configfs, echo 0 > poll_queues will trigger following panic: BUG: kernel NULL pointer dereference, address: 0000000000000010 Oops: Oops: 0000 [#1] SMP NOPTI CPU: 27 UID: 0 PID: 920 Comm: bash Not tainted 6.15.0-02023-gadbdb95c8696-dirty #1238 PREEMPT(undef) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/01/2014 RIP: 0010:__bitmap_or+0x48/0x70 Call Trace: __group_cpus_evenly+0x822/0x8c0 group_cpus_evenly+0x2d9/0x490 blk_mq_map_queues+0x1e/0x110 null_map_queues+0xc9/0x170 [null_blk] blk_mq_update_queue_map+0xdb/0x160 blk_mq_update_nr_hw_queues+0x22b/0x560 nullb_update_nr_hw_queues+0x71/0xf0 [null_blk] nullb_device_poll_queues_store+0xa4/0x130 [null_blk] configfs_write_iter+0x109/0x1d0 vfs_write+0x26e/0x6f0 ksys_write+0x79/0x180 __x64_sys_write+0x1d/0x30 x64_sys_call+0x45c4/0x45f0 do_syscall_64+0xa5/0x240 entry_SYSCALL_64_after_hwframe+0x76/0x7e Root cause is that numgrps is set to 0, and ZERO_SIZE_PTR is returned from kcalloc(), and later ZERO_SIZE_PTR will be deferenced. Fix the problem by checking numgrps first in group_cpus_evenly(), and return NULL directly if numgrps is zero. [yukuai3@huawei.com: also fix the non-SMP version] Link: https://lkml.kernel.org/r/20250620010958.1265984-1-yukuai1@huaweicloud.com Link: https://lkml.kernel.org/r/20250619132655.3318883-1-yukuai1@huaweicloud.com Fixes: 6a6dcae8f486 ("blk-mq: Build default queue map via group_cpus_evenly()") Signed-off-by: Yu Kuai Reviewed-by: Ming Lei Reviewed-by: Jens Axboe Cc: ErKun Yang Cc: John Garry Cc: Thomas Gleinxer Cc: "zhangyi (F)" Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- lib/group_cpus.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/group_cpus.c b/lib/group_cpus.c index ee272c4cefcc..18d43a406114 100644 --- a/lib/group_cpus.c +++ b/lib/group_cpus.c @@ -352,6 +352,9 @@ struct cpumask *group_cpus_evenly(unsigned int numgrps) int ret = -ENOMEM; struct cpumask *masks = NULL; + if (numgrps == 0) + return NULL; + if (!zalloc_cpumask_var(&nmsk, GFP_KERNEL)) return NULL; @@ -426,8 +429,12 @@ struct cpumask *group_cpus_evenly(unsigned int numgrps) #else /* CONFIG_SMP */ struct cpumask *group_cpus_evenly(unsigned int numgrps) { - struct cpumask *masks = kcalloc(numgrps, sizeof(*masks), GFP_KERNEL); + struct cpumask *masks; + if (numgrps == 0) + return NULL; + + masks = kcalloc(numgrps, sizeof(*masks), GFP_KERNEL); if (!masks) return NULL; From 3c709dce16999bf6a1d2ce377deb5dd6fdd8cb08 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 20 Jun 2025 14:28:44 +0000 Subject: [PATCH 768/971] atm: clip: prevent NULL deref in clip_push() [ Upstream commit b993ea46b3b601915ceaaf3c802adf11e7d6bac6 ] Blamed commit missed that vcc_destroy_socket() calls clip_push() with a NULL skb. If clip_devs is NULL, clip_push() then crashes when reading skb->truesize. Fixes: 93a2014afbac ("atm: fix a UAF in lec_arp_clear_vccs()") Reported-by: syzbot+1316233c4c6803382a8b@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/68556f59.a00a0220.137b3.004e.GAE@google.com/T/#u Signed-off-by: Eric Dumazet Cc: Cong Wang Cc: Gengming Liu Reviewed-by: Simon Horman Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/atm/clip.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/net/atm/clip.c b/net/atm/clip.c index 294cb9efe3d3..511467bb7fe4 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c @@ -193,12 +193,6 @@ static void clip_push(struct atm_vcc *vcc, struct sk_buff *skb) pr_debug("\n"); - if (!clip_devs) { - atm_return(vcc, skb->truesize); - kfree_skb(skb); - return; - } - if (!skb) { pr_debug("removing VCC %p\n", clip_vcc); if (clip_vcc->entry) @@ -208,6 +202,11 @@ static void clip_push(struct atm_vcc *vcc, struct sk_buff *skb) return; } atm_return(vcc, skb->truesize); + if (!clip_devs) { + kfree_skb(skb); + return; + } + skb->dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : clip_devs; /* clip_vcc->entry == NULL if we don't have an IP address yet */ if (!skb->dev) { From 74fcb3852a2f579151ce80b9ed96cd916ba0d5d8 Mon Sep 17 00:00:00 2001 From: Youngjun Lee Date: Mon, 23 Jun 2025 20:05:25 +0900 Subject: [PATCH 769/971] ALSA: usb-audio: Fix out-of-bounds read in snd_usb_get_audioformat_uac3() [ Upstream commit fb4e2a6e8f28a3c0ad382e363aeb9cd822007b8a ] In snd_usb_get_audioformat_uac3(), the length value returned from snd_usb_ctl_msg() is used directly for memory allocation without validation. This length is controlled by the USB device. The allocated buffer is cast to a uac3_cluster_header_descriptor and its fields are accessed without verifying that the buffer is large enough. If the device returns a smaller than expected length, this leads to an out-of-bounds read. Add a length check to ensure the buffer is large enough for uac3_cluster_header_descriptor. Signed-off-by: Youngjun Lee Fixes: 9a2fe9b801f5 ("ALSA: usb: initial USB Audio Device Class 3.0 support") Link: https://patch.msgid.link/20250623-uac3-oob-fix-v1-1-527303eaf40a@samsung.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/usb/stream.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/usb/stream.c b/sound/usb/stream.c index e14c725acebf..0f1558ef8555 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c @@ -982,6 +982,8 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip, * and request Cluster Descriptor */ wLength = le16_to_cpu(hc_header.wLength); + if (wLength < sizeof(cluster)) + return NULL; cluster = kzalloc(wLength, GFP_KERNEL); if (!cluster) return ERR_PTR(-ENOMEM); From 591f79625702f1666a3e93f0c712902cc44da1f9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 22 Jun 2025 18:03:29 -0400 Subject: [PATCH 770/971] attach_recursive_mnt(): do not lock the covering tree when sliding something under it [ Upstream commit ce7df19686530920f2f6b636e71ce5eb1d9303ef ] If we are propagating across the userns boundary, we need to lock the mounts added there. However, in case when something has already been mounted there and we end up sliding a new tree under that, the stuff that had been there before should not get locked. IOW, lock_mnt_tree() should be called before we reparent the preexisting tree on top of what we are adding. Fixes: 3bd045cc9c4b ("separate copying and locking mount tree on cross-userns copies") Signed-off-by: Al Viro Signed-off-by: Sasha Levin --- fs/namespace.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index eab9185e2285..cebcb9fa2acc 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2364,14 +2364,14 @@ static int attach_recursive_mnt(struct mount *source_mnt, hlist_for_each_entry_safe(child, n, &tree_list, mnt_hash) { struct mount *q; hlist_del_init(&child->mnt_hash); - q = __lookup_mnt(&child->mnt_parent->mnt, - child->mnt_mountpoint); - if (q) - mnt_change_mountpoint(child, smp, q); /* Notice when we are propagating across user namespaces */ if (child->mnt_parent->mnt_ns->user_ns != user_ns) lock_mnt_tree(child); child->mnt.mnt_flags &= ~MNT_LOCKED; + q = __lookup_mnt(&child->mnt_parent->mnt, + child->mnt_mountpoint); + if (q) + mnt_change_mountpoint(child, smp, q); commit_tree(child); } put_mountpoint(smp); From 9b9a87f0bd1817108562b67a95ee4d5cbec636fe Mon Sep 17 00:00:00 2001 From: Yuan Chen Date: Wed, 18 Jun 2025 09:19:33 +0800 Subject: [PATCH 771/971] libbpf: Fix null pointer dereference in btf_dump__free on allocation failure [ Upstream commit aa485e8789d56a4573f7c8d000a182b749eaa64d ] When btf_dump__new() fails to allocate memory for the internal hashmap (btf_dump->type_names), it returns an error code. However, the cleanup function btf_dump__free() does not check if btf_dump->type_names is NULL before attempting to free it. This leads to a null pointer dereference when btf_dump__free() is called on a btf_dump object. Fixes: 351131b51c7a ("libbpf: add btf_dump API for BTF-to-C conversion") Signed-off-by: Yuan Chen Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20250618011933.11423-1-chenyuan_fl@163.com Signed-off-by: Sasha Levin --- tools/lib/bpf/btf_dump.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c index ebf56d21d08e..cf4db51b99eb 100644 --- a/tools/lib/bpf/btf_dump.c +++ b/tools/lib/bpf/btf_dump.c @@ -225,6 +225,9 @@ static void btf_dump_free_names(struct hashmap *map) size_t bkt; struct hashmap_entry *cur; + if (!map) + return; + hashmap__for_each_entry(map, cur, bkt) free((void *)cur->pkey); From 86136c6705691de9eb3da4dbd931a8bd60035347 Mon Sep 17 00:00:00 2001 From: Lachlan Hodges Date: Sat, 21 Jun 2025 22:32:09 +1000 Subject: [PATCH 772/971] wifi: mac80211: fix beacon interval calculation overflow [ Upstream commit 7a3750ff0f2e8fee338a9c168f429f6c37f0e820 ] As we are converting from TU to usecs, a beacon interval of 100*1024 usecs will lead to integer wrapping. To fix change to use a u32. Fixes: 057d5f4ba1e4 ("mac80211: sync dtim_count to TSF") Signed-off-by: Lachlan Hodges Link: https://patch.msgid.link/20250621123209.511796-1-lachlan.hodges@morsemicro.com Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- net/mac80211/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 154b41af4157..3a3cd09bdab6 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -4753,7 +4753,7 @@ void ieee80211_recalc_dtim(struct ieee80211_local *local, { u64 tsf = drv_get_tsf(local, sdata); u64 dtim_count = 0; - u16 beacon_int = sdata->vif.bss_conf.beacon_int * 1024; + u32 beacon_int = sdata->vif.bss_conf.beacon_int * 1024; u8 dtim_period = sdata->vif.bss_conf.dtim_period; struct ps_data *ps; u8 bcns_from_dtim; From d58343f813540807048b0ca329f54127f25942b3 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 18 Jun 2025 21:13:57 -0700 Subject: [PATCH 773/971] af_unix: Don't set -ECONNRESET for consumed OOB skb. [ Upstream commit 2a5a4841846b079b5fca5752fe94e59346fbda40 ] Christian Brauner reported that even after MSG_OOB data is consumed, calling close() on the receiver socket causes the peer's recv() to return -ECONNRESET: 1. send() and recv() an OOB data. >>> from socket import * >>> s1, s2 = socketpair(AF_UNIX, SOCK_STREAM) >>> s1.send(b'x', MSG_OOB) 1 >>> s2.recv(1, MSG_OOB) b'x' 2. close() for s2 sets ECONNRESET to s1->sk_err even though s2 consumed the OOB data >>> s2.close() >>> s1.recv(10, MSG_DONTWAIT) ... ConnectionResetError: [Errno 104] Connection reset by peer Even after being consumed, the skb holding the OOB 1-byte data stays in the recv queue to mark the OOB boundary and break recv() at that point. This must be considered while close()ing a socket. Let's skip the leading consumed OOB skb while checking the -ECONNRESET condition in unix_release_sock(). Fixes: 314001f0bf92 ("af_unix: Add OOB support") Reported-by: Christian Brauner Closes: https://lore.kernel.org/netdev/20250529-sinkt-abfeuern-e7b08200c6b0@brauner/ Signed-off-by: Kuniyuki Iwashima Acked-by: Christian Brauner Link: https://patch.msgid.link/20250619041457.1132791-4-kuni1840@gmail.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- net/unix/af_unix.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 7604d399a778..f89cd01247f6 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -630,6 +630,11 @@ static void unix_sock_destructor(struct sock *sk) #endif } +static unsigned int unix_skb_len(const struct sk_buff *skb) +{ + return skb->len - UNIXCB(skb).consumed; +} + static void unix_release_sock(struct sock *sk, int embrion) { struct unix_sock *u = unix_sk(sk); @@ -664,10 +669,16 @@ static void unix_release_sock(struct sock *sk, int embrion) if (skpair != NULL) { if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) { + struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); + +#if IS_ENABLED(CONFIG_AF_UNIX_OOB) + if (skb && !unix_skb_len(skb)) + skb = skb_peek_next(skb, &sk->sk_receive_queue); +#endif unix_state_lock(skpair); /* No more writes */ WRITE_ONCE(skpair->sk_shutdown, SHUTDOWN_MASK); - if (!skb_queue_empty_lockless(&sk->sk_receive_queue) || embrion) + if (skb || embrion) WRITE_ONCE(skpair->sk_err, ECONNRESET); unix_state_unlock(skpair); skpair->sk_state_change(skpair); @@ -2552,11 +2563,6 @@ static long unix_stream_data_wait(struct sock *sk, long timeo, return timeo; } -static unsigned int unix_skb_len(const struct sk_buff *skb) -{ - return skb->len - UNIXCB(skb).consumed; -} - struct unix_stream_read_state { int (*recv_actor)(struct sk_buff *, int, int, struct unix_stream_read_state *); From 8f96a2ae16b5ede2746a2f4f5186b6981e1638fe Mon Sep 17 00:00:00 2001 From: Stefano Garzarella Date: Mon, 23 Jun 2025 12:00:53 +0200 Subject: [PATCH 774/971] vsock/uapi: fix linux/vm_sockets.h userspace compilation errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 22bbc1dcd0d6785fb390c41f0dd5b5e218d23bdd ] If a userspace application just include will fail to build with the following errors: /usr/include/linux/vm_sockets.h:182:39: error: invalid application of ‘sizeof’ to incomplete type ‘struct sockaddr’ 182 | unsigned char svm_zero[sizeof(struct sockaddr) - | ^~~~~~ /usr/include/linux/vm_sockets.h:183:39: error: ‘sa_family_t’ undeclared here (not in a function) 183 | sizeof(sa_family_t) - | Include for userspace (guarded by ifndef __KERNEL__) where `struct sockaddr` and `sa_family_t` are defined. We already do something similar in and . Fixes: d021c344051a ("VSOCK: Introduce VM Sockets") Reported-by: Daan De Meyer Signed-off-by: Stefano Garzarella Link: https://patch.msgid.link/20250623100053.40979-1-sgarzare@redhat.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- include/uapi/linux/vm_sockets.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/uapi/linux/vm_sockets.h b/include/uapi/linux/vm_sockets.h index ed07181d4eff..e05280e41522 100644 --- a/include/uapi/linux/vm_sockets.h +++ b/include/uapi/linux/vm_sockets.h @@ -17,6 +17,10 @@ #ifndef _UAPI_VM_SOCKETS_H #define _UAPI_VM_SOCKETS_H +#ifndef __KERNEL__ +#include /* for struct sockaddr and sa_family_t */ +#endif + #include #include From c61e284d72d68171686ac0846e92aa420e9eb5d0 Mon Sep 17 00:00:00 2001 From: Tiwei Bie Date: Fri, 6 Jun 2025 20:44:25 +0800 Subject: [PATCH 775/971] um: ubd: Add missing error check in start_io_thread() [ Upstream commit c55c7a85e02a7bfee20a3ffebdff7cbeb41613ef ] The subsequent call to os_set_fd_block() overwrites the previous return value. OR the two return values together to fix it. Fixes: f88f0bdfc32f ("um: UBD Improvements") Signed-off-by: Tiwei Bie Link: https://patch.msgid.link/20250606124428.148164-2-tiwei.btw@antgroup.com Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- arch/um/drivers/ubd_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c index a1afe414ce48..fb5b1e7c133d 100644 --- a/arch/um/drivers/ubd_user.c +++ b/arch/um/drivers/ubd_user.c @@ -41,7 +41,7 @@ int start_io_thread(unsigned long sp, int *fd_out) *fd_out = fds[1]; err = os_set_fd_block(*fd_out, 0); - err = os_set_fd_block(kernel_fd, 0); + err |= os_set_fd_block(kernel_fd, 0); if (err) { printk("start_io_thread - failed to set nonblocking I/O.\n"); goto out_close; From ad9c4941d32e1c35d878b50a2e7036282b8a213a Mon Sep 17 00:00:00 2001 From: Adin Scannell Date: Tue, 24 Jun 2025 22:02:15 -0700 Subject: [PATCH 776/971] libbpf: Fix possible use-after-free for externs [ Upstream commit fa6f092cc0a02d0fcee37e9e8172eda372a03d33 ] The `name` field in `obj->externs` points into the BTF data at initial open time. However, some functions may invalidate this after opening and before loading (e.g. `bpf_map__set_value_size`), which results in pointers into freed memory and undefined behavior. The simplest solution is to simply `strdup` these strings, similar to the `essent_name`, and free them at the same time. In order to test this path, the `global_map_resize` BPF selftest is modified slightly to ensure the presence of an extern, which causes this test to fail prior to the fix. Given there isn't an obvious API or error to test against, I opted to add this to the existing test as an aspect of the resizing feature rather than duplicate the test. Fixes: 9d0a23313b1a ("libbpf: Add capability for resizing datasec maps") Signed-off-by: Adin Scannell Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20250625050215.2777374-1-amscanne@meta.com Signed-off-by: Sasha Levin --- tools/lib/bpf/libbpf.c | 10 +++++++--- .../selftests/bpf/progs/test_global_map_resize.c | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 5dc2e5555335..aefbfa2df620 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -554,7 +554,7 @@ struct extern_desc { int sym_idx; int btf_id; int sec_btf_id; - const char *name; + char *name; char *essent_name; bool is_set; bool is_weak; @@ -3822,7 +3822,9 @@ static int bpf_object__collect_externs(struct bpf_object *obj) return ext->btf_id; } t = btf__type_by_id(obj->btf, ext->btf_id); - ext->name = btf__name_by_offset(obj->btf, t->name_off); + ext->name = strdup(btf__name_by_offset(obj->btf, t->name_off)); + if (!ext->name) + return -ENOMEM; ext->sym_idx = i; ext->is_weak = ELF64_ST_BIND(sym->st_info) == STB_WEAK; @@ -8457,8 +8459,10 @@ void bpf_object__close(struct bpf_object *obj) zfree(&obj->btf_custom_path); zfree(&obj->kconfig); - for (i = 0; i < obj->nr_extern; i++) + for (i = 0; i < obj->nr_extern; i++) { + zfree(&obj->externs[i].name); zfree(&obj->externs[i].essent_name); + } zfree(&obj->externs); obj->nr_extern = 0; diff --git a/tools/testing/selftests/bpf/progs/test_global_map_resize.c b/tools/testing/selftests/bpf/progs/test_global_map_resize.c index 1fbb73d3e5d5..9be0e32cfeee 100644 --- a/tools/testing/selftests/bpf/progs/test_global_map_resize.c +++ b/tools/testing/selftests/bpf/progs/test_global_map_resize.c @@ -31,6 +31,16 @@ int my_int_last SEC(".data.array_not_last"); int percpu_arr[1] SEC(".data.percpu_arr"); +/* at least one extern is included, to ensure that a specific + * regression is tested whereby resizing resulted in a free-after-use + * bug after type information is invalidated by the resize operation. + * + * There isn't a particularly good API to test for this specific condition, + * but by having externs for the resizing tests it will cover this path. + */ +extern int LINUX_KERNEL_VERSION __kconfig; +long version_sink; + SEC("tp/syscalls/sys_enter_getpid") int bss_array_sum(void *ctx) { @@ -43,6 +53,9 @@ int bss_array_sum(void *ctx) for (size_t i = 0; i < bss_array_len; ++i) sum += array[i]; + /* see above; ensure this is not optimized out */ + version_sink = LINUX_KERNEL_VERSION; + return 0; } @@ -58,5 +71,8 @@ int data_array_sum(void *ctx) for (size_t i = 0; i < data_array_len; ++i) sum += my_array[i]; + /* see above; ensure this is not optimized out */ + version_sink = LINUX_KERNEL_VERSION; + return 0; } From 63528d60673a93bbc53f0cf4fa7dbae3bc1e31f7 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Tue, 24 Jun 2025 17:35:12 +0100 Subject: [PATCH 777/971] net: enetc: Correct endianness handling in _enetc_rd_reg64 [ Upstream commit 7b515f35a911fdc31fbde6531828dcd6ae9803d3 ] enetc_hw.h provides two versions of _enetc_rd_reg64. One which simply calls ioread64() when available. And another that composes the 64-bit result from ioread32() calls. In the second case the code appears to assume that each ioread32() call returns a little-endian value. However both the shift and logical or used to compose the return value would not work correctly on big endian systems if this were the case. Moreover, this is inconsistent with the first case where the return value of ioread64() is assumed to be in host byte order. It appears that the correct approach is for both versions to treat the return value of ioread*() functions as being in host byte order. And this patch corrects the ioread32()-based version to do so. This is a bug but would only manifest on big endian systems that make use of the ioread32-based implementation of _enetc_rd_reg64. While all in-tree users of this driver are little endian and make use of the ioread64-based implementation of _enetc_rd_reg64. Thus, no in-tree user of this driver is affected by this bug. Flagged by Sparse. Compile tested only. Fixes: 16eb4c85c964 ("enetc: Add ethtool statistics") Closes: https://lore.kernel.org/all/AM9PR04MB850500D3FC24FE23DEFCEA158879A@AM9PR04MB8505.eurprd04.prod.outlook.com/ Signed-off-by: Simon Horman Reviewed-by: Wei Fang Link: https://patch.msgid.link/20250624-etnetc-le-v1-1-a73a95d96e4e@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/freescale/enetc/enetc_hw.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h b/drivers/net/ethernet/freescale/enetc/enetc_hw.h index 1619943fb263..4e8881b479e4 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h +++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h @@ -485,7 +485,7 @@ static inline u64 _enetc_rd_reg64(void __iomem *reg) tmp = ioread32(reg + 4); } while (high != tmp); - return le64_to_cpu((__le64)high << 32 | low); + return (u64)high << 32 | low; } #endif From cabed6ba92a9a8c09da02a3f20e32ecd80989896 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Tue, 24 Jun 2025 14:45:00 -0700 Subject: [PATCH 778/971] atm: Release atm_dev_mutex after removing procfs in atm_dev_deregister(). [ Upstream commit a433791aeaea6e84df709e0b9584b9bbe040cd1c ] syzbot reported a warning below during atm_dev_register(). [0] Before creating a new device and procfs/sysfs for it, atm_dev_register() looks up a duplicated device by __atm_dev_lookup(). These operations are done under atm_dev_mutex. However, when removing a device in atm_dev_deregister(), it releases the mutex just after removing the device from the list that __atm_dev_lookup() iterates over. So, there will be a small race window where the device does not exist on the device list but procfs/sysfs are still not removed, triggering the splat. Let's hold the mutex until procfs/sysfs are removed in atm_dev_deregister(). [0]: proc_dir_entry 'atm/atmtcp:0' already registered WARNING: CPU: 0 PID: 5919 at fs/proc/generic.c:377 proc_register+0x455/0x5f0 fs/proc/generic.c:377 Modules linked in: CPU: 0 UID: 0 PID: 5919 Comm: syz-executor284 Not tainted 6.16.0-rc2-syzkaller-00047-g52da431bf03b #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/07/2025 RIP: 0010:proc_register+0x455/0x5f0 fs/proc/generic.c:377 Code: 48 89 f9 48 c1 e9 03 80 3c 01 00 0f 85 a2 01 00 00 48 8b 44 24 10 48 c7 c7 20 c0 c2 8b 48 8b b0 d8 00 00 00 e8 0c 02 1c ff 90 <0f> 0b 90 90 48 c7 c7 80 f2 82 8e e8 0b de 23 09 48 8b 4c 24 28 48 RSP: 0018:ffffc9000466fa30 EFLAGS: 00010282 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffff817ae248 RDX: ffff888026280000 RSI: ffffffff817ae255 RDI: 0000000000000001 RBP: ffff8880232bed48 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000001 R12: ffff888076ed2140 R13: dffffc0000000000 R14: ffff888078a61340 R15: ffffed100edda444 FS: 00007f38b3b0c6c0(0000) GS:ffff888124753000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f38b3bdf953 CR3: 0000000076d58000 CR4: 00000000003526f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: proc_create_data+0xbe/0x110 fs/proc/generic.c:585 atm_proc_dev_register+0x112/0x1e0 net/atm/proc.c:361 atm_dev_register+0x46d/0x890 net/atm/resources.c:113 atmtcp_create+0x77/0x210 drivers/atm/atmtcp.c:369 atmtcp_attach drivers/atm/atmtcp.c:403 [inline] atmtcp_ioctl+0x2f9/0xd60 drivers/atm/atmtcp.c:464 do_vcc_ioctl+0x12c/0x930 net/atm/ioctl.c:159 sock_do_ioctl+0x115/0x280 net/socket.c:1190 sock_ioctl+0x227/0x6b0 net/socket.c:1311 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:907 [inline] __se_sys_ioctl fs/ioctl.c:893 [inline] __x64_sys_ioctl+0x18b/0x210 fs/ioctl.c:893 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcd/0x4c0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f38b3b74459 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f38b3b0c198 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007f38b3bfe318 RCX: 00007f38b3b74459 RDX: 0000000000000000 RSI: 0000000000006180 RDI: 0000000000000005 RBP: 00007f38b3bfe310 R08: 65732f636f72702f R09: 65732f636f72702f R10: 65732f636f72702f R11: 0000000000000246 R12: 00007f38b3bcb0ac R13: 00007f38b3b0c1a0 R14: 0000200000000200 R15: 00007f38b3bcb03b Fixes: 64bf69ddff76 ("[ATM]: deregistration removes device from atm_devs list immediately") Reported-by: syzbot+8bd335d2ad3b93e80715@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/685316de.050a0220.216029.0087.GAE@google.com/ Tested-by: syzbot+8bd335d2ad3b93e80715@syzkaller.appspotmail.com Signed-off-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20250624214505.570679-1-kuni1840@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/atm/resources.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/atm/resources.c b/net/atm/resources.c index 995d29e7fb13..b19d851e1f44 100644 --- a/net/atm/resources.c +++ b/net/atm/resources.c @@ -146,11 +146,10 @@ void atm_dev_deregister(struct atm_dev *dev) */ mutex_lock(&atm_dev_mutex); list_del(&dev->dev_list); - mutex_unlock(&atm_dev_mutex); - atm_dev_release_vccs(dev); atm_unregister_sysfs(dev); atm_proc_dev_deregister(dev); + mutex_unlock(&atm_dev_mutex); atm_dev_put(dev); } From 5b63793da82af309b429f3265a6c269bc183a5e2 Mon Sep 17 00:00:00 2001 From: Salvatore Bonaccorso Date: Wed, 25 Jun 2025 20:41:28 +0200 Subject: [PATCH 779/971] ALSA: hda/realtek: Fix built-in mic on ASUS VivoBook X507UAR [ Upstream commit 7ab6847a03229e73bb7c58ca397630f699e79b53 ] The built-in mic of ASUS VivoBook X507UAR is broken recently by the fix of the pin sort. The fixup ALC256_FIXUP_ASUS_MIC_NO_PRESENCE is working for addressing the regression, too. Fixes: 3b4309546b48 ("ALSA: hda: Fix headset detection failure due to unstable sort") Reported-by: Igor Tamara Closes: https://bugs.debian.org/1108069 Signed-off-by: Salvatore Bonaccorso Link: https://lore.kernel.org/CADdHDco7_o=4h_epjEAb92Dj-vUz_PoTC2-W9g5ncT2E0NzfeQ@mail.gmail.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 82210b1e3b97..0d367cec03ad 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10325,6 +10325,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE), SND_PCI_QUIRK(0x1043, 0x1da2, "ASUS UP6502ZA/ZD", ALC245_FIXUP_CS35L41_SPI_2), SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402ZA", ALC245_FIXUP_CS35L41_SPI_2), + SND_PCI_QUIRK(0x1043, 0x1e10, "ASUS VivoBook X507UAR", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502), SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS), From 0804d77fd6e67426328ad94b2fed6b4afee6dc18 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Tue, 24 Jun 2025 11:32:58 -0700 Subject: [PATCH 780/971] net: selftests: fix TCP packet checksum [ Upstream commit 8d89661a36dd3bb8c9902cff36dc0c144dce3faf ] The length in the pseudo header should be the length of the L3 payload AKA the L4 header+payload. The selftest code builds the packet from the lower layers up, so all the headers are pushed already when it constructs L4. We need to subtract the lower layer headers from skb->len. Fixes: 3e1e58d64c3d ("net: add generic selftest support") Signed-off-by: Jakub Kicinski Reviewed-by: Gerhard Engleder Reported-by: Oleksij Rempel Tested-by: Oleksij Rempel Reviewed-by: Oleksij Rempel Link: https://patch.msgid.link/20250624183258.3377740-1-kuba@kernel.org Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- net/core/selftests.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/core/selftests.c b/net/core/selftests.c index 7af99d07762e..946e92cca211 100644 --- a/net/core/selftests.c +++ b/net/core/selftests.c @@ -160,8 +160,9 @@ static struct sk_buff *net_test_get_skb(struct net_device *ndev, skb->csum = 0; skb->ip_summed = CHECKSUM_PARTIAL; if (attr->tcp) { - thdr->check = ~tcp_v4_check(skb->len, ihdr->saddr, - ihdr->daddr, 0); + int l4len = skb->len - skb_transport_offset(skb); + + thdr->check = ~tcp_v4_check(l4len, ihdr->saddr, ihdr->daddr, 0); skb->csum_start = skb_transport_header(skb) - skb->head; skb->csum_offset = offsetof(struct tcphdr, check); } else { From ee800ff711c963a2933996b6b9874bc299de4935 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 20 Jun 2025 13:18:18 +0200 Subject: [PATCH 781/971] drm/i915: fix build error some more [ Upstream commit d02b2103a08b6d6908f1d3d8e8783d3f342555ac ] An earlier patch fixed a build failure with clang, but I still see the same problem with some configurations using gcc: drivers/gpu/drm/i915/i915_pmu.c: In function 'config_mask': include/linux/compiler_types.h:568:38: error: call to '__compiletime_assert_462' declared with attribute error: BUILD_BUG_ON failed: bit > BITS_PER_TYPE(typeof_member(struct i915_pmu, enable)) - 1 drivers/gpu/drm/i915/i915_pmu.c:116:3: note: in expansion of macro 'BUILD_BUG_ON' 116 | BUILD_BUG_ON(bit > As I understand it, the problem is that the function is not always fully inlined, but the __builtin_constant_p() can still evaluate the argument as being constant. Marking it as __always_inline so far works for me in all configurations. Fixes: a7137b1825b5 ("drm/i915/pmu: Fix build error with GCOV and AutoFDO enabled") Fixes: a644fde77ff7 ("drm/i915/pmu: Change bitmask of enabled events to u32") Reviewed-by: Rodrigo Vivi Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20250620111824.3395007-1-arnd@kernel.org Signed-off-by: Rodrigo Vivi (cherry picked from commit ef69f9dd1cd7301cdf04ba326ed28152a3affcf6) Signed-off-by: Joonas Lahtinen Signed-off-by: Sasha Levin --- drivers/gpu/drm/i915/i915_pmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c index 33ab82c334a8..461aafc2ae9a 100644 --- a/drivers/gpu/drm/i915/i915_pmu.c +++ b/drivers/gpu/drm/i915/i915_pmu.c @@ -101,7 +101,7 @@ static unsigned int config_bit(const u64 config) return other_bit(config); } -static u32 config_mask(const u64 config) +static __always_inline u32 config_mask(const u64 config) { unsigned int bit = config_bit(config); From 1c9a8a84c5a8023567642d433d5be85f8f7929c0 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 15 Mar 2025 21:15:11 +0100 Subject: [PATCH 782/971] drm/bridge: ti-sn65dsi86: make use of debugfs_init callback [ Upstream commit 1d1f7b15cb9c11974cebfd39da51dc69b8cb31ff ] Do not create a custom directory in debugfs-root, but use the debugfs_init callback to create a custom directory at the given place for the bridge. The new directory layout looks like this on a Renesas GrayHawk-Single with a R-Car V4M SoC: /sys/kernel/debug/dri/feb00000.display/DP-1/1-002c Signed-off-by: Wolfram Sang Reviewed-by: Dmitry Baryshkov Reviewed-by: Douglas Anderson Signed-off-by: Douglas Anderson Link: https://patchwork.freedesktop.org/patch/msgid/20250315201651.7339-2-wsa+renesas@sang-engineering.com Stable-dep-of: 55e8ff842051 ("drm/bridge: ti-sn65dsi86: Add HPD for DisplayPort connector type") Signed-off-by: Sasha Levin --- drivers/gpu/drm/bridge/ti-sn65dsi86.c | 40 +++++++-------------------- 1 file changed, 10 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index bfbd3fee1256..3e31a0c5a6d2 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -424,36 +424,8 @@ static int status_show(struct seq_file *s, void *data) return 0; } - DEFINE_SHOW_ATTRIBUTE(status); -static void ti_sn65dsi86_debugfs_remove(void *data) -{ - debugfs_remove_recursive(data); -} - -static void ti_sn65dsi86_debugfs_init(struct ti_sn65dsi86 *pdata) -{ - struct device *dev = pdata->dev; - struct dentry *debugfs; - int ret; - - debugfs = debugfs_create_dir(dev_name(dev), NULL); - - /* - * We might get an error back if debugfs wasn't enabled in the kernel - * so let's just silently return upon failure. - */ - if (IS_ERR_OR_NULL(debugfs)) - return; - - ret = devm_add_action_or_reset(dev, ti_sn65dsi86_debugfs_remove, debugfs); - if (ret) - return; - - debugfs_create_file("status", 0600, debugfs, pdata, &status_fops); -} - /* ----------------------------------------------------------------------------- * Auxiliary Devices (*not* AUX) */ @@ -1217,6 +1189,15 @@ static struct edid *ti_sn_bridge_get_edid(struct drm_bridge *bridge, return drm_get_edid(connector, &pdata->aux.ddc); } +static void ti_sn65dsi86_debugfs_init(struct drm_bridge *bridge, struct dentry *root) +{ + struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge); + struct dentry *debugfs; + + debugfs = debugfs_create_dir(dev_name(pdata->dev), root); + debugfs_create_file("status", 0600, debugfs, pdata, &status_fops); +} + static const struct drm_bridge_funcs ti_sn_bridge_funcs = { .attach = ti_sn_bridge_attach, .detach = ti_sn_bridge_detach, @@ -1230,6 +1211,7 @@ static const struct drm_bridge_funcs ti_sn_bridge_funcs = { .atomic_reset = drm_atomic_helper_bridge_reset, .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .debugfs_init = ti_sn65dsi86_debugfs_init, }; static void ti_sn_bridge_parse_lanes(struct ti_sn65dsi86 *pdata, @@ -1935,8 +1917,6 @@ static int ti_sn65dsi86_probe(struct i2c_client *client) if (ret) return ret; - ti_sn65dsi86_debugfs_init(pdata); - /* * Break ourselves up into a collection of aux devices. The only real * motiviation here is to solve the chicken-and-egg problem of probe From ced8eff11a4f0859ab507918f041f48dade182e5 Mon Sep 17 00:00:00 2001 From: Jayesh Choudhary Date: Tue, 24 Jun 2025 10:18:35 +0530 Subject: [PATCH 783/971] drm/bridge: ti-sn65dsi86: Add HPD for DisplayPort connector type [ Upstream commit 55e8ff842051b1150461d7595d8f1d033c69d66b ] By default, HPD was disabled on SN65DSI86 bridge. When the driver was added (commit "a095f15c00e27"), the HPD_DISABLE bit was set in pre-enable call which was moved to other function calls subsequently. Later on, commit "c312b0df3b13" added detect utility for DP mode. But with HPD_DISABLE bit set, all the HPD events are disabled[0] and the debounced state always return 1 (always connected state). Set HPD_DISABLE bit conditionally based on display sink's connector type. Since the HPD_STATE is reflected correctly only after waiting for debounce time (~100-400ms) and adding this delay in detect() is not feasible owing to the performace impact (glitches and frame drop), remove runtime calls in detect() and add hpd_enable()/disable() bridge hooks with runtime calls, to detect hpd properly without any delay. [0]: (Pg. 32) Fixes: c312b0df3b13 ("drm/bridge: ti-sn65dsi86: Implement bridge connector operations for DP") Cc: Max Krummenacher Reviewed-by: Douglas Anderson Tested-by: Ernest Van Hoecke Signed-off-by: Jayesh Choudhary Signed-off-by: Douglas Anderson Link: https://lore.kernel.org/r/20250624044835.165708-1-j-choudhary@ti.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/bridge/ti-sn65dsi86.c | 69 +++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 3e31a0c5a6d2..002f8aaa509b 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -331,12 +331,18 @@ static void ti_sn65dsi86_enable_comms(struct ti_sn65dsi86 *pdata) * 200 ms. We'll assume that the panel driver will have the hardcoded * delay in its prepare and always disable HPD. * - * If HPD somehow makes sense on some future panel we'll have to - * change this to be conditional on someone specifying that HPD should - * be used. + * For DisplayPort bridge type, we need HPD. So we use the bridge type + * to conditionally disable HPD. + * NOTE: The bridge type is set in ti_sn_bridge_probe() but enable_comms() + * can be called before. So for DisplayPort, HPD will be enabled once + * bridge type is set. We are using bridge type instead of "no-hpd" + * property because it is not used properly in devicetree description + * and hence is unreliable. */ - regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG, HPD_DISABLE, - HPD_DISABLE); + + if (pdata->bridge.type != DRM_MODE_CONNECTOR_DisplayPort) + regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG, HPD_DISABLE, + HPD_DISABLE); pdata->comms_enabled = true; @@ -1173,9 +1179,14 @@ static enum drm_connector_status ti_sn_bridge_detect(struct drm_bridge *bridge) struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge); int val = 0; - pm_runtime_get_sync(pdata->dev); + /* + * Runtime reference is grabbed in ti_sn_bridge_hpd_enable() + * as the chip won't report HPD just after being powered on. + * HPD_DEBOUNCED_STATE reflects correct state only after the + * debounce time (~100-400 ms). + */ + regmap_read(pdata->regmap, SN_HPD_DISABLE_REG, &val); - pm_runtime_put_autosuspend(pdata->dev); return val & HPD_DEBOUNCED_STATE ? connector_status_connected : connector_status_disconnected; @@ -1198,6 +1209,26 @@ static void ti_sn65dsi86_debugfs_init(struct drm_bridge *bridge, struct dentry * debugfs_create_file("status", 0600, debugfs, pdata, &status_fops); } +static void ti_sn_bridge_hpd_enable(struct drm_bridge *bridge) +{ + struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge); + + /* + * Device needs to be powered on before reading the HPD state + * for reliable hpd detection in ti_sn_bridge_detect() due to + * the high debounce time. + */ + + pm_runtime_get_sync(pdata->dev); +} + +static void ti_sn_bridge_hpd_disable(struct drm_bridge *bridge) +{ + struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge); + + pm_runtime_put_autosuspend(pdata->dev); +} + static const struct drm_bridge_funcs ti_sn_bridge_funcs = { .attach = ti_sn_bridge_attach, .detach = ti_sn_bridge_detach, @@ -1212,6 +1243,8 @@ static const struct drm_bridge_funcs ti_sn_bridge_funcs = { .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, .debugfs_init = ti_sn65dsi86_debugfs_init, + .hpd_enable = ti_sn_bridge_hpd_enable, + .hpd_disable = ti_sn_bridge_hpd_disable, }; static void ti_sn_bridge_parse_lanes(struct ti_sn65dsi86 *pdata, @@ -1300,8 +1333,26 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev, pdata->bridge.type = pdata->next_bridge->type == DRM_MODE_CONNECTOR_DisplayPort ? DRM_MODE_CONNECTOR_DisplayPort : DRM_MODE_CONNECTOR_eDP; - if (pdata->bridge.type == DRM_MODE_CONNECTOR_DisplayPort) - pdata->bridge.ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT; + if (pdata->bridge.type == DRM_MODE_CONNECTOR_DisplayPort) { + pdata->bridge.ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT | + DRM_BRIDGE_OP_HPD; + /* + * If comms were already enabled they would have been enabled + * with the wrong value of HPD_DISABLE. Update it now. Comms + * could be enabled if anyone is holding a pm_runtime reference + * (like if a GPIO is in use). Note that in most cases nobody + * is doing AUX channel xfers before the bridge is added so + * HPD doesn't _really_ matter then. The only exception is in + * the eDP case where the panel wants to read the EDID before + * the bridge is added. We always consistently have HPD disabled + * for eDP. + */ + mutex_lock(&pdata->comms_mutex); + if (pdata->comms_enabled) + regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG, + HPD_DISABLE, 0); + mutex_unlock(&pdata->comms_mutex); + }; drm_bridge_add(&pdata->bridge); From c82c7041258d96e3286f6790ab700e4edd3cc9e3 Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Wed, 25 Jun 2025 12:22:38 -0300 Subject: [PATCH 784/971] smb: client: fix potential deadlock when reconnecting channels [ Upstream commit 711741f94ac3cf9f4e3aa73aa171e76d188c0819 ] Fix cifs_signal_cifsd_for_reconnect() to take the correct lock order and prevent the following deadlock from happening ====================================================== WARNING: possible circular locking dependency detected 6.16.0-rc3-build2+ #1301 Tainted: G S W ------------------------------------------------------ cifsd/6055 is trying to acquire lock: ffff88810ad56038 (&tcp_ses->srv_lock){+.+.}-{3:3}, at: cifs_signal_cifsd_for_reconnect+0x134/0x200 but task is already holding lock: ffff888119c64330 (&ret_buf->chan_lock){+.+.}-{3:3}, at: cifs_signal_cifsd_for_reconnect+0xcf/0x200 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #2 (&ret_buf->chan_lock){+.+.}-{3:3}: validate_chain+0x1cf/0x270 __lock_acquire+0x60e/0x780 lock_acquire.part.0+0xb4/0x1f0 _raw_spin_lock+0x2f/0x40 cifs_setup_session+0x81/0x4b0 cifs_get_smb_ses+0x771/0x900 cifs_mount_get_session+0x7e/0x170 cifs_mount+0x92/0x2d0 cifs_smb3_do_mount+0x161/0x460 smb3_get_tree+0x55/0x90 vfs_get_tree+0x46/0x180 do_new_mount+0x1b0/0x2e0 path_mount+0x6ee/0x740 do_mount+0x98/0xe0 __do_sys_mount+0x148/0x180 do_syscall_64+0xa4/0x260 entry_SYSCALL_64_after_hwframe+0x76/0x7e -> #1 (&ret_buf->ses_lock){+.+.}-{3:3}: validate_chain+0x1cf/0x270 __lock_acquire+0x60e/0x780 lock_acquire.part.0+0xb4/0x1f0 _raw_spin_lock+0x2f/0x40 cifs_match_super+0x101/0x320 sget+0xab/0x270 cifs_smb3_do_mount+0x1e0/0x460 smb3_get_tree+0x55/0x90 vfs_get_tree+0x46/0x180 do_new_mount+0x1b0/0x2e0 path_mount+0x6ee/0x740 do_mount+0x98/0xe0 __do_sys_mount+0x148/0x180 do_syscall_64+0xa4/0x260 entry_SYSCALL_64_after_hwframe+0x76/0x7e -> #0 (&tcp_ses->srv_lock){+.+.}-{3:3}: check_noncircular+0x95/0xc0 check_prev_add+0x115/0x2f0 validate_chain+0x1cf/0x270 __lock_acquire+0x60e/0x780 lock_acquire.part.0+0xb4/0x1f0 _raw_spin_lock+0x2f/0x40 cifs_signal_cifsd_for_reconnect+0x134/0x200 __cifs_reconnect+0x8f/0x500 cifs_handle_standard+0x112/0x280 cifs_demultiplex_thread+0x64d/0xbc0 kthread+0x2f7/0x310 ret_from_fork+0x2a/0x230 ret_from_fork_asm+0x1a/0x30 other info that might help us debug this: Chain exists of: &tcp_ses->srv_lock --> &ret_buf->ses_lock --> &ret_buf->chan_lock Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&ret_buf->chan_lock); lock(&ret_buf->ses_lock); lock(&ret_buf->chan_lock); lock(&tcp_ses->srv_lock); *** DEADLOCK *** 3 locks held by cifsd/6055: #0: ffffffff857de398 (&cifs_tcp_ses_lock){+.+.}-{3:3}, at: cifs_signal_cifsd_for_reconnect+0x7b/0x200 #1: ffff888119c64060 (&ret_buf->ses_lock){+.+.}-{3:3}, at: cifs_signal_cifsd_for_reconnect+0x9c/0x200 #2: ffff888119c64330 (&ret_buf->chan_lock){+.+.}-{3:3}, at: cifs_signal_cifsd_for_reconnect+0xcf/0x200 Cc: linux-cifs@vger.kernel.org Reported-by: David Howells Fixes: d7d7a66aacd6 ("cifs: avoid use of global locks for high contention data") Reviewed-by: David Howells Tested-by: David Howells Signed-off-by: Paulo Alcantara (Red Hat) Signed-off-by: David Howells Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/smb/client/cifsglob.h | 1 + fs/smb/client/connect.c | 58 +++++++++++++++++++++++++--------------- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index c7da6bf2f44b..d776340ad91c 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -677,6 +677,7 @@ inc_rfc1001_len(void *buf, int count) struct TCP_Server_Info { struct list_head tcp_ses_list; struct list_head smb_ses_list; + struct list_head rlist; /* reconnect list */ spinlock_t srv_lock; /* protect anything here that is not protected */ __u64 conn_id; /* connection identifier (useful for debugging) */ int srv_count; /* reference counter */ diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c index 8fa5fe0a8c5c..454420aa0222 100644 --- a/fs/smb/client/connect.c +++ b/fs/smb/client/connect.c @@ -140,6 +140,14 @@ static void smb2_query_server_interfaces(struct work_struct *work) (SMB_INTERFACE_POLL_INTERVAL * HZ)); } +#define set_need_reco(server) \ +do { \ + spin_lock(&server->srv_lock); \ + if (server->tcpStatus != CifsExiting) \ + server->tcpStatus = CifsNeedReconnect; \ + spin_unlock(&server->srv_lock); \ +} while (0) + /* * Update the tcpStatus for the server. * This is used to signal the cifsd thread to call cifs_reconnect @@ -153,39 +161,45 @@ void cifs_signal_cifsd_for_reconnect(struct TCP_Server_Info *server, bool all_channels) { - struct TCP_Server_Info *pserver; + struct TCP_Server_Info *nserver; struct cifs_ses *ses; + LIST_HEAD(reco); int i; - /* If server is a channel, select the primary channel */ - pserver = SERVER_IS_CHAN(server) ? server->primary_server : server; - /* if we need to signal just this channel */ if (!all_channels) { - spin_lock(&server->srv_lock); - if (server->tcpStatus != CifsExiting) - server->tcpStatus = CifsNeedReconnect; - spin_unlock(&server->srv_lock); + set_need_reco(server); return; } - spin_lock(&cifs_tcp_ses_lock); - list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) { - if (cifs_ses_exiting(ses)) - continue; - spin_lock(&ses->chan_lock); - for (i = 0; i < ses->chan_count; i++) { - if (!ses->chans[i].server) + if (SERVER_IS_CHAN(server)) + server = server->primary_server; + scoped_guard(spinlock, &cifs_tcp_ses_lock) { + set_need_reco(server); + list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { + spin_lock(&ses->ses_lock); + if (ses->ses_status == SES_EXITING) { + spin_unlock(&ses->ses_lock); continue; - - spin_lock(&ses->chans[i].server->srv_lock); - if (ses->chans[i].server->tcpStatus != CifsExiting) - ses->chans[i].server->tcpStatus = CifsNeedReconnect; - spin_unlock(&ses->chans[i].server->srv_lock); + } + spin_lock(&ses->chan_lock); + for (i = 1; i < ses->chan_count; i++) { + nserver = ses->chans[i].server; + if (!nserver) + continue; + nserver->srv_count++; + list_add(&nserver->rlist, &reco); + } + spin_unlock(&ses->chan_lock); + spin_unlock(&ses->ses_lock); } - spin_unlock(&ses->chan_lock); } - spin_unlock(&cifs_tcp_ses_lock); + + list_for_each_entry_safe(server, nserver, &reco, rlist) { + list_del_init(&server->rlist); + set_need_reco(server); + cifs_put_tcp_session(server, 0); + } } /* From e5e6a5aa3915507f1a5a67fea1a24bb61e63704d Mon Sep 17 00:00:00 2001 From: Avadhut Naik Date: Thu, 29 May 2025 20:50:04 +0000 Subject: [PATCH 785/971] EDAC/amd64: Fix size calculation for Non-Power-of-Two DIMMs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit a3f3040657417aeadb9622c629d4a0c2693a0f93 upstream. Each Chip-Select (CS) of a Unified Memory Controller (UMC) on AMD Zen-based SOCs has an Address Mask and a Secondary Address Mask register associated with it. The amd64_edac module logs DIMM sizes on a per-UMC per-CS granularity during init using these two registers. Currently, the module primarily considers only the Address Mask register for computing DIMM sizes. The Secondary Address Mask register is only considered for odd CS. Additionally, if it has been considered, the Address Mask register is ignored altogether for that CS. For power-of-two DIMMs i.e. DIMMs whose total capacity is a power of two (32GB, 64GB, etc), this is not an issue since only the Address Mask register is used. For non-power-of-two DIMMs i.e., DIMMs whose total capacity is not a power of two (48GB, 96GB, etc), however, the Secondary Address Mask register is used in conjunction with the Address Mask register. However, since the module only considers either of the two registers for a CS, the size computed by the module is incorrect. The Secondary Address Mask register is not considered for even CS, and the Address Mask register is not considered for odd CS. Introduce a new helper function so that both Address Mask and Secondary Address Mask registers are considered, when valid, for computing DIMM sizes. Furthermore, also rename some variables for greater clarity. Fixes: 81f5090db843 ("EDAC/amd64: Support asymmetric dual-rank DIMMs") Closes: https://lore.kernel.org/dbec22b6-00f2-498b-b70d-ab6f8a5ec87e@natrix.lt Reported-by: Žilvinas Žaltiena Signed-off-by: Avadhut Naik Signed-off-by: Borislav Petkov (AMD) Reviewed-by: Yazen Ghannam Tested-by: Žilvinas Žaltiena Cc: stable@vger.kernel.org Link: https://lore.kernel.org/20250529205013.403450-1-avadhut.naik@amd.com Signed-off-by: Greg Kroah-Hartman --- drivers/edac/amd64_edac.c | 57 ++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 10119cf27ffd..a8db2bde6384 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -1475,7 +1475,9 @@ static int umc_get_cs_mode(int dimm, u8 ctrl, struct amd64_pvt *pvt) if (csrow_enabled(2 * dimm + 1, ctrl, pvt)) cs_mode |= CS_ODD_PRIMARY; - /* Asymmetric dual-rank DIMM support. */ + if (csrow_sec_enabled(2 * dimm, ctrl, pvt)) + cs_mode |= CS_EVEN_SECONDARY; + if (csrow_sec_enabled(2 * dimm + 1, ctrl, pvt)) cs_mode |= CS_ODD_SECONDARY; @@ -1496,12 +1498,13 @@ static int umc_get_cs_mode(int dimm, u8 ctrl, struct amd64_pvt *pvt) return cs_mode; } -static int __addr_mask_to_cs_size(u32 addr_mask_orig, unsigned int cs_mode, - int csrow_nr, int dimm) +static int calculate_cs_size(u32 mask, unsigned int cs_mode) { - u32 msb, weight, num_zero_bits; - u32 addr_mask_deinterleaved; - int size = 0; + int msb, weight, num_zero_bits; + u32 deinterleaved_mask; + + if (!mask) + return 0; /* * The number of zero bits in the mask is equal to the number of bits @@ -1514,19 +1517,30 @@ static int __addr_mask_to_cs_size(u32 addr_mask_orig, unsigned int cs_mode, * without swapping with the most significant bit. This can be handled * by keeping the MSB where it is and ignoring the single zero bit. */ - msb = fls(addr_mask_orig) - 1; - weight = hweight_long(addr_mask_orig); + msb = fls(mask) - 1; + weight = hweight_long(mask); num_zero_bits = msb - weight - !!(cs_mode & CS_3R_INTERLEAVE); /* Take the number of zero bits off from the top of the mask. */ - addr_mask_deinterleaved = GENMASK_ULL(msb - num_zero_bits, 1); + deinterleaved_mask = GENMASK(msb - num_zero_bits, 1); + edac_dbg(1, " Deinterleaved AddrMask: 0x%x\n", deinterleaved_mask); + + return (deinterleaved_mask >> 2) + 1; +} + +static int __addr_mask_to_cs_size(u32 addr_mask, u32 addr_mask_sec, + unsigned int cs_mode, int csrow_nr, int dimm) +{ + int size; edac_dbg(1, "CS%d DIMM%d AddrMasks:\n", csrow_nr, dimm); - edac_dbg(1, " Original AddrMask: 0x%x\n", addr_mask_orig); - edac_dbg(1, " Deinterleaved AddrMask: 0x%x\n", addr_mask_deinterleaved); + edac_dbg(1, " Primary AddrMask: 0x%x\n", addr_mask); /* Register [31:1] = Address [39:9]. Size is in kBs here. */ - size = (addr_mask_deinterleaved >> 2) + 1; + size = calculate_cs_size(addr_mask, cs_mode); + + edac_dbg(1, " Secondary AddrMask: 0x%x\n", addr_mask_sec); + size += calculate_cs_size(addr_mask_sec, cs_mode); /* Return size in MBs. */ return size >> 10; @@ -1535,8 +1549,8 @@ static int __addr_mask_to_cs_size(u32 addr_mask_orig, unsigned int cs_mode, static int umc_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc, unsigned int cs_mode, int csrow_nr) { + u32 addr_mask = 0, addr_mask_sec = 0; int cs_mask_nr = csrow_nr; - u32 addr_mask_orig; int dimm, size = 0; /* No Chip Selects are enabled. */ @@ -1574,13 +1588,13 @@ static int umc_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc, if (!pvt->flags.zn_regs_v2) cs_mask_nr >>= 1; - /* Asymmetric dual-rank DIMM support. */ - if ((csrow_nr & 1) && (cs_mode & CS_ODD_SECONDARY)) - addr_mask_orig = pvt->csels[umc].csmasks_sec[cs_mask_nr]; - else - addr_mask_orig = pvt->csels[umc].csmasks[cs_mask_nr]; + if (cs_mode & (CS_EVEN_PRIMARY | CS_ODD_PRIMARY)) + addr_mask = pvt->csels[umc].csmasks[cs_mask_nr]; - return __addr_mask_to_cs_size(addr_mask_orig, cs_mode, csrow_nr, dimm); + if (cs_mode & (CS_EVEN_SECONDARY | CS_ODD_SECONDARY)) + addr_mask_sec = pvt->csels[umc].csmasks_sec[cs_mask_nr]; + + return __addr_mask_to_cs_size(addr_mask, addr_mask_sec, cs_mode, csrow_nr, dimm); } static void umc_debug_display_dimm_sizes(struct amd64_pvt *pvt, u8 ctrl) @@ -3773,9 +3787,10 @@ static void gpu_get_err_info(struct mce *m, struct err_info *err) static int gpu_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc, unsigned int cs_mode, int csrow_nr) { - u32 addr_mask_orig = pvt->csels[umc].csmasks[csrow_nr]; + u32 addr_mask = pvt->csels[umc].csmasks[csrow_nr]; + u32 addr_mask_sec = pvt->csels[umc].csmasks_sec[csrow_nr]; - return __addr_mask_to_cs_size(addr_mask_orig, cs_mode, csrow_nr, csrow_nr >> 1); + return __addr_mask_to_cs_size(addr_mask, addr_mask_sec, cs_mode, csrow_nr, csrow_nr >> 1); } static void gpu_debug_display_dimm_sizes(struct amd64_pvt *pvt, u8 ctrl) From f89c40520fa17527f4983c38325041370bdf07a9 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 9 Jun 2025 14:13:14 -0700 Subject: [PATCH 786/971] staging: rtl8723bs: Avoid memset() in aes_cipher() and aes_decipher() commit a55bc4ffc06d8c965a7d6f0a01ed0ed41380df28 upstream. After commit 6f110a5e4f99 ("Disable SLUB_TINY for build testing"), which causes CONFIG_KASAN to be enabled in allmodconfig again, arm64 allmodconfig builds with older versions of clang (15 through 17) show an instance of -Wframe-larger-than (which breaks the build with CONFIG_WERROR=y): drivers/staging/rtl8723bs/core/rtw_security.c:1287:5: error: stack frame size (2208) exceeds limit (2048) in 'rtw_aes_decrypt' [-Werror,-Wframe-larger-than] 1287 | u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe) | ^ This comes from aes_decipher() being inlined in rtw_aes_decrypt(). Running the same build with CONFIG_FRAME_WARN=128 shows aes_cipher() also uses a decent amount of stack, just under the limit of 2048: drivers/staging/rtl8723bs/core/rtw_security.c:864:19: warning: stack frame size (1952) exceeds limit (128) in 'aes_cipher' [-Wframe-larger-than] 864 | static signed int aes_cipher(u8 *key, uint hdrlen, | ^ -Rpass-analysis=stack-frame-layout only shows one large structure on the stack, which is the ctx variable inlined from aes128k128d(). A good number of the other variables come from the additional checks of fortified string routines, which are present in memset(), which both aes_cipher() and aes_decipher() use to initialize some temporary buffers. In this case, since the size is known at compile time, these additional checks should not result in any code generation changes but allmodconfig has several sanitizers enabled, which may make it harder for the compiler to eliminate the compile time checks and the variables that come about from them. The memset() calls are just initializing these buffers to zero, so use '= {}' instead, which is used all over the kernel and does the exact same thing as memset() without the fortify checks, which drops the stack usage of these functions by a few hundred kilobytes. drivers/staging/rtl8723bs/core/rtw_security.c:864:19: warning: stack frame size (1584) exceeds limit (128) in 'aes_cipher' [-Wframe-larger-than] 864 | static signed int aes_cipher(u8 *key, uint hdrlen, | ^ drivers/staging/rtl8723bs/core/rtw_security.c:1271:5: warning: stack frame size (1456) exceeds limit (128) in 'rtw_aes_decrypt' [-Wframe-larger-than] 1271 | u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe) | ^ Cc: stable@vger.kernel.org Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver") Signed-off-by: Nathan Chancellor Reviewed-by: Dan Carpenter Link: https://lore.kernel.org/r/20250609-rtl8723bs-fix-clang-arm64-wflt-v1-1-e2accba43def@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723bs/core/rtw_security.c | 44 ++++++------------- 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_security.c b/drivers/staging/rtl8723bs/core/rtw_security.c index 7ecdaa2eeaf3..83fdee444c1c 100644 --- a/drivers/staging/rtl8723bs/core/rtw_security.c +++ b/drivers/staging/rtl8723bs/core/rtw_security.c @@ -869,29 +869,21 @@ static signed int aes_cipher(u8 *key, uint hdrlen, num_blocks, payload_index; u8 pn_vector[6]; - u8 mic_iv[16]; - u8 mic_header1[16]; - u8 mic_header2[16]; - u8 ctr_preload[16]; + u8 mic_iv[16] = {}; + u8 mic_header1[16] = {}; + u8 mic_header2[16] = {}; + u8 ctr_preload[16] = {}; /* Intermediate Buffers */ - u8 chain_buffer[16]; - u8 aes_out[16]; - u8 padded_buffer[16]; + u8 chain_buffer[16] = {}; + u8 aes_out[16] = {}; + u8 padded_buffer[16] = {}; u8 mic[8]; uint frtype = GetFrameType(pframe); uint frsubtype = GetFrameSubType(pframe); frsubtype = frsubtype>>4; - memset((void *)mic_iv, 0, 16); - memset((void *)mic_header1, 0, 16); - memset((void *)mic_header2, 0, 16); - memset((void *)ctr_preload, 0, 16); - memset((void *)chain_buffer, 0, 16); - memset((void *)aes_out, 0, 16); - memset((void *)padded_buffer, 0, 16); - if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN)) a4_exists = 0; else @@ -1081,15 +1073,15 @@ static signed int aes_decipher(u8 *key, uint hdrlen, num_blocks, payload_index; signed int res = _SUCCESS; u8 pn_vector[6]; - u8 mic_iv[16]; - u8 mic_header1[16]; - u8 mic_header2[16]; - u8 ctr_preload[16]; + u8 mic_iv[16] = {}; + u8 mic_header1[16] = {}; + u8 mic_header2[16] = {}; + u8 ctr_preload[16] = {}; /* Intermediate Buffers */ - u8 chain_buffer[16]; - u8 aes_out[16]; - u8 padded_buffer[16]; + u8 chain_buffer[16] = {}; + u8 aes_out[16] = {}; + u8 padded_buffer[16] = {}; u8 mic[8]; uint frtype = GetFrameType(pframe); @@ -1097,14 +1089,6 @@ static signed int aes_decipher(u8 *key, uint hdrlen, frsubtype = frsubtype>>4; - memset((void *)mic_iv, 0, 16); - memset((void *)mic_header1, 0, 16); - memset((void *)mic_header2, 0, 16); - memset((void *)ctr_preload, 0, 16); - memset((void *)chain_buffer, 0, 16); - memset((void *)aes_out, 0, 16); - memset((void *)padded_buffer, 0, 16); - /* start to decrypt the payload */ num_blocks = (plen-8) / 16; /* plen including LLC, payload_length and mic) */ From 40f62f8cf8547231e132a91fddfabc6500208aa4 Mon Sep 17 00:00:00 2001 From: Yao Zi Date: Mon, 23 Jun 2025 09:34:45 +0000 Subject: [PATCH 787/971] dt-bindings: serial: 8250: Make clocks and clock-frequency exclusive commit 09812134071b3941fb81def30b61ed36d3a5dfb5 upstream. The 8250 binding before converting to json-schema states, - clock-frequency : the input clock frequency for the UART or - clocks phandle to refer to the clk used as per Documentation/devicetree for clock-related properties, where "or" indicates these properties shouldn't exist at the same time. Additionally, the behavior of Linux's driver is strange when both clocks and clock-frequency are specified: it ignores clocks and obtains the frequency from clock-frequency, left the specified clocks unclaimed. It may even be disabled, which is undesired most of the time. But "anyOf" doesn't prevent these two properties from coexisting, as it considers the object valid as long as there's at LEAST one match. Let's switch to "oneOf" and disallows the other property if one exists, precisely matching the original binding and avoiding future confusion on the driver's behavior. Fixes: e69f5dc623f9 ("dt-bindings: serial: Convert 8250 to json-schema") Cc: stable Signed-off-by: Yao Zi Reviewed-by: Conor Dooley Link: https://lore.kernel.org/r/20250623093445.62327-1-ziyao@disroot.org Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/8250.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/serial/8250.yaml b/Documentation/devicetree/bindings/serial/8250.yaml index 692aa05500fd..6ba0325039be 100644 --- a/Documentation/devicetree/bindings/serial/8250.yaml +++ b/Documentation/devicetree/bindings/serial/8250.yaml @@ -45,7 +45,7 @@ allOf: - ns16550 - ns16550a then: - anyOf: + oneOf: - required: [ clock-frequency ] - required: [ clocks ] From f90d78d65cccbce5f5909fdc7ac9eda26f7699da Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 19 Jun 2025 08:46:17 -0300 Subject: [PATCH 788/971] serial: imx: Restore original RXTL for console to fix data loss commit f23c52aafb1675ab1d1f46914556d8e29cbbf7b3 upstream. Commit 7a637784d517 ("serial: imx: reduce RX interrupt frequency") introduced a regression on the i.MX6UL EVK board. The issue can be reproduced with the following steps: - Open vi on the board. - Paste a text file (~150 characters). - Save the file, then repeat the process. - Compare the sha256sum of the saved files. The checksums do not match due to missing characters or entire lines. Fix this by restoring the RXTL value to 1 when the UART is used as a console. This ensures timely RX interrupts and reliable data reception in console mode. With this change, pasted content is saved correctly, and checksums are always consistent. Cc: stable Fixes: 7a637784d517 ("serial: imx: reduce RX interrupt frequency") Signed-off-by: Fabio Estevam Reviewed-by: Stefan Wahren Link: https://lore.kernel.org/r/20250619114617.2791939-1-festevam@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 04809b781f45..60d48d857b1c 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -234,6 +234,7 @@ struct imx_port { enum imx_tx_state tx_state; struct hrtimer trigger_start_tx; struct hrtimer trigger_stop_tx; + unsigned int rxtl; }; struct imx_port_ucrs { @@ -1337,6 +1338,7 @@ static void imx_uart_clear_rx_errors(struct imx_port *sport) #define TXTL_DEFAULT 8 #define RXTL_DEFAULT 8 /* 8 characters or aging timer */ +#define RXTL_CONSOLE_DEFAULT 1 #define TXTL_DMA 8 /* DMA burst setting */ #define RXTL_DMA 9 /* DMA burst setting */ @@ -1449,7 +1451,7 @@ static void imx_uart_disable_dma(struct imx_port *sport) ucr1 &= ~(UCR1_RXDMAEN | UCR1_TXDMAEN | UCR1_ATDMAEN); imx_uart_writel(sport, ucr1, UCR1); - imx_uart_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT); + imx_uart_setup_ufcr(sport, TXTL_DEFAULT, sport->rxtl); sport->dma_is_enabled = 0; } @@ -1474,7 +1476,12 @@ static int imx_uart_startup(struct uart_port *port) return retval; } - imx_uart_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT); + if (uart_console(&sport->port)) + sport->rxtl = RXTL_CONSOLE_DEFAULT; + else + sport->rxtl = RXTL_DEFAULT; + + imx_uart_setup_ufcr(sport, TXTL_DEFAULT, sport->rxtl); /* disable the DREN bit (Data Ready interrupt enable) before * requesting IRQs @@ -1887,7 +1894,7 @@ static int imx_uart_poll_init(struct uart_port *port) if (retval) clk_disable_unprepare(sport->clk_ipg); - imx_uart_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT); + imx_uart_setup_ufcr(sport, TXTL_DEFAULT, sport->rxtl); spin_lock_irqsave(&sport->port.lock, flags); @@ -1979,7 +1986,7 @@ static int imx_uart_rs485_config(struct uart_port *port, struct ktermios *termio /* If the receiver trigger is 0, set it to a default value */ ufcr = imx_uart_readl(sport, UFCR); if ((ufcr & UFCR_RXTL_MASK) == 0) - imx_uart_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT); + imx_uart_setup_ufcr(sport, TXTL_DEFAULT, sport->rxtl); imx_uart_start_rx(port); } @@ -2164,7 +2171,7 @@ imx_uart_console_setup(struct console *co, char *options) else imx_uart_console_get_options(sport, &baud, &parity, &bits); - imx_uart_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT); + imx_uart_setup_ufcr(sport, TXTL_DEFAULT, sport->rxtl); retval = uart_set_options(&sport->port, co, baud, parity, bits, flow); From e395e34b0652413d54a5acb96028dc5adc4ea711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Danis?= Date: Thu, 12 Jun 2025 09:50:34 +0200 Subject: [PATCH 789/971] Bluetooth: L2CAP: Fix L2CAP MTU negotiation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 042bb9603c44620dce98717a2d23235ca57a00d7 upstream. OBEX download from iPhone is currently slow due to small packet size used to transfer data which doesn't follow the MTU negotiated during L2CAP connection, i.e. 672 bytes instead of 32767: < ACL Data TX: Handle 11 flags 0x00 dlen 12 L2CAP: Connection Request (0x02) ident 18 len 4 PSM: 4103 (0x1007) Source CID: 72 > ACL Data RX: Handle 11 flags 0x02 dlen 16 L2CAP: Connection Response (0x03) ident 18 len 8 Destination CID: 14608 Source CID: 72 Result: Connection successful (0x0000) Status: No further information available (0x0000) < ACL Data TX: Handle 11 flags 0x00 dlen 27 L2CAP: Configure Request (0x04) ident 20 len 19 Destination CID: 14608 Flags: 0x0000 Option: Maximum Transmission Unit (0x01) [mandatory] MTU: 32767 Option: Retransmission and Flow Control (0x04) [mandatory] Mode: Enhanced Retransmission (0x03) TX window size: 63 Max transmit: 3 Retransmission timeout: 2000 Monitor timeout: 12000 Maximum PDU size: 1009 > ACL Data RX: Handle 11 flags 0x02 dlen 26 L2CAP: Configure Request (0x04) ident 72 len 18 Destination CID: 72 Flags: 0x0000 Option: Retransmission and Flow Control (0x04) [mandatory] Mode: Enhanced Retransmission (0x03) TX window size: 32 Max transmit: 255 Retransmission timeout: 0 Monitor timeout: 0 Maximum PDU size: 65527 Option: Frame Check Sequence (0x05) [mandatory] FCS: 16-bit FCS (0x01) < ACL Data TX: Handle 11 flags 0x00 dlen 29 L2CAP: Configure Response (0x05) ident 72 len 21 Source CID: 14608 Flags: 0x0000 Result: Success (0x0000) Option: Maximum Transmission Unit (0x01) [mandatory] MTU: 672 Option: Retransmission and Flow Control (0x04) [mandatory] Mode: Enhanced Retransmission (0x03) TX window size: 32 Max transmit: 255 Retransmission timeout: 2000 Monitor timeout: 12000 Maximum PDU size: 1009 > ACL Data RX: Handle 11 flags 0x02 dlen 32 L2CAP: Configure Response (0x05) ident 20 len 24 Source CID: 72 Flags: 0x0000 Result: Success (0x0000) Option: Maximum Transmission Unit (0x01) [mandatory] MTU: 32767 Option: Retransmission and Flow Control (0x04) [mandatory] Mode: Enhanced Retransmission (0x03) TX window size: 63 Max transmit: 3 Retransmission timeout: 2000 Monitor timeout: 12000 Maximum PDU size: 1009 Option: Frame Check Sequence (0x05) [mandatory] FCS: 16-bit FCS (0x01) ... > ACL Data RX: Handle 11 flags 0x02 dlen 680 Channel: 72 len 676 ctrl 0x0202 [PSM 4103 mode Enhanced Retransmission (0x03)] {chan 8} I-frame: Unsegmented TxSeq 1 ReqSeq 2 < ACL Data TX: Handle 11 flags 0x00 dlen 13 Channel: 14608 len 9 ctrl 0x0204 [PSM 4103 mode Enhanced Retransmission (0x03)] {chan 8} I-frame: Unsegmented TxSeq 2 ReqSeq 2 > ACL Data RX: Handle 11 flags 0x02 dlen 680 Channel: 72 len 676 ctrl 0x0304 [PSM 4103 mode Enhanced Retransmission (0x03)] {chan 8} I-frame: Unsegmented TxSeq 2 ReqSeq 3 The MTUs are negotiated for each direction. In this traces 32767 for iPhone->localhost and no MTU for localhost->iPhone, which based on '4.4 L2CAP_CONFIGURATION_REQ' (Core specification v5.4, Vol. 3, Part A): The only parameters that should be included in the L2CAP_CONFIGURATION_REQ packet are those that require different values than the default or previously agreed values. ... Any missing configuration parameters are assumed to have their most recently explicitly or implicitly accepted values. and '5.1 Maximum transmission unit (MTU)': If the remote device sends a positive L2CAP_CONFIGURATION_RSP packet it should include the actual MTU to be used on this channel for traffic flowing into the local device. ... The default value is 672 octets. is set by BlueZ to 672 bytes. It seems that the iPhone used the lowest negotiated value to transfer data to the localhost instead of the negotiated one for the incoming direction. This could be fixed by using the MTU negotiated for the other direction, if exists, in the L2CAP_CONFIGURATION_RSP. This allows to use segmented packets as in the following traces: < ACL Data TX: Handle 11 flags 0x00 dlen 12 L2CAP: Connection Request (0x02) ident 22 len 4 PSM: 4103 (0x1007) Source CID: 72 < ACL Data TX: Handle 11 flags 0x00 dlen 27 L2CAP: Configure Request (0x04) ident 24 len 19 Destination CID: 2832 Flags: 0x0000 Option: Maximum Transmission Unit (0x01) [mandatory] MTU: 32767 Option: Retransmission and Flow Control (0x04) [mandatory] Mode: Enhanced Retransmission (0x03) TX window size: 63 Max transmit: 3 Retransmission timeout: 2000 Monitor timeout: 12000 Maximum PDU size: 1009 > ACL Data RX: Handle 11 flags 0x02 dlen 26 L2CAP: Configure Request (0x04) ident 15 len 18 Destination CID: 72 Flags: 0x0000 Option: Retransmission and Flow Control (0x04) [mandatory] Mode: Enhanced Retransmission (0x03) TX window size: 32 Max transmit: 255 Retransmission timeout: 0 Monitor timeout: 0 Maximum PDU size: 65527 Option: Frame Check Sequence (0x05) [mandatory] FCS: 16-bit FCS (0x01) < ACL Data TX: Handle 11 flags 0x00 dlen 29 L2CAP: Configure Response (0x05) ident 15 len 21 Source CID: 2832 Flags: 0x0000 Result: Success (0x0000) Option: Maximum Transmission Unit (0x01) [mandatory] MTU: 32767 Option: Retransmission and Flow Control (0x04) [mandatory] Mode: Enhanced Retransmission (0x03) TX window size: 32 Max transmit: 255 Retransmission timeout: 2000 Monitor timeout: 12000 Maximum PDU size: 1009 > ACL Data RX: Handle 11 flags 0x02 dlen 32 L2CAP: Configure Response (0x05) ident 24 len 24 Source CID: 72 Flags: 0x0000 Result: Success (0x0000) Option: Maximum Transmission Unit (0x01) [mandatory] MTU: 32767 Option: Retransmission and Flow Control (0x04) [mandatory] Mode: Enhanced Retransmission (0x03) TX window size: 63 Max transmit: 3 Retransmission timeout: 2000 Monitor timeout: 12000 Maximum PDU size: 1009 Option: Frame Check Sequence (0x05) [mandatory] FCS: 16-bit FCS (0x01) ... > ACL Data RX: Handle 11 flags 0x02 dlen 1009 Channel: 72 len 1005 ctrl 0x4202 [PSM 4103 mode Enhanced Retransmission (0x03)] {chan 8} I-frame: Start (len 21884) TxSeq 1 ReqSeq 2 > ACL Data RX: Handle 11 flags 0x02 dlen 1009 Channel: 72 len 1005 ctrl 0xc204 [PSM 4103 mode Enhanced Retransmission (0x03)] {chan 8} I-frame: Continuation TxSeq 2 ReqSeq 2 This has been tested with kernel 5.4 and BlueZ 5.77. Cc: stable@vger.kernel.org Signed-off-by: Frédéric Danis Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Greg Kroah-Hartman --- net/bluetooth/l2cap_core.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 2744ad11687c..f9995a405e35 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -3380,7 +3380,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; struct l2cap_conf_efs efs; u8 remote_efs = 0; - u16 mtu = L2CAP_DEFAULT_MTU; + u16 mtu = 0; u16 result = L2CAP_CONF_SUCCESS; u16 size; @@ -3485,6 +3485,13 @@ done: /* Configure output options and let the other side know * which ones we don't like. */ + /* If MTU is not provided in configure request, use the most recently + * explicitly or implicitly accepted value for the other direction, + * or the default value. + */ + if (mtu == 0) + mtu = chan->imtu ? chan->imtu : L2CAP_DEFAULT_MTU; + if (mtu < L2CAP_DEFAULT_MIN_MTU) result = L2CAP_CONF_UNACCEPT; else { From 6ad80378f928a28e4afb6e82f582dcfc369d6f3a Mon Sep 17 00:00:00 2001 From: Heinz Mauelshagen Date: Tue, 10 Jun 2025 20:53:30 +0200 Subject: [PATCH 790/971] dm-raid: fix variable in journal device check commit db53805156f1e0aa6d059c0d3f9ac660d4ef3eb4 upstream. Replace "rdev" with correct loop variable name "r". Signed-off-by: Heinz Mauelshagen Cc: stable@vger.kernel.org Fixes: 63c32ed4afc2 ("dm raid: add raid4/5/6 journaling support") Signed-off-by: Mikulas Patocka Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-raid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 385e24f55ec0..f23edd79df45 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -2378,7 +2378,7 @@ static int super_init_validation(struct raid_set *rs, struct md_rdev *rdev) */ sb_retrieve_failed_devices(sb, failed_devices); rdev_for_each(r, mddev) { - if (test_bit(Journal, &rdev->flags) || + if (test_bit(Journal, &r->flags) || !r->sb_page) continue; sb2 = page_address(r->sb_page); From aeeae8feeaae4445a86f9815273e81f902dc1f5b Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Wed, 28 May 2025 12:28:27 +0100 Subject: [PATCH 791/971] btrfs: fix a race between renames and directory logging commit 3ca864de852bc91007b32d2a0d48993724f4abad upstream. We have a race between a rename and directory inode logging that if it happens and we crash/power fail before the rename completes, the next time the filesystem is mounted, the log replay code will end up deleting the file that was being renamed. This is best explained following a step by step analysis of an interleaving of steps that lead into this situation. Consider the initial conditions: 1) We are at transaction N; 2) We have directories A and B created in a past transaction (< N); 3) We have inode X corresponding to a file that has 2 hardlinks, one in directory A and the other in directory B, so we'll name them as "A/foo_link1" and "B/foo_link2". Both hard links were persisted in a past transaction (< N); 4) We have inode Y corresponding to a file that as a single hard link and is located in directory A, we'll name it as "A/bar". This file was also persisted in a past transaction (< N). The steps leading to a file loss are the following and for all of them we are under transaction N: 1) Link "A/foo_link1" is removed, so inode's X last_unlink_trans field is updated to N, through btrfs_unlink() -> btrfs_record_unlink_dir(); 2) Task A starts a rename for inode Y, with the goal of renaming from "A/bar" to "A/baz", so we enter btrfs_rename(); 3) Task A inserts the new BTRFS_INODE_REF_KEY for inode Y by calling btrfs_insert_inode_ref(); 4) Because the rename happens in the same directory, we don't set the last_unlink_trans field of directoty A's inode to the current transaction id, that is, we don't cal btrfs_record_unlink_dir(); 5) Task A then removes the entries from directory A (BTRFS_DIR_ITEM_KEY and BTRFS_DIR_INDEX_KEY items) when calling __btrfs_unlink_inode() (actually the dir index item is added as a delayed item, but the effect is the same); 6) Now before task A adds the new entry "A/baz" to directory A by calling btrfs_add_link(), another task, task B is logging inode X; 7) Task B starts a fsync of inode X and after logging inode X, at btrfs_log_inode_parent() it calls btrfs_log_all_parents(), since inode X has a last_unlink_trans value of N, set at in step 1; 8) At btrfs_log_all_parents() we search for all parent directories of inode X using the commit root, so we find directories A and B and log them. Bu when logging direct A, we don't have a dir index item for inode Y anymore, neither the old name "A/bar" nor for the new name "A/baz" since the rename has deleted the old name but has not yet inserted the new name - task A hasn't called yet btrfs_add_link() to do that. Note that logging directory A doesn't fallback to a transaction commit because its last_unlink_trans has a lower value than the current transaction's id (see step 4); 9) Task B finishes logging directories A and B and gets back to btrfs_sync_file() where it calls btrfs_sync_log() to persist the log tree; 10) Task B successfully persisted the log tree, btrfs_sync_log() completed with success, and a power failure happened. We have a log tree without any directory entry for inode Y, so the log replay code deletes the entry for inode Y, name "A/bar", from the subvolume tree since it doesn't exist in the log tree and the log tree is authorative for its index (we logged a BTRFS_DIR_LOG_INDEX_KEY item that covers the index range for the dentry that corresponds to "A/bar"). Since there's no other hard link for inode Y and the log replay code deletes the name "A/bar", the file is lost. The issue wouldn't happen if task B synced the log only after task A called btrfs_log_new_name(), which would update the log with the new name for inode Y ("A/bar"). Fix this by pinning the log root during renames before removing the old directory entry, and unpinning after btrfs_log_new_name() is called. Fixes: 259c4b96d78d ("btrfs: stop doing unnecessary log updates during a rename") CC: stable@vger.kernel.org # 5.18+ Reviewed-by: Boris Burkov Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/inode.c | 83 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 18 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 48d257923672..af1f22b3cff7 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -8754,6 +8754,7 @@ static int btrfs_rename_exchange(struct inode *old_dir, int ret; int ret2; bool need_abort = false; + bool logs_pinned = false; struct fscrypt_name old_fname, new_fname; struct fscrypt_str *old_name, *new_name; @@ -8877,6 +8878,31 @@ static int btrfs_rename_exchange(struct inode *old_dir, inode_inc_iversion(new_inode); simple_rename_timestamp(old_dir, old_dentry, new_dir, new_dentry); + if (old_ino != BTRFS_FIRST_FREE_OBJECTID && + new_ino != BTRFS_FIRST_FREE_OBJECTID) { + /* + * If we are renaming in the same directory (and it's not for + * root entries) pin the log early to prevent any concurrent + * task from logging the directory after we removed the old + * entries and before we add the new entries, otherwise that + * task can sync a log without any entry for the inodes we are + * renaming and therefore replaying that log, if a power failure + * happens after syncing the log, would result in deleting the + * inodes. + * + * If the rename affects two different directories, we want to + * make sure the that there's no log commit that contains + * updates for only one of the directories but not for the + * other. + * + * If we are renaming an entry for a root, we don't care about + * log updates since we called btrfs_set_log_full_commit(). + */ + btrfs_pin_log_trans(root); + btrfs_pin_log_trans(dest); + logs_pinned = true; + } + if (old_dentry->d_parent != new_dentry->d_parent) { btrfs_record_unlink_dir(trans, BTRFS_I(old_dir), BTRFS_I(old_inode), true); @@ -8934,30 +8960,23 @@ static int btrfs_rename_exchange(struct inode *old_dir, BTRFS_I(new_inode)->dir_index = new_idx; /* - * Now pin the logs of the roots. We do it to ensure that no other task - * can sync the logs while we are in progress with the rename, because - * that could result in an inconsistency in case any of the inodes that - * are part of this rename operation were logged before. + * Do the log updates for all inodes. + * + * If either entry is for a root we don't need to update the logs since + * we've called btrfs_set_log_full_commit() before. */ - if (old_ino != BTRFS_FIRST_FREE_OBJECTID) - btrfs_pin_log_trans(root); - if (new_ino != BTRFS_FIRST_FREE_OBJECTID) - btrfs_pin_log_trans(dest); - - /* Do the log updates for all inodes. */ - if (old_ino != BTRFS_FIRST_FREE_OBJECTID) + if (logs_pinned) { btrfs_log_new_name(trans, old_dentry, BTRFS_I(old_dir), old_rename_ctx.index, new_dentry->d_parent); - if (new_ino != BTRFS_FIRST_FREE_OBJECTID) btrfs_log_new_name(trans, new_dentry, BTRFS_I(new_dir), new_rename_ctx.index, old_dentry->d_parent); + } - /* Now unpin the logs. */ - if (old_ino != BTRFS_FIRST_FREE_OBJECTID) - btrfs_end_log_trans(root); - if (new_ino != BTRFS_FIRST_FREE_OBJECTID) - btrfs_end_log_trans(dest); out_fail: + if (logs_pinned) { + btrfs_end_log_trans(root); + btrfs_end_log_trans(dest); + } ret2 = btrfs_end_transaction(trans); ret = ret ? ret : ret2; out_notrans: @@ -9007,6 +9026,7 @@ static int btrfs_rename(struct mnt_idmap *idmap, int ret2; u64 old_ino = btrfs_ino(BTRFS_I(old_inode)); struct fscrypt_name old_fname, new_fname; + bool logs_pinned = false; if (btrfs_ino(BTRFS_I(new_dir)) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) return -EPERM; @@ -9141,6 +9161,29 @@ static int btrfs_rename(struct mnt_idmap *idmap, inode_inc_iversion(old_inode); simple_rename_timestamp(old_dir, old_dentry, new_dir, new_dentry); + if (old_ino != BTRFS_FIRST_FREE_OBJECTID) { + /* + * If we are renaming in the same directory (and it's not a + * root entry) pin the log to prevent any concurrent task from + * logging the directory after we removed the old entry and + * before we add the new entry, otherwise that task can sync + * a log without any entry for the inode we are renaming and + * therefore replaying that log, if a power failure happens + * after syncing the log, would result in deleting the inode. + * + * If the rename affects two different directories, we want to + * make sure the that there's no log commit that contains + * updates for only one of the directories but not for the + * other. + * + * If we are renaming an entry for a root, we don't care about + * log updates since we called btrfs_set_log_full_commit(). + */ + btrfs_pin_log_trans(root); + btrfs_pin_log_trans(dest); + logs_pinned = true; + } + if (old_dentry->d_parent != new_dentry->d_parent) btrfs_record_unlink_dir(trans, BTRFS_I(old_dir), BTRFS_I(old_inode), true); @@ -9189,7 +9232,7 @@ static int btrfs_rename(struct mnt_idmap *idmap, if (old_inode->i_nlink == 1) BTRFS_I(old_inode)->dir_index = index; - if (old_ino != BTRFS_FIRST_FREE_OBJECTID) + if (logs_pinned) btrfs_log_new_name(trans, old_dentry, BTRFS_I(old_dir), rename_ctx.index, new_dentry->d_parent); @@ -9205,6 +9248,10 @@ static int btrfs_rename(struct mnt_idmap *idmap, } } out_fail: + if (logs_pinned) { + btrfs_end_log_trans(root); + btrfs_end_log_trans(dest); + } ret2 = btrfs_end_transaction(trans); ret = ret ? ret : ret2; out_notrans: From 9052c7bca391bac0598c5f31302313539899a218 Mon Sep 17 00:00:00 2001 From: Mark Harmstone Date: Thu, 29 May 2025 10:37:44 +0100 Subject: [PATCH 792/971] btrfs: update superblock's device bytes_used when dropping chunk commit ae4477f937569d097ca5dbce92a89ba384b49bc6 upstream. Each superblock contains a copy of the device item for that device. In a transaction which drops a chunk but doesn't create any new ones, we were correctly updating the device item in the chunk tree but not copying over the new bytes_used value to the superblock. This can be seen by doing the following: # dd if=/dev/zero of=test bs=4096 count=2621440 # mkfs.btrfs test # mount test /root/temp # cd /root/temp # for i in {00..10}; do dd if=/dev/zero of=$i bs=4096 count=32768; done # sync # rm * # sync # btrfs balance start -dusage=0 . # sync # cd # umount /root/temp # btrfs check test For btrfs-check to detect this, you will also need my patch at https://github.com/kdave/btrfs-progs/pull/991. Change btrfs_remove_dev_extents() so that it adds the devices to the fs_info->post_commit_list if they're not there already. This causes btrfs_commit_device_sizes() to be called, which updates the bytes_used value in the superblock. Fixes: bbbf7243d62d ("btrfs: combine device update operations during transaction commit") CC: stable@vger.kernel.org # 5.10+ Reviewed-by: Qu Wenruo Signed-off-by: Mark Harmstone Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/volumes.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index b9a0b26d08e1..1eb543602ff1 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -3174,6 +3174,12 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans, u64 chunk_offset) device->bytes_used - dev_extent_len); atomic64_add(dev_extent_len, &fs_info->free_chunk_space); btrfs_clear_space_info_full(fs_info); + + if (list_empty(&device->post_commit_list)) { + list_add_tail(&device->post_commit_list, + &trans->transaction->dev_update_list); + } + mutex_unlock(&fs_info->chunk_mutex); } } From 8a89e9c27b7734920b43ec7188d720603499d18a Mon Sep 17 00:00:00 2001 From: Jiawen Wu Date: Wed, 25 Jun 2025 10:39:24 +0800 Subject: [PATCH 793/971] net: libwx: fix the creation of page_pool commit 85720e04d9af0b77f8092b12a06661a8d459d4a0 upstream. 'rx_ring->size' means the count of ring descriptors multiplied by the size of one descriptor. When increasing the count of ring descriptors, it may exceed the limit of pool size. [ 864.209610] page_pool_create_percpu() gave up with errno -7 [ 864.209613] txgbe 0000:11:00.0: Page pool creation failed: -7 Fix to set the pool_size to the count of ring descriptors. Fixes: 850b971110b2 ("net: libwx: Allocate Rx and Tx resources") Cc: stable@vger.kernel.org Signed-off-by: Jiawen Wu Reviewed-by: Simon Horman Reviewed-by: Mina Almasry Link: https://patch.msgid.link/434C72BFB40E350A+20250625023924.21821-1-jiawenwu@trustnetic.com Signed-off-by: Paolo Abeni Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/wangxun/libwx/wx_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/wangxun/libwx/wx_lib.c b/drivers/net/ethernet/wangxun/libwx/wx_lib.c index c019fe964ece..97c6b4d27634 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_lib.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_lib.c @@ -2368,7 +2368,7 @@ static int wx_alloc_page_pool(struct wx_ring *rx_ring) struct page_pool_params pp_params = { .flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV, .order = 0, - .pool_size = rx_ring->size, + .pool_size = rx_ring->count, .nid = dev_to_node(rx_ring->dev), .dev = rx_ring->dev, .dma_dir = DMA_FROM_DEVICE, From f0ffc8076d39a81d8dc21bdb2b19810310f6a4f3 Mon Sep 17 00:00:00 2001 From: Iusico Maxim Date: Thu, 5 Jun 2025 19:55:50 +0200 Subject: [PATCH 794/971] HID: lenovo: Restrict F7/9/11 mode to compact keyboards only commit 9327e3ee5b077c4ab4495a09b67624f670ed88b6 upstream. Commit 2f2bd7cbd1d1 ("hid: lenovo: Resend all settings on reset_resume for compact keyboards") introduced a regression for ThinkPad TrackPoint Keyboard II by removing the conditional check for enabling F7/9/11 mode needed for compact keyboards only. As a result, the non-compact keyboards can no longer toggle Fn-lock via Fn+Esc, although it can be controlled via sysfs knob that directly sends raw commands. This patch restores the previous conditional check without any additions. Cc: stable@vger.kernel.org Fixes: 2f2bd7cbd1d1 ("hid: lenovo: Resend all settings on reset_resume for compact keyboards") Signed-off-by: Iusico Maxim Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-lenovo.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c index a4062f617ba2..ee65da98c7d5 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c @@ -529,11 +529,14 @@ static void lenovo_features_set_cptkbd(struct hid_device *hdev) /* * Tell the keyboard a driver understands it, and turn F7, F9, F11 into - * regular keys + * regular keys (Compact only) */ - ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03); - if (ret) - hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret); + if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD || + hdev->product == USB_DEVICE_ID_LENOVO_CBTKBD) { + ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03); + if (ret) + hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret); + } /* Switch middle button to native mode */ ret = lenovo_send_cmd_cptkbd(hdev, 0x09, 0x01); From 33acbeeb5ad6263ad0482f98c2bfa2cca2963dbd Mon Sep 17 00:00:00 2001 From: Qasim Ijaz Date: Fri, 6 Jun 2025 19:49:57 +0100 Subject: [PATCH 795/971] HID: wacom: fix memory leak on kobject creation failure commit 5ae416c5b1e2e816aee7b3fc8347adf70afabb4c upstream. During wacom_initialize_remotes() a fifo buffer is allocated with kfifo_alloc() and later a cleanup action is registered during devm_add_action_or_reset() to clean it up. However if the code fails to create a kobject and register it with sysfs the code simply returns -ENOMEM before the cleanup action is registered leading to a memory leak. Fix this by ensuring the fifo is freed when the kobject creation and registration process fails. Fixes: 83e6b40e2de6 ("HID: wacom: EKR: have the wacom resources dynamically allocated") Reviewed-by: Ping Cheng Cc: stable@vger.kernel.org Signed-off-by: Qasim Ijaz Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/hid/wacom_sys.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 5a72cf8d6944..925298b6f869 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -2012,8 +2012,10 @@ static int wacom_initialize_remotes(struct wacom *wacom) remote->remote_dir = kobject_create_and_add("wacom_remote", &wacom->hdev->dev.kobj); - if (!remote->remote_dir) + if (!remote->remote_dir) { + kfifo_free(&remote->remote_fifo); return -ENOMEM; + } error = sysfs_create_files(remote->remote_dir, remote_unpair_attrs); From f531651c394eb0d9277da0c137dd63ebb8dd1109 Mon Sep 17 00:00:00 2001 From: Qasim Ijaz Date: Fri, 6 Jun 2025 19:49:58 +0100 Subject: [PATCH 796/971] HID: wacom: fix memory leak on sysfs attribute creation failure commit 1a19ae437ca5d5c7d9ec2678946fb339b1c706bf upstream. When sysfs_create_files() fails during wacom_initialize_remotes() the fifo buffer is not freed leading to a memory leak. Fix this by calling kfifo_free() before returning. Fixes: 83e6b40e2de6 ("HID: wacom: EKR: have the wacom resources dynamically allocated") Reviewed-by: Ping Cheng Cc: stable@vger.kernel.org Signed-off-by: Qasim Ijaz Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/hid/wacom_sys.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 925298b6f869..1269a756ea9c 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -2022,6 +2022,7 @@ static int wacom_initialize_remotes(struct wacom *wacom) if (error) { hid_err(wacom->hdev, "cannot create sysfs group err: %d\n", error); + kfifo_free(&remote->remote_fifo); return error; } From 42cf4f016173d4aa42d8701999a496f71b7aedd9 Mon Sep 17 00:00:00 2001 From: Qasim Ijaz Date: Fri, 6 Jun 2025 19:49:59 +0100 Subject: [PATCH 797/971] HID: wacom: fix kobject reference count leak commit 85a720f4337f0ddf1603c8b75a8f1ffbbe022ef9 upstream. When sysfs_create_files() fails in wacom_initialize_remotes() the error is returned and the cleanup action will not have been registered yet. As a result the kobject???s refcount is never dropped, so the kobject can never be freed leading to a reference leak. Fix this by calling kobject_put() before returning. Fixes: 83e6b40e2de6 ("HID: wacom: EKR: have the wacom resources dynamically allocated") Acked-by: Ping Cheng Cc: stable@vger.kernel.org Signed-off-by: Qasim Ijaz Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/hid/wacom_sys.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 1269a756ea9c..52011503ff3b 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -2023,6 +2023,7 @@ static int wacom_initialize_remotes(struct wacom *wacom) hid_err(wacom->hdev, "cannot create sysfs group err: %d\n", error); kfifo_free(&remote->remote_fifo); + kobject_put(remote->remote_dir); return error; } From bf2c1643abc3b2507d56bb6c22bf9897272f8a35 Mon Sep 17 00:00:00 2001 From: Chen Yu Date: Wed, 4 Jun 2025 12:25:56 +0800 Subject: [PATCH 798/971] scsi: megaraid_sas: Fix invalid node index commit 752eb816b55adb0673727ba0ed96609a17895654 upstream. On a system with DRAM interleave enabled, out-of-bound access is detected: megaraid_sas 0000:3f:00.0: requested/available msix 128/128 poll_queue 0 ------------[ cut here ]------------ UBSAN: array-index-out-of-bounds in ./arch/x86/include/asm/topology.h:72:28 index -1 is out of range for type 'cpumask *[1024]' dump_stack_lvl+0x5d/0x80 ubsan_epilogue+0x5/0x2b __ubsan_handle_out_of_bounds.cold+0x46/0x4b megasas_alloc_irq_vectors+0x149/0x190 [megaraid_sas] megasas_probe_one.cold+0xa4d/0x189c [megaraid_sas] local_pci_probe+0x42/0x90 pci_device_probe+0xdc/0x290 really_probe+0xdb/0x340 __driver_probe_device+0x78/0x110 driver_probe_device+0x1f/0xa0 __driver_attach+0xba/0x1c0 bus_for_each_dev+0x8b/0xe0 bus_add_driver+0x142/0x220 driver_register+0x72/0xd0 megasas_init+0xdf/0xff0 [megaraid_sas] do_one_initcall+0x57/0x310 do_init_module+0x90/0x250 init_module_from_file+0x85/0xc0 idempotent_init_module+0x114/0x310 __x64_sys_finit_module+0x65/0xc0 do_syscall_64+0x82/0x170 entry_SYSCALL_64_after_hwframe+0x76/0x7e Fix it accordingly. Signed-off-by: Chen Yu Link: https://lore.kernel.org/r/20250604042556.3731059-1-yu.c.chen@intel.com Fixes: 8049da6f3943 ("scsi: megaraid_sas: Use irq_set_affinity_and_hint()") Cc: stable@vger.kernel.org Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/megaraid/megaraid_sas_base.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index dd3630b09aa2..54f66142e14a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -5908,7 +5908,11 @@ megasas_set_high_iops_queue_affinity_and_hint(struct megasas_instance *instance) const struct cpumask *mask; if (instance->perf_mode == MR_BALANCED_PERF_MODE) { - mask = cpumask_of_node(dev_to_node(&instance->pdev->dev)); + int nid = dev_to_node(&instance->pdev->dev); + + if (nid == NUMA_NO_NODE) + nid = 0; + mask = cpumask_of_node(nid); for (i = 0; i < instance->low_latency_index_start; i++) { irq = pci_irq_vector(instance->pdev, i); From 66f122e67261330ee9bea738d75f6ea0ce5b064f Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 24 Mar 2025 10:44:09 +0100 Subject: [PATCH 799/971] drm/ast: Fix comment on modeset lock commit 7cce65f3789e04c0f7668a66563e680d81d54493 upstream. The ast driver protects the commit tail against concurrent reads of the display modes by acquiring a lock. The comment is misleading as the lock is not released in atomic_flush, but at the end of the commit-tail helper. Rewrite the comment. Signed-off-by: Thomas Zimmermann Fixes: 1fe182154984 ("drm/ast: Acquire I/O-register lock in atomic_commit_tail function") Cc: Thomas Zimmermann Cc: Jocelyn Falempe Cc: Dave Airlie Cc: dri-devel@lists.freedesktop.org Cc: # v6.2+ Reviewed-by: Jocelyn Falempe Link: https://lore.kernel.org/r/20250324094520.192974-2-tzimmermann@suse.de Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/ast/ast_mode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 5f58da6ebaad..27e660e92489 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -1868,9 +1868,9 @@ static void ast_mode_config_helper_atomic_commit_tail(struct drm_atomic_state *s /* * Concurrent operations could possibly trigger a call to - * drm_connector_helper_funcs.get_modes by trying to read the - * display modes. Protect access to I/O registers by acquiring - * the I/O-register lock. Released in atomic_flush(). + * drm_connector_helper_funcs.get_modes by reading the display + * modes. Protect access to registers by acquiring the modeset + * lock. */ mutex_lock(&ast->ioregs_lock); drm_atomic_helper_commit_tail_rpm(state); From 6d7b814c527c16b5ccf3f8961e2fe1d74e1888a4 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 28 Mar 2025 10:17:05 +0100 Subject: [PATCH 800/971] drm/cirrus-qemu: Fix pitch programming commit 4bfb389a0136a13f0802eeb5e97a0e76d88f77ae upstream. Do not set CR1B[6] when programming the pitch. The bit effects VGA text mode and is not interpreted by qemu. [1] It has no affect on the scanline pitch. The scanline bit that is set into CR1B[6] belongs into CR13[7], which the driver sets up correctly. This bug goes back to the driver's initial commit. Signed-off-by: Thomas Zimmermann Acked-by: Gerd Hoffmann Link: https://gitlab.com/qemu-project/qemu/-/blob/stable-9.2/hw/display/cirrus_vga.c?ref_type=heads#L1112 # 1 Fixes: f9aa76a85248 ("drm/kms: driver for virtual cirrus under qemu") Cc: Adam Jackson Cc: Dave Airlie Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: # v3.5+ Link: https://lore.kernel.org/r/20250328091821.195061-2-tzimmermann@suse.de Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/tiny/cirrus.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/tiny/cirrus.c b/drivers/gpu/drm/tiny/cirrus.c index 594bc472862f..b0361ef53c46 100644 --- a/drivers/gpu/drm/tiny/cirrus.c +++ b/drivers/gpu/drm/tiny/cirrus.c @@ -318,7 +318,6 @@ static void cirrus_pitch_set(struct cirrus_device *cirrus, unsigned int pitch) /* Enable extended blanking and pitch bits, and enable full memory */ cr1b = 0x22; cr1b |= (pitch >> 7) & 0x10; - cr1b |= (pitch >> 6) & 0x40; wreg_crt(cirrus, 0x1b, cr1b); cirrus_set_start_address(cirrus, 0); From 9ec447c23753529e0376e14cb44c2812b2b761b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ADra=20Canal?= Date: Mon, 2 Jun 2025 10:22:16 -0300 Subject: [PATCH 801/971] drm/etnaviv: Protect the scheduler's pending list with its lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 61ee19dedb8d753249e20308782bf4e9e2fb7344 upstream. Commit 704d3d60fec4 ("drm/etnaviv: don't block scheduler when GPU is still active") ensured that active jobs are returned to the pending list when extending the timeout. However, it didn't use the pending list's lock to manipulate the list, which causes a race condition as the scheduler's workqueues are running. Hold the lock while manipulating the scheduler's pending list to prevent a race. Cc: stable@vger.kernel.org Fixes: 704d3d60fec4 ("drm/etnaviv: don't block scheduler when GPU is still active") Reported-by: Philipp Stanner Closes: https://lore.kernel.org/dri-devel/964e59ba1539083ef29b06d3c78f5e2e9b138ab8.camel@mailbox.org/ Reviewed-by: Lucas Stach Reviewed-by: Philipp Stanner Link: https://lore.kernel.org/r/20250602132240.93314-1-mcanal@igalia.com Signed-off-by: Maíra Canal Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/etnaviv/etnaviv_sched.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c b/drivers/gpu/drm/etnaviv/etnaviv_sched.c index 97e406d9ac06..a3bd396c9d82 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c @@ -34,6 +34,7 @@ static enum drm_gpu_sched_stat etnaviv_sched_timedout_job(struct drm_sched_job *sched_job) { struct etnaviv_gem_submit *submit = to_etnaviv_submit(sched_job); + struct drm_gpu_scheduler *sched = sched_job->sched; struct etnaviv_gpu *gpu = submit->gpu; u32 dma_addr; int change; @@ -76,7 +77,9 @@ static enum drm_gpu_sched_stat etnaviv_sched_timedout_job(struct drm_sched_job return DRM_GPU_SCHED_STAT_NOMINAL; out_no_timeout: - list_add(&sched_job->list, &sched_job->sched->pending_list); + spin_lock(&sched->job_list_lock); + list_add(&sched_job->list, &sched->pending_list); + spin_unlock(&sched->job_list_lock); return DRM_GPU_SCHED_STAT_NOMINAL; } From 23134a5227588fe4b574c9eaadf2198f24804a8f Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 21 Apr 2025 11:13:05 -0500 Subject: [PATCH 802/971] drm/tegra: Assign plane type before registration commit 9ff4fdf4f44b69237c0afc1d3a8dac916ce66f3e upstream. Changes to a plane's type after it has been registered aren't propagated to userspace automatically. This could possibly be achieved by updating the property, but since we can already determine which type this should be before the registration, passing in the right type from the start is a much better solution. Suggested-by: Aaron Kling Signed-off-by: Thierry Reding Cc: stable@vger.kernel.org Fixes: 473079549f27 ("drm/tegra: dc: Add Tegra186 support") Signed-off-by: Aaron Kling Signed-off-by: Thierry Reding Link: https://lore.kernel.org/r/20250421-tegra-drm-primary-v2-1-7f740c4c2121@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/tegra/dc.c | 12 ++++++++---- drivers/gpu/drm/tegra/hub.c | 4 ++-- drivers/gpu/drm/tegra/hub.h | 3 ++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 13b182ab905f..b016c3c95a84 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -1320,10 +1320,16 @@ static struct drm_plane *tegra_dc_add_shared_planes(struct drm_device *drm, if (wgrp->dc == dc->pipe) { for (j = 0; j < wgrp->num_windows; j++) { unsigned int index = wgrp->windows[j]; + enum drm_plane_type type; + + if (primary) + type = DRM_PLANE_TYPE_OVERLAY; + else + type = DRM_PLANE_TYPE_PRIMARY; plane = tegra_shared_plane_create(drm, dc, wgrp->index, - index); + index, type); if (IS_ERR(plane)) return plane; @@ -1331,10 +1337,8 @@ static struct drm_plane *tegra_dc_add_shared_planes(struct drm_device *drm, * Choose the first shared plane owned by this * head as the primary plane. */ - if (!primary) { - plane->type = DRM_PLANE_TYPE_PRIMARY; + if (!primary) primary = plane; - } } } } diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c index 1af5f8318d91..0f88cbb33317 100644 --- a/drivers/gpu/drm/tegra/hub.c +++ b/drivers/gpu/drm/tegra/hub.c @@ -756,9 +756,9 @@ static const struct drm_plane_helper_funcs tegra_shared_plane_helper_funcs = { struct drm_plane *tegra_shared_plane_create(struct drm_device *drm, struct tegra_dc *dc, unsigned int wgrp, - unsigned int index) + unsigned int index, + enum drm_plane_type type) { - enum drm_plane_type type = DRM_PLANE_TYPE_OVERLAY; struct tegra_drm *tegra = drm->dev_private; struct tegra_display_hub *hub = tegra->hub; struct tegra_shared_plane *plane; diff --git a/drivers/gpu/drm/tegra/hub.h b/drivers/gpu/drm/tegra/hub.h index 23c4b2115ed1..a66f18c4facc 100644 --- a/drivers/gpu/drm/tegra/hub.h +++ b/drivers/gpu/drm/tegra/hub.h @@ -80,7 +80,8 @@ void tegra_display_hub_cleanup(struct tegra_display_hub *hub); struct drm_plane *tegra_shared_plane_create(struct drm_device *drm, struct tegra_dc *dc, unsigned int wgrp, - unsigned int index); + unsigned int index, + enum drm_plane_type type); int tegra_display_hub_atomic_check(struct drm_device *drm, struct drm_atomic_state *state); From 5ff3636bcc32e1cb747f6f820bcf2bb6990a7d41 Mon Sep 17 00:00:00 2001 From: Qiu-ji Chen Date: Wed, 6 Nov 2024 17:59:06 +0800 Subject: [PATCH 803/971] drm/tegra: Fix a possible null pointer dereference commit 780351a5f61416ed2ba1199cc57e4a076fca644d upstream. In tegra_crtc_reset(), new memory is allocated with kzalloc(), but no check is performed. Before calling __drm_atomic_helper_crtc_reset, state should be checked to prevent possible null pointer dereference. Fixes: b7e0b04ae450 ("drm/tegra: Convert to using __drm_atomic_helper_crtc_reset() for reset.") Cc: stable@vger.kernel.org Signed-off-by: Qiu-ji Chen Signed-off-by: Thierry Reding Link: https://lore.kernel.org/r/20241106095906.15247-1-chenqiuji666@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/tegra/dc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index b016c3c95a84..980d85bc7f37 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -1392,7 +1392,10 @@ static void tegra_crtc_reset(struct drm_crtc *crtc) if (crtc->state) tegra_crtc_atomic_destroy_state(crtc, crtc->state); - __drm_atomic_helper_crtc_reset(crtc, &state->base); + if (state) + __drm_atomic_helper_crtc_reset(crtc, &state->base); + else + __drm_atomic_helper_crtc_reset(crtc, NULL); } static struct drm_crtc_state * From 50e48e9403295702c48845721052fb205f834d31 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 3 Mar 2025 15:52:56 +0100 Subject: [PATCH 804/971] drm/udl: Unregister device before cleaning up on disconnect commit ff9cb6d2035c586ea7c8f1754d4409eec7a2d26d upstream. Disconnecting a DisplayLink device results in the following kernel error messages [ 93.041748] [drm:udl_urb_completion [udl]] *ERROR* udl_urb_completion - nonzero write bulk status received: -115 [ 93.055299] [drm:udl_submit_urb [udl]] *ERROR* usb_submit_urb error fffffffe [ 93.065363] [drm:udl_urb_completion [udl]] *ERROR* udl_urb_completion - nonzero write bulk status received: -115 [ 93.078207] [drm:udl_submit_urb [udl]] *ERROR* usb_submit_urb error fffffffe coming from KMS poll helpers. Shutting down poll helpers runs them one final time when the USB device is already gone. Run drm_dev_unplug() first in udl's USB disconnect handler. Udl's polling code already handles disconnects gracefully if the device has been marked as unplugged. Signed-off-by: Thomas Zimmermann Fixes: b1a981bd5576 ("drm/udl: drop drm_driver.release hook") Cc: dri-devel@lists.freedesktop.org Cc: # v5.8+ Reviewed-by: Patrik Jakobsson Link: https://patchwork.freedesktop.org/patch/msgid/20250303145604.62962-2-tzimmermann@suse.de Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/udl/udl_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 1506094a8009..ac357ab1aee5 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -126,9 +126,9 @@ static void udl_usb_disconnect(struct usb_interface *interface) { struct drm_device *dev = usb_get_intfdata(interface); + drm_dev_unplug(dev); drm_kms_helper_poll_fini(dev); udl_drop_usb(dev); - drm_dev_unplug(dev); } /* From 7946a10f8da75abc494e4bb80243e153e93e459a Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Tue, 29 Apr 2025 10:33:56 +0200 Subject: [PATCH 805/971] drm/msm/gpu: Fix crash when throttling GPU immediately during boot commit b71717735be48d7743a34897e9e44a0b53e30c0e upstream. There is a small chance that the GPU is already hot during boot. In that case, the call to of_devfreq_cooling_register() will immediately try to apply devfreq cooling, as seen in the following crash: Unable to handle kernel paging request at virtual address 0000000000014110 pc : a6xx_gpu_busy+0x1c/0x58 [msm] lr : msm_devfreq_get_dev_status+0xbc/0x140 [msm] Call trace: a6xx_gpu_busy+0x1c/0x58 [msm] (P) devfreq_simple_ondemand_func+0x3c/0x150 devfreq_update_target+0x44/0xd8 qos_max_notifier_call+0x30/0x84 blocking_notifier_call_chain+0x6c/0xa0 pm_qos_update_target+0xd0/0x110 freq_qos_apply+0x3c/0x74 apply_constraint+0x88/0x148 __dev_pm_qos_update_request+0x7c/0xcc dev_pm_qos_update_request+0x38/0x5c devfreq_cooling_set_cur_state+0x98/0xf0 __thermal_cdev_update+0x64/0xb4 thermal_cdev_update+0x4c/0x58 step_wise_manage+0x1f0/0x318 __thermal_zone_device_update+0x278/0x424 __thermal_cooling_device_register+0x2bc/0x308 thermal_of_cooling_device_register+0x10/0x1c of_devfreq_cooling_register_power+0x240/0x2bc of_devfreq_cooling_register+0x14/0x20 msm_devfreq_init+0xc4/0x1a0 [msm] msm_gpu_init+0x304/0x574 [msm] adreno_gpu_init+0x1c4/0x2e0 [msm] a6xx_gpu_init+0x5c8/0x9c8 [msm] adreno_bind+0x2a8/0x33c [msm] ... At this point we haven't initialized the GMU at all yet, so we cannot read the GMU registers inside a6xx_gpu_busy(). A similar issue was fixed before in commit 6694482a70e9 ("drm/msm: Avoid unclocked GMU register access in 6xx gpu_busy"): msm_devfreq_init() does call devfreq_suspend_device(), but unlike msm_devfreq_suspend(), it doesn't set the df->suspended flag accordingly. This means the df->suspended flag does not match the actual devfreq state after initialization and msm_devfreq_get_dev_status() will end up accessing GMU registers, causing the crash. Fix this by setting df->suspended correctly during initialization. Cc: stable@vger.kernel.org Fixes: 6694482a70e9 ("drm/msm: Avoid unclocked GMU register access in 6xx gpu_busy") Signed-off-by: Stephan Gerhold Reviewed-by: Douglas Anderson Reviewed-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/650772/ Signed-off-by: Rob Clark Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/msm/msm_gpu_devfreq.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c index 6970b0f7f457..2e1d5c343272 100644 --- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c @@ -156,6 +156,7 @@ void msm_devfreq_init(struct msm_gpu *gpu) priv->gpu_devfreq_config.downdifferential = 10; mutex_init(&df->lock); + df->suspended = true; ret = dev_pm_qos_add_request(&gpu->pdev->dev, &df->boost_freq, DEV_PM_QOS_MIN_FREQUENCY, 0); From 76115eafad121fe7a2bfab8cac64c73939ebb47e Mon Sep 17 00:00:00 2001 From: Jay Cornwall Date: Wed, 11 Jun 2025 09:52:14 -0500 Subject: [PATCH 806/971] drm/amdkfd: Fix race in GWS queue scheduling commit cfb05257ae168a0496c7637e1d9e3ab8a25cbffe upstream. q->gws is not updated atomically with qpd->mapped_gws_queue. If a runlist is created between pqm_set_gws and update_queue it will contain a queue which uses GWS in a process with no GWS allocated. This will result in a scheduler hang. Use q->properties.is_gws which is changed while holding the DQM lock. Signed-off-by: Jay Cornwall Reviewed-by: Harish Kasiviswanathan Signed-off-by: Alex Deucher (cherry picked from commit b98370220eb3110e82248e3354e16a489a492cfb) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c index 1a03173e2313..18e82d0da75b 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c @@ -225,7 +225,7 @@ static int pm_map_queues_v9(struct packet_manager *pm, uint32_t *buffer, packet->bitfields2.engine_sel = engine_sel__mes_map_queues__compute_vi; - packet->bitfields2.gws_control_queue = q->gws ? 1 : 0; + packet->bitfields2.gws_control_queue = q->properties.is_gws ? 1 : 0; packet->bitfields2.extended_engine_sel = extended_engine_sel__mes_map_queues__legacy_engine_sel; packet->bitfields2.queue_type = From 2565ff3ac3f529b443de33b73a208301d33c3ff1 Mon Sep 17 00:00:00 2001 From: Aradhya Bhatia Date: Sat, 29 Mar 2025 17:09:14 +0530 Subject: [PATCH 807/971] drm/bridge: cdns-dsi: Fix the clock variable for mode_valid() commit 132bdcec399be6ae947582249a134b38cf56731c upstream. The crtc_* mode parameters do not get generated (duplicated in this case) from the regular parameters before the mode validation phase begins. The rest of the code conditionally uses the crtc_* parameters only during the bridge enable phase, but sticks to the regular parameters for mode validation. In this singular instance, however, the driver tries to use the crtc_clock parameter even during the mode validation, causing the validation to fail. Allow the D-Phy config checks to use mode->clock instead of mode->crtc_clock during mode_valid checks, like everywhere else in the driver. Fixes: fced5a364dee ("drm/bridge: cdns: Convert to phy framework") Cc: stable@vger.kernel.org Reviewed-by: Tomi Valkeinen Reviewed-by: Dmitry Baryshkov Tested-by: Tomi Valkeinen Signed-off-by: Aradhya Bhatia Signed-off-by: Aradhya Bhatia Link: https://lore.kernel.org/r/20250329113925.68204-4-aradhya.bhatia@linux.dev Signed-off-by: Dmitry Baryshkov Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index 7457d38622b0..1e93da035afb 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -568,13 +568,14 @@ static int cdns_dsi_check_conf(struct cdns_dsi *dsi, struct phy_configure_opts_mipi_dphy *phy_cfg = &output->phy_opts.mipi_dphy; unsigned long dsi_hss_hsa_hse_hbp; unsigned int nlanes = output->dev->lanes; + int mode_clock = (mode_valid_check ? mode->clock : mode->crtc_clock); int ret; ret = cdns_dsi_mode2cfg(dsi, mode, dsi_cfg, mode_valid_check); if (ret) return ret; - phy_mipi_dphy_get_default_config(mode->crtc_clock * 1000, + phy_mipi_dphy_get_default_config(mode_clock * 1000, mipi_dsi_pixel_format_to_bpp(output->dev->format), nlanes, phy_cfg); From f9b819c39d13d89262918feba10e1e752e56a3cf Mon Sep 17 00:00:00 2001 From: Aradhya Bhatia Date: Sat, 29 Mar 2025 17:09:13 +0530 Subject: [PATCH 808/971] drm/bridge: cdns-dsi: Fix phy de-init and flag it so commit fd2611c13f69cbbc6b81d9fc7502abf4f7031d21 upstream. The driver code doesn't have a Phy de-initialization path as yet, and so it does not clear the phy_initialized flag while suspending. This is a problem because after resume the driver looks at this flag to determine if a Phy re-initialization is required or not. It is in fact required because the hardware is resuming from a suspend, but the driver does not carry out any re-initialization causing the D-Phy to not work at all. Call the counterparts of phy_init() and phy_power_on(), that are phy_exit() and phy_power_off(), from _bridge_post_disable(), and clear the flags so that the Phy can be initialized again when required. Fixes: fced5a364dee ("drm/bridge: cdns: Convert to phy framework") Cc: stable@vger.kernel.org Reviewed-by: Dmitry Baryshkov Reviewed-by: Tomi Valkeinen Tested-by: Tomi Valkeinen Signed-off-by: Aradhya Bhatia Signed-off-by: Aradhya Bhatia Link: https://lore.kernel.org/r/20250329113925.68204-3-aradhya.bhatia@linux.dev Signed-off-by: Dmitry Baryshkov Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index 1e93da035afb..f8f48a57e837 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -681,6 +681,11 @@ static void cdns_dsi_bridge_post_disable(struct drm_bridge *bridge) struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge); struct cdns_dsi *dsi = input_to_dsi(input); + dsi->phy_initialized = false; + dsi->link_initialized = false; + phy_power_off(dsi->dphy); + phy_exit(dsi->dphy); + pm_runtime_put(dsi->base.dev); } @@ -1153,7 +1158,6 @@ static int __maybe_unused cdns_dsi_suspend(struct device *dev) clk_disable_unprepare(dsi->dsi_sys_clk); clk_disable_unprepare(dsi->dsi_p_clk); reset_control_assert(dsi->dsi_p_rst); - dsi->link_initialized = false; return 0; } From c4ee1b31a54085ed2f2c7aa36a9f5690f8d5ea78 Mon Sep 17 00:00:00 2001 From: Aradhya Bhatia Date: Sat, 29 Mar 2025 17:09:12 +0530 Subject: [PATCH 809/971] drm/bridge: cdns-dsi: Fix connecting to next bridge commit 688eb4d465484bc2a3471a6a6f06f833b58c7867 upstream. Fix the OF node pointer passed to the of_drm_find_bridge() call to find the next bridge in the display chain. The code to find the next panel (and create its panel-bridge) works fine, but to find the next (non-panel) bridge does not. To find the next bridge in the pipeline, we need to pass "np" - the OF node pointer of the next entity in the devicetree chain. Passing "of_node" to of_drm_find_bridge (which is what the code does currently) will fetch the bridge for the cdns-dsi which is not what's required. Fix that. Fixes: e19233955d9e ("drm/bridge: Add Cadence DSI driver") Cc: stable@vger.kernel.org Reviewed-by: Dmitry Baryshkov Reviewed-by: Tomi Valkeinen Tested-by: Tomi Valkeinen Signed-off-by: Aradhya Bhatia Signed-off-by: Aradhya Bhatia Link: https://lore.kernel.org/r/20250329113925.68204-2-aradhya.bhatia@linux.dev Signed-off-by: Dmitry Baryshkov Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index f8f48a57e837..19c21daa84e9 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -958,7 +958,7 @@ static int cdns_dsi_attach(struct mipi_dsi_host *host, bridge = drm_panel_bridge_add_typed(panel, DRM_MODE_CONNECTOR_DSI); } else { - bridge = of_drm_find_bridge(dev->dev.of_node); + bridge = of_drm_find_bridge(np); if (!bridge) bridge = ERR_PTR(-EINVAL); } From 252e6e96f9b6547800e0739270dd94f636f5dd86 Mon Sep 17 00:00:00 2001 From: Aradhya Bhatia Date: Sat, 29 Mar 2025 17:09:15 +0530 Subject: [PATCH 810/971] drm/bridge: cdns-dsi: Check return value when getting default PHY config commit c6a7ef0d4856b9629df390e9935d7fd67fe39f81 upstream. Check for the return value of the phy_mipi_dphy_get_default_config() call, and in case of an error, return back the same. Fixes: fced5a364dee ("drm/bridge: cdns: Convert to phy framework") Cc: stable@vger.kernel.org Reviewed-by: Tomi Valkeinen Reviewed-by: Dmitry Baryshkov Tested-by: Tomi Valkeinen Signed-off-by: Aradhya Bhatia Signed-off-by: Aradhya Bhatia Link: https://lore.kernel.org/r/20250329113925.68204-5-aradhya.bhatia@linux.dev Signed-off-by: Dmitry Baryshkov Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index 19c21daa84e9..738fb24991d9 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -575,9 +575,11 @@ static int cdns_dsi_check_conf(struct cdns_dsi *dsi, if (ret) return ret; - phy_mipi_dphy_get_default_config(mode_clock * 1000, - mipi_dsi_pixel_format_to_bpp(output->dev->format), - nlanes, phy_cfg); + ret = phy_mipi_dphy_get_default_config(mode_clock * 1000, + mipi_dsi_pixel_format_to_bpp(output->dev->format), + nlanes, phy_cfg); + if (ret) + return ret; ret = cdns_dsi_adjust_phy_config(dsi, dsi_cfg, phy_cfg, mode, mode_valid_check); if (ret) From ede04b471596c0e535f6d9fe84933e79b42b5b36 Mon Sep 17 00:00:00 2001 From: Aradhya Bhatia Date: Sat, 29 Mar 2025 17:09:16 +0530 Subject: [PATCH 811/971] drm/bridge: cdns-dsi: Wait for Clk and Data Lanes to be ready commit 47c03e6660e96cbba0239125b1d4a9db3c724b1d upstream. Once the DSI Link and DSI Phy are initialized, the code needs to wait for Clk and Data Lanes to be ready, before continuing configuration. This is in accordance with the DSI Start-up procedure, found in the Technical Reference Manual of Texas Instrument's J721E SoC[0] which houses this DSI TX controller. If the previous bridge (or crtc/encoder) are configured pre-maturely, the input signal FIFO gets corrupt. This introduces a color-shift on the display. Allow the driver to wait for the clk and data lanes to get ready during DSI enable. [0]: See section 12.6.5.7.3 "Start-up Procedure" in J721E SoC TRM TRM Link: http://www.ti.com/lit/pdf/spruil1 Fixes: e19233955d9e ("drm/bridge: Add Cadence DSI driver") Cc: stable@vger.kernel.org Tested-by: Dominik Haller Reviewed-by: Tomi Valkeinen Tested-by: Tomi Valkeinen Signed-off-by: Aradhya Bhatia Signed-off-by: Aradhya Bhatia Link: https://lore.kernel.org/r/20250329113925.68204-6-aradhya.bhatia@linux.dev Signed-off-by: Dmitry Baryshkov Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index 738fb24991d9..89eed0668bfb 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -769,7 +769,7 @@ static void cdns_dsi_bridge_enable(struct drm_bridge *bridge) struct phy_configure_opts_mipi_dphy *phy_cfg = &output->phy_opts.mipi_dphy; unsigned long tx_byte_period; struct cdns_dsi_cfg dsi_cfg; - u32 tmp, reg_wakeup, div; + u32 tmp, reg_wakeup, div, status; int nlanes; if (WARN_ON(pm_runtime_get_sync(dsi->base.dev) < 0)) @@ -786,6 +786,19 @@ static void cdns_dsi_bridge_enable(struct drm_bridge *bridge) cdns_dsi_hs_init(dsi); cdns_dsi_init_link(dsi); + /* + * Now that the DSI Link and DSI Phy are initialized, + * wait for the CLK and Data Lanes to be ready. + */ + tmp = CLK_LANE_RDY; + for (int i = 0; i < nlanes; i++) + tmp |= DATA_LANE_RDY(i); + + if (readl_poll_timeout(dsi->regs + MCTL_MAIN_STS, status, + (tmp == (status & tmp)), 100, 500000)) + dev_err(dsi->base.dev, + "Timed Out: DSI-DPhy Clock and Data Lanes not ready.\n"); + writel(HBP_LEN(dsi_cfg.hbp) | HSA_LEN(dsi_cfg.hsa), dsi->regs + VID_HSIZE1); writel(HFP_LEN(dsi_cfg.hfp) | HACT_LEN(dsi_cfg.hact), From 5148c7ea69e9c5bf2f05081190f45ba96d3d1e7a Mon Sep 17 00:00:00 2001 From: Wentao Liang Date: Mon, 26 May 2025 10:37:31 +0800 Subject: [PATCH 812/971] drm/amd/display: Add null pointer check for get_first_active_display() commit c3e9826a22027a21d998d3e64882fa377b613006 upstream. The function mod_hdcp_hdcp1_enable_encryption() calls the function get_first_active_display(), but does not check its return value. The return value is a null pointer if the display list is empty. This will lead to a null pointer dereference in mod_hdcp_hdcp2_enable_encryption(). Add a null pointer check for get_first_active_display() and return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND if the function return null. Fixes: 2deade5ede56 ("drm/amd/display: Remove hdcp display state with mst fix") Signed-off-by: Wentao Liang Reviewed-by: Alex Hung Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org # v5.8 Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c index ff930a71e496..7f8f127e7722 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c @@ -368,6 +368,9 @@ enum mod_hdcp_status mod_hdcp_hdcp1_enable_encryption(struct mod_hdcp *hdcp) struct mod_hdcp_display *display = get_first_active_display(hdcp); enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; + if (!display) + return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND; + mutex_lock(&psp->hdcp_context.mutex); hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); From a8ceffaeb780da40dc722e92a6476c309688f426 Mon Sep 17 00:00:00 2001 From: John Olender Date: Tue, 29 Apr 2025 07:24:28 -0400 Subject: [PATCH 813/971] drm/amdgpu: amdgpu_vram_mgr_new(): Clamp lpfn to total vram commit 4d2f6b4e4c7ed32e7fa39fcea37344a9eab99094 upstream. The drm_mm allocator tolerated being passed end > mm->size, but the drm_buddy allocator does not. Restore the pre-buddy-allocator behavior of allowing such placements. Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3448 Signed-off-by: John Olender Reviewed-by: Alex Deucher Reviewed-by: Arunpravin Paneer Selvam Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c index c7085a747b03..451c37d04e45 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c @@ -435,7 +435,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man, int r; lpfn = (u64)place->lpfn << PAGE_SHIFT; - if (!lpfn) + if (!lpfn || lpfn > man->size) lpfn = man->size; fpfn = (u64)place->fpfn << PAGE_SHIFT; From f640d011080d6f4baeee44ebe02f4ebbb73a598c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 12 May 2025 21:22:15 +0200 Subject: [PATCH 814/971] drm/i915/gem: Allow EXEC_CAPTURE on recoverable contexts on DG1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 25eeba495b2fc16037647c1a51bcdf6fc157af5c upstream. The intel-media-driver is currently broken on DG1 because it uses EXEC_CAPTURE with recovarable contexts. Relax the check to allow that. I've also submitted a fix for the intel-media-driver: https://github.com/intel/media-driver/pull/1920 Cc: stable@vger.kernel.org # v6.0+ Cc: Matthew Auld Cc: Thomas Hellström Testcase: igt/gem_exec_capture/capture-invisible Fixes: 71b1669ea9bd ("drm/i915/uapi: tweak error capture on recoverable contexts") Reviewed-by: Andi Shyti Signed-off-by: Ville Syrjälä Signed-off-by: Andi Shyti Link: https://lore.kernel.org/r/20250411144313.11660-2-ville.syrjala@linux.intel.com (cherry picked from commit d6e020819612a4a06207af858e0978be4d3e3140) Signed-off-by: Joonas Lahtinen Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 5a687a3686bd..023b2ea74c36 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -2013,7 +2013,7 @@ static int eb_capture_stage(struct i915_execbuffer *eb) continue; if (i915_gem_context_is_recoverable(eb->gem_context) && - (IS_DGFX(eb->i915) || GRAPHICS_VER_FULL(eb->i915) > IP_VER(12, 0))) + GRAPHICS_VER_FULL(eb->i915) > IP_VER(12, 10)) return -EINVAL; for_each_batch_create_order(eb, j) { From a5d7cc1647f949caf0441e50c6075ea062429b04 Mon Sep 17 00:00:00 2001 From: Frank Min Date: Wed, 4 Jun 2025 21:00:44 +0800 Subject: [PATCH 815/971] drm/amdgpu: Add kicker device detection commit 0bbf5fd86c585d437b75003f11365b324360a5d6 upstream. 1. add kicker device list 2. add kicker device checking helper function Signed-off-by: Frank Min Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher (cherry picked from commit 09aa2b408f4ab689c3541d22b0968de0392ee406) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 17 +++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h | 6 ++++++ 2 files changed, 23 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index bef754177064..e9d2fcdde0e1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c @@ -28,6 +28,10 @@ #include "amdgpu.h" #include "amdgpu_ucode.h" +static const struct kicker_device kicker_device_list[] = { + {0x744B, 0x00}, +}; + static void amdgpu_ucode_print_common_hdr(const struct common_firmware_header *hdr) { DRM_DEBUG("size_bytes: %u\n", le32_to_cpu(hdr->size_bytes)); @@ -1268,6 +1272,19 @@ static const char *amdgpu_ucode_legacy_naming(struct amdgpu_device *adev, int bl return NULL; } +bool amdgpu_is_kicker_fw(struct amdgpu_device *adev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(kicker_device_list); i++) { + if (adev->pdev->device == kicker_device_list[i].device && + adev->pdev->revision == kicker_device_list[i].revision) + return true; + } + + return false; +} + void amdgpu_ucode_ip_version_decode(struct amdgpu_device *adev, int block_type, char *ucode_prefix, int len) { int maj, min, rev; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h index b03321e7d2d8..4760092aafd7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h @@ -536,6 +536,11 @@ struct amdgpu_firmware { uint64_t fw_buf_mc; }; +struct kicker_device{ + unsigned short device; + u8 revision; +}; + void amdgpu_ucode_print_mc_hdr(const struct common_firmware_header *hdr); void amdgpu_ucode_print_smc_hdr(const struct common_firmware_header *hdr); void amdgpu_ucode_print_imu_hdr(const struct common_firmware_header *hdr); @@ -562,5 +567,6 @@ amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type); const char *amdgpu_ucode_name(enum AMDGPU_UCODE_ID ucode_id); void amdgpu_ucode_ip_version_decode(struct amdgpu_device *adev, int block_type, char *ucode_prefix, int len); +bool amdgpu_is_kicker_fw(struct amdgpu_device *adev); #endif From 8302adf60aba60da707af566801c0641c8d367c9 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 2 Jun 2025 11:31:52 -0400 Subject: [PATCH 816/971] drm/amdgpu: switch job hw_fence to amdgpu_fence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit ebe43542702c3d15d1a1d95e8e13b1b54076f05a upstream. Use the amdgpu fence container so we can store additional data in the fence. This also fixes the start_time handling for MCBP since we were casting the fence to an amdgpu_fence and it wasn't. Fixes: 3f4c175d62d8 ("drm/amdgpu: MCBP based on DRM scheduler (v9)") Reviewed-by: Christian König Signed-off-by: Alex Deucher (cherry picked from commit bf1cd14f9e2e1fdf981eed273ddd595863f5288c) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 30 +++++---------------- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 12 ++++----- drivers/gpu/drm/amd/amdgpu/amdgpu_job.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 16 +++++++++++ 6 files changed, 32 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c index 963e106d32ee..256cc15fc9b5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c @@ -1890,7 +1890,7 @@ no_preempt: continue; } job = to_amdgpu_job(s_job); - if (preempted && (&job->hw_fence) == fence) + if (preempted && (&job->hw_fence.base) == fence) /* mark the job as preempted */ job->preemption_status |= AMDGPU_IB_PREEMPTED; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index f8058dd5356a..200b59318759 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -5367,7 +5367,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, * * job->base holds a reference to parent fence */ - if (job && dma_fence_is_signaled(&job->hw_fence)) { + if (job && dma_fence_is_signaled(&job->hw_fence.base)) { job_signaled = true; dev_info(adev->dev, "Guilty job already signaled, skipping HW reset"); goto skip_hw_reset; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 7537f5aa76f0..017dd494d0a2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -41,22 +41,6 @@ #include "amdgpu_trace.h" #include "amdgpu_reset.h" -/* - * Fences mark an event in the GPUs pipeline and are used - * for GPU/CPU synchronization. When the fence is written, - * it is expected that all buffers associated with that fence - * are no longer in use by the associated ring on the GPU and - * that the relevant GPU caches have been flushed. - */ - -struct amdgpu_fence { - struct dma_fence base; - - /* RB, DMA, etc. */ - struct amdgpu_ring *ring; - ktime_t start_timestamp; -}; - static struct kmem_cache *amdgpu_fence_slab; int amdgpu_fence_slab_init(void) @@ -153,12 +137,12 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f, struct amd am_fence = kmem_cache_alloc(amdgpu_fence_slab, GFP_ATOMIC); if (am_fence == NULL) return -ENOMEM; - fence = &am_fence->base; - am_fence->ring = ring; } else { /* take use of job-embedded fence */ - fence = &job->hw_fence; + am_fence = &job->hw_fence; } + fence = &am_fence->base; + am_fence->ring = ring; seq = ++ring->fence_drv.sync_seq; if (job && job->job_run_counter) { @@ -719,7 +703,7 @@ void amdgpu_fence_driver_clear_job_fences(struct amdgpu_ring *ring) * it right here or we won't be able to track them in fence_drv * and they will remain unsignaled during sa_bo free. */ - job = container_of(old, struct amdgpu_job, hw_fence); + job = container_of(old, struct amdgpu_job, hw_fence.base); if (!job->base.s_fence && !dma_fence_is_signaled(old)) dma_fence_signal(old); RCU_INIT_POINTER(*ptr, NULL); @@ -781,7 +765,7 @@ static const char *amdgpu_fence_get_timeline_name(struct dma_fence *f) static const char *amdgpu_job_fence_get_timeline_name(struct dma_fence *f) { - struct amdgpu_job *job = container_of(f, struct amdgpu_job, hw_fence); + struct amdgpu_job *job = container_of(f, struct amdgpu_job, hw_fence.base); return (const char *)to_amdgpu_ring(job->base.sched)->name; } @@ -811,7 +795,7 @@ static bool amdgpu_fence_enable_signaling(struct dma_fence *f) */ static bool amdgpu_job_fence_enable_signaling(struct dma_fence *f) { - struct amdgpu_job *job = container_of(f, struct amdgpu_job, hw_fence); + struct amdgpu_job *job = container_of(f, struct amdgpu_job, hw_fence.base); if (!timer_pending(&to_amdgpu_ring(job->base.sched)->fence_drv.fallback_timer)) amdgpu_fence_schedule_fallback(to_amdgpu_ring(job->base.sched)); @@ -846,7 +830,7 @@ static void amdgpu_job_fence_free(struct rcu_head *rcu) struct dma_fence *f = container_of(rcu, struct dma_fence, rcu); /* free job if fence has a parent job */ - kfree(container_of(f, struct amdgpu_job, hw_fence)); + kfree(container_of(f, struct amdgpu_job, hw_fence.base)); } /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index 49a6b6b88843..e9adfc88a54a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -165,8 +165,8 @@ void amdgpu_job_free_resources(struct amdgpu_job *job) /* Check if any fences where initialized */ if (job->base.s_fence && job->base.s_fence->finished.ops) f = &job->base.s_fence->finished; - else if (job->hw_fence.ops) - f = &job->hw_fence; + else if (job->hw_fence.base.ops) + f = &job->hw_fence.base; else f = NULL; @@ -183,10 +183,10 @@ static void amdgpu_job_free_cb(struct drm_sched_job *s_job) amdgpu_sync_free(&job->explicit_sync); /* only put the hw fence if has embedded fence */ - if (!job->hw_fence.ops) + if (!job->hw_fence.base.ops) kfree(job); else - dma_fence_put(&job->hw_fence); + dma_fence_put(&job->hw_fence.base); } void amdgpu_job_set_gang_leader(struct amdgpu_job *job, @@ -215,10 +215,10 @@ void amdgpu_job_free(struct amdgpu_job *job) if (job->gang_submit != &job->base.s_fence->scheduled) dma_fence_put(job->gang_submit); - if (!job->hw_fence.ops) + if (!job->hw_fence.base.ops) kfree(job); else - dma_fence_put(&job->hw_fence); + dma_fence_put(&job->hw_fence.base); } struct dma_fence *amdgpu_job_submit(struct amdgpu_job *job) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h index a963a25ddd62..65b6fbab544e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h @@ -48,7 +48,7 @@ struct amdgpu_job { struct drm_sched_job base; struct amdgpu_vm *vm; struct amdgpu_sync explicit_sync; - struct dma_fence hw_fence; + struct amdgpu_fence hw_fence; struct dma_fence *gang_submit; uint32_t preamble_status; uint32_t preemption_status; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index e2ab303ad270..60f770b99c2c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -123,6 +123,22 @@ struct amdgpu_fence_driver { struct dma_fence **fences; }; +/* + * Fences mark an event in the GPUs pipeline and are used + * for GPU/CPU synchronization. When the fence is written, + * it is expected that all buffers associated with that fence + * are no longer in use by the associated ring on the GPU and + * that the relevant GPU caches have been flushed. + */ + +struct amdgpu_fence { + struct dma_fence base; + + /* RB, DMA, etc. */ + struct amdgpu_ring *ring; + ktime_t start_timestamp; +}; + extern const struct drm_sched_backend_ops amdgpu_sched_ops; void amdgpu_fence_driver_clear_job_fences(struct amdgpu_ring *ring); From 107a48df3f942c49f9e0a96aaec96e7c6e89d8ff Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Thu, 15 Aug 2024 08:56:35 +0900 Subject: [PATCH 817/971] ksmbd: Use unsafe_memcpy() for ntlm_negotiate commit dfd046d0ced19b6ff5f11ec4ceab0a83de924771 upstream. rsp buffer is allocated larger than spnego_blob from smb2_allocate_rsp_buf(). Signed-off-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/smb/server/smb2pdu.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 185f7e0744f8..9edf84da099f 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -1380,7 +1380,8 @@ static int ntlm_negotiate(struct ksmbd_work *work, } sz = le16_to_cpu(rsp->SecurityBufferOffset); - memcpy((char *)&rsp->hdr.ProtocolId + sz, spnego_blob, spnego_blob_len); + unsafe_memcpy((char *)&rsp->hdr.ProtocolId + sz, spnego_blob, spnego_blob_len, + /* alloc is larger than blob, see smb2_allocate_rsp_buf() */); rsp->SecurityBufferLength = cpu_to_le16(spnego_blob_len); out: @@ -1463,7 +1464,9 @@ static int ntlm_authenticate(struct ksmbd_work *work, return -ENOMEM; sz = le16_to_cpu(rsp->SecurityBufferOffset); - memcpy((char *)&rsp->hdr.ProtocolId + sz, spnego_blob, spnego_blob_len); + unsafe_memcpy((char *)&rsp->hdr.ProtocolId + sz, spnego_blob, + spnego_blob_len, + /* alloc is larger than blob, see smb2_allocate_rsp_buf() */); rsp->SecurityBufferLength = cpu_to_le16(spnego_blob_len); kfree(spnego_blob); } From b90dc5d67b68b7346e7d2d40e0140c2b562135c1 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Mon, 23 Sep 2024 22:39:11 +0900 Subject: [PATCH 818/971] ksmbd: remove unsafe_memcpy use in session setup commit d782d6e1d9078d6b82f8468dd6421050165e7d75 upstream. Kees pointed out to just use directly ->Buffer instead of pointing ->Buffer using offset not to use unsafe_memcpy(). Suggested-by: Kees Cook Signed-off-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/smb/server/smb2pdu.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 9edf84da099f..6c22240368ab 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -1345,8 +1345,7 @@ static int ntlm_negotiate(struct ksmbd_work *work, return rc; sz = le16_to_cpu(rsp->SecurityBufferOffset); - chgblob = - (struct challenge_message *)((char *)&rsp->hdr.ProtocolId + sz); + chgblob = (struct challenge_message *)rsp->Buffer; memset(chgblob, 0, sizeof(struct challenge_message)); if (!work->conn->use_spnego) { @@ -1379,9 +1378,7 @@ static int ntlm_negotiate(struct ksmbd_work *work, goto out; } - sz = le16_to_cpu(rsp->SecurityBufferOffset); - unsafe_memcpy((char *)&rsp->hdr.ProtocolId + sz, spnego_blob, spnego_blob_len, - /* alloc is larger than blob, see smb2_allocate_rsp_buf() */); + memcpy(rsp->Buffer, spnego_blob, spnego_blob_len); rsp->SecurityBufferLength = cpu_to_le16(spnego_blob_len); out: @@ -1463,10 +1460,7 @@ static int ntlm_authenticate(struct ksmbd_work *work, if (rc) return -ENOMEM; - sz = le16_to_cpu(rsp->SecurityBufferOffset); - unsafe_memcpy((char *)&rsp->hdr.ProtocolId + sz, spnego_blob, - spnego_blob_len, - /* alloc is larger than blob, see smb2_allocate_rsp_buf() */); + memcpy(rsp->Buffer, spnego_blob, spnego_blob_len); rsp->SecurityBufferLength = cpu_to_le16(spnego_blob_len); kfree(spnego_blob); } From cca5bb42b7367717f7614e09c71343fb7167d80e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 24 Nov 2023 23:09:08 +0900 Subject: [PATCH 819/971] scripts: clean up IA-64 code commit 0df8e97085946dd79c06720678a845778b6d6bf8 upstream. A little more janitorial work after commit cf8e8658100d ("arch: Remove Itanium (IA-64) architecture"). Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier Signed-off-by: Chuck Lever Signed-off-by: Greg Kroah-Hartman --- scripts/checkstack.pl | 3 --- scripts/gdb/linux/tasks.py | 15 +++------------ scripts/head-object-list.txt | 1 - scripts/kconfig/mconf.c | 2 +- scripts/kconfig/nconf.c | 2 +- scripts/package/kernel.spec | 6 ------ scripts/package/mkdebian | 2 +- scripts/recordmcount.c | 1 - scripts/recordmcount.pl | 7 ------- scripts/xz_wrap.sh | 1 - 10 files changed, 6 insertions(+), 34 deletions(-) diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl index f27d552aec43..aad423c5181a 100755 --- a/scripts/checkstack.pl +++ b/scripts/checkstack.pl @@ -68,9 +68,6 @@ my (@stack, $re, $dre, $sub, $x, $xs, $funcre, $min_stack); # 2f60: 48 81 ec e8 05 00 00 sub $0x5e8,%rsp $re = qr/^.*[as][du][db] \$(0x$x{1,8}),\%(e|r)sp$/o; $dre = qr/^.*[as][du][db] (%.*),\%(e|r)sp$/o; - } elsif ($arch eq 'ia64') { - #e0000000044011fc: 01 0f fc 8c adds r12=-384,r12 - $re = qr/.*adds.*r12=-(([0-9]{2}|[3-9])[0-9]{2}),r12/o; } elsif ($arch eq 'm68k') { # 2b6c: 4e56 fb70 linkw %fp,#-1168 # 1df770: defc ffe4 addaw #-28,%sp diff --git a/scripts/gdb/linux/tasks.py b/scripts/gdb/linux/tasks.py index 17ec19e9b5bf..5be53b372a69 100644 --- a/scripts/gdb/linux/tasks.py +++ b/scripts/gdb/linux/tasks.py @@ -86,21 +86,12 @@ LxPs() thread_info_type = utils.CachedType("struct thread_info") -ia64_task_size = None - def get_thread_info(task): thread_info_ptr_type = thread_info_type.get_type().pointer() - if utils.is_target_arch("ia64"): - global ia64_task_size - if ia64_task_size is None: - ia64_task_size = gdb.parse_and_eval("sizeof(struct task_struct)") - thread_info_addr = task.address + ia64_task_size - thread_info = thread_info_addr.cast(thread_info_ptr_type) - else: - if task.type.fields()[0].type == thread_info_type.get_type(): - return task['thread_info'] - thread_info = task['stack'].cast(thread_info_ptr_type) + if task.type.fields()[0].type == thread_info_type.get_type(): + return task['thread_info'] + thread_info = task['stack'].cast(thread_info_ptr_type) return thread_info.dereference() diff --git a/scripts/head-object-list.txt b/scripts/head-object-list.txt index 26359968744e..890f69005bab 100644 --- a/scripts/head-object-list.txt +++ b/scripts/head-object-list.txt @@ -17,7 +17,6 @@ arch/arm/kernel/head-nommu.o arch/arm/kernel/head.o arch/csky/kernel/head.o arch/hexagon/kernel/head.o -arch/ia64/kernel/head.o arch/loongarch/kernel/head.o arch/m68k/68000/head.o arch/m68k/coldfire/head.o diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index eccc87a441e7..3795c36a9181 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -247,7 +247,7 @@ search_help[] = " -> PCI support (PCI [=y])\n" "(1) -> PCI access mode ( [=y])\n" " Defined at drivers/pci/Kconfig:47\n" - " Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" + " Depends on: X86_LOCAL_APIC && X86_IO_APIC\n" " Selects: LIBCRC32\n" " Selected by: BAR [=n]\n" "-----------------------------------------------------------------\n" diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 143a2c351d57..8cd72fe25974 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -216,7 +216,7 @@ search_help[] = "Symbol: FOO [ = m]\n" "Prompt: Foo bus is used to drive the bar HW\n" "Defined at drivers/pci/Kconfig:47\n" -"Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" +"Depends on: X86_LOCAL_APIC && X86_IO_APIC\n" "Location:\n" " -> Bus options (PCI, PCMCIA, EISA, ISA)\n" " -> PCI support (PCI [ = y])\n" diff --git a/scripts/package/kernel.spec b/scripts/package/kernel.spec index 3eee0143e0c5..89298983a169 100644 --- a/scripts/package/kernel.spec +++ b/scripts/package/kernel.spec @@ -56,13 +56,7 @@ patch -p1 < %{SOURCE2} %install mkdir -p %{buildroot}/boot -%ifarch ia64 -mkdir -p %{buildroot}/boot/efi -cp $(%{make} %{makeflags} -s image_name) %{buildroot}/boot/efi/vmlinuz-%{KERNELRELEASE} -ln -s efi/vmlinuz-%{KERNELRELEASE} %{buildroot}/boot/ -%else cp $(%{make} %{makeflags} -s image_name) %{buildroot}/boot/vmlinuz-%{KERNELRELEASE} -%endif %{make} %{makeflags} INSTALL_MOD_PATH=%{buildroot} modules_install %{make} %{makeflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install cp System.map %{buildroot}/boot/System.map-%{KERNELRELEASE} diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian index 5044224cf671..c1a36da85e84 100755 --- a/scripts/package/mkdebian +++ b/scripts/package/mkdebian @@ -26,7 +26,7 @@ set_debarch() { # Attempt to find the correct Debian architecture case "$UTS_MACHINE" in - i386|ia64|alpha|m68k|riscv*) + i386|alpha|m68k|riscv*) debarch="$UTS_MACHINE" ;; x86_64) debarch=amd64 ;; diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index 40ae6b2c7a6d..3e4f54799cc0 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -590,7 +590,6 @@ static int do_file(char const *const fname) ideal_nop = ideal_nop4_arm64; is_fake_mcount64 = arm64_is_fake_mcount; break; - case EM_IA_64: reltype = R_IA64_IMM64; break; case EM_MIPS: /* reltype: e_class */ break; case EM_LOONGARCH: /* reltype: e_class */ break; case EM_PPC: reltype = R_PPC_ADDR32; break; diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 6a4645a57976..f84df9e383fd 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -275,13 +275,6 @@ if ($arch eq "x86_64") { $section_type = '%progbits'; $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_AARCH64_CALL26\\s+_mcount\$"; $type = ".quad"; -} elsif ($arch eq "ia64") { - $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; - $type = "data8"; - - if ($is_module eq "0") { - $cc .= " -mconstant-gp"; - } } elsif ($arch eq "sparc64") { # In the objdump output there are giblets like: # 0000000000000000 : diff --git a/scripts/xz_wrap.sh b/scripts/xz_wrap.sh index 76e9cbcfbeab..d06baf626abe 100755 --- a/scripts/xz_wrap.sh +++ b/scripts/xz_wrap.sh @@ -15,7 +15,6 @@ LZMA2OPTS= case $SRCARCH in x86) BCJ=--x86 ;; powerpc) BCJ=--powerpc ;; - ia64) BCJ=--ia64; LZMA2OPTS=pb=4 ;; arm) BCJ=--arm ;; sparc) BCJ=--sparc ;; esac From f165d04c41a390c3a999d767302e6e385694897a Mon Sep 17 00:00:00 2001 From: Jose Ignacio Tornos Martinez Date: Mon, 29 Jan 2024 10:28:19 +0100 Subject: [PATCH 820/971] kbuild: rpm-pkg: simplify installkernel %post commit 358de8b4f201bc05712484b15f0109b1ae3516a8 upstream. The new installkernel application that is now included in systemd-udev package allows installation although destination files are already present in the boot directory of the kernel package, but is failing with the implemented workaround for the old installkernel application from grubby package. For the new installkernel application, as Davide says: <> But we need to keep the old behavior as well, because the old installkernel application from grubby package, does not allow this simplification and we need to be backward compatible to avoid issues with the different packages. Mimic Fedora shipping process and store vmlinuz, config amd System.map in the module directory instead of the boot directory. In this way, we will avoid the commented problem for all the cases, because the new destination files are not going to exist in the boot directory of the kernel package. Replace installkernel tool with kernel-install tool, because the latter is more complete. Besides, after installkernel tool execution, check to complete if the correct package files vmlinuz, System.map and config files are present in /boot directory, and if necessary, copy manually for install operation. In this way, take into account if files were not previously copied from /usr/lib/kernel/install.d/* scripts and if the suitable files for the requested package are present (it could be others if the rpm files were replace with a new pacakge with the same release and a different build). Tested with Fedora 38, Fedora 39, RHEL 9, Oracle Linux 9.3, openSUSE Tumbleweed and openMandrive ROME, using dnf/zypper and rpm tools. cc: stable@vger.kernel.org Co-Developed-by: Davide Cavalca Signed-off-by: Jose Ignacio Tornos Martinez Signed-off-by: Masahiro Yamada Signed-off-by: Chuck Lever Signed-off-by: Greg Kroah-Hartman --- scripts/package/kernel.spec | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/scripts/package/kernel.spec b/scripts/package/kernel.spec index 89298983a169..f58726671fb3 100644 --- a/scripts/package/kernel.spec +++ b/scripts/package/kernel.spec @@ -55,12 +55,12 @@ patch -p1 < %{SOURCE2} %{make} %{makeflags} KERNELRELEASE=%{KERNELRELEASE} KBUILD_BUILD_VERSION=%{release} %install -mkdir -p %{buildroot}/boot -cp $(%{make} %{makeflags} -s image_name) %{buildroot}/boot/vmlinuz-%{KERNELRELEASE} +mkdir -p %{buildroot}/lib/modules/%{KERNELRELEASE} +cp $(%{make} %{makeflags} -s image_name) %{buildroot}/lib/modules/%{KERNELRELEASE}/vmlinuz %{make} %{makeflags} INSTALL_MOD_PATH=%{buildroot} modules_install %{make} %{makeflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install -cp System.map %{buildroot}/boot/System.map-%{KERNELRELEASE} -cp .config %{buildroot}/boot/config-%{KERNELRELEASE} +cp System.map %{buildroot}/lib/modules/%{KERNELRELEASE} +cp .config %{buildroot}/lib/modules/%{KERNELRELEASE}/config ln -fns /usr/src/kernels/%{KERNELRELEASE} %{buildroot}/lib/modules/%{KERNELRELEASE}/build %if %{with_devel} %{make} %{makeflags} run-command KBUILD_RUN_COMMAND='${srctree}/scripts/package/install-extmod-build %{buildroot}/usr/src/kernels/%{KERNELRELEASE}' @@ -70,13 +70,14 @@ ln -fns /usr/src/kernels/%{KERNELRELEASE} %{buildroot}/lib/modules/%{KERNELRELEA rm -rf %{buildroot} %post -if [ -x /sbin/installkernel -a -r /boot/vmlinuz-%{KERNELRELEASE} -a -r /boot/System.map-%{KERNELRELEASE} ]; then -cp /boot/vmlinuz-%{KERNELRELEASE} /boot/.vmlinuz-%{KERNELRELEASE}-rpm -cp /boot/System.map-%{KERNELRELEASE} /boot/.System.map-%{KERNELRELEASE}-rpm -rm -f /boot/vmlinuz-%{KERNELRELEASE} /boot/System.map-%{KERNELRELEASE} -/sbin/installkernel %{KERNELRELEASE} /boot/.vmlinuz-%{KERNELRELEASE}-rpm /boot/.System.map-%{KERNELRELEASE}-rpm -rm -f /boot/.vmlinuz-%{KERNELRELEASE}-rpm /boot/.System.map-%{KERNELRELEASE}-rpm +if [ -x /usr/bin/kernel-install ]; then + /usr/bin/kernel-install add %{KERNELRELEASE} /lib/modules/%{KERNELRELEASE}/vmlinuz fi +for file in vmlinuz System.map config; do + if ! cmp --silent "/lib/modules/%{KERNELRELEASE}/${file}" "/boot/${file}-%{KERNELRELEASE}"; then + cp "/lib/modules/%{KERNELRELEASE}/${file}" "/boot/${file}-%{KERNELRELEASE}" + fi +done %preun if [ -x /sbin/new-kernel-pkg ]; then @@ -94,7 +95,6 @@ fi %defattr (-, root, root) /lib/modules/%{KERNELRELEASE} %exclude /lib/modules/%{KERNELRELEASE}/build -/boot/* %files headers %defattr (-, root, root) From 56aa7679c9f3673bef25c4c18f5af8f138c0d243 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Mon, 24 Feb 2025 10:34:55 +0000 Subject: [PATCH 821/971] media: uvcvideo: Rollback non processed entities on error commit a70705d3c020d0d5c3ab6a5cc93e011ac35e7d48 upstream. If we fail to commit an entity, we need to restore the UVC_CTRL_DATA_BACKUP for the other uncommitted entities. Otherwise the control cache and the device would be out of sync. Cc: stable@kernel.org Fixes: b4012002f3a3 ("[media] uvcvideo: Add support for control events") Reported-by: Hans de Goede Closes: https://lore.kernel.org/linux-media/fe845e04-9fde-46ee-9763-a6f00867929a@redhat.com/ Signed-off-by: Ricardo Ribalda Message-ID: <20250224-uvc-data-backup-v2-3-de993ed9823b@chromium.org> Signed-off-by: Hans de Goede Signed-off-by: Hans Verkuil Signed-off-by: Ricardo Ribalda Signed-off-by: Greg Kroah-Hartman --- drivers/media/usb/uvc/uvc_ctrl.c | 41 +++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 59e21746f550..bd90d8bacd5e 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -1801,7 +1801,7 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, unsigned int processed_ctrls = 0; struct uvc_control *ctrl; unsigned int i; - int ret; + int ret = 0; if (entity == NULL) return 0; @@ -1830,8 +1830,6 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, dev->intfnum, ctrl->info.selector, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), ctrl->info.size); - else - ret = 0; if (!ret) processed_ctrls++; @@ -1843,17 +1841,25 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, ctrl->dirty = 0; - if (ret < 0) { - if (err_ctrl) - *err_ctrl = ctrl; - return ret; - } - if (!rollback && handle && ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) uvc_ctrl_set_handle(handle, ctrl, handle); + + if (ret < 0 && !rollback) { + if (err_ctrl) + *err_ctrl = ctrl; + /* + * If we fail to set a control, we need to rollback + * the next ones. + */ + rollback = 1; + } + } + if (ret) + return ret; + return processed_ctrls; } @@ -1884,7 +1890,8 @@ int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback, struct uvc_video_chain *chain = handle->chain; struct uvc_control *err_ctrl; struct uvc_entity *entity; - int ret = 0; + int ret_out = 0; + int ret; /* Find the control. */ list_for_each_entry(entity, &chain->entities, chain) { @@ -1895,17 +1902,23 @@ int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback, ctrls->error_idx = uvc_ctrl_find_ctrl_idx(entity, ctrls, err_ctrl); - goto done; + /* + * When we fail to commit an entity, we need to + * restore the UVC_CTRL_DATA_BACKUP for all the + * controls in the other entities, otherwise our cache + * and the hardware will be out of sync. + */ + rollback = 1; + + ret_out = ret; } else if (ret > 0 && !rollback) { uvc_ctrl_send_events(handle, entity, ctrls->controls, ctrls->count); } } - ret = 0; -done: mutex_unlock(&chain->ctrl_mutex); - return ret; + return ret_out; } int uvc_ctrl_get(struct uvc_video_chain *chain, From 5f4787834cb7cd8c625e46f798ed059f5a5f3712 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 24 Apr 2025 17:07:01 +0200 Subject: [PATCH 822/971] s390/entry: Fix last breaking event handling in case of stack corruption commit ae952eea6f4a7e2193f8721a5366049946e012e7 upstream. In case of stack corruption stack_invalid() is called and the expectation is that register r10 contains the last breaking event address. This dependency is quite subtle and broke a couple of years ago without that anybody noticed. Fix this by getting rid of the dependency and read the last breaking event address from lowcore. Fixes: 56e62a737028 ("s390: convert to generic entry") Acked-by: Ilya Leoshkevich Reviewed-by: Alexander Gordeev Signed-off-by: Heiko Carstens Signed-off-by: Greg Kroah-Hartman --- arch/s390/kernel/entry.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index ebad8c8b8c57..0476ce7700df 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -639,7 +639,7 @@ SYM_CODE_START(stack_overflow) stmg %r0,%r7,__PT_R0(%r11) stmg %r8,%r9,__PT_PSW(%r11) mvc __PT_R8(64,%r11),0(%r14) - stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2 + mvc __PT_ORIG_GPR2(8,%r11),__LC_PGM_LAST_BREAK xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) lgr %r2,%r11 # pass pointer to pt_regs jg kernel_stack_overflow From ed1f395ea5c05053dc253f0f74b6e6b5c97e3bba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Gonz=C3=A1lez=20Collado?= Date: Sun, 2 Mar 2025 23:15:18 +0100 Subject: [PATCH 823/971] Kunit to check the longest symbol length MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit c104c16073b7fdb3e4eae18f66f4009f6b073d6f upstream. The longest length of a symbol (KSYM_NAME_LEN) was increased to 512 in the reference [1]. This patch adds kunit test suite to check the longest symbol length. These tests verify that the longest symbol length defined is supported. This test can also help other efforts for longer symbol length, like [2]. The test suite defines one symbol with the longest possible length. The first test verify that functions with names of the created symbol, can be called or not. The second test, verify that the symbols are created (or not) in the kernel symbol table. [1] https://lore.kernel.org/lkml/20220802015052.10452-6-ojeda@kernel.org/ [2] https://lore.kernel.org/lkml/20240605032120.3179157-1-song@kernel.org/ Link: https://lore.kernel.org/r/20250302221518.76874-1-sergio.collado@gmail.com Tested-by: Martin Rodriguez Reboredo Reviewed-by: Shuah Khan Reviewed-by: Rae Moar Signed-off-by: Sergio González Collado Link: https://github.com/Rust-for-Linux/linux/issues/504 Reviewed-by: Rae Moar Acked-by: David Gow Signed-off-by: Shuah Khan Signed-off-by: Shuah Khan Signed-off-by: Greg Kroah-Hartman --- arch/x86/tools/insn_decoder_test.c | 3 +- lib/Kconfig.debug | 9 ++++ lib/Makefile | 2 + lib/longest_symbol_kunit.c | 82 ++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 lib/longest_symbol_kunit.c diff --git a/arch/x86/tools/insn_decoder_test.c b/arch/x86/tools/insn_decoder_test.c index 472540aeabc2..6c2986d2ad11 100644 --- a/arch/x86/tools/insn_decoder_test.c +++ b/arch/x86/tools/insn_decoder_test.c @@ -10,6 +10,7 @@ #include #include #include +#include #define unlikely(cond) (cond) @@ -106,7 +107,7 @@ static void parse_args(int argc, char **argv) } } -#define BUFSIZE 256 +#define BUFSIZE (256 + KSYM_NAME_LEN) int main(int argc, char **argv) { diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index e809b6d8bc53..1aae81c57b2c 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -2747,6 +2747,15 @@ config FORTIFY_KUNIT_TEST by the str*() and mem*() family of functions. For testing runtime traps of FORTIFY_SOURCE, see LKDTM's "FORTIFY_*" tests. +config LONGEST_SYM_KUNIT_TEST + tristate "Test the longest symbol possible" if !KUNIT_ALL_TESTS + depends on KUNIT && KPROBES + default KUNIT_ALL_TESTS + help + Tests the longest symbol possible + + If unsure, say N. + config HW_BREAKPOINT_KUNIT_TEST bool "Test hw_breakpoint constraints accounting" if !KUNIT_ALL_TESTS depends on HAVE_HW_BREAKPOINT diff --git a/lib/Makefile b/lib/Makefile index 740109b6e2c8..b9d2577fbbe1 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -402,6 +402,8 @@ obj-$(CONFIG_FORTIFY_KUNIT_TEST) += fortify_kunit.o obj-$(CONFIG_STRCAT_KUNIT_TEST) += strcat_kunit.o obj-$(CONFIG_STRSCPY_KUNIT_TEST) += strscpy_kunit.o obj-$(CONFIG_SIPHASH_KUNIT_TEST) += siphash_kunit.o +obj-$(CONFIG_LONGEST_SYM_KUNIT_TEST) += longest_symbol_kunit.o +CFLAGS_longest_symbol_kunit.o += $(call cc-disable-warning, missing-prototypes) obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) += devmem_is_allowed.o diff --git a/lib/longest_symbol_kunit.c b/lib/longest_symbol_kunit.c new file mode 100644 index 000000000000..2fea82a6d34e --- /dev/null +++ b/lib/longest_symbol_kunit.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Test the longest symbol length. Execute with: + * ./tools/testing/kunit/kunit.py run longest-symbol + * --arch=x86_64 --kconfig_add CONFIG_KPROBES=y --kconfig_add CONFIG_MODULES=y + * --kconfig_add CONFIG_RETPOLINE=n --kconfig_add CONFIG_CFI_CLANG=n + * --kconfig_add CONFIG_MITIGATION_RETPOLINE=n + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include + +#define DI(name) s##name##name +#define DDI(name) DI(n##name##name) +#define DDDI(name) DDI(n##name##name) +#define DDDDI(name) DDDI(n##name##name) +#define DDDDDI(name) DDDDI(n##name##name) + +/*Generate a symbol whose name length is 511 */ +#define LONGEST_SYM_NAME DDDDDI(g1h2i3j4k5l6m7n) + +#define RETURN_LONGEST_SYM 0xAAAAA + +noinline int LONGEST_SYM_NAME(void); +noinline int LONGEST_SYM_NAME(void) +{ + return RETURN_LONGEST_SYM; +} + +_Static_assert(sizeof(__stringify(LONGEST_SYM_NAME)) == KSYM_NAME_LEN, +"Incorrect symbol length found. Expected KSYM_NAME_LEN: " +__stringify(KSYM_NAME_LEN) ", but found: " +__stringify(sizeof(LONGEST_SYM_NAME))); + +static void test_longest_symbol(struct kunit *test) +{ + KUNIT_EXPECT_EQ(test, RETURN_LONGEST_SYM, LONGEST_SYM_NAME()); +}; + +static void test_longest_symbol_kallsyms(struct kunit *test) +{ + unsigned long (*kallsyms_lookup_name)(const char *name); + static int (*longest_sym)(void); + + struct kprobe kp = { + .symbol_name = "kallsyms_lookup_name", + }; + + if (register_kprobe(&kp) < 0) { + pr_info("%s: kprobe not registered", __func__); + KUNIT_FAIL(test, "test_longest_symbol kallsyms: kprobe not registered\n"); + return; + } + + kunit_warn(test, "test_longest_symbol kallsyms: kprobe registered\n"); + kallsyms_lookup_name = (unsigned long (*)(const char *name))kp.addr; + unregister_kprobe(&kp); + + longest_sym = + (void *) kallsyms_lookup_name(__stringify(LONGEST_SYM_NAME)); + KUNIT_EXPECT_EQ(test, RETURN_LONGEST_SYM, longest_sym()); +}; + +static struct kunit_case longest_symbol_test_cases[] = { + KUNIT_CASE(test_longest_symbol), + KUNIT_CASE(test_longest_symbol_kallsyms), + {} +}; + +static struct kunit_suite longest_symbol_test_suite = { + .name = "longest-symbol", + .test_cases = longest_symbol_test_cases, +}; +kunit_test_suite(longest_symbol_test_suite); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Test the longest symbol length"); +MODULE_AUTHOR("Sergio González Collado"); From 1583d908cc7748e026a3984dd4cbbb6adfe64c05 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 18 Mar 2025 15:32:30 -0700 Subject: [PATCH 824/971] x86/tools: Drop duplicate unlikely() definition in insn_decoder_test.c commit f710202b2a45addea3dcdcd862770ecbaf6597ef upstream. After commit c104c16073b7 ("Kunit to check the longest symbol length"), there is a warning when building with clang because there is now a definition of unlikely from compiler.h in tools/include/linux, which conflicts with the one in the instruction decoder selftest: arch/x86/tools/insn_decoder_test.c:15:9: warning: 'unlikely' macro redefined [-Wmacro-redefined] Remove the second unlikely() definition, as it is no longer necessary, clearing up the warning. Fixes: c104c16073b7 ("Kunit to check the longest symbol length") Signed-off-by: Nathan Chancellor Signed-off-by: Ingo Molnar Acked-by: Shuah Khan Link: https://lore.kernel.org/r/20250318-x86-decoder-test-fix-unlikely-redef-v1-1-74c84a7bf05b@kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/x86/tools/insn_decoder_test.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/x86/tools/insn_decoder_test.c b/arch/x86/tools/insn_decoder_test.c index 6c2986d2ad11..08cd913cbd4e 100644 --- a/arch/x86/tools/insn_decoder_test.c +++ b/arch/x86/tools/insn_decoder_test.c @@ -12,8 +12,6 @@ #include #include -#define unlikely(cond) (cond) - #include #include #include From c46358d0275953b27c3d86f7a224e229f2d57d05 Mon Sep 17 00:00:00 2001 From: "Brett A C Sheffield (Librecast)" Date: Wed, 2 Jul 2025 13:37:32 +0200 Subject: [PATCH 825/971] Revert "ipv6: save dontfrag in cork" This reverts commit 8ebf2709fe4dcd0a1b7b95bf61e529ddcd3cdf51 which is commit a18dfa9925b9ef6107ea3aa5814ca3c704d34a8a upstream. A regression was introduced when backporting this to the stable kernels without applying previous commits in this series. When sending IPv6 UDP packets larger than MTU, EMSGSIZE was returned instead of fragmenting the packets as expected. As there is no compelling reason for this commit to be present in the stable kernels it should be reverted. Signed-off-by: Brett A C Sheffield Signed-off-by: Greg Kroah-Hartman --- include/linux/ipv6.h | 1 - net/ipv6/ip6_output.c | 9 ++++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index d79851c5fabd..af8a771a053c 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -199,7 +199,6 @@ struct inet6_cork { struct ipv6_txoptions *opt; u8 hop_limit; u8 tclass; - u8 dontfrag:1; }; /* struct ipv6_pinfo - ipv6 private area */ diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 28777b142240..c86d5dca29df 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1452,7 +1452,6 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork, } v6_cork->hop_limit = ipc6->hlimit; v6_cork->tclass = ipc6->tclass; - v6_cork->dontfrag = ipc6->dontfrag; if (rt->dst.flags & DST_XFRM_TUNNEL) mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ? READ_ONCE(rt->dst.dev->mtu) : dst_mtu(&rt->dst); @@ -1486,7 +1485,7 @@ static int __ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), void *from, size_t length, int transhdrlen, - unsigned int flags) + unsigned int flags, struct ipcm6_cookie *ipc6) { struct sk_buff *skb, *skb_prev = NULL; struct inet_cork *cork = &cork_full->base; @@ -1542,7 +1541,7 @@ static int __ip6_append_data(struct sock *sk, if (headersize + transhdrlen > mtu) goto emsgsize; - if (cork->length + length > mtu - headersize && v6_cork->dontfrag && + if (cork->length + length > mtu - headersize && ipc6->dontfrag && (sk->sk_protocol == IPPROTO_UDP || sk->sk_protocol == IPPROTO_ICMPV6 || sk->sk_protocol == IPPROTO_RAW)) { @@ -1914,7 +1913,7 @@ int ip6_append_data(struct sock *sk, return __ip6_append_data(sk, &sk->sk_write_queue, &inet->cork, &np->cork, sk_page_frag(sk), getfrag, - from, length, transhdrlen, flags); + from, length, transhdrlen, flags, ipc6); } EXPORT_SYMBOL_GPL(ip6_append_data); @@ -2119,7 +2118,7 @@ struct sk_buff *ip6_make_skb(struct sock *sk, err = __ip6_append_data(sk, &queue, cork, &v6_cork, ¤t->task_frag, getfrag, from, length + exthdrlen, transhdrlen + exthdrlen, - flags); + flags, ipc6); if (err) { __ip6_flush_pending_frames(sk, &queue, cork, &v6_cork); return ERR_PTR(err); From cdfb20e4b34ad99b3fe122aafb4f8ee7b9856e1f Mon Sep 17 00:00:00 2001 From: Khairul Anuar Romli Date: Mon, 16 Jun 2025 09:13:53 +0800 Subject: [PATCH 826/971] spi: spi-cadence-quadspi: Fix pm runtime unbalance commit b07f349d1864abe29436f45e3047da2bdd476462 upstream. Having PM put sync in remove function is causing PM underflow during remove operation. This is caused by the function, runtime_pm_get_sync, not being called anywhere during the op. Ensure that calls to pm_runtime_enable()/pm_runtime_disable() and pm_runtime_get_sync()/pm_runtime_put_sync() match. echo 108d2000.spi > /sys/bus/platform/drivers/cadence-qspi/unbind [ 49.644256] Deleting MTD partitions on "108d2000.spi.0": [ 49.649575] Deleting u-boot MTD partition [ 49.684087] Deleting root MTD partition [ 49.724188] cadence-qspi 108d2000.spi: Runtime PM usage count underflow! Continuous bind/unbind will result in an "Unbalanced pm_runtime_enable" error. Subsequent unbind attempts will return a "No such device" error, while bind attempts will return a "Resource temporarily unavailable" error. [ 47.592434] cadence-qspi 108d2000.spi: Runtime PM usage count underflow! [ 49.592233] cadence-qspi 108d2000.spi: detected FIFO depth (1024) different from config (128) [ 53.232309] cadence-qspi 108d2000.spi: Runtime PM usage count underflow! [ 55.828550] cadence-qspi 108d2000.spi: detected FIFO depth (1024) different from config (128) [ 57.940627] cadence-qspi 108d2000.spi: Runtime PM usage count underflow! [ 59.912490] cadence-qspi 108d2000.spi: detected FIFO depth (1024) different from config (128) [ 61.876243] cadence-qspi 108d2000.spi: Runtime PM usage count underflow! [ 61.883000] platform 108d2000.spi: Unbalanced pm_runtime_enable! [ 532.012270] cadence-qspi 108d2000.spi: probe with driver cadence-qspi failed1 Also, change clk_disable_unprepare() to clk_disable() since continuous bind and unbind operations will trigger a warning indicating that the clock is already unprepared. Fixes: 4892b374c9b7 ("mtd: spi-nor: cadence-quadspi: Add runtime PM support") cc: stable@vger.kernel.org # 6.6+ Signed-off-by: Khairul Anuar Romli Reviewed-by: Matthew Gerlach Link: https://patch.msgid.link/4e7a4b8aba300e629b45a04f90bddf665fbdb335.1749601877.git.khairul.anuar.romli@altera.com Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/spi/spi-cadence-quadspi.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index bf9b816637d0..9285a683324f 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -1868,6 +1868,13 @@ static int cqspi_probe(struct platform_device *pdev) goto probe_setup_failed; } + pm_runtime_enable(dev); + + if (cqspi->rx_chan) { + dma_release_channel(cqspi->rx_chan); + goto probe_setup_failed; + } + ret = spi_register_controller(host); if (ret) { dev_err(&pdev->dev, "failed to register SPI ctlr %d\n", ret); @@ -1877,6 +1884,7 @@ static int cqspi_probe(struct platform_device *pdev) return 0; probe_setup_failed: cqspi_controller_enable(cqspi, 0); + pm_runtime_disable(dev); probe_reset_failed: if (cqspi->is_jh7110) cqspi_jh7110_disable_clk(pdev, cqspi); @@ -1898,7 +1906,8 @@ static void cqspi_remove(struct platform_device *pdev) if (cqspi->rx_chan) dma_release_channel(cqspi->rx_chan); - clk_disable_unprepare(cqspi->clk); + if (pm_runtime_get_sync(&pdev->dev) >= 0) + clk_disable(cqspi->clk); if (cqspi->is_jh7110) cqspi_jh7110_disable_clk(pdev, cqspi); From 6f27bbf3de0d26090c298a58fcd9bb99f941ea07 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 13 Jun 2025 13:37:41 -0600 Subject: [PATCH 827/971] nvme: always punt polled uring_cmd end_io work to task_work Commit 9ce6c9875f3e995be5fd720b65835291f8a609b1 upstream. Currently NVMe uring_cmd completions will complete locally, if they are polled. This is done because those completions are always invoked from task context. And while that is true, there's no guarantee that it's invoked under the right ring context, or even task. If someone does NVMe passthrough via multiple threads and with a limited number of poll queues, then ringA may find completions from ringB. For that case, completing the request may not be sound. Always just punt the passthrough completions via task_work, which will redirect the completion, if needed. Cc: stable@vger.kernel.org Fixes: 585079b6e425 ("nvme: wire up async polling for io passthrough commands") Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- drivers/nvme/host/ioctl.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c index 4ce31f9f0694..5cf050e562b7 100644 --- a/drivers/nvme/host/ioctl.c +++ b/drivers/nvme/host/ioctl.c @@ -526,16 +526,14 @@ static enum rq_end_io_ret nvme_uring_cmd_end_io(struct request *req, pdu->u.result = le64_to_cpu(nvme_req(req)->result.u64); /* - * For iopoll, complete it directly. - * Otherwise, move the completion to task work. + * IOPOLL could potentially complete this request directly, but + * if multiple rings are polling on the same queue, then it's possible + * for one ring to find completions for another ring. Punting the + * completion via task_work will always direct it to the right + * location, rather than potentially complete requests for ringA + * under iopoll invocations from ringB. */ - if (blk_rq_is_poll(req)) { - WRITE_ONCE(ioucmd->cookie, NULL); - nvme_uring_task_cb(ioucmd, IO_URING_F_UNLOCKED); - } else { - io_uring_cmd_do_in_task_lazy(ioucmd, nvme_uring_task_cb); - } - + io_uring_cmd_do_in_task_lazy(ioucmd, nvme_uring_task_cb); return RQ_END_IO_FREE; } From 67a50f5721787f3372085634a028311f8cd83713 Mon Sep 17 00:00:00 2001 From: Cristian Marussi Date: Mon, 12 Feb 2024 12:32:24 +0000 Subject: [PATCH 828/971] firmware: arm_scmi: Add a common helper to check if a message is supported commit 637b6d6cae9c42db5a9525da67c991294924d2cd upstream. A common helper is provided to check if a specific protocol message is supported or not. Signed-off-by: Cristian Marussi Link: https://lore.kernel.org/r/20240212123233.1230090-3-cristian.marussi@arm.com Signed-off-by: Sudeep Holla Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/arm_scmi/driver.c | 34 +++++++++++++++++++++++++++ drivers/firmware/arm_scmi/protocols.h | 4 ++++ 2 files changed, 38 insertions(+) diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 65d1e66a347d..24babf87adb9 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -1820,10 +1820,44 @@ static void scmi_common_fastchannel_db_ring(struct scmi_fc_db_info *db) #endif } +/** + * scmi_protocol_msg_check - Check protocol message attributes + * + * @ph: A reference to the protocol handle. + * @message_id: The ID of the message to check. + * @attributes: A parameter to optionally return the retrieved message + * attributes, in case of Success. + * + * An helper to check protocol message attributes for a specific protocol + * and message pair. + * + * Return: 0 on SUCCESS + */ +static int scmi_protocol_msg_check(const struct scmi_protocol_handle *ph, + u32 message_id, u32 *attributes) +{ + int ret; + struct scmi_xfer *t; + + ret = xfer_get_init(ph, PROTOCOL_MESSAGE_ATTRIBUTES, + sizeof(__le32), 0, &t); + if (ret) + return ret; + + put_unaligned_le32(message_id, t->tx.buf); + ret = do_xfer(ph, t); + if (!ret && attributes) + *attributes = get_unaligned_le32(t->rx.buf); + xfer_put(ph, t); + + return ret; +} + static const struct scmi_proto_helpers_ops helpers_ops = { .extended_name_get = scmi_common_extended_name_get, .iter_response_init = scmi_iterator_init, .iter_response_run = scmi_iterator_run, + .protocol_msg_check = scmi_protocol_msg_check, .fastchannel_init = scmi_common_fastchannel_init, .fastchannel_db_ring = scmi_common_fastchannel_db_ring, }; diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_scmi/protocols.h index 78e1a01eb656..9fc2f1e293d4 100644 --- a/drivers/firmware/arm_scmi/protocols.h +++ b/drivers/firmware/arm_scmi/protocols.h @@ -250,6 +250,8 @@ struct scmi_fc_info { * provided in @ops. * @iter_response_run: A common helper to trigger the run of a previously * initialized iterator. + * @protocol_msg_check: A common helper to check is a specific protocol message + * is supported. * @fastchannel_init: A common helper used to initialize FC descriptors by * gathering FC descriptions from the SCMI platform server. * @fastchannel_db_ring: A common helper to ring a FC doorbell. @@ -262,6 +264,8 @@ struct scmi_proto_helpers_ops { unsigned int max_resources, u8 msg_id, size_t tx_size, void *priv); int (*iter_response_run)(void *iter); + int (*protocol_msg_check)(const struct scmi_protocol_handle *ph, + u32 message_id, u32 *attributes); void (*fastchannel_init)(const struct scmi_protocol_handle *ph, u8 describe_id, u32 message_id, u32 valid_size, u32 domain, From f9917821c527d7d1321b41aa4b4e3acdd8651946 Mon Sep 17 00:00:00 2001 From: Sibi Sankar Date: Tue, 29 Apr 2025 15:11:06 +0100 Subject: [PATCH 829/971] firmware: arm_scmi: Ensure that the message-id supports fastchannel commit 94a263f981a3fa3d93f65c31e0fed0756736be43 upstream. Currently the perf and powercap protocol relies on the protocol domain attributes, which just ensures that one fastchannel per domain, before instantiating fastchannels for all possible message-ids. Fix this by ensuring that each message-id supports fastchannel before initialization. Logs: | scmi: Failed to get FC for protocol 13 [MSG_ID:6 / RES_ID:0] - ret:-95. Using regular messaging | scmi: Failed to get FC for protocol 13 [MSG_ID:6 / RES_ID:1] - ret:-95. Using regular messaging | scmi: Failed to get FC for protocol 13 [MSG_ID:6 / RES_ID:2] - ret:-95. Using regular messaging CC: stable@vger.kernel.org Reported-by: Johan Hovold Closes: https://lore.kernel.org/lkml/ZoQjAWse2YxwyRJv@hovoldconsulting.com/ Fixes: 6f9ea4dabd2d ("firmware: arm_scmi: Generalize the fast channel support") Reviewed-by: Johan Hovold Tested-by: Johan Hovold Signed-off-by: Sibi Sankar [Cristian: Modified the condition checked to establish support or not] Signed-off-by: Cristian Marussi Message-Id: <20250429141108.406045-2-cristian.marussi@arm.com> Signed-off-by: Sudeep Holla Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/arm_scmi/driver.c | 76 +++++++++++++++------------ drivers/firmware/arm_scmi/protocols.h | 2 + 2 files changed, 45 insertions(+), 33 deletions(-) diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 24babf87adb9..d1fd2e492909 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -1547,6 +1547,39 @@ out: return ret; } +/** + * scmi_protocol_msg_check - Check protocol message attributes + * + * @ph: A reference to the protocol handle. + * @message_id: The ID of the message to check. + * @attributes: A parameter to optionally return the retrieved message + * attributes, in case of Success. + * + * An helper to check protocol message attributes for a specific protocol + * and message pair. + * + * Return: 0 on SUCCESS + */ +static int scmi_protocol_msg_check(const struct scmi_protocol_handle *ph, + u32 message_id, u32 *attributes) +{ + int ret; + struct scmi_xfer *t; + + ret = xfer_get_init(ph, PROTOCOL_MESSAGE_ATTRIBUTES, + sizeof(__le32), 0, &t); + if (ret) + return ret; + + put_unaligned_le32(message_id, t->tx.buf); + ret = do_xfer(ph, t); + if (!ret && attributes) + *attributes = get_unaligned_le32(t->rx.buf); + xfer_put(ph, t); + + return ret; +} + /** * struct scmi_iterator - Iterator descriptor * @msg: A reference to the message TX buffer; filled by @prepare_message with @@ -1688,6 +1721,7 @@ scmi_common_fastchannel_init(const struct scmi_protocol_handle *ph, int ret; u32 flags; u64 phys_addr; + u32 attributes; u8 size; void __iomem *addr; struct scmi_xfer *t; @@ -1696,6 +1730,15 @@ scmi_common_fastchannel_init(const struct scmi_protocol_handle *ph, struct scmi_msg_resp_desc_fc *resp; const struct scmi_protocol_instance *pi = ph_to_pi(ph); + /* Check if the MSG_ID supports fastchannel */ + ret = scmi_protocol_msg_check(ph, message_id, &attributes); + if (ret || !MSG_SUPPORTS_FASTCHANNEL(attributes)) { + dev_dbg(ph->dev, + "Skip FC init for 0x%02X/%d domain:%d - ret:%d\n", + pi->proto->id, message_id, domain, ret); + return; + } + if (!p_addr) { ret = -EINVAL; goto err_out; @@ -1820,39 +1863,6 @@ static void scmi_common_fastchannel_db_ring(struct scmi_fc_db_info *db) #endif } -/** - * scmi_protocol_msg_check - Check protocol message attributes - * - * @ph: A reference to the protocol handle. - * @message_id: The ID of the message to check. - * @attributes: A parameter to optionally return the retrieved message - * attributes, in case of Success. - * - * An helper to check protocol message attributes for a specific protocol - * and message pair. - * - * Return: 0 on SUCCESS - */ -static int scmi_protocol_msg_check(const struct scmi_protocol_handle *ph, - u32 message_id, u32 *attributes) -{ - int ret; - struct scmi_xfer *t; - - ret = xfer_get_init(ph, PROTOCOL_MESSAGE_ATTRIBUTES, - sizeof(__le32), 0, &t); - if (ret) - return ret; - - put_unaligned_le32(message_id, t->tx.buf); - ret = do_xfer(ph, t); - if (!ret && attributes) - *attributes = get_unaligned_le32(t->rx.buf); - xfer_put(ph, t); - - return ret; -} - static const struct scmi_proto_helpers_ops helpers_ops = { .extended_name_get = scmi_common_extended_name_get, .iter_response_init = scmi_iterator_init, diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_scmi/protocols.h index 9fc2f1e293d4..095b14a2d0a3 100644 --- a/drivers/firmware/arm_scmi/protocols.h +++ b/drivers/firmware/arm_scmi/protocols.h @@ -29,6 +29,8 @@ #define PROTOCOL_REV_MAJOR(x) ((u16)(FIELD_GET(PROTOCOL_REV_MAJOR_MASK, (x)))) #define PROTOCOL_REV_MINOR(x) ((u16)(FIELD_GET(PROTOCOL_REV_MINOR_MASK, (x)))) +#define MSG_SUPPORTS_FASTCHANNEL(x) ((x) & BIT(0)) + enum scmi_common_cmd { PROTOCOL_VERSION = 0x0, PROTOCOL_ATTRIBUTES = 0x1, From 18d3f9b8e4b99bc7d7c0da6f792cb0cae3cc7a93 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 26 Feb 2024 12:25:01 +0100 Subject: [PATCH 830/971] ARM: 9354/1: ptrace: Use bitfield helpers commit b36e78b216e632d90138751e4ff80044de303656 upstream. The isa_mode() macro extracts two fields, and recombines them into a single value. Make this more obvious by using the FIELD_GET() helper, and shifting the result into its final resting place. Signed-off-by: Geert Uytterhoeven Reviewed-by: Oleg Nesterov Signed-off-by: Russell King (Oracle) Signed-off-by: Greg Kroah-Hartman --- arch/arm/include/asm/ptrace.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index 7f44e88d1f25..14a38cc67e0b 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h @@ -10,6 +10,7 @@ #include #ifndef __ASSEMBLY__ +#include #include struct pt_regs { @@ -35,8 +36,8 @@ struct svc_pt_regs { #ifndef CONFIG_CPU_V7M #define isa_mode(regs) \ - ((((regs)->ARM_cpsr & PSR_J_BIT) >> (__ffs(PSR_J_BIT) - 1)) | \ - (((regs)->ARM_cpsr & PSR_T_BIT) >> (__ffs(PSR_T_BIT)))) + (FIELD_GET(PSR_J_BIT, (regs)->ARM_cpsr) << 1 | \ + FIELD_GET(PSR_T_BIT, (regs)->ARM_cpsr)) #else #define isa_mode(regs) 1 /* Thumb */ #endif From a5df3a702b2cba82bcfb066fa9f5e4a349c33924 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 6 Jul 2025 11:00:17 +0200 Subject: [PATCH 831/971] Linux 6.6.96 Link: https://lore.kernel.org/r/20250703143941.182414597@linuxfoundation.org Tested-by: Florian Fainelli Tested-by: Hardik Garg Tested-by: Shuah Khan Tested-by: Ron Economos Tested-by: Jon Hunter Tested-by: Mark Brown Tested-by: Miguel Ojeda Tested-by: Peter Schneider Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 679dff5e165c..038fc8e0982b 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 6 PATCHLEVEL = 6 -SUBLEVEL = 95 +SUBLEVEL = 96 EXTRAVERSION = NAME = Pinguïn Aangedreven From 3925dd0a8c63f973352f5eba0f90f62754bc5f93 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 9 Jul 2025 09:52:18 +0000 Subject: [PATCH 832/971] Revert "firmware: arm_scmi: Add a common helper to check if a message is supported" This reverts commit 67a50f5721787f3372085634a028311f8cd83713 which is commit 637b6d6cae9c42db5a9525da67c991294924d2cd upstream. It breaks the Android kernel abi and can be brought back in the future in an abi-safe way if it is really needed. Bug: 161946584 Change-Id: I82ce5a24c8c9d1459b6222c30c330b393340fdbe Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/arm_scmi/driver.c | 1 - drivers/firmware/arm_scmi/protocols.h | 4 ---- 2 files changed, 5 deletions(-) diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 2f67c3c7a046..bae9a2fb234b 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -1892,7 +1892,6 @@ static const struct scmi_proto_helpers_ops helpers_ops = { .get_max_msg_size = scmi_common_get_max_msg_size, .iter_response_init = scmi_iterator_init, .iter_response_run = scmi_iterator_run, - .protocol_msg_check = scmi_protocol_msg_check, .fastchannel_init = scmi_common_fastchannel_init, .fastchannel_db_ring = scmi_common_fastchannel_db_ring, }; diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_scmi/protocols.h index 259b4625fb23..26e24eca2d19 100644 --- a/drivers/firmware/arm_scmi/protocols.h +++ b/drivers/firmware/arm_scmi/protocols.h @@ -253,8 +253,6 @@ struct scmi_fc_info { * provided in @ops. * @iter_response_run: A common helper to trigger the run of a previously * initialized iterator. - * @protocol_msg_check: A common helper to check is a specific protocol message - * is supported. * @fastchannel_init: A common helper used to initialize FC descriptors by * gathering FC descriptions from the SCMI platform server. * @fastchannel_db_ring: A common helper to ring a FC doorbell. @@ -269,8 +267,6 @@ struct scmi_proto_helpers_ops { unsigned int max_resources, u8 msg_id, size_t tx_size, void *priv); int (*iter_response_run)(void *iter); - int (*protocol_msg_check)(const struct scmi_protocol_handle *ph, - u32 message_id, u32 *attributes); void (*fastchannel_init)(const struct scmi_protocol_handle *ph, u8 describe_id, u32 message_id, u32 valid_size, u32 domain, From 1cb814dbb03d78a907ba4cd19b01d33a92c89b11 Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Thu, 29 May 2025 16:29:22 -0400 Subject: [PATCH 833/971] rtc: pcf2127: add missing semicolon after statement commit 08d82d0cad51c2b1d454fe41ea1ff96ade676961 upstream. Replace comma with semicolon at the end of the statement when setting config.max_register. Fixes: fd28ceb4603f ("rtc: pcf2127: add variant-specific configuration structure") Cc: stable@vger.kernel.org Cc: Elena Popa Signed-off-by: Hugo Villeneuve Link: https://lore.kernel.org/r/20250529202923.1552560-1-hugo@hugovil.com Signed-off-by: Alexandre Belloni Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/rtc-pcf2127.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index 9c04c4e1a49c..b8cb09a82ea9 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -1456,7 +1456,7 @@ static int pcf2127_spi_probe(struct spi_device *spi) variant = &pcf21xx_cfg[type]; } - config.max_register = variant->max_register, + config.max_register = variant->max_register; regmap = devm_regmap_init_spi(spi, &config); if (IS_ERR(regmap)) { From 5cdd1f73401d689159aa1886b1d7a725dae2dcce Mon Sep 17 00:00:00 2001 From: Elena Popa Date: Fri, 30 May 2025 13:40:00 +0300 Subject: [PATCH 834/971] rtc: pcf2127: fix SPI command byte for PCF2131 commit fa78e9b606a472495ef5b6b3d8b45c37f7727f9d upstream. PCF2131 was not responding to read/write operations using SPI. PCF2131 has a different command byte definition, compared to PCF2127/29. Added the new command byte definition when PCF2131 is detected. Fixes: afc505bf9039 ("rtc: pcf2127: add support for PCF2131 RTC") Cc: stable@vger.kernel.org Signed-off-by: Elena Popa Acked-by: Hugo Villeneuve Link: https://lore.kernel.org/r/20250530104001.957977-1-elena.popa@nxp.com Signed-off-by: Alexandre Belloni Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/rtc-pcf2127.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index b8cb09a82ea9..fc079b9dcf71 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -1383,6 +1383,11 @@ static int pcf2127_i2c_probe(struct i2c_client *client) variant = &pcf21xx_cfg[type]; } + if (variant->type == PCF2131) { + config.read_flag_mask = 0x0; + config.write_flag_mask = 0x0; + } + config.max_register = variant->max_register, regmap = devm_regmap_init(&client->dev, &pcf2127_i2c_regmap, From 39617dc3fafefc0fed154a2d84cda54a6d328419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Jo=C5=84czyk?= Date: Sat, 7 Jun 2025 23:06:08 +0200 Subject: [PATCH 835/971] rtc: cmos: use spin_lock_irqsave in cmos_interrupt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 00a39d8652ff9088de07a6fe6e9e1893452fe0dd upstream. cmos_interrupt() can be called in a non-interrupt context, such as in an ACPI event handler (which runs in an interrupt thread). Therefore, usage of spin_lock(&rtc_lock) is insecure. Use spin_lock_irqsave() / spin_unlock_irqrestore() instead. Before a misguided commit 6950d046eb6e ("rtc: cmos: Replace spin_lock_irqsave with spin_lock in hard IRQ") the cmos_interrupt() function used spin_lock_irqsave(). That commit changed it to spin_lock() and broke locking, which was partially fixed in commit 13be2efc390a ("rtc: cmos: Disable irq around direct invocation of cmos_interrupt()") That second commit did not take account of the ACPI fixed event handler pathway, however. It introduced local_irq_disable() workarounds in cmos_check_wkalrm(), which can cause problems on PREEMPT_RT kernels and are now unnecessary. Add an explicit comment so that this change will not be reverted by mistake. Cc: stable@vger.kernel.org Fixes: 6950d046eb6e ("rtc: cmos: Replace spin_lock_irqsave with spin_lock in hard IRQ") Signed-off-by: Mateusz Jończyk Reviewed-by: Sebastian Andrzej Siewior Tested-by: Chris Bainbridge Reported-by: Chris Bainbridge Closes: https://lore.kernel.org/all/aDtJ92foPUYmGheF@debian.local/ Link: https://lore.kernel.org/r/20250607210608.14835-1-mat.jonczyk@o2.pl Signed-off-by: Alexandre Belloni Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/rtc-cmos.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 5849d2970bba..095de4e0e4f3 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -697,8 +697,12 @@ static irqreturn_t cmos_interrupt(int irq, void *p) { u8 irqstat; u8 rtc_control; + unsigned long flags; - spin_lock(&rtc_lock); + /* We cannot use spin_lock() here, as cmos_interrupt() is also called + * in a non-irq context. + */ + spin_lock_irqsave(&rtc_lock, flags); /* When the HPET interrupt handler calls us, the interrupt * status is passed as arg1 instead of the irq number. But @@ -732,7 +736,7 @@ static irqreturn_t cmos_interrupt(int irq, void *p) hpet_mask_rtc_irq_bit(RTC_AIE); CMOS_READ(RTC_INTR_FLAGS); } - spin_unlock(&rtc_lock); + spin_unlock_irqrestore(&rtc_lock, flags); if (is_intr(irqstat)) { rtc_update_irq(p, 1, irqstat); @@ -1300,9 +1304,7 @@ static void cmos_check_wkalrm(struct device *dev) * ACK the rtc irq here */ if (t_now >= cmos->alarm_expires && cmos_use_acpi_alarm()) { - local_irq_disable(); cmos_interrupt(0, (void *)cmos->rtc); - local_irq_enable(); return; } From 80b971be4c37a4d23a7f1abc5ff33dc7733d649b Mon Sep 17 00:00:00 2001 From: Bui Quang Minh Date: Mon, 30 Jun 2025 21:42:10 +0700 Subject: [PATCH 836/971] virtio-net: ensure the received length does not exceed allocated size commit 315dbdd7cdf6aa533829774caaf4d25f1fd20e73 upstream. In xdp_linearize_page, when reading the following buffers from the ring, we forget to check the received length with the true allocate size. This can lead to an out-of-bound read. This commit adds that missing check. Cc: Fixes: 4941d472bf95 ("virtio-net: do not reset during XDP set") Signed-off-by: Bui Quang Minh Acked-by: Jason Wang Link: https://patch.msgid.link/20250630144212.48471-2-minhquangbui99@gmail.com Signed-off-by: Paolo Abeni Signed-off-by: Greg Kroah-Hartman --- drivers/net/virtio_net.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 3bf394b24d97..5a949f9446a8 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -487,6 +487,26 @@ static unsigned int mergeable_ctx_to_truesize(void *mrg_ctx) return (unsigned long)mrg_ctx & ((1 << MRG_CTX_HEADER_SHIFT) - 1); } +static int check_mergeable_len(struct net_device *dev, void *mrg_ctx, + unsigned int len) +{ + unsigned int headroom, tailroom, room, truesize; + + truesize = mergeable_ctx_to_truesize(mrg_ctx); + headroom = mergeable_ctx_to_headroom(mrg_ctx); + tailroom = headroom ? sizeof(struct skb_shared_info) : 0; + room = SKB_DATA_ALIGN(headroom + tailroom); + + if (len > truesize - room) { + pr_debug("%s: rx error: len %u exceeds truesize %lu\n", + dev->name, len, (unsigned long)(truesize - room)); + DEV_STATS_INC(dev, rx_length_errors); + return -1; + } + + return 0; +} + static struct sk_buff *virtnet_build_skb(void *buf, unsigned int buflen, unsigned int headroom, unsigned int len) @@ -1084,7 +1104,8 @@ static unsigned int virtnet_get_headroom(struct virtnet_info *vi) * across multiple buffers (num_buf > 1), and we make sure buffers * have enough headroom. */ -static struct page *xdp_linearize_page(struct receive_queue *rq, +static struct page *xdp_linearize_page(struct net_device *dev, + struct receive_queue *rq, int *num_buf, struct page *p, int offset, @@ -1104,18 +1125,27 @@ static struct page *xdp_linearize_page(struct receive_queue *rq, memcpy(page_address(page) + page_off, page_address(p) + offset, *len); page_off += *len; + /* Only mergeable mode can go inside this while loop. In small mode, + * *num_buf == 1, so it cannot go inside. + */ while (--*num_buf) { unsigned int buflen; void *buf; + void *ctx; int off; - buf = virtnet_rq_get_buf(rq, &buflen, NULL); + buf = virtnet_rq_get_buf(rq, &buflen, &ctx); if (unlikely(!buf)) goto err_buf; p = virt_to_head_page(buf); off = buf - page_address(p); + if (check_mergeable_len(dev, ctx, buflen)) { + put_page(p); + goto err_buf; + } + /* guard against a misconfigured or uncooperative backend that * is sending packet larger than the MTU. */ @@ -1204,7 +1234,7 @@ static struct sk_buff *receive_small_xdp(struct net_device *dev, headroom = vi->hdr_len + header_offset; buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); - xdp_page = xdp_linearize_page(rq, &num_buf, page, + xdp_page = xdp_linearize_page(dev, rq, &num_buf, page, offset, header_offset, &tlen); if (!xdp_page) @@ -1539,7 +1569,7 @@ static void *mergeable_xdp_get_buf(struct virtnet_info *vi, */ if (!xdp_prog->aux->xdp_has_frags) { /* linearize data for XDP */ - xdp_page = xdp_linearize_page(rq, num_buf, + xdp_page = xdp_linearize_page(vi->dev, rq, num_buf, *page, offset, VIRTIO_XDP_HEADROOM, len); From e7191481d6ae98303758a00498ef3868ce66a84a Mon Sep 17 00:00:00 2001 From: Niklas Schnelle Date: Wed, 25 Jun 2025 11:28:29 +0200 Subject: [PATCH 837/971] s390/pci: Do not try re-enabling load/store if device is disabled commit b97a7972b1f4f81417840b9a2ab0c19722b577d5 upstream. If a device is disabled unblocking load/store on its own is not useful as a full re-enable of the function is necessary anyway. Note that SCLP Write Event Data Action Qualifier 0 (Reset) leaves the device disabled and triggers this case unless the driver already requests a reset. Cc: stable@vger.kernel.org Fixes: 4cdf2f4e24ff ("s390/pci: implement minimal PCI error recovery") Reviewed-by: Farhan Ali Signed-off-by: Niklas Schnelle Signed-off-by: Alexander Gordeev Signed-off-by: Greg Kroah-Hartman --- arch/s390/pci/pci_event.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c index b3961f1016ea..d969f36bf186 100644 --- a/arch/s390/pci/pci_event.c +++ b/arch/s390/pci/pci_event.c @@ -98,6 +98,10 @@ static pci_ers_result_t zpci_event_do_error_state_clear(struct pci_dev *pdev, struct zpci_dev *zdev = to_zpci(pdev); int rc; + /* The underlying device may have been disabled by the event */ + if (!zdev_enabled(zdev)) + return PCI_ERS_RESULT_NEED_RESET; + pr_info("%s: Unblocking device access for examination\n", pci_name(pdev)); rc = zpci_reset_load_store_blocked(zdev); if (rc) { From 94d0c326cb3ee6b0f8bd00e209550b93fcc5c839 Mon Sep 17 00:00:00 2001 From: HarshaVardhana S A Date: Tue, 1 Jul 2025 14:22:54 +0200 Subject: [PATCH 838/971] vsock/vmci: Clear the vmci transport packet properly when initializing it commit 223e2288f4b8c262a864e2c03964ffac91744cd5 upstream. In vmci_transport_packet_init memset the vmci_transport_packet before populating the fields to avoid any uninitialised data being left in the structure. Cc: Bryan Tan Cc: Vishnu Dasa Cc: Broadcom internal kernel review list Cc: Stefano Garzarella Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Simon Horman Cc: virtualization@lists.linux.dev Cc: netdev@vger.kernel.org Cc: stable Signed-off-by: HarshaVardhana S A Signed-off-by: Greg Kroah-Hartman Fixes: d021c344051a ("VSOCK: Introduce VM Sockets") Acked-by: Stefano Garzarella Link: https://patch.msgid.link/20250701122254.2397440-1-gregkh@linuxfoundation.org Signed-off-by: Paolo Abeni Signed-off-by: Greg Kroah-Hartman --- net/vmw_vsock/vmci_transport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index b370070194fa..7eccd6708d66 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c @@ -119,6 +119,8 @@ vmci_transport_packet_init(struct vmci_transport_packet *pkt, u16 proto, struct vmci_handle handle) { + memset(pkt, 0, sizeof(*pkt)); + /* We register the stream control handler as an any cid handle so we * must always send from a source address of VMADDR_CID_ANY */ @@ -131,8 +133,6 @@ vmci_transport_packet_init(struct vmci_transport_packet *pkt, pkt->type = type; pkt->src_port = src->svm_port; pkt->dst_port = dst->svm_port; - memset(&pkt->proto, 0, sizeof(pkt->proto)); - memset(&pkt->_reserved2, 0, sizeof(pkt->_reserved2)); switch (pkt->type) { case VMCI_TRANSPORT_PACKET_TYPE_INVALID: From 3855b7ace3f9d1f984a8c5fb561080bed3c7c002 Mon Sep 17 00:00:00 2001 From: Victor Shih Date: Fri, 6 Jun 2025 19:01:20 +0800 Subject: [PATCH 839/971] mmc: sdhci: Add a helper function for dump register in dynamic debug mode commit 2881ba9af073faa8ee7408a8d1e0575e50eb3f6c upstream. Add a helper function for dump register in dynamic debug mode. Signed-off-by: Victor Shih Acked-by: Adrian Hunter Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20250606110121.96314-3-victorshihgli@gmail.com Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/sdhci.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index a315cee69809..16d7bff9eae5 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -825,4 +825,20 @@ void sdhci_switch_external_dma(struct sdhci_host *host, bool en); void sdhci_set_data_timeout_irq(struct sdhci_host *host, bool enable); void __sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd); +#if defined(CONFIG_DYNAMIC_DEBUG) || \ + (defined(CONFIG_DYNAMIC_DEBUG_CORE) && defined(DYNAMIC_DEBUG_MODULE)) +#define SDHCI_DBG_ANYWAY 0 +#elif defined(DEBUG) +#define SDHCI_DBG_ANYWAY 1 +#else +#define SDHCI_DBG_ANYWAY 0 +#endif + +#define sdhci_dbg_dumpregs(host, fmt) \ +do { \ + DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ + if (DYNAMIC_DEBUG_BRANCH(descriptor) || SDHCI_DBG_ANYWAY) \ + sdhci_dumpregs(host); \ +} while (0) + #endif /* __SDHCI_HW_H */ From c4fad2460c1721b93c446512fc8828e8222011c9 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 24 Jun 2025 13:09:32 +0200 Subject: [PATCH 840/971] Revert "mmc: sdhci: Disable SD card clock before changing parameters" commit dcc3bcfc5b50c625b475dcc25d167b6b947a6637 upstream. It has turned out the trying to strictly conform to the SDHCI specification is causing problems. Let's revert and start over. This reverts commit fb3bbc46c94f261b6156ee863c1b06c84cf157dc. Cc: Erick Shepherd Cc: stable@vger.kernel.org Fixes: fb3bbc46c94f ("mmc: sdhci: Disable SD card clock before changing parameters") Suggested-by: Adrian Hunter Reported-by: Jonathan Liu Reported-by: Salvatore Bonaccorso Closes: https://bugs.debian.org/1108065 Acked-by: Adrian Hunter Signed-off-by: Ulf Hansson Link: https://lore.kernel.org/r/20250624110932.176925-1-ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/sdhci.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index f32429ff905f..9796a3cb3ca6 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2035,15 +2035,10 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) host->mmc->actual_clock = 0; - clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); - if (clk & SDHCI_CLOCK_CARD_EN) - sdhci_writew(host, clk & ~SDHCI_CLOCK_CARD_EN, - SDHCI_CLOCK_CONTROL); + sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); - if (clock == 0) { - sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); + if (clock == 0) return; - } clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock); sdhci_enable_clk(host, clk); From 3c0c18ef4c7907d1b36119a5c273b7ee01619652 Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Mon, 26 May 2025 14:44:45 +0300 Subject: [PATCH 841/971] mmc: core: sd: Apply BROKEN_SD_DISCARD quirk earlier commit 009c3a4bc41e855fd76f92727f9fbae4e5917d7f upstream. Move the BROKEN_SD_DISCARD quirk for certain SanDisk SD cards from the `mmc_blk_fixups[]` to `mmc_sd_fixups[]`. This ensures the quirk is applied earlier in the device initialization process, aligning with the reasoning in [1]. Applying the quirk sooner prevents the kernel from incorrectly enabling discard support on affected cards during initial setup. [1] https://lore.kernel.org/all/20240820230631.GA436523@sony.com Fixes: 07d2872bf4c8 ("mmc: core: Add SD card quirk for broken discard") Signed-off-by: Avri Altman Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20250526114445.675548-1-avri.altman@sandisk.com Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/core/quirks.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h index 7f893bafaa60..c417ed34c057 100644 --- a/drivers/mmc/core/quirks.h +++ b/drivers/mmc/core/quirks.h @@ -44,6 +44,12 @@ static const struct mmc_fixup __maybe_unused mmc_sd_fixups[] = { 0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd, MMC_QUIRK_NO_UHS_DDR50_TUNING, EXT_CSD_REV_ANY), + /* + * Some SD cards reports discard support while they don't + */ + MMC_FIXUP(CID_NAME_ANY, CID_MANFID_SANDISK_SD, 0x5344, add_quirk_sd, + MMC_QUIRK_BROKEN_SD_DISCARD), + END_FIXUP }; @@ -147,12 +153,6 @@ static const struct mmc_fixup __maybe_unused mmc_blk_fixups[] = { MMC_FIXUP("M62704", CID_MANFID_KINGSTON, 0x0100, add_quirk_mmc, MMC_QUIRK_TRIM_BROKEN), - /* - * Some SD cards reports discard support while they don't - */ - MMC_FIXUP(CID_NAME_ANY, CID_MANFID_SANDISK_SD, 0x5344, add_quirk_sd, - MMC_QUIRK_BROKEN_SD_DISCARD), - END_FIXUP }; From 7e88ad41b63e72a83a46094a7d254e2597992b8f Mon Sep 17 00:00:00 2001 From: Christian Eggers Date: Wed, 25 Jun 2025 15:09:29 +0200 Subject: [PATCH 842/971] Bluetooth: hci_sync: revert some mesh modifications commit 46c0d947b64ac8efcf89dd754213dab5d1bd00aa upstream. This reverts minor parts of the changes made in commit b338d91703fa ("Bluetooth: Implement support for Mesh"). It looks like these changes were only made for development purposes but shouldn't have been part of the commit. Fixes: b338d91703fa ("Bluetooth: Implement support for Mesh") Cc: stable@vger.kernel.org Signed-off-by: Christian Eggers Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Greg Kroah-Hartman --- net/bluetooth/hci_sync.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index e92bc4ceb5ad..9ba4cb90891b 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -2010,13 +2010,10 @@ static int hci_clear_adv_sets_sync(struct hci_dev *hdev, struct sock *sk) static int hci_clear_adv_sync(struct hci_dev *hdev, struct sock *sk, bool force) { struct adv_info *adv, *n; - int err = 0; if (ext_adv_capable(hdev)) /* Remove all existing sets */ - err = hci_clear_adv_sets_sync(hdev, sk); - if (ext_adv_capable(hdev)) - return err; + return hci_clear_adv_sets_sync(hdev, sk); /* This is safe as long as there is no command send while the lock is * held. @@ -2044,13 +2041,11 @@ static int hci_clear_adv_sync(struct hci_dev *hdev, struct sock *sk, bool force) static int hci_remove_adv_sync(struct hci_dev *hdev, u8 instance, struct sock *sk) { - int err = 0; + int err; /* If we use extended advertising, instance has to be removed first. */ if (ext_adv_capable(hdev)) - err = hci_remove_ext_adv_instance_sync(hdev, instance, sk); - if (ext_adv_capable(hdev)) - return err; + return hci_remove_ext_adv_instance_sync(hdev, instance, sk); /* This is safe as long as there is no command send while the lock is * held. @@ -2149,16 +2144,13 @@ int hci_read_tx_power_sync(struct hci_dev *hdev, __le16 handle, u8 type) int hci_disable_advertising_sync(struct hci_dev *hdev) { u8 enable = 0x00; - int err = 0; /* If controller is not advertising we are done. */ if (!hci_dev_test_flag(hdev, HCI_LE_ADV)) return 0; if (ext_adv_capable(hdev)) - err = hci_disable_ext_adv_instance_sync(hdev, 0x00); - if (ext_adv_capable(hdev)) - return err; + return hci_disable_ext_adv_instance_sync(hdev, 0x00); return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable, HCI_CMD_TIMEOUT); From 8af1406949c1e45b1f925996b42c53c44259ba07 Mon Sep 17 00:00:00 2001 From: Christian Eggers Date: Wed, 25 Jun 2025 15:09:30 +0200 Subject: [PATCH 843/971] Bluetooth: MGMT: set_mesh: update LE scan interval and window commit e5af67a870f738bb8a4594b6c60c2caf4c87a3c9 upstream. According to the message of commit b338d91703fa ("Bluetooth: Implement support for Mesh"), MGMT_OP_SET_MESH_RECEIVER should set the passive scan parameters. Currently the scan interval and window parameters are silently ignored, although user space (bluetooth-meshd) expects that they can be used [1] [1] https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/mesh/mesh-io-mgmt.c#n344 Fixes: b338d91703fa ("Bluetooth: Implement support for Mesh") Cc: stable@vger.kernel.org Signed-off-by: Christian Eggers Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Greg Kroah-Hartman --- net/bluetooth/mgmt.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 853d217cabc9..8bef24228b5c 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -2140,6 +2140,9 @@ static int set_mesh_sync(struct hci_dev *hdev, void *data) else hci_dev_clear_flag(hdev, HCI_MESH); + hdev->le_scan_interval = __le16_to_cpu(cp->period); + hdev->le_scan_window = __le16_to_cpu(cp->window); + len -= sizeof(*cp); /* If filters don't fit, forward all adv pkts */ @@ -2154,6 +2157,7 @@ static int set_mesh(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_cp_set_mesh *cp = data; struct mgmt_pending_cmd *cmd; + __u16 period, window; int err = 0; bt_dev_dbg(hdev, "sock %p", sk); @@ -2167,6 +2171,23 @@ static int set_mesh(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER, MGMT_STATUS_INVALID_PARAMS); + /* Keep allowed ranges in sync with set_scan_params() */ + period = __le16_to_cpu(cp->period); + + if (period < 0x0004 || period > 0x4000) + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER, + MGMT_STATUS_INVALID_PARAMS); + + window = __le16_to_cpu(cp->window); + + if (window < 0x0004 || window > 0x4000) + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER, + MGMT_STATUS_INVALID_PARAMS); + + if (window > period) + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER, + MGMT_STATUS_INVALID_PARAMS); + hci_dev_lock(hdev); cmd = mgmt_pending_add(sk, MGMT_OP_SET_MESH_RECEIVER, hdev, data, len); @@ -6529,6 +6550,7 @@ static int set_scan_params(struct sock *sk, struct hci_dev *hdev, return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS, MGMT_STATUS_NOT_SUPPORTED); + /* Keep allowed ranges in sync with set_mesh() */ interval = __le16_to_cpu(cp->interval); if (interval < 0x0004 || interval > 0x4000) From 0506547f6e3d2a1db4e3967975b65f46d12e331c Mon Sep 17 00:00:00 2001 From: Christian Eggers Date: Wed, 25 Jun 2025 15:09:31 +0200 Subject: [PATCH 844/971] Bluetooth: MGMT: mesh_send: check instances prior disabling advertising commit f3cb5676e5c11c896ba647ee309a993e73531588 upstream. The unconditional call of hci_disable_advertising_sync() in mesh_send_done_sync() also disables other LE advertisings (non mesh related). I am not sure whether this call is required at all, but checking the adv_instances list (like done at other places) seems to solve the problem. Fixes: b338d91703fa ("Bluetooth: Implement support for Mesh") Cc: stable@vger.kernel.org Signed-off-by: Christian Eggers Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Greg Kroah-Hartman --- net/bluetooth/mgmt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 8bef24228b5c..82fa8c28438f 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1074,7 +1074,8 @@ static int mesh_send_done_sync(struct hci_dev *hdev, void *data) struct mgmt_mesh_tx *mesh_tx; hci_dev_clear_flag(hdev, HCI_MESH_SENDING); - hci_disable_advertising_sync(hdev); + if (list_empty(&hdev->adv_instances)) + hci_disable_advertising_sync(hdev); mesh_tx = mgmt_mesh_next(hdev, NULL); if (mesh_tx) From 24418bc77a66cb5be9f5a837431ba3674ed8b52f Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Thu, 3 Jul 2025 16:05:49 +0530 Subject: [PATCH 845/971] regulator: gpio: Fix the out-of-bounds access to drvdata::gpiods commit c9764fd88bc744592b0604ccb6b6fc1a5f76b4e3 upstream. drvdata::gpiods is supposed to hold an array of 'gpio_desc' pointers. But the memory is allocated for only one pointer. This will lead to out-of-bounds access later in the code if 'config::ngpios' is > 1. So fix the code to allocate enough memory to hold 'config::ngpios' of GPIO descriptors. While at it, also move the check for memory allocation failure to be below the allocation to make it more readable. Cc: stable@vger.kernel.org # 5.0 Fixes: d6cd33ad7102 ("regulator: gpio: Convert to use descriptors") Signed-off-by: Manivannan Sadhasivam Link: https://patch.msgid.link/20250703103549.16558-1-mani@kernel.org Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/regulator/gpio-regulator.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index 65927fa2ef16..1bdd494cf882 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -260,8 +260,10 @@ static int gpio_regulator_probe(struct platform_device *pdev) return -ENOMEM; } - drvdata->gpiods = devm_kzalloc(dev, sizeof(struct gpio_desc *), - GFP_KERNEL); + drvdata->gpiods = devm_kcalloc(dev, config->ngpios, + sizeof(struct gpio_desc *), GFP_KERNEL); + if (!drvdata->gpiods) + return -ENOMEM; if (config->input_supply) { drvdata->desc.supply_name = devm_kstrdup(&pdev->dev, @@ -274,8 +276,6 @@ static int gpio_regulator_probe(struct platform_device *pdev) } } - if (!drvdata->gpiods) - return -ENOMEM; for (i = 0; i < config->ngpios; i++) { drvdata->gpiods[i] = devm_gpiod_get_index(dev, NULL, From 45e9444b3b97eaf51a5024f1fea92f44f39b50c6 Mon Sep 17 00:00:00 2001 From: RD Babiera Date: Wed, 18 Jun 2025 22:49:42 +0000 Subject: [PATCH 846/971] usb: typec: altmodes/displayport: do not index invalid pin_assignments commit af4db5a35a4ef7a68046883bfd12468007db38f1 upstream. A poorly implemented DisplayPort Alt Mode port partner can indicate that its pin assignment capabilities are greater than the maximum value, DP_PIN_ASSIGN_F. In this case, calls to pin_assignment_show will cause a BRK exception due to an out of bounds array access. Prevent for loop in pin_assignment_show from accessing invalid values in pin_assignments by adding DP_PIN_ASSIGN_MAX value in typec_dp.h and using i < DP_PIN_ASSIGN_MAX as a loop condition. Fixes: 0e3bb7d6894d ("usb: typec: Add driver for DisplayPort alternate mode") Cc: stable Signed-off-by: RD Babiera Reviewed-by: Badhri Jagan Sridharan Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20250618224943.3263103-2-rdbabiera@google.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/altmodes/displayport.c | 2 +- include/linux/usb/typec_dp.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c index 5f6fc5b79212..2f8d3ed01d5b 100644 --- a/drivers/usb/typec/altmodes/displayport.c +++ b/drivers/usb/typec/altmodes/displayport.c @@ -528,7 +528,7 @@ static ssize_t pin_assignment_show(struct device *dev, assignments = get_current_pin_assignments(dp); - for (i = 0; assignments; assignments >>= 1, i++) { + for (i = 0; assignments && i < DP_PIN_ASSIGN_MAX; assignments >>= 1, i++) { if (assignments & 1) { if (i == cur) len += sprintf(buf + len, "[%s] ", diff --git a/include/linux/usb/typec_dp.h b/include/linux/usb/typec_dp.h index 8d09c2f0a9b8..c3f08af20295 100644 --- a/include/linux/usb/typec_dp.h +++ b/include/linux/usb/typec_dp.h @@ -56,6 +56,7 @@ enum { DP_PIN_ASSIGN_D, DP_PIN_ASSIGN_E, DP_PIN_ASSIGN_F, /* Not supported after v1.0b */ + DP_PIN_ASSIGN_MAX, }; /* DisplayPort alt mode specific commands */ From b3b00e9b03d3a328869ea05f0ac02000bcb497a2 Mon Sep 17 00:00:00 2001 From: "Masami Hiramatsu (Google)" Date: Thu, 5 Jun 2025 10:07:38 +0900 Subject: [PATCH 847/971] mtk-sd: Fix a pagefault in dma_unmap_sg() for not prepared data commit 539d80575b810c7a5987c7ac8915e3bc99c03695 upstream. When swiotlb buffer is full, the dma_map_sg() returns 0 to msdc_prepare_data(), but it does not check it and sets the MSDC_PREPARE_FLAG. swiotlb_tbl_map_single() /* prints "swiotlb buffer is full" */ <-swiotlb_map() <-dma_direct_map_page() <-dma_direct_map_sg() <-__dma_map_sg_attrs() <-dma_map_sg_attrs() <-dma_map_sg() /* returns 0 (pages mapped) */ <-msdc_prepare_data() Then, the msdc_unprepare_data() checks MSDC_PREPARE_FLAG and calls dma_unmap_sg() with unmapped pages. It causes a page fault. To fix this problem, Do not set MSDC_PREPARE_FLAG if dma_map_sg() fails because this is not prepared. Fixes: 208489032bdd ("mmc: mediatek: Add Mediatek MMC driver") Signed-off-by: Masami Hiramatsu (Google) Tested-by: Sergey Senozhatsky Reviewed-by: AngeloGioacchino Del Regno Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/174908565814.4056588.769599127120955383.stgit@mhiramat.tok.corp.google.com Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/mtk-sd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c index 02f3748e46c1..f201edbacd68 100644 --- a/drivers/mmc/host/mtk-sd.c +++ b/drivers/mmc/host/mtk-sd.c @@ -770,9 +770,10 @@ static inline void msdc_dma_setup(struct msdc_host *host, struct msdc_dma *dma, static void msdc_prepare_data(struct msdc_host *host, struct mmc_data *data) { if (!(data->host_cookie & MSDC_PREPARE_FLAG)) { - data->host_cookie |= MSDC_PREPARE_FLAG; data->sg_count = dma_map_sg(host->dev, data->sg, data->sg_len, mmc_get_dma_dir(data)); + if (data->sg_count) + data->host_cookie |= MSDC_PREPARE_FLAG; } } From 61cdd663564674ea21ceb50aa9d3697cbe9e45f9 Mon Sep 17 00:00:00 2001 From: "Masami Hiramatsu (Google)" Date: Thu, 12 Jun 2025 20:26:10 +0900 Subject: [PATCH 848/971] mtk-sd: Prevent memory corruption from DMA map failure commit f5de469990f19569627ea0dd56536ff5a13beaa3 upstream. If msdc_prepare_data() fails to map the DMA region, the request is not prepared for data receiving, but msdc_start_data() proceeds the DMA with previous setting. Since this will lead a memory corruption, we have to stop the request operation soon after the msdc_prepare_data() fails to prepare it. Signed-off-by: Masami Hiramatsu (Google) Fixes: 208489032bdd ("mmc: mediatek: Add Mediatek MMC driver") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/174972756982.3337526.6755001617701603082.stgit@mhiramat.tok.corp.google.com Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/mtk-sd.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c index f201edbacd68..d1bceb85c9eb 100644 --- a/drivers/mmc/host/mtk-sd.c +++ b/drivers/mmc/host/mtk-sd.c @@ -777,6 +777,11 @@ static void msdc_prepare_data(struct msdc_host *host, struct mmc_data *data) } } +static bool msdc_data_prepared(struct mmc_data *data) +{ + return data->host_cookie & MSDC_PREPARE_FLAG; +} + static void msdc_unprepare_data(struct msdc_host *host, struct mmc_data *data) { if (data->host_cookie & MSDC_ASYNC_FLAG) @@ -1339,8 +1344,18 @@ static void msdc_ops_request(struct mmc_host *mmc, struct mmc_request *mrq) WARN_ON(host->mrq); host->mrq = mrq; - if (mrq->data) + if (mrq->data) { msdc_prepare_data(host, mrq->data); + if (!msdc_data_prepared(mrq->data)) { + /* + * Failed to prepare DMA area, fail fast before + * starting any commands. + */ + mrq->cmd->error = -ENOSPC; + mmc_request_done(mmc_from_priv(host), mrq); + return; + } + } /* if SBC is required, we have HW option and SW option. * if HW option is enabled, and SBC does not have "special" flags, From b935c1e734d238fba1732079f320b6bdd793fa18 Mon Sep 17 00:00:00 2001 From: Sergey Senozhatsky Date: Wed, 25 Jun 2025 14:20:37 +0900 Subject: [PATCH 849/971] mtk-sd: reset host->mrq on prepare_data() error commit ec54c0a20709ed6e56f40a8d59eee725c31a916b upstream. Do not leave host with dangling ->mrq pointer if we hit the msdc_prepare_data() error out path. Signed-off-by: Sergey Senozhatsky Reviewed-by: Masami Hiramatsu (Google) Fixes: f5de469990f1 ("mtk-sd: Prevent memory corruption from DMA map failure") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20250625052106.584905-1-senozhatsky@chromium.org Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/mtk-sd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c index d1bceb85c9eb..cf685c0a17ed 100644 --- a/drivers/mmc/host/mtk-sd.c +++ b/drivers/mmc/host/mtk-sd.c @@ -1347,6 +1347,7 @@ static void msdc_ops_request(struct mmc_host *mmc, struct mmc_request *mrq) if (mrq->data) { msdc_prepare_data(host, mrq->data); if (!msdc_data_prepared(mrq->data)) { + host->mrq = NULL; /* * Failed to prepare DMA area, fail fast before * starting any commands. From 3962e5a3845dfd66d9918598f1e0c974e9841f3c Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Wed, 11 Jun 2025 22:30:31 +0200 Subject: [PATCH 850/971] arm64: dts: apple: t8103: Fix PCIe BCM4377 nodename [ Upstream commit ac1daa91e9370e3b88ef7826a73d62a4d09e2717 ] Fix the following `make dtbs_check` warnings for all t8103 based devices: arch/arm64/boot/dts/apple/t8103-j274.dtb: network@0,0: $nodename:0: 'network@0,0' does not match '^wifi(@.*)?$' from schema $id: http://devicetree.org/schemas/net/wireless/brcm,bcm4329-fmac.yaml# arch/arm64/boot/dts/apple/t8103-j274.dtb: network@0,0: Unevaluated properties are not allowed ('local-mac-address' was unexpected) from schema $id: http://devicetree.org/schemas/net/wireless/brcm,bcm4329-fmac.yaml# Fixes: bf2c05b619ff ("arm64: dts: apple: t8103: Expose PCI node for the WiFi MAC address") Signed-off-by: Janne Grunau Reviewed-by: Sven Peter Link: https://lore.kernel.org/r/20250611-arm64_dts_apple_wifi-v1-1-fb959d8e1eb4@jannau.net Signed-off-by: Sven Peter Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/apple/t8103-jxxx.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi index 5988a4eb6efa..cb78ce7af0b3 100644 --- a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi +++ b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi @@ -71,7 +71,7 @@ */ &port00 { bus-range = <1 1>; - wifi0: network@0,0 { + wifi0: wifi@0,0 { compatible = "pci14e4,4425"; reg = <0x10000 0x0 0x0 0x0 0x0>; /* To be filled by the loader */ From edca475158f7d25d6595080c7be8d7ce886d831d Mon Sep 17 00:00:00 2001 From: David Thompson Date: Fri, 13 Jun 2025 21:46:08 +0000 Subject: [PATCH 851/971] platform/mellanox: mlxbf-tmfifo: fix vring_desc.len assignment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 109f4d29dade8ae5b4ac6325af9d1bc24b4230f8 ] Fix warnings reported by sparse, related to incorrect type: drivers/platform/mellanox/mlxbf-tmfifo.c:284:38: warning: incorrect type in assignment (different base types) drivers/platform/mellanox/mlxbf-tmfifo.c:284:38: expected restricted __virtio32 [usertype] len drivers/platform/mellanox/mlxbf-tmfifo.c:284:38: got unsigned long Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202404040339.S7CUIgf3-lkp@intel.com/ Fixes: 78034cbece79 ("platform/mellanox: mlxbf-tmfifo: Drop the Rx packet if no more descriptors") Signed-off-by: David Thompson Link: https://lore.kernel.org/r/20250613214608.2250130-1-davthompson@nvidia.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin --- drivers/platform/mellanox/mlxbf-tmfifo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/platform/mellanox/mlxbf-tmfifo.c b/drivers/platform/mellanox/mlxbf-tmfifo.c index 39828eb84e0b..1015948ef43e 100644 --- a/drivers/platform/mellanox/mlxbf-tmfifo.c +++ b/drivers/platform/mellanox/mlxbf-tmfifo.c @@ -281,7 +281,8 @@ static int mlxbf_tmfifo_alloc_vrings(struct mlxbf_tmfifo *fifo, vring->align = SMP_CACHE_BYTES; vring->index = i; vring->vdev_id = tm_vdev->vdev.id.device; - vring->drop_desc.len = VRING_DROP_DESC_MAX_LEN; + vring->drop_desc.len = cpu_to_virtio32(&tm_vdev->vdev, + VRING_DROP_DESC_MAX_LEN); dev = &tm_vdev->vdev.dev; size = vring_size(vring->num, vring->align); From 23a3b32a274a8d6f33480d0eff436eb100981651 Mon Sep 17 00:00:00 2001 From: Mark Zhang Date: Tue, 17 Jun 2025 11:13:55 +0300 Subject: [PATCH 852/971] RDMA/mlx5: Initialize obj_event->obj_sub_list before xa_insert [ Upstream commit 8edab8a72d67742f87e9dc2e2b0cdfddda5dc29a ] The obj_event may be loaded immediately after inserted, then if the list_head is not initialized then we may get a poisonous pointer. This fixes the crash below: mlx5_core 0000:03:00.0: MLX5E: StrdRq(1) RqSz(8) StrdSz(2048) RxCqeCmprss(0 enhanced) mlx5_core.sf mlx5_core.sf.4: firmware version: 32.38.3056 mlx5_core 0000:03:00.0 en3f0pf0sf2002: renamed from eth0 mlx5_core.sf mlx5_core.sf.4: Rate limit: 127 rates are supported, range: 0Mbps to 195312Mbps IPv6: ADDRCONF(NETDEV_CHANGE): en3f0pf0sf2002: link becomes ready Unable to handle kernel NULL pointer dereference at virtual address 0000000000000060 Mem abort info: ESR = 0x96000006 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 Data abort info: ISV = 0, ISS = 0x00000006 CM = 0, WnR = 0 user pgtable: 4k pages, 48-bit VAs, pgdp=00000007760fb000 [0000000000000060] pgd=000000076f6d7003, p4d=000000076f6d7003, pud=0000000777841003, pmd=0000000000000000 Internal error: Oops: 96000006 [#1] SMP Modules linked in: ipmb_host(OE) act_mirred(E) cls_flower(E) sch_ingress(E) mptcp_diag(E) udp_diag(E) raw_diag(E) unix_diag(E) tcp_diag(E) inet_diag(E) binfmt_misc(E) bonding(OE) rdma_ucm(OE) rdma_cm(OE) iw_cm(OE) ib_ipoib(OE) ib_cm(OE) isofs(E) cdrom(E) mst_pciconf(OE) ib_umad(OE) mlx5_ib(OE) ipmb_dev_int(OE) mlx5_core(OE) kpatch_15237886(OEK) mlxdevm(OE) auxiliary(OE) ib_uverbs(OE) ib_core(OE) psample(E) mlxfw(OE) tls(E) sunrpc(E) vfat(E) fat(E) crct10dif_ce(E) ghash_ce(E) sha1_ce(E) sbsa_gwdt(E) virtio_console(E) ext4(E) mbcache(E) jbd2(E) xfs(E) libcrc32c(E) mmc_block(E) virtio_net(E) net_failover(E) failover(E) sha2_ce(E) sha256_arm64(E) nvme(OE) nvme_core(OE) gpio_mlxbf3(OE) mlx_compat(OE) mlxbf_pmc(OE) i2c_mlxbf(OE) sdhci_of_dwcmshc(OE) pinctrl_mlxbf3(OE) mlxbf_pka(OE) gpio_generic(E) i2c_core(E) mmc_core(E) mlxbf_gige(OE) vitesse(E) pwr_mlxbf(OE) mlxbf_tmfifo(OE) micrel(E) mlxbf_bootctl(OE) virtio_ring(E) virtio(E) ipmi_devintf(E) ipmi_msghandler(E) [last unloaded: mst_pci] CPU: 11 PID: 20913 Comm: rte-worker-11 Kdump: loaded Tainted: G OE K 5.10.134-13.1.an8.aarch64 #1 Hardware name: https://www.mellanox.com BlueField-3 SmartNIC Main Card/BlueField-3 SmartNIC Main Card, BIOS 4.2.2.12968 Oct 26 2023 pstate: a0400089 (NzCv daIf +PAN -UAO -TCO BTYPE=--) pc : dispatch_event_fd+0x68/0x300 [mlx5_ib] lr : devx_event_notifier+0xcc/0x228 [mlx5_ib] sp : ffff80001005bcf0 x29: ffff80001005bcf0 x28: 0000000000000001 x27: ffff244e0740a1d8 x26: ffff244e0740a1d0 x25: ffffda56beff5ae0 x24: ffffda56bf911618 x23: ffff244e0596a480 x22: ffff244e0596a480 x21: ffff244d8312ad90 x20: ffff244e0596a480 x19: fffffffffffffff0 x18: 0000000000000000 x17: 0000000000000000 x16: ffffda56be66d620 x15: 0000000000000000 x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000 x11: 0000000000000040 x10: ffffda56bfcafb50 x9 : ffffda5655c25f2c x8 : 0000000000000010 x7 : 0000000000000000 x6 : ffff24545a2e24b8 x5 : 0000000000000003 x4 : ffff80001005bd28 x3 : 0000000000000000 x2 : 0000000000000000 x1 : ffff244e0596a480 x0 : ffff244d8312ad90 Call trace: dispatch_event_fd+0x68/0x300 [mlx5_ib] devx_event_notifier+0xcc/0x228 [mlx5_ib] atomic_notifier_call_chain+0x58/0x80 mlx5_eq_async_int+0x148/0x2b0 [mlx5_core] atomic_notifier_call_chain+0x58/0x80 irq_int_handler+0x20/0x30 [mlx5_core] __handle_irq_event_percpu+0x60/0x220 handle_irq_event_percpu+0x3c/0x90 handle_irq_event+0x58/0x158 handle_fasteoi_irq+0xfc/0x188 generic_handle_irq+0x34/0x48 ... Fixes: 759738537142 ("IB/mlx5: Enable subscription for device events over DEVX") Link: https://patch.msgid.link/r/3ce7f20e0d1a03dc7de6e57494ec4b8eaf1f05c2.1750147949.git.leon@kernel.org Signed-off-by: Mark Zhang Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin --- drivers/infiniband/hw/mlx5/devx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/mlx5/devx.c b/drivers/infiniband/hw/mlx5/devx.c index 6e19974ecf6e..3f1fa45d9368 100644 --- a/drivers/infiniband/hw/mlx5/devx.c +++ b/drivers/infiniband/hw/mlx5/devx.c @@ -1914,6 +1914,7 @@ subscribe_event_xa_alloc(struct mlx5_devx_event_table *devx_event_table, /* Level1 is valid for future use, no need to free */ return -ENOMEM; + INIT_LIST_HEAD(&obj_event->obj_sub_list); err = xa_insert(&event->object_ids, key_level2, obj_event, @@ -1922,7 +1923,6 @@ subscribe_event_xa_alloc(struct mlx5_devx_event_table *devx_event_table, kfree(obj_event); return err; } - INIT_LIST_HEAD(&obj_event->obj_sub_list); } return 0; From d0877c479f44fe475f4c8c02c88ce9ad43e90298 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Thu, 12 Jun 2025 14:52:50 -0700 Subject: [PATCH 853/971] nfs: Clean up /proc/net/rpc/nfs when nfs_fs_proc_net_init() fails. [ Upstream commit e8d6f3ab59468e230f3253efe5cb63efa35289f7 ] syzbot reported a warning below [1] following a fault injection in nfs_fs_proc_net_init(). [0] When nfs_fs_proc_net_init() fails, /proc/net/rpc/nfs is not removed. Later, rpc_proc_exit() tries to remove /proc/net/rpc, and the warning is logged as the directory is not empty. Let's handle the error of nfs_fs_proc_net_init() properly. [0]: FAULT_INJECTION: forcing a failure. name failslab, interval 1, probability 0, space 0, times 0 CPU: 1 UID: 0 PID: 6120 Comm: syz.2.27 Not tainted 6.16.0-rc1-syzkaller-00010-g2c4a1f3fe03e #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/07/2025 Call Trace: dump_stack_lvl (lib/dump_stack.c:123) should_fail_ex (lib/fault-inject.c:73 lib/fault-inject.c:174) should_failslab (mm/failslab.c:46) kmem_cache_alloc_noprof (mm/slub.c:4178 mm/slub.c:4204) __proc_create (fs/proc/generic.c:427) proc_create_reg (fs/proc/generic.c:554) proc_create_net_data (fs/proc/proc_net.c:120) nfs_fs_proc_net_init (fs/nfs/client.c:1409) nfs_net_init (fs/nfs/inode.c:2600) ops_init (net/core/net_namespace.c:138) setup_net (net/core/net_namespace.c:443) copy_net_ns (net/core/net_namespace.c:576) create_new_namespaces (kernel/nsproxy.c:110) unshare_nsproxy_namespaces (kernel/nsproxy.c:218 (discriminator 4)) ksys_unshare (kernel/fork.c:3123) __x64_sys_unshare (kernel/fork.c:3190) do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130) [1]: remove_proc_entry: removing non-empty directory 'net/rpc', leaking at least 'nfs' WARNING: CPU: 1 PID: 6120 at fs/proc/generic.c:727 remove_proc_entry+0x45e/0x530 fs/proc/generic.c:727 Modules linked in: CPU: 1 UID: 0 PID: 6120 Comm: syz.2.27 Not tainted 6.16.0-rc1-syzkaller-00010-g2c4a1f3fe03e #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/07/2025 RIP: 0010:remove_proc_entry+0x45e/0x530 fs/proc/generic.c:727 Code: 3c 02 00 0f 85 85 00 00 00 48 8b 93 d8 00 00 00 4d 89 f0 4c 89 e9 48 c7 c6 40 ba a2 8b 48 c7 c7 60 b9 a2 8b e8 33 81 1d ff 90 <0f> 0b 90 90 e9 5f fe ff ff e8 04 69 5e ff 90 48 b8 00 00 00 00 00 RSP: 0018:ffffc90003637b08 EFLAGS: 00010282 RAX: 0000000000000000 RBX: ffff88805f534140 RCX: ffffffff817a92c8 RDX: ffff88807da99e00 RSI: ffffffff817a92d5 RDI: 0000000000000001 RBP: ffff888033431ac0 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000001 R12: ffff888033431a00 R13: ffff888033431ae4 R14: ffff888033184724 R15: dffffc0000000000 FS: 0000555580328500(0000) GS:ffff888124a62000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f71733743e0 CR3: 000000007f618000 CR4: 00000000003526f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: sunrpc_exit_net+0x46/0x90 net/sunrpc/sunrpc_syms.c:76 ops_exit_list net/core/net_namespace.c:200 [inline] ops_undo_list+0x2eb/0xab0 net/core/net_namespace.c:253 setup_net+0x2e1/0x510 net/core/net_namespace.c:457 copy_net_ns+0x2a6/0x5f0 net/core/net_namespace.c:574 create_new_namespaces+0x3ea/0xa90 kernel/nsproxy.c:110 unshare_nsproxy_namespaces+0xc0/0x1f0 kernel/nsproxy.c:218 ksys_unshare+0x45b/0xa40 kernel/fork.c:3121 __do_sys_unshare kernel/fork.c:3192 [inline] __se_sys_unshare kernel/fork.c:3190 [inline] __x64_sys_unshare+0x31/0x40 kernel/fork.c:3190 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcd/0x490 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7fa1a6b8e929 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fff3a090368 EFLAGS: 00000246 ORIG_RAX: 0000000000000110 RAX: ffffffffffffffda RBX: 00007fa1a6db5fa0 RCX: 00007fa1a6b8e929 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000040000080 RBP: 00007fa1a6c10b39 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007fa1a6db5fa0 R14: 00007fa1a6db5fa0 R15: 0000000000000001 Fixes: d47151b79e32 ("nfs: expose /proc/net/sunrpc/nfs in net namespaces") Reported-by: syzbot+a4cc4ac22daa4a71b87c@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=a4cc4ac22daa4a71b87c Tested-by: syzbot+a4cc4ac22daa4a71b87c@syzkaller.appspotmail.com Signed-off-by: Kuniyuki Iwashima Signed-off-by: Anna Schumaker Signed-off-by: Sasha Levin --- fs/nfs/inode.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 419d98cf9e29..7e7dd2aab449 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -2442,15 +2442,26 @@ EXPORT_SYMBOL_GPL(nfs_net_id); static int nfs_net_init(struct net *net) { struct nfs_net *nn = net_generic(net, nfs_net_id); + int err; nfs_clients_init(net); if (!rpc_proc_register(net, &nn->rpcstats)) { - nfs_clients_exit(net); - return -ENOMEM; + err = -ENOMEM; + goto err_proc_rpc; } - return nfs_fs_proc_net_init(net); + err = nfs_fs_proc_net_init(net); + if (err) + goto err_proc_nfs; + + return 0; + +err_proc_nfs: + rpc_proc_unregister(net, "nfs"); +err_proc_rpc: + nfs_clients_exit(net); + return err; } static void nfs_net_exit(struct net *net) From 8ca65fa71024a1767a59ffbc6a6e2278af84735e Mon Sep 17 00:00:00 2001 From: Benjamin Coddington Date: Thu, 19 Jun 2025 11:02:21 -0400 Subject: [PATCH 854/971] NFSv4/pNFS: Fix a race to wake on NFS_LAYOUT_DRAIN [ Upstream commit c01776287414ca43412d1319d2877cbad65444ac ] We found a few different systems hung up in writeback waiting on the same page lock, and one task waiting on the NFS_LAYOUT_DRAIN bit in pnfs_update_layout(), however the pnfs_layout_hdr's plh_outstanding count was zero. It seems most likely that this is another race between the waiter and waker similar to commit ed0172af5d6f ("SUNRPC: Fix a race to wake a sync task"). Fix it up by applying the advised barrier. Fixes: 880265c77ac4 ("pNFS: Avoid a live lock condition in pnfs_update_layout()") Signed-off-by: Benjamin Coddington Signed-off-by: Anna Schumaker Signed-off-by: Sasha Levin --- fs/nfs/pnfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 73aa5a63afe3..79d1ffdcbebd 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -1930,8 +1930,10 @@ static void nfs_layoutget_begin(struct pnfs_layout_hdr *lo) static void nfs_layoutget_end(struct pnfs_layout_hdr *lo) { if (atomic_dec_and_test(&lo->plh_outstanding) && - test_and_clear_bit(NFS_LAYOUT_DRAIN, &lo->plh_flags)) + test_and_clear_bit(NFS_LAYOUT_DRAIN, &lo->plh_flags)) { + smp_mb__after_atomic(); wake_up_bit(&lo->plh_flags, NFS_LAYOUT_DRAIN); + } } static bool pnfs_is_first_layoutget(struct pnfs_layout_hdr *lo) From c3ec87fbb00deb5ca1b7e2383441a81d65c4e1f7 Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Tue, 17 Jun 2025 18:11:11 +0200 Subject: [PATCH 855/971] scsi: qla2xxx: Fix DMA mapping test in qla24xx_get_port_database() [ Upstream commit c3b214719a87735d4f67333a8ef3c0e31a34837c ] dma_map_XXX() functions return as error values DMA_MAPPING_ERROR which is often ~0. The error value should be tested with dma_mapping_error() like it was done in qla26xx_dport_diagnostics(). Fixes: 818c7f87a177 ("scsi: qla2xxx: Add changes in preparation for vendor extended FDMI/RDP") Signed-off-by: Thomas Fourier Link: https://lore.kernel.org/r/20250617161115.39888-2-fourier.thomas@gmail.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/qla2xxx/qla_mbx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 0cd6f3e14882..13b6cb1b93ac 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -2147,7 +2147,7 @@ qla24xx_get_port_database(scsi_qla_host_t *vha, u16 nport_handle, pdb_dma = dma_map_single(&vha->hw->pdev->dev, pdb, sizeof(*pdb), DMA_FROM_DEVICE); - if (!pdb_dma) { + if (dma_mapping_error(&vha->hw->pdev->dev, pdb_dma)) { ql_log(ql_log_warn, vha, 0x1116, "Failed to map dma buffer.\n"); return QLA_MEMORY_ALLOC_FAILED; } From 39dac98aca12200cac8014442acf071b5423fe1f Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Wed, 18 Jun 2025 09:17:37 +0200 Subject: [PATCH 856/971] scsi: qla4xxx: Fix missing DMA mapping error in qla4xxx_alloc_pdu() [ Upstream commit 00f452a1b084efbe8dcb60a29860527944a002a1 ] dma_map_XXX() can fail and should be tested for errors with dma_mapping_error(). Fixes: b3a271a94d00 ("[SCSI] qla4xxx: support iscsiadm session mgmt") Signed-off-by: Thomas Fourier Link: https://lore.kernel.org/r/20250618071742.21822-2-fourier.thomas@gmail.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/qla4xxx/ql4_os.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 675332e49a7b..77c28d2ebf01 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -3420,6 +3420,8 @@ static int qla4xxx_alloc_pdu(struct iscsi_task *task, uint8_t opcode) task_data->data_dma = dma_map_single(&ha->pdev->dev, task->data, task->data_count, DMA_TO_DEVICE); + if (dma_mapping_error(&ha->pdev->dev, task_data->data_dma)) + return -ENOMEM; } DEBUG2(ql4_printk(KERN_INFO, ha, "%s: MaxRecvLen %u, iscsi hrd %d\n", From ee9cb28675a5d0a6c4471c083112b86e77798e35 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 24 Jun 2025 11:16:44 -0700 Subject: [PATCH 857/971] scsi: ufs: core: Fix spelling of a sysfs attribute name [ Upstream commit 021f243627ead17eb6500170256d3d9be787dad8 ] Change "resourse" into "resource" in the name of a sysfs attribute. Fixes: d829fc8a1058 ("scsi: ufs: sysfs: unit descriptor") Signed-off-by: Bart Van Assche Link: https://lore.kernel.org/r/20250624181658.336035-1-bvanassche@acm.org Reviewed-by: Avri Altman Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- Documentation/ABI/testing/sysfs-driver-ufs | 2 +- drivers/ufs/core/ufs-sysfs.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs index 0c7efaf62de0..84131641580c 100644 --- a/Documentation/ABI/testing/sysfs-driver-ufs +++ b/Documentation/ABI/testing/sysfs-driver-ufs @@ -711,7 +711,7 @@ Description: This file shows the thin provisioning type. This is one of The file is read only. -What: /sys/class/scsi_device/*/device/unit_descriptor/physical_memory_resourse_count +What: /sys/class/scsi_device/*/device/unit_descriptor/physical_memory_resource_count Date: February 2018 Contact: Stanislav Nijnikov Description: This file shows the total physical memory resources. This is diff --git a/drivers/ufs/core/ufs-sysfs.c b/drivers/ufs/core/ufs-sysfs.c index 3692b39b35e7..6c48255dfff0 100644 --- a/drivers/ufs/core/ufs-sysfs.c +++ b/drivers/ufs/core/ufs-sysfs.c @@ -1278,7 +1278,7 @@ UFS_UNIT_DESC_PARAM(logical_block_size, _LOGICAL_BLK_SIZE, 1); UFS_UNIT_DESC_PARAM(logical_block_count, _LOGICAL_BLK_COUNT, 8); UFS_UNIT_DESC_PARAM(erase_block_size, _ERASE_BLK_SIZE, 4); UFS_UNIT_DESC_PARAM(provisioning_type, _PROVISIONING_TYPE, 1); -UFS_UNIT_DESC_PARAM(physical_memory_resourse_count, _PHY_MEM_RSRC_CNT, 8); +UFS_UNIT_DESC_PARAM(physical_memory_resource_count, _PHY_MEM_RSRC_CNT, 8); UFS_UNIT_DESC_PARAM(context_capabilities, _CTX_CAPABILITIES, 2); UFS_UNIT_DESC_PARAM(large_unit_granularity, _LARGE_UNIT_SIZE_M1, 1); UFS_UNIT_DESC_PARAM(wb_buf_alloc_units, _WB_BUF_ALLOC_UNITS, 4); @@ -1295,7 +1295,7 @@ static struct attribute *ufs_sysfs_unit_descriptor[] = { &dev_attr_logical_block_count.attr, &dev_attr_erase_block_size.attr, &dev_attr_provisioning_type.attr, - &dev_attr_physical_memory_resourse_count.attr, + &dev_attr_physical_memory_resource_count.attr, &dev_attr_context_capabilities.attr, &dev_attr_large_unit_granularity.attr, &dev_attr_wb_buf_alloc_units.attr, From 301303d14da6a1b840fc078158ac4b94cf7a4bc1 Mon Sep 17 00:00:00 2001 From: Patrisious Haddad Date: Mon, 16 Jun 2025 12:14:52 +0300 Subject: [PATCH 858/971] RDMA/mlx5: Fix HW counters query for non-representor devices [ Upstream commit 3cc1dbfddf88dc5ecce0a75185061403b1f7352d ] To get the device HW counters, a non-representor switchdev device should use the mlx5_ib_query_q_counters() function and query all of the available counters. While a representor device in switchdev mode should use the mlx5_ib_query_q_counters_vport() function and query only the Q_Counters without the PPCNT counters and congestion control counters, since they aren't relevant for a representor device. Currently a non-representor switchdev device skips querying the PPCNT counters and congestion control counters, leaving them unupdated. Fix that by properly querying those counters for non-representor devices. Fixes: d22467a71ebe ("RDMA/mlx5: Expand switchdev Q-counters to expose representor statistics") Signed-off-by: Patrisious Haddad Reviewed-by: Maher Sanalla Link: https://patch.msgid.link/56bf8af4ca8c58e3fb9f7e47b1dca2009eeeed81.1750064969.git.leon@kernel.org Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin --- drivers/infiniband/hw/mlx5/counters.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/mlx5/counters.c b/drivers/infiniband/hw/mlx5/counters.c index b049bba21579..f4aa72166cf3 100644 --- a/drivers/infiniband/hw/mlx5/counters.c +++ b/drivers/infiniband/hw/mlx5/counters.c @@ -387,7 +387,7 @@ static int do_get_hw_stats(struct ib_device *ibdev, return ret; /* We don't expose device counters over Vports */ - if (is_mdev_switchdev_mode(dev->mdev) && port_num != 0) + if (is_mdev_switchdev_mode(dev->mdev) && dev->is_rep && port_num != 0) goto done; if (MLX5_CAP_PCAM_FEATURE(dev->mdev, rx_icrc_encapsulated_counter)) { From efb3413f6ba953ff774cab301705d8fca0576dd1 Mon Sep 17 00:00:00 2001 From: Patrisious Haddad Date: Mon, 16 Jun 2025 12:14:53 +0300 Subject: [PATCH 859/971] RDMA/mlx5: Fix CC counters query for MPV [ Upstream commit acd245b1e33fc4b9d0f2e3372021d632f7ee0652 ] In case, CC counters are querying for the second port use the correct core device for the query instead of always using the master core device. Fixes: aac4492ef23a ("IB/mlx5: Update counter implementation for dual port RoCE") Signed-off-by: Patrisious Haddad Reviewed-by: Michael Guralnik Link: https://patch.msgid.link/9cace74dcf106116118bebfa9146d40d4166c6b0.1750064969.git.leon@kernel.org Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin --- drivers/infiniband/hw/mlx5/counters.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/mlx5/counters.c b/drivers/infiniband/hw/mlx5/counters.c index f4aa72166cf3..d06128501ce4 100644 --- a/drivers/infiniband/hw/mlx5/counters.c +++ b/drivers/infiniband/hw/mlx5/counters.c @@ -407,7 +407,7 @@ static int do_get_hw_stats(struct ib_device *ibdev, */ goto done; } - ret = mlx5_lag_query_cong_counters(dev->mdev, + ret = mlx5_lag_query_cong_counters(mdev, stats->value + cnts->num_q_counters, cnts->num_cong_counters, From d8a1ad180c24fc186d6f927a0ac9482da06f9869 Mon Sep 17 00:00:00 2001 From: Patrisious Haddad Date: Mon, 16 Jun 2025 12:14:54 +0300 Subject: [PATCH 860/971] RDMA/mlx5: Fix vport loopback for MPV device [ Upstream commit a9a9e68954f29b1e197663f76289db4879fd51bb ] Always enable vport loopback for both MPV devices on driver start. Previously in some cases related to MPV RoCE, packets weren't correctly executing loopback check at vport in FW, since it was disabled. Due to complexity of identifying such cases for MPV always enable vport loopback for both GVMIs when binding the slave to the master port. Fixes: 0042f9e458a5 ("RDMA/mlx5: Enable vport loopback when user context or QP mandate") Signed-off-by: Patrisious Haddad Reviewed-by: Mark Bloch Link: https://patch.msgid.link/d4298f5ebb2197459e9e7221c51ecd6a34699847.1750064969.git.leon@kernel.org Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin --- drivers/infiniband/hw/mlx5/main.c | 33 +++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index ada7dbf8eb1c..e922fb872865 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -1690,6 +1690,33 @@ static void deallocate_uars(struct mlx5_ib_dev *dev, context->devx_uid); } +static int mlx5_ib_enable_lb_mp(struct mlx5_core_dev *master, + struct mlx5_core_dev *slave) +{ + int err; + + err = mlx5_nic_vport_update_local_lb(master, true); + if (err) + return err; + + err = mlx5_nic_vport_update_local_lb(slave, true); + if (err) + goto out; + + return 0; + +out: + mlx5_nic_vport_update_local_lb(master, false); + return err; +} + +static void mlx5_ib_disable_lb_mp(struct mlx5_core_dev *master, + struct mlx5_core_dev *slave) +{ + mlx5_nic_vport_update_local_lb(slave, false); + mlx5_nic_vport_update_local_lb(master, false); +} + int mlx5_ib_enable_lb(struct mlx5_ib_dev *dev, bool td, bool qp) { int err = 0; @@ -3224,6 +3251,8 @@ static void mlx5_ib_unbind_slave_port(struct mlx5_ib_dev *ibdev, lockdep_assert_held(&mlx5_ib_multiport_mutex); + mlx5_ib_disable_lb_mp(ibdev->mdev, mpi->mdev); + mlx5_core_mp_event_replay(ibdev->mdev, MLX5_DRIVER_EVENT_AFFILIATION_REMOVED, NULL); @@ -3319,6 +3348,10 @@ static bool mlx5_ib_bind_slave_port(struct mlx5_ib_dev *ibdev, MLX5_DRIVER_EVENT_AFFILIATION_DONE, &key); + err = mlx5_ib_enable_lb_mp(ibdev->mdev, mpi->mdev); + if (err) + goto unbind; + return true; unbind: From e373354ecfbf0fbf779098fd551735771f94df62 Mon Sep 17 00:00:00 2001 From: Alok Tiwari Date: Sun, 22 Jun 2025 00:29:12 -0700 Subject: [PATCH 861/971] platform/mellanox: nvsw-sn2201: Fix bus number in adapter error message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit d07143b507c51c04c091081627c5a130e9d3c517 ] change error log to use correct bus number from main_mux_devs instead of cpld_devs. Fixes: 662f24826f95 ("platform/mellanox: Add support for new SN2201 system") Signed-off-by: Alok Tiwari Reviewed-by: Vadim Pasternak Link: https://lore.kernel.org/r/20250622072921.4111552-2-alok.a.tiwari@oracle.com Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin --- drivers/platform/mellanox/nvsw-sn2201.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/mellanox/nvsw-sn2201.c b/drivers/platform/mellanox/nvsw-sn2201.c index 1a7c45aa41bb..6b4d3c44d7bd 100644 --- a/drivers/platform/mellanox/nvsw-sn2201.c +++ b/drivers/platform/mellanox/nvsw-sn2201.c @@ -1088,7 +1088,7 @@ static int nvsw_sn2201_i2c_completion_notify(void *handle, int id) if (!nvsw_sn2201->main_mux_devs->adapter) { err = -ENODEV; dev_err(nvsw_sn2201->dev, "Failed to get adapter for bus %d\n", - nvsw_sn2201->cpld_devs->nr); + nvsw_sn2201->main_mux_devs->nr); goto i2c_get_adapter_main_fail; } From 529281206f1167d875a8dde4a9eb85298d40fcf4 Mon Sep 17 00:00:00 2001 From: Yang Li Date: Thu, 19 Jun 2025 11:01:07 +0800 Subject: [PATCH 862/971] Bluetooth: Prevent unintended pause by checking if advertising is active [ Upstream commit 1f029b4e30a602db33dedee5ac676e9236ad193c ] When PA Create Sync is enabled, advertising resumes unexpectedly. Therefore, it's necessary to check whether advertising is currently active before attempting to pause it. < HCI Command: LE Add Device To... (0x08|0x0011) plen 7 #1345 [hci0] 48.306205 Address type: Random (0x01) Address: 4F:84:84:5F:88:17 (Resolvable) Identity type: Random (0x01) Identity: FC:5B:8C:F7:5D:FB (Static) < HCI Command: LE Set Address Re.. (0x08|0x002d) plen 1 #1347 [hci0] 48.308023 Address resolution: Enabled (0x01) ... < HCI Command: LE Set Extended A.. (0x08|0x0039) plen 6 #1349 [hci0] 48.309650 Extended advertising: Enabled (0x01) Number of sets: 1 (0x01) Entry 0 Handle: 0x01 Duration: 0 ms (0x00) Max ext adv events: 0 ... < HCI Command: LE Periodic Adve.. (0x08|0x0044) plen 14 #1355 [hci0] 48.314575 Options: 0x0000 Use advertising SID, Advertiser Address Type and address Reporting initially enabled SID: 0x02 Adv address type: Random (0x01) Adv address: 4F:84:84:5F:88:17 (Resolvable) Identity type: Random (0x01) Identity: FC:5B:8C:F7:5D:FB (Static) Skip: 0x0000 Sync timeout: 20000 msec (0x07d0) Sync CTE type: 0x0000 Fixes: ad383c2c65a5 ("Bluetooth: hci_sync: Enable advertising when LL privacy is enabled") Signed-off-by: Yang Li Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- net/bluetooth/hci_sync.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index 9ba4cb90891b..d602e9d8eff4 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -2518,6 +2518,10 @@ static int hci_pause_advertising_sync(struct hci_dev *hdev) int err; int old_state; + /* If controller is not advertising we are done. */ + if (!hci_dev_test_flag(hdev, HCI_LE_ADV)) + return 0; + /* If already been paused there is nothing to do. */ if (hdev->advertising_paused) return 0; From 79b025ebc1c0a4394b558f913056c0b270627f25 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Wed, 18 Jun 2025 16:57:07 +0100 Subject: [PATCH 863/971] btrfs: fix missing error handling when searching for inode refs during log replay [ Upstream commit 6561a40ceced9082f50c374a22d5966cf9fc5f5c ] During log replay, at __add_inode_ref(), when we are searching for inode ref keys we totally ignore if btrfs_search_slot() returns an error. This may make a log replay succeed when there was an actual error and leave some metadata inconsistency in a subvolume tree. Fix this by checking if an error was returned from btrfs_search_slot() and if so, return it to the caller. Fixes: e02119d5a7b4 ("Btrfs: Add a write ahead tree log to optimize synchronous operations") Reviewed-by: Johannes Thumshirn Reviewed-by: Qu Wenruo Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/tree-log.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index cc9a2f8a4ae3..6dbb62f83f8c 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -1087,7 +1087,9 @@ again: search_key.type = BTRFS_INODE_REF_KEY; search_key.offset = parent_objectid; ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); - if (ret == 0) { + if (ret < 0) { + return ret; + } else if (ret == 0) { struct btrfs_inode_ref *victim_ref; unsigned long ptr; unsigned long ptr_end; From 2d11d274e2e1d7c79e2ca8461ce3ff3a95c11171 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Mon, 23 Jun 2025 12:11:58 +0100 Subject: [PATCH 864/971] btrfs: fix iteration of extrefs during log replay [ Upstream commit 54a7081ed168b72a8a2d6ef4ba3a1259705a2926 ] At __inode_add_ref() when processing extrefs, if we jump into the next label we have an undefined value of victim_name.len, since we haven't initialized it before we did the goto. This results in an invalid memory access in the next iteration of the loop since victim_name.len was not initialized to the length of the name of the current extref. Fix this by initializing victim_name.len with the current extref's name length. Fixes: e43eec81c516 ("btrfs: use struct qstr instead of name and namelen pairs") Reviewed-by: Johannes Thumshirn Reviewed-by: Qu Wenruo Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/tree-log.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 6dbb62f83f8c..13377c3b2289 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -1162,13 +1162,13 @@ again: struct fscrypt_str victim_name; extref = (struct btrfs_inode_extref *)(base + cur_offset); + victim_name.len = btrfs_inode_extref_name_len(leaf, extref); if (btrfs_inode_extref_parent(leaf, extref) != parent_objectid) goto next; ret = read_alloc_one_name(leaf, &extref->name, - btrfs_inode_extref_name_len(leaf, extref), - &victim_name); + victim_name.len, &victim_name); if (ret) return ret; From 65d7f92db8a9548b4265fd11eef3a3cf5ba1fe87 Mon Sep 17 00:00:00 2001 From: Anand Jain Date: Tue, 19 Mar 2024 11:40:23 +0800 Subject: [PATCH 865/971] btrfs: rename err to ret in btrfs_rmdir() [ Upstream commit c3a1cc8ff48875b050fda5285ac8a9889eb7898d ] Unify naming of return value to the preferred way. Signed-off-by: Anand Jain Reviewed-by: David Sterba Signed-off-by: David Sterba Stable-dep-of: c466e33e729a ("btrfs: propagate last_unlink_trans earlier when doing a rmdir") Signed-off-by: Sasha Levin --- fs/btrfs/inode.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index af1f22b3cff7..c2c07ad194c0 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4615,7 +4615,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) { struct inode *inode = d_inode(dentry); struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info; - int err = 0; + int ret = 0; struct btrfs_trans_handle *trans; u64 last_unlink_trans; struct fscrypt_name fname; @@ -4631,33 +4631,33 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) return btrfs_delete_subvolume(BTRFS_I(dir), dentry); } - err = fscrypt_setup_filename(dir, &dentry->d_name, 1, &fname); - if (err) - return err; + ret = fscrypt_setup_filename(dir, &dentry->d_name, 1, &fname); + if (ret) + return ret; /* This needs to handle no-key deletions later on */ trans = __unlink_start_trans(BTRFS_I(dir)); if (IS_ERR(trans)) { - err = PTR_ERR(trans); + ret = PTR_ERR(trans); goto out_notrans; } if (unlikely(btrfs_ino(BTRFS_I(inode)) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) { - err = btrfs_unlink_subvol(trans, BTRFS_I(dir), dentry); + ret = btrfs_unlink_subvol(trans, BTRFS_I(dir), dentry); goto out; } - err = btrfs_orphan_add(trans, BTRFS_I(inode)); - if (err) + ret = btrfs_orphan_add(trans, BTRFS_I(inode)); + if (ret) goto out; last_unlink_trans = BTRFS_I(inode)->last_unlink_trans; /* now the directory is empty */ - err = btrfs_unlink_inode(trans, BTRFS_I(dir), BTRFS_I(d_inode(dentry)), + ret = btrfs_unlink_inode(trans, BTRFS_I(dir), BTRFS_I(d_inode(dentry)), &fname.disk_name); - if (!err) { + if (!ret) { btrfs_i_size_write(BTRFS_I(inode), 0); /* * Propagate the last_unlink_trans value of the deleted dir to @@ -4679,7 +4679,7 @@ out_notrans: btrfs_btree_balance_dirty(fs_info); fscrypt_free_filename(&fname); - return err; + return ret; } /* From d77a16802896bcc0cbe66facf87d7af57262ea1a Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Fri, 20 Jun 2025 15:54:05 +0100 Subject: [PATCH 866/971] btrfs: propagate last_unlink_trans earlier when doing a rmdir [ Upstream commit c466e33e729a0ee017d10d919cba18f503853c60 ] In case the removed directory had a snapshot that was deleted, we are propagating its inode's last_unlink_trans to the parent directory after we removed the entry from the parent directory. This leaves a small race window where someone can log the parent directory after we removed the entry and before we updated last_unlink_trans, and as a result if we ever try to replay such a log tree, we will fail since we will attempt to remove a snapshot during log replay, which is currently not possible and results in the log replay (and mount) to fail. This is the type of failure described in commit 1ec9a1ae1e30 ("Btrfs: fix unreplayable log after snapshot delete + parent dir fsync"). So fix this by propagating the last_unlink_trans to the parent directory before we remove the entry from it. Fixes: 44f714dae50a ("Btrfs: improve performance on fsync against new inode after rename/unlink") Reviewed-by: Johannes Thumshirn Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/inode.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index c2c07ad194c0..cee1a11959c5 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4617,7 +4617,6 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info; int ret = 0; struct btrfs_trans_handle *trans; - u64 last_unlink_trans; struct fscrypt_name fname; if (inode->i_size > BTRFS_EMPTY_DIR_SIZE) @@ -4643,6 +4642,23 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) goto out_notrans; } + /* + * Propagate the last_unlink_trans value of the deleted dir to its + * parent directory. This is to prevent an unrecoverable log tree in the + * case we do something like this: + * 1) create dir foo + * 2) create snapshot under dir foo + * 3) delete the snapshot + * 4) rmdir foo + * 5) mkdir foo + * 6) fsync foo or some file inside foo + * + * This is because we can't unlink other roots when replaying the dir + * deletes for directory foo. + */ + if (BTRFS_I(inode)->last_unlink_trans >= trans->transid) + BTRFS_I(dir)->last_unlink_trans = BTRFS_I(inode)->last_unlink_trans; + if (unlikely(btrfs_ino(BTRFS_I(inode)) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) { ret = btrfs_unlink_subvol(trans, BTRFS_I(dir), dentry); goto out; @@ -4652,27 +4668,11 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) if (ret) goto out; - last_unlink_trans = BTRFS_I(inode)->last_unlink_trans; - /* now the directory is empty */ ret = btrfs_unlink_inode(trans, BTRFS_I(dir), BTRFS_I(d_inode(dentry)), &fname.disk_name); - if (!ret) { + if (!ret) btrfs_i_size_write(BTRFS_I(inode), 0); - /* - * Propagate the last_unlink_trans value of the deleted dir to - * its parent directory. This is to prevent an unrecoverable - * log tree in the case we do something like this: - * 1) create dir foo - * 2) create snapshot under dir foo - * 3) delete the snapshot - * 4) rmdir foo - * 5) mkdir foo - * 6) fsync foo or some file inside foo - */ - if (last_unlink_trans >= trans->transid) - BTRFS_I(dir)->last_unlink_trans = last_unlink_trans; - } out: btrfs_end_transaction(trans); out_notrans: From 2a7ac29f10d89f614bae7d5595e476892e1709fe Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Fri, 20 Jun 2025 16:37:01 +0100 Subject: [PATCH 867/971] btrfs: use btrfs_record_snapshot_destroy() during rmdir [ Upstream commit 157501b0469969fc1ba53add5049575aadd79d80 ] We are setting the parent directory's last_unlink_trans directly which may result in a concurrent task starting to log the directory not see the update and therefore can log the directory after we removed a child directory which had a snapshot within instead of falling back to a transaction commit. Replaying such a log tree would result in a mount failure since we can't currently delete snapshots (and subvolumes) during log replay. This is the type of failure described in commit 1ec9a1ae1e30 ("Btrfs: fix unreplayable log after snapshot delete + parent dir fsync"). Fix this by using btrfs_record_snapshot_destroy() which updates the last_unlink_trans field while holding the inode's log_mutex lock. Fixes: 44f714dae50a ("Btrfs: improve performance on fsync against new inode after rename/unlink") Reviewed-by: Johannes Thumshirn Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index cee1a11959c5..e8e57abb032d 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4657,7 +4657,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) * deletes for directory foo. */ if (BTRFS_I(inode)->last_unlink_trans >= trans->transid) - BTRFS_I(dir)->last_unlink_trans = BTRFS_I(inode)->last_unlink_trans; + btrfs_record_snapshot_destroy(trans, BTRFS_I(dir)); if (unlikely(btrfs_ino(BTRFS_I(inode)) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) { ret = btrfs_unlink_subvol(trans, BTRFS_I(dir), dentry); From 31afd307975f314153969c1ea0fb37d26251c57d Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Wed, 25 Jun 2025 16:16:24 +0200 Subject: [PATCH 868/971] ethernet: atl1: Add missing DMA mapping error checks and count errors [ Upstream commit d72411d20905180cdc452c553be17481b24463d2 ] The `dma_map_XXX()` functions can fail and must be checked using `dma_mapping_error()`. This patch adds proper error handling for all DMA mapping calls. In `atl1_alloc_rx_buffers()`, if DMA mapping fails, the buffer is deallocated and marked accordingly. In `atl1_tx_map()`, previously mapped buffers are unmapped and the packet is dropped on failure. If `atl1_xmit_frame()` drops the packet, increment the tx_error counter. Fixes: f3cc28c79760 ("Add Attansic L1 ethernet driver.") Signed-off-by: Thomas Fourier Link: https://patch.msgid.link/20250625141629.114984-2-fourier.thomas@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/atheros/atlx/atl1.c | 79 +++++++++++++++++------- 1 file changed, 57 insertions(+), 22 deletions(-) diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c index 02aa6fd8ebc2..4ed165702d58 100644 --- a/drivers/net/ethernet/atheros/atlx/atl1.c +++ b/drivers/net/ethernet/atheros/atlx/atl1.c @@ -1861,14 +1861,21 @@ static u16 atl1_alloc_rx_buffers(struct atl1_adapter *adapter) break; } - buffer_info->alloced = 1; - buffer_info->skb = skb; - buffer_info->length = (u16) adapter->rx_buffer_len; page = virt_to_page(skb->data); offset = offset_in_page(skb->data); buffer_info->dma = dma_map_page(&pdev->dev, page, offset, adapter->rx_buffer_len, DMA_FROM_DEVICE); + if (dma_mapping_error(&pdev->dev, buffer_info->dma)) { + kfree_skb(skb); + adapter->soft_stats.rx_dropped++; + break; + } + + buffer_info->alloced = 1; + buffer_info->skb = skb; + buffer_info->length = (u16)adapter->rx_buffer_len; + rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma); rfd_desc->buf_len = cpu_to_le16(adapter->rx_buffer_len); rfd_desc->coalese = 0; @@ -2183,8 +2190,8 @@ static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb, return 0; } -static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb, - struct tx_packet_desc *ptpd) +static bool atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb, + struct tx_packet_desc *ptpd) { struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring; struct atl1_buffer *buffer_info; @@ -2194,6 +2201,7 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb, unsigned int nr_frags; unsigned int f; int retval; + u16 first_mapped; u16 next_to_use; u16 data_len; u8 hdr_len; @@ -2201,6 +2209,7 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb, buf_len -= skb->data_len; nr_frags = skb_shinfo(skb)->nr_frags; next_to_use = atomic_read(&tpd_ring->next_to_use); + first_mapped = next_to_use; buffer_info = &tpd_ring->buffer_info[next_to_use]; BUG_ON(buffer_info->skb); /* put skb in last TPD */ @@ -2216,6 +2225,8 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb, buffer_info->dma = dma_map_page(&adapter->pdev->dev, page, offset, hdr_len, DMA_TO_DEVICE); + if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma)) + goto dma_err; if (++next_to_use == tpd_ring->count) next_to_use = 0; @@ -2242,6 +2253,9 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb, page, offset, buffer_info->length, DMA_TO_DEVICE); + if (dma_mapping_error(&adapter->pdev->dev, + buffer_info->dma)) + goto dma_err; if (++next_to_use == tpd_ring->count) next_to_use = 0; } @@ -2254,6 +2268,8 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb, buffer_info->dma = dma_map_page(&adapter->pdev->dev, page, offset, buf_len, DMA_TO_DEVICE); + if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma)) + goto dma_err; if (++next_to_use == tpd_ring->count) next_to_use = 0; } @@ -2277,6 +2293,9 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb, buffer_info->dma = skb_frag_dma_map(&adapter->pdev->dev, frag, i * ATL1_MAX_TX_BUF_LEN, buffer_info->length, DMA_TO_DEVICE); + if (dma_mapping_error(&adapter->pdev->dev, + buffer_info->dma)) + goto dma_err; if (++next_to_use == tpd_ring->count) next_to_use = 0; @@ -2285,6 +2304,22 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb, /* last tpd's buffer-info */ buffer_info->skb = skb; + + return true; + + dma_err: + while (first_mapped != next_to_use) { + buffer_info = &tpd_ring->buffer_info[first_mapped]; + dma_unmap_page(&adapter->pdev->dev, + buffer_info->dma, + buffer_info->length, + DMA_TO_DEVICE); + buffer_info->dma = 0; + + if (++first_mapped == tpd_ring->count) + first_mapped = 0; + } + return false; } static void atl1_tx_queue(struct atl1_adapter *adapter, u16 count, @@ -2355,10 +2390,8 @@ static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb, len = skb_headlen(skb); - if (unlikely(skb->len <= 0)) { - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } + if (unlikely(skb->len <= 0)) + goto drop_packet; nr_frags = skb_shinfo(skb)->nr_frags; for (f = 0; f < nr_frags; f++) { @@ -2371,10 +2404,9 @@ static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb, if (mss) { if (skb->protocol == htons(ETH_P_IP)) { proto_hdr_len = skb_tcp_all_headers(skb); - if (unlikely(proto_hdr_len > len)) { - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } + if (unlikely(proto_hdr_len > len)) + goto drop_packet; + /* need additional TPD ? */ if (proto_hdr_len != len) count += (len - proto_hdr_len + @@ -2406,23 +2438,26 @@ static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb, } tso = atl1_tso(adapter, skb, ptpd); - if (tso < 0) { - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } + if (tso < 0) + goto drop_packet; if (!tso) { ret_val = atl1_tx_csum(adapter, skb, ptpd); - if (ret_val < 0) { - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } + if (ret_val < 0) + goto drop_packet; } - atl1_tx_map(adapter, skb, ptpd); + if (!atl1_tx_map(adapter, skb, ptpd)) + goto drop_packet; + atl1_tx_queue(adapter, count, ptpd); atl1_update_mailbox(adapter); return NETDEV_TX_OK; + +drop_packet: + adapter->soft_stats.tx_errors++; + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; } static int atl1_rings_clean(struct napi_struct *napi, int budget) From 7e6423f80bd65b5a420348182d93666bcca8399b Mon Sep 17 00:00:00 2001 From: Fushuai Wang Date: Thu, 26 Jun 2025 21:30:03 +0800 Subject: [PATCH 869/971] dpaa2-eth: fix xdp_rxq_info leak [ Upstream commit 2def09ead4ad5907988b655d1e1454003aaf8297 ] The driver registered xdp_rxq_info structures via xdp_rxq_info_reg() but failed to properly unregister them in error paths and during removal. Fixes: d678be1dc1ec ("dpaa2-eth: add XDP_REDIRECT support") Signed-off-by: Fushuai Wang Reviewed-by: Simon Horman Reviewed-by: Ioana Ciornei Link: https://patch.msgid.link/20250626133003.80136-1-wangfushuai@baidu.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- .../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c index 40e881829595..d3c36a6f84b0 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c @@ -3928,6 +3928,7 @@ static int dpaa2_eth_setup_rx_flow(struct dpaa2_eth_priv *priv, MEM_TYPE_PAGE_ORDER0, NULL); if (err) { dev_err(dev, "xdp_rxq_info_reg_mem_model failed\n"); + xdp_rxq_info_unreg(&fq->channel->xdp_rxq); return err; } @@ -4421,17 +4422,25 @@ static int dpaa2_eth_bind_dpni(struct dpaa2_eth_priv *priv) return -EINVAL; } if (err) - return err; + goto out; } err = dpni_get_qdid(priv->mc_io, 0, priv->mc_token, DPNI_QUEUE_TX, &priv->tx_qdid); if (err) { dev_err(dev, "dpni_get_qdid() failed\n"); - return err; + goto out; } return 0; + +out: + while (i--) { + if (priv->fq[i].type == DPAA2_RX_FQ && + xdp_rxq_info_is_reg(&priv->fq[i].channel->xdp_rxq)) + xdp_rxq_info_unreg(&priv->fq[i].channel->xdp_rxq); + } + return err; } /* Allocate rings for storing incoming frame descriptors */ @@ -4813,6 +4822,17 @@ static void dpaa2_eth_del_ch_napi(struct dpaa2_eth_priv *priv) } } +static void dpaa2_eth_free_rx_xdp_rxq(struct dpaa2_eth_priv *priv) +{ + int i; + + for (i = 0; i < priv->num_fqs; i++) { + if (priv->fq[i].type == DPAA2_RX_FQ && + xdp_rxq_info_is_reg(&priv->fq[i].channel->xdp_rxq)) + xdp_rxq_info_unreg(&priv->fq[i].channel->xdp_rxq); + } +} + static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev) { struct device *dev; @@ -5016,6 +5036,7 @@ err_alloc_percpu_extras: free_percpu(priv->percpu_stats); err_alloc_percpu_stats: dpaa2_eth_del_ch_napi(priv); + dpaa2_eth_free_rx_xdp_rxq(priv); err_bind: dpaa2_eth_free_dpbps(priv); err_dpbp_setup: @@ -5068,6 +5089,7 @@ static void dpaa2_eth_remove(struct fsl_mc_device *ls_dev) free_percpu(priv->percpu_extras); dpaa2_eth_del_ch_napi(priv); + dpaa2_eth_free_rx_xdp_rxq(priv); dpaa2_eth_free_dpbps(priv); dpaa2_eth_free_dpio(priv); dpaa2_eth_free_dpni(priv); From 1fc5dc930137f6a31262c7f84aa74d379800ef3d Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 18 Jun 2025 14:06:26 +0200 Subject: [PATCH 870/971] drm/exynos: fimd: Guard display clock control with runtime PM calls [ Upstream commit 5d91394f236167ac624b823820faf4aa928b889e ] Commit c9b1150a68d9 ("drm/atomic-helper: Re-order bridge chain pre-enable and post-disable") changed the call sequence to the CRTC enable/disable and bridge pre_enable/post_disable methods, so those bridge methods are now called when CRTC is not yet enabled. This causes a lockup observed on Samsung Peach-Pit/Pi Chromebooks. The source of this lockup is a call to fimd_dp_clock_enable() function, when FIMD device is not yet runtime resumed. It worked before the mentioned commit only because the CRTC implemented by the FIMD driver was always enabled what guaranteed the FIMD device to be runtime resumed. This patch adds runtime PM guards to the fimd_dp_clock_enable() function to enable its proper operation also when the CRTC implemented by FIMD is not yet enabled. Fixes: 196e059a8a6a ("drm/exynos: convert clock_enable crtc callback to pipeline clock") Signed-off-by: Marek Szyprowski Reviewed-by: Tomi Valkeinen Signed-off-by: Inki Dae Signed-off-by: Sasha Levin --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 5bdc246f5fad..341e95269836 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -187,6 +187,7 @@ struct fimd_context { u32 i80ifcon; bool i80_if; bool suspended; + bool dp_clk_enabled; wait_queue_head_t wait_vsync_queue; atomic_t wait_vsync_event; atomic_t win_updated; @@ -1047,7 +1048,18 @@ static void fimd_dp_clock_enable(struct exynos_drm_clk *clk, bool enable) struct fimd_context *ctx = container_of(clk, struct fimd_context, dp_clk); u32 val = enable ? DP_MIE_CLK_DP_ENABLE : DP_MIE_CLK_DISABLE; + + if (enable == ctx->dp_clk_enabled) + return; + + if (enable) + pm_runtime_resume_and_get(ctx->dev); + + ctx->dp_clk_enabled = enable; writel(val, ctx->regs + DP_MIE_CLKCON); + + if (!enable) + pm_runtime_put(ctx->dev); } static const struct exynos_drm_crtc_ops fimd_crtc_ops = { From 822c05444ffae495a61499ab11f75caeda0a1917 Mon Sep 17 00:00:00 2001 From: James Clark Date: Fri, 27 Jun 2025 11:21:37 +0100 Subject: [PATCH 871/971] spi: spi-fsl-dspi: Clear completion counter before initiating transfer [ Upstream commit fa60c094c19b97e103d653f528f8d9c178b6a5f5 ] In target mode, extra interrupts can be received between the end of a transfer and halting the module if the host continues sending more data. If the interrupt from this occurs after the reinit_completion() then the completion counter is left at a non-zero value. The next unrelated transfer initiated by userspace will then complete immediately without waiting for the interrupt or writing to the RX buffer. Fix it by resetting the counter before the transfer so that lingering values are cleared. This is done after clearing the FIFOs and the status register but before the transfer is initiated, so no interrupts should be received at this point resulting in other race conditions. Fixes: 4f5ee75ea171 ("spi: spi-fsl-dspi: Replace interruptible wait queue with a simple completion") Signed-off-by: James Clark Reviewed-by: Frank Li Link: https://patch.msgid.link/20250627-james-nxp-spi-dma-v4-1-178dba20c120@linaro.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-fsl-dspi.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 7dd94369abb4..3206c84c6f22 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -988,11 +988,20 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr, if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) { status = dspi_dma_xfer(dspi); } else { + /* + * Reinitialize the completion before transferring data + * to avoid the case where it might remain in the done + * state due to a spurious interrupt from a previous + * transfer. This could falsely signal that the current + * transfer has completed. + */ + if (dspi->irq) + reinit_completion(&dspi->xfer_done); + dspi_fifo_write(dspi); if (dspi->irq) { wait_for_completion(&dspi->xfer_done); - reinit_completion(&dspi->xfer_done); } else { do { status = dspi_poll(dspi); From 55a90f82d4ffe7d140ac870a0a35130753c25d1c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 25 Jun 2025 10:21:58 -0500 Subject: [PATCH 872/971] drm/i915/selftests: Change mock_request() to return error pointers [ Upstream commit caa7c7a76b78ce41d347003f84975125383e6b59 ] There was an error pointer vs NULL bug in __igt_breadcrumbs_smoketest(). The __mock_request_alloc() function implements the smoketest->request_alloc() function pointer. It was supposed to return error pointers, but it propogates the NULL return from mock_request() so in the event of a failure, it would lead to a NULL pointer dereference. To fix this, change the mock_request() function to return error pointers and update all the callers to expect that. Fixes: 52c0fdb25c7c ("drm/i915: Replace global breadcrumbs with per-context interrupt tracking") Signed-off-by: Dan Carpenter Reviewed-by: Rodrigo Vivi Link: https://lore.kernel.org/r/685c1417.050a0220.696f5.5c05@mx.google.com Signed-off-by: Rodrigo Vivi (cherry picked from commit 778fa8ad5f0f23397d045c7ebca048ce8def1c43) Signed-off-by: Joonas Lahtinen Signed-off-by: Sasha Levin --- drivers/gpu/drm/i915/selftests/i915_request.c | 20 +++++++++---------- drivers/gpu/drm/i915/selftests/mock_request.c | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c index a9b79888c193..c7ce2c570ad1 100644 --- a/drivers/gpu/drm/i915/selftests/i915_request.c +++ b/drivers/gpu/drm/i915/selftests/i915_request.c @@ -73,8 +73,8 @@ static int igt_add_request(void *arg) /* Basic preliminary test to create a request and let it loose! */ request = mock_request(rcs0(i915)->kernel_context, HZ / 10); - if (!request) - return -ENOMEM; + if (IS_ERR(request)) + return PTR_ERR(request); i915_request_add(request); @@ -91,8 +91,8 @@ static int igt_wait_request(void *arg) /* Submit a request, then wait upon it */ request = mock_request(rcs0(i915)->kernel_context, T); - if (!request) - return -ENOMEM; + if (IS_ERR(request)) + return PTR_ERR(request); i915_request_get(request); @@ -160,8 +160,8 @@ static int igt_fence_wait(void *arg) /* Submit a request, treat it as a fence and wait upon it */ request = mock_request(rcs0(i915)->kernel_context, T); - if (!request) - return -ENOMEM; + if (IS_ERR(request)) + return PTR_ERR(request); if (dma_fence_wait_timeout(&request->fence, false, T) != -ETIME) { pr_err("fence wait success before submit (expected timeout)!\n"); @@ -219,8 +219,8 @@ static int igt_request_rewind(void *arg) GEM_BUG_ON(IS_ERR(ce)); request = mock_request(ce, 2 * HZ); intel_context_put(ce); - if (!request) { - err = -ENOMEM; + if (IS_ERR(request)) { + err = PTR_ERR(request); goto err_context_0; } @@ -237,8 +237,8 @@ static int igt_request_rewind(void *arg) GEM_BUG_ON(IS_ERR(ce)); vip = mock_request(ce, 0); intel_context_put(ce); - if (!vip) { - err = -ENOMEM; + if (IS_ERR(vip)) { + err = PTR_ERR(vip); goto err_context_1; } diff --git a/drivers/gpu/drm/i915/selftests/mock_request.c b/drivers/gpu/drm/i915/selftests/mock_request.c index 09f747228dff..1b0cf073e964 100644 --- a/drivers/gpu/drm/i915/selftests/mock_request.c +++ b/drivers/gpu/drm/i915/selftests/mock_request.c @@ -35,7 +35,7 @@ mock_request(struct intel_context *ce, unsigned long delay) /* NB the i915->requests slab cache is enlarged to fit mock_request */ request = intel_context_create_request(ce); if (IS_ERR(request)) - return NULL; + return request; request->mock.delay = delay; return request; From 0deb3eb78ebf225cb41aa9b2b2150f46cbfd359e Mon Sep 17 00:00:00 2001 From: Kurt Borja Date: Mon, 30 Jun 2025 00:43:12 -0300 Subject: [PATCH 873/971] platform/x86: dell-wmi-sysman: Fix WMI data block retrieval in sysfs callbacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit eb617dd25ca176f3fee24f873f0fd60010773d67 ] After retrieving WMI data blocks in sysfs callbacks, check for the validity of them before dereferencing their content. Reported-by: Jan Graczyk Closes: https://lore.kernel.org/r/CAHk-=wgMiSKXf7SvQrfEnxVtmT=QVQPjJdNjfm3aXS7wc=rzTw@mail.gmail.com/ Fixes: e8a60aa7404b ("platform/x86: Introduce support for Systems Management Driver over WMI for Dell Systems") Suggested-by: Linus Torvalds Reviewed-by: Armin Wolf Signed-off-by: Kurt Borja Link: https://lore.kernel.org/r/20250630-sysman-fix-v2-1-d185674d0a30@gmail.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin --- .../platform/x86/dell/dell-wmi-sysman/dell-wmi-sysman.h | 5 +++++ .../platform/x86/dell/dell-wmi-sysman/enum-attributes.c | 5 +++-- .../platform/x86/dell/dell-wmi-sysman/int-attributes.c | 5 +++-- .../x86/dell/dell-wmi-sysman/passobj-attributes.c | 5 +++-- .../platform/x86/dell/dell-wmi-sysman/string-attributes.c | 5 +++-- drivers/platform/x86/dell/dell-wmi-sysman/sysman.c | 8 ++++---- 6 files changed, 21 insertions(+), 12 deletions(-) diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/dell-wmi-sysman.h b/drivers/platform/x86/dell/dell-wmi-sysman/dell-wmi-sysman.h index 3ad33a094588..817ee7ba07ca 100644 --- a/drivers/platform/x86/dell/dell-wmi-sysman/dell-wmi-sysman.h +++ b/drivers/platform/x86/dell/dell-wmi-sysman/dell-wmi-sysman.h @@ -89,6 +89,11 @@ extern struct wmi_sysman_priv wmi_priv; enum { ENUM, INT, STR, PO }; +#define ENUM_MIN_ELEMENTS 8 +#define INT_MIN_ELEMENTS 9 +#define STR_MIN_ELEMENTS 8 +#define PO_MIN_ELEMENTS 4 + enum { ATTR_NAME, DISPL_NAME_LANG_CODE, diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/enum-attributes.c b/drivers/platform/x86/dell/dell-wmi-sysman/enum-attributes.c index 8cc212c85266..fc2f58b4cbc6 100644 --- a/drivers/platform/x86/dell/dell-wmi-sysman/enum-attributes.c +++ b/drivers/platform/x86/dell/dell-wmi-sysman/enum-attributes.c @@ -23,9 +23,10 @@ static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *a obj = get_wmiobj_pointer(instance_id, DELL_WMI_BIOS_ENUMERATION_ATTRIBUTE_GUID); if (!obj) return -EIO; - if (obj->package.elements[CURRENT_VAL].type != ACPI_TYPE_STRING) { + if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count < ENUM_MIN_ELEMENTS || + obj->package.elements[CURRENT_VAL].type != ACPI_TYPE_STRING) { kfree(obj); - return -EINVAL; + return -EIO; } ret = snprintf(buf, PAGE_SIZE, "%s\n", obj->package.elements[CURRENT_VAL].string.pointer); kfree(obj); diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/int-attributes.c b/drivers/platform/x86/dell/dell-wmi-sysman/int-attributes.c index 951e75b538fa..735248064239 100644 --- a/drivers/platform/x86/dell/dell-wmi-sysman/int-attributes.c +++ b/drivers/platform/x86/dell/dell-wmi-sysman/int-attributes.c @@ -25,9 +25,10 @@ static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *a obj = get_wmiobj_pointer(instance_id, DELL_WMI_BIOS_INTEGER_ATTRIBUTE_GUID); if (!obj) return -EIO; - if (obj->package.elements[CURRENT_VAL].type != ACPI_TYPE_INTEGER) { + if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count < INT_MIN_ELEMENTS || + obj->package.elements[CURRENT_VAL].type != ACPI_TYPE_INTEGER) { kfree(obj); - return -EINVAL; + return -EIO; } ret = snprintf(buf, PAGE_SIZE, "%lld\n", obj->package.elements[CURRENT_VAL].integer.value); kfree(obj); diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/passobj-attributes.c b/drivers/platform/x86/dell/dell-wmi-sysman/passobj-attributes.c index d8f1bf5e58a0..3167e06d416e 100644 --- a/drivers/platform/x86/dell/dell-wmi-sysman/passobj-attributes.c +++ b/drivers/platform/x86/dell/dell-wmi-sysman/passobj-attributes.c @@ -26,9 +26,10 @@ static ssize_t is_enabled_show(struct kobject *kobj, struct kobj_attribute *attr obj = get_wmiobj_pointer(instance_id, DELL_WMI_BIOS_PASSOBJ_ATTRIBUTE_GUID); if (!obj) return -EIO; - if (obj->package.elements[IS_PASS_SET].type != ACPI_TYPE_INTEGER) { + if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count < PO_MIN_ELEMENTS || + obj->package.elements[IS_PASS_SET].type != ACPI_TYPE_INTEGER) { kfree(obj); - return -EINVAL; + return -EIO; } ret = snprintf(buf, PAGE_SIZE, "%lld\n", obj->package.elements[IS_PASS_SET].integer.value); kfree(obj); diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/string-attributes.c b/drivers/platform/x86/dell/dell-wmi-sysman/string-attributes.c index c392f0ecf8b5..0d2c74f8d1aa 100644 --- a/drivers/platform/x86/dell/dell-wmi-sysman/string-attributes.c +++ b/drivers/platform/x86/dell/dell-wmi-sysman/string-attributes.c @@ -25,9 +25,10 @@ static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *a obj = get_wmiobj_pointer(instance_id, DELL_WMI_BIOS_STRING_ATTRIBUTE_GUID); if (!obj) return -EIO; - if (obj->package.elements[CURRENT_VAL].type != ACPI_TYPE_STRING) { + if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count < STR_MIN_ELEMENTS || + obj->package.elements[CURRENT_VAL].type != ACPI_TYPE_STRING) { kfree(obj); - return -EINVAL; + return -EIO; } ret = snprintf(buf, PAGE_SIZE, "%s\n", obj->package.elements[CURRENT_VAL].string.pointer); kfree(obj); diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c b/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c index af49dd6b31ad..f567d37a64a3 100644 --- a/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c +++ b/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c @@ -408,10 +408,10 @@ static int init_bios_attributes(int attr_type, const char *guid) return retval; switch (attr_type) { - case ENUM: min_elements = 8; break; - case INT: min_elements = 9; break; - case STR: min_elements = 8; break; - case PO: min_elements = 4; break; + case ENUM: min_elements = ENUM_MIN_ELEMENTS; break; + case INT: min_elements = INT_MIN_ELEMENTS; break; + case STR: min_elements = STR_MIN_ELEMENTS; break; + case PO: min_elements = PO_MIN_ELEMENTS; break; default: pr_err("Error: Unknown attr_type: %d\n", attr_type); return -EINVAL; From 3df1e72b7bfed2f5ae0454f5f649e21fc541bef6 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 11 Sep 2023 09:28:46 +0200 Subject: [PATCH 874/971] arm64: dts: qcom: sm8550: add UART14 nodes [ Upstream commit 75cac7090298978c12c59dbca377d957f6f8a8bb ] Add the Geni High Speed UART QUP instance 2 element 6 node and associated default pinctrl. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20230911-topic-sm8550-upstream-bt-v4-1-a5a428c77418@linaro.org Signed-off-by: Bjorn Andersson Stable-dep-of: 5ff1fbb30597 ("platform/x86: think-lmi: Fix class device unregistration") Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/qcom/sm8550.dtsi | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi index c14c6f8583d5..2f0f1c2ab739 100644 --- a/arch/arm64/boot/dts/qcom/sm8550.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi @@ -1064,6 +1064,20 @@ status = "disabled"; }; + uart14: serial@898000 { + compatible = "qcom,geni-uart"; + reg = <0 0x898000 0 0x4000>; + clock-names = "se"; + clocks = <&gcc GCC_QUPV3_WRAP2_S6_CLK>; + pinctrl-names = "default"; + pinctrl-0 = <&qup_uart14_default>, <&qup_uart14_cts_rts>; + interrupts = ; + interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>; + interconnect-names = "qup-core", "qup-config"; + status = "disabled"; + }; + i2c15: i2c@89c000 { compatible = "qcom,geni-i2c"; reg = <0 0x0089c000 0 0x4000>; @@ -3640,6 +3654,22 @@ bias-disable; }; + qup_uart14_default: qup-uart14-default-state { + /* TX, RX */ + pins = "gpio78", "gpio79"; + function = "qup2_se6"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_uart14_cts_rts: qup-uart14-cts-rts-state { + /* CTS, RTS */ + pins = "gpio76", "gpio77"; + function = "qup2_se6"; + drive-strength = <2>; + bias-pull-down; + }; + sdc2_sleep: sdc2-sleep-state { clk-pins { pins = "sdc2_clk"; From 9143d22a09b5c11f2f711f07a62bf7f900c60d07 Mon Sep 17 00:00:00 2001 From: "Ricardo B. Marliere" Date: Tue, 5 Mar 2024 15:55:04 -0300 Subject: [PATCH 875/971] platform/x86: make fw_attr_class constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 5878e5b760b6fcf7bc00dec085ba2b439a929871 ] Since commit 43a7206b0963 ("driver core: class: make class_register() take a const *"), the driver core allows for struct class to be in read-only memory, so move the fw_attr_class structure to be declared at build time placing it into read-only memory, instead of having to be dynamically allocated at boot time. Cc: Greg Kroah-Hartman Suggested-by: Greg Kroah-Hartman Signed-off-by: "Ricardo B. Marliere" Link: https://lore.kernel.org/r/20240305-class_cleanup-platform-v1-1-9085c97b9355@marliere.net Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Stable-dep-of: 5ff1fbb30597 ("platform/x86: think-lmi: Fix class device unregistration") Signed-off-by: Sasha Levin --- drivers/platform/x86/dell/dell-wmi-sysman/sysman.c | 2 +- drivers/platform/x86/firmware_attributes_class.c | 4 ++-- drivers/platform/x86/firmware_attributes_class.h | 2 +- drivers/platform/x86/hp/hp-bioscfg/bioscfg.c | 2 +- drivers/platform/x86/think-lmi.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c b/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c index f567d37a64a3..decb3b997d86 100644 --- a/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c +++ b/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c @@ -25,7 +25,7 @@ struct wmi_sysman_priv wmi_priv = { /* reset bios to defaults */ static const char * const reset_types[] = {"builtinsafe", "lastknowngood", "factory", "custom"}; static int reset_option = -1; -static struct class *fw_attr_class; +static const struct class *fw_attr_class; /** diff --git a/drivers/platform/x86/firmware_attributes_class.c b/drivers/platform/x86/firmware_attributes_class.c index fafe8eaf6e3e..dd8240009565 100644 --- a/drivers/platform/x86/firmware_attributes_class.c +++ b/drivers/platform/x86/firmware_attributes_class.c @@ -10,11 +10,11 @@ static DEFINE_MUTEX(fw_attr_lock); static int fw_attr_inuse; -static struct class firmware_attributes_class = { +static const struct class firmware_attributes_class = { .name = "firmware-attributes", }; -int fw_attributes_class_get(struct class **fw_attr_class) +int fw_attributes_class_get(const struct class **fw_attr_class) { int err; diff --git a/drivers/platform/x86/firmware_attributes_class.h b/drivers/platform/x86/firmware_attributes_class.h index 486485cb1f54..363c75f1ac1b 100644 --- a/drivers/platform/x86/firmware_attributes_class.h +++ b/drivers/platform/x86/firmware_attributes_class.h @@ -5,7 +5,7 @@ #ifndef FW_ATTR_CLASS_H #define FW_ATTR_CLASS_H -int fw_attributes_class_get(struct class **fw_attr_class); +int fw_attributes_class_get(const struct class **fw_attr_class); int fw_attributes_class_put(void); #endif /* FW_ATTR_CLASS_H */ diff --git a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c index 6ddca857cc4d..b8bac35ebd42 100644 --- a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c +++ b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c @@ -24,7 +24,7 @@ struct bioscfg_priv bioscfg_drv = { .mutex = __MUTEX_INITIALIZER(bioscfg_drv.mutex), }; -static struct class *fw_attr_class; +static const struct class *fw_attr_class; ssize_t display_name_language_code_show(struct kobject *kobj, struct kobj_attribute *attr, diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index 2396decdb3cb..3a496c615ce6 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -195,7 +195,7 @@ static const char * const level_options[] = { [TLMI_LEVEL_MASTER] = "master", }; static struct think_lmi tlmi_priv; -static struct class *fw_attr_class; +static const struct class *fw_attr_class; static DEFINE_MUTEX(tlmi_mutex); /* ------ Utility functions ------------*/ From e52b896d5fb70dd140624d6a478c944f5e174e25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Sat, 4 Jan 2025 00:05:09 +0100 Subject: [PATCH 876/971] platform/x86: firmware_attributes_class: Move include linux/device/class.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit d0eee1be379204d2ee6cdb09bd98b3fd0165b6d3 ] The header firmware_attributes_class.h uses 'struct class'. It should also include the necessary dependency header. Signed-off-by: Thomas Weißschuh Reviewed-by: Armin Wolf Reviewed-by: Mario Limonciello Reviewed-by: Mark Pearson Tested-by: Mark Pearson Link: https://lore.kernel.org/r/20250104-firmware-attributes-simplify-v1-1-949f9709e405@weissschuh.net Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Stable-dep-of: 5ff1fbb30597 ("platform/x86: think-lmi: Fix class device unregistration") Signed-off-by: Sasha Levin --- drivers/platform/x86/firmware_attributes_class.c | 1 - drivers/platform/x86/firmware_attributes_class.h | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/firmware_attributes_class.c b/drivers/platform/x86/firmware_attributes_class.c index dd8240009565..4801f9f44aaa 100644 --- a/drivers/platform/x86/firmware_attributes_class.c +++ b/drivers/platform/x86/firmware_attributes_class.c @@ -3,7 +3,6 @@ /* Firmware attributes class helper module */ #include -#include #include #include "firmware_attributes_class.h" diff --git a/drivers/platform/x86/firmware_attributes_class.h b/drivers/platform/x86/firmware_attributes_class.h index 363c75f1ac1b..8e0f47cfdf92 100644 --- a/drivers/platform/x86/firmware_attributes_class.h +++ b/drivers/platform/x86/firmware_attributes_class.h @@ -5,6 +5,8 @@ #ifndef FW_ATTR_CLASS_H #define FW_ATTR_CLASS_H +#include + int fw_attributes_class_get(const struct class **fw_attr_class); int fw_attributes_class_put(void); From ee813c62af62029916339f86f22da63fadc242aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Sat, 4 Jan 2025 00:05:10 +0100 Subject: [PATCH 877/971] platform/x86: firmware_attributes_class: Simplify API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit d03cfde56f5cf9ec50b4cf099a42bf056fc80ddd ] The module core already guarantees that a module can only be unloaded after all other modules using its symbols have been unloaded. As it's already the responsibility of the drivers using firmware_attributes_class to clean up their devices before unloading, the lifetime of the firmware_attributes_class can be bound to the lifetime of the module. This enables the direct usage of firmware_attributes_class from the drivers, without having to go through the lifecycle functions, leading to simplifications for both the subsystem and its users. Signed-off-by: Thomas Weißschuh Reviewed-by: Armin Wolf Reviewed-by: Mario Limonciello Reviewed-by: Mark Pearson Tested-by: Mark Pearson Link: https://lore.kernel.org/r/20250104-firmware-attributes-simplify-v1-2-949f9709e405@weissschuh.net Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Stable-dep-of: 5ff1fbb30597 ("platform/x86: think-lmi: Fix class device unregistration") Signed-off-by: Sasha Levin --- .../platform/x86/firmware_attributes_class.c | 40 +++++++------------ .../platform/x86/firmware_attributes_class.h | 1 + 2 files changed, 15 insertions(+), 26 deletions(-) diff --git a/drivers/platform/x86/firmware_attributes_class.c b/drivers/platform/x86/firmware_attributes_class.c index 4801f9f44aaa..e214efc97311 100644 --- a/drivers/platform/x86/firmware_attributes_class.c +++ b/drivers/platform/x86/firmware_attributes_class.c @@ -2,47 +2,35 @@ /* Firmware attributes class helper module */ -#include #include #include "firmware_attributes_class.h" -static DEFINE_MUTEX(fw_attr_lock); -static int fw_attr_inuse; - -static const struct class firmware_attributes_class = { +const struct class firmware_attributes_class = { .name = "firmware-attributes", }; +EXPORT_SYMBOL_GPL(firmware_attributes_class); + +static __init int fw_attributes_class_init(void) +{ + return class_register(&firmware_attributes_class); +} +module_init(fw_attributes_class_init); + +static __exit void fw_attributes_class_exit(void) +{ + class_unregister(&firmware_attributes_class); +} +module_exit(fw_attributes_class_exit); int fw_attributes_class_get(const struct class **fw_attr_class) { - int err; - - mutex_lock(&fw_attr_lock); - if (!fw_attr_inuse) { /*first time class is being used*/ - err = class_register(&firmware_attributes_class); - if (err) { - mutex_unlock(&fw_attr_lock); - return err; - } - } - fw_attr_inuse++; *fw_attr_class = &firmware_attributes_class; - mutex_unlock(&fw_attr_lock); return 0; } EXPORT_SYMBOL_GPL(fw_attributes_class_get); int fw_attributes_class_put(void) { - mutex_lock(&fw_attr_lock); - if (!fw_attr_inuse) { - mutex_unlock(&fw_attr_lock); - return -EINVAL; - } - fw_attr_inuse--; - if (!fw_attr_inuse) /* No more consumers */ - class_unregister(&firmware_attributes_class); - mutex_unlock(&fw_attr_lock); return 0; } EXPORT_SYMBOL_GPL(fw_attributes_class_put); diff --git a/drivers/platform/x86/firmware_attributes_class.h b/drivers/platform/x86/firmware_attributes_class.h index 8e0f47cfdf92..ef6c3764a834 100644 --- a/drivers/platform/x86/firmware_attributes_class.h +++ b/drivers/platform/x86/firmware_attributes_class.h @@ -7,6 +7,7 @@ #include +extern const struct class firmware_attributes_class; int fw_attributes_class_get(const struct class **fw_attr_class); int fw_attributes_class_put(void); From 093ee65bdafb723c79ce085442cb907ba5e19025 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Sat, 4 Jan 2025 00:05:11 +0100 Subject: [PATCH 878/971] platform/x86: think-lmi: Directly use firmware_attributes_class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 55922403807a12d4f96c67ba01a920edfb6f2633 ] The usage of the lifecycle functions is not necessary anymore. Signed-off-by: Thomas Weißschuh Reviewed-by: Armin Wolf Reviewed-by: Mario Limonciello Reviewed-by: Mark Pearson Tested-by: Mark Pearson Link: https://lore.kernel.org/r/20250104-firmware-attributes-simplify-v1-3-949f9709e405@weissschuh.net Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Stable-dep-of: 5ff1fbb30597 ("platform/x86: think-lmi: Fix class device unregistration") Signed-off-by: Sasha Levin --- drivers/platform/x86/think-lmi.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index 3a496c615ce6..f0efa60cf8ee 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -195,7 +195,6 @@ static const char * const level_options[] = { [TLMI_LEVEL_MASTER] = "master", }; static struct think_lmi tlmi_priv; -static const struct class *fw_attr_class; static DEFINE_MUTEX(tlmi_mutex); /* ------ Utility functions ------------*/ @@ -1272,11 +1271,7 @@ static int tlmi_sysfs_init(void) { int i, ret; - ret = fw_attributes_class_get(&fw_attr_class); - if (ret) - return ret; - - tlmi_priv.class_dev = device_create(fw_attr_class, NULL, MKDEV(0, 0), + tlmi_priv.class_dev = device_create(&firmware_attributes_class, NULL, MKDEV(0, 0), NULL, "%s", "thinklmi"); if (IS_ERR(tlmi_priv.class_dev)) { ret = PTR_ERR(tlmi_priv.class_dev); @@ -1385,9 +1380,8 @@ static int tlmi_sysfs_init(void) fail_create_attr: tlmi_release_attr(); fail_device_created: - device_destroy(fw_attr_class, MKDEV(0, 0)); + device_destroy(&firmware_attributes_class, MKDEV(0, 0)); fail_class_created: - fw_attributes_class_put(); return ret; } @@ -1610,8 +1604,7 @@ fail_clear_attr: static void tlmi_remove(struct wmi_device *wdev) { tlmi_release_attr(); - device_destroy(fw_attr_class, MKDEV(0, 0)); - fw_attributes_class_put(); + device_destroy(&firmware_attributes_class, MKDEV(0, 0)); } static int tlmi_probe(struct wmi_device *wdev, const void *context) From 4074f6a15e95986deb01b1ca50a71b9f86a0be43 Mon Sep 17 00:00:00 2001 From: Kurt Borja Date: Wed, 25 Jun 2025 22:17:36 -0300 Subject: [PATCH 879/971] platform/x86: think-lmi: Fix class device unregistration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 5ff1fbb3059730700b4823f43999fc1315984632 ] Devices under the firmware_attributes_class do not have unique a dev_t. Therefore, device_unregister() should be used instead of device_destroy(), since the latter may match any device with a given dev_t. Fixes: a40cd7ef22fb ("platform/x86: think-lmi: Add WMI interface support on Lenovo platforms") Signed-off-by: Kurt Borja Link: https://lore.kernel.org/r/20250625-dest-fix-v1-2-3a0f342312bb@gmail.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin --- drivers/platform/x86/think-lmi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index f0efa60cf8ee..626990d103e3 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -1380,7 +1380,7 @@ static int tlmi_sysfs_init(void) fail_create_attr: tlmi_release_attr(); fail_device_created: - device_destroy(&firmware_attributes_class, MKDEV(0, 0)); + device_unregister(tlmi_priv.class_dev); fail_class_created: return ret; } @@ -1604,7 +1604,7 @@ fail_clear_attr: static void tlmi_remove(struct wmi_device *wdev) { tlmi_release_attr(); - device_destroy(&firmware_attributes_class, MKDEV(0, 0)); + device_unregister(tlmi_priv.class_dev); } static int tlmi_probe(struct wmi_device *wdev, const void *context) From dba37f72aae3a60bc1961b77b0602eaa98b38464 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Sat, 4 Jan 2025 00:05:13 +0100 Subject: [PATCH 880/971] platform/x86: dell-sysman: Directly use firmware_attributes_class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 501d2f0e78951b9a933bbff73404b25aec45f389 ] The usage of the lifecycle functions is not necessary anymore. Signed-off-by: Thomas Weißschuh Reviewed-by: Armin Wolf Reviewed-by: Mario Limonciello Reviewed-by: Mark Pearson Tested-by: Mark Pearson Link: https://lore.kernel.org/r/20250104-firmware-attributes-simplify-v1-5-949f9709e405@weissschuh.net Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Stable-dep-of: 314e5ad4782d ("platform/x86: dell-wmi-sysman: Fix class device unregistration") Signed-off-by: Sasha Levin --- .../platform/x86/dell/dell-wmi-sysman/sysman.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c b/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c index decb3b997d86..3c74d5e8350a 100644 --- a/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c +++ b/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c @@ -25,7 +25,6 @@ struct wmi_sysman_priv wmi_priv = { /* reset bios to defaults */ static const char * const reset_types[] = {"builtinsafe", "lastknowngood", "factory", "custom"}; static int reset_option = -1; -static const struct class *fw_attr_class; /** @@ -541,15 +540,11 @@ static int __init sysman_init(void) goto err_exit_bios_attr_pass_interface; } - ret = fw_attributes_class_get(&fw_attr_class); - if (ret) - goto err_exit_bios_attr_pass_interface; - - wmi_priv.class_dev = device_create(fw_attr_class, NULL, MKDEV(0, 0), + wmi_priv.class_dev = device_create(&firmware_attributes_class, NULL, MKDEV(0, 0), NULL, "%s", DRIVER_NAME); if (IS_ERR(wmi_priv.class_dev)) { ret = PTR_ERR(wmi_priv.class_dev); - goto err_unregister_class; + goto err_exit_bios_attr_pass_interface; } wmi_priv.main_dir_kset = kset_create_and_add("attributes", NULL, @@ -602,10 +597,7 @@ err_release_attributes_data: release_attributes_data(); err_destroy_classdev: - device_destroy(fw_attr_class, MKDEV(0, 0)); - -err_unregister_class: - fw_attributes_class_put(); + device_destroy(&firmware_attributes_class, MKDEV(0, 0)); err_exit_bios_attr_pass_interface: exit_bios_attr_pass_interface(); @@ -619,8 +611,7 @@ err_exit_bios_attr_set_interface: static void __exit sysman_exit(void) { release_attributes_data(); - device_destroy(fw_attr_class, MKDEV(0, 0)); - fw_attributes_class_put(); + device_destroy(&firmware_attributes_class, MKDEV(0, 0)); exit_bios_attr_set_interface(); exit_bios_attr_pass_interface(); } From 0cee638d92ac898d73eccc4e4bab70e9fc95946a Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Wed, 25 Jun 2025 00:00:17 -0300 Subject: [PATCH 881/971] smb: client: fix warning when reconnecting channel [ Upstream commit 3bbe46716092d8ef6b0df4b956f585c5cd0fc78e ] When reconnecting a channel in smb2_reconnect_server(), a dummy tcon is passed down to smb2_reconnect() with ->query_interface uninitialized, so we can't call queue_delayed_work() on it. Fix the following warning by ensuring that we're queueing the delayed worker from correct tcon. WARNING: CPU: 4 PID: 1126 at kernel/workqueue.c:2498 __queue_delayed_work+0x1d2/0x200 Modules linked in: cifs cifs_arc4 nls_ucs2_utils cifs_md4 [last unloaded: cifs] CPU: 4 UID: 0 PID: 1126 Comm: kworker/4:0 Not tainted 6.16.0-rc3 #5 PREEMPT(voluntary) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-4.fc42 04/01/2014 Workqueue: cifsiod smb2_reconnect_server [cifs] RIP: 0010:__queue_delayed_work+0x1d2/0x200 Code: 41 5e 41 5f e9 7f ee ff ff 90 0f 0b 90 e9 5d ff ff ff bf 02 00 00 00 e8 6c f3 07 00 89 c3 eb bd 90 0f 0b 90 e9 57 f> 0b 90 e9 65 fe ff ff 90 0f 0b 90 e9 72 fe ff ff 90 0f 0b 90 e9 RSP: 0018:ffffc900014afad8 EFLAGS: 00010003 RAX: 0000000000000000 RBX: ffff888124d99988 RCX: ffffffff81399cc1 RDX: dffffc0000000000 RSI: ffff888114326e00 RDI: ffff888124d999f0 RBP: 000000000000ea60 R08: 0000000000000001 R09: ffffed10249b3331 R10: ffff888124d9998f R11: 0000000000000004 R12: 0000000000000040 R13: ffff888114326e00 R14: ffff888124d999d8 R15: ffff888114939020 FS: 0000000000000000(0000) GS:ffff88829f7fe000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ffe7a2b4038 CR3: 0000000120a6f000 CR4: 0000000000750ef0 PKRU: 55555554 Call Trace: queue_delayed_work_on+0xb4/0xc0 smb2_reconnect+0xb22/0xf50 [cifs] smb2_reconnect_server+0x413/0xd40 [cifs] ? __pfx_smb2_reconnect_server+0x10/0x10 [cifs] ? local_clock_noinstr+0xd/0xd0 ? local_clock+0x15/0x30 ? lock_release+0x29b/0x390 process_one_work+0x4c5/0xa10 ? __pfx_process_one_work+0x10/0x10 ? __list_add_valid_or_report+0x37/0x120 worker_thread+0x2f1/0x5a0 ? __kthread_parkme+0xde/0x100 ? __pfx_worker_thread+0x10/0x10 kthread+0x1fe/0x380 ? kthread+0x10f/0x380 ? __pfx_kthread+0x10/0x10 ? local_clock_noinstr+0xd/0xd0 ? ret_from_fork+0x1b/0x1f0 ? local_clock+0x15/0x30 ? lock_release+0x29b/0x390 ? rcu_is_watching+0x20/0x50 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x15b/0x1f0 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 irq event stamp: 1116206 hardirqs last enabled at (1116205): [] __up_console_sem+0x52/0x60 hardirqs last disabled at (1116206): [] queue_delayed_work_on+0x6e/0xc0 softirqs last enabled at (1116138): [] __smb_send_rqst+0x42d/0x950 [cifs] softirqs last disabled at (1116136): [] release_sock+0x21/0xf0 Cc: linux-cifs@vger.kernel.org Reported-by: David Howells Fixes: 42ca547b13a2 ("cifs: do not disable interface polling on failure") Reviewed-by: David Howells Tested-by: David Howells Reviewed-by: Shyam Prasad N Signed-off-by: Paulo Alcantara (Red Hat) Signed-off-by: David Howells Tested-by: Steve French Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/smb/client/cifsglob.h | 1 + fs/smb/client/smb2pdu.c | 10 ++++------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index d776340ad91c..a6020f7408fe 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -1268,6 +1268,7 @@ struct cifs_tcon { bool use_persistent:1; /* use persistent instead of durable handles */ bool no_lease:1; /* Do not request leases on files or directories */ bool use_witness:1; /* use witness protocol */ + bool dummy:1; /* dummy tcon used for reconnecting channels */ __le32 capabilities; __u32 share_flags; __u32 maximal_access; diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c index e0f586009330..357abb0170c4 100644 --- a/fs/smb/client/smb2pdu.c +++ b/fs/smb/client/smb2pdu.c @@ -437,9 +437,9 @@ skip_sess_setup: free_xid(xid); ses->flags &= ~CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES; - /* regardless of rc value, setup polling */ - queue_delayed_work(cifsiod_wq, &tcon->query_interfaces, - (SMB_INTERFACE_POLL_INTERVAL * HZ)); + if (!tcon->ipc && !tcon->dummy) + queue_delayed_work(cifsiod_wq, &tcon->query_interfaces, + (SMB_INTERFACE_POLL_INTERVAL * HZ)); mutex_unlock(&ses->session_mutex); @@ -4228,10 +4228,8 @@ void smb2_reconnect_server(struct work_struct *work) } goto done; } - tcon->status = TID_GOOD; - tcon->retry = false; - tcon->need_reconnect = false; + tcon->dummy = true; /* now reconnect sessions for necessary channels */ list_for_each_entry_safe(ses, ses2, &tmp_ses_list, rlist) { From 421672fb7f1339895900728ddd79a6459a309427 Mon Sep 17 00:00:00 2001 From: Kurt Borja Date: Wed, 25 Jun 2025 22:17:37 -0300 Subject: [PATCH 882/971] platform/x86: dell-wmi-sysman: Fix class device unregistration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 314e5ad4782d08858b3abc325c0487bd2abc23a1 ] Devices under the firmware_attributes_class do not have unique a dev_t. Therefore, device_unregister() should be used instead of device_destroy(), since the latter may match any device with a given dev_t. Fixes: e8a60aa7404b ("platform/x86: Introduce support for Systems Management Driver over WMI for Dell Systems") Signed-off-by: Kurt Borja Link: https://lore.kernel.org/r/20250625-dest-fix-v1-3-3a0f342312bb@gmail.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin --- drivers/platform/x86/dell/dell-wmi-sysman/sysman.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c b/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c index 3c74d5e8350a..f5402b714657 100644 --- a/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c +++ b/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c @@ -597,7 +597,7 @@ err_release_attributes_data: release_attributes_data(); err_destroy_classdev: - device_destroy(&firmware_attributes_class, MKDEV(0, 0)); + device_unregister(wmi_priv.class_dev); err_exit_bios_attr_pass_interface: exit_bios_attr_pass_interface(); @@ -611,7 +611,7 @@ err_exit_bios_attr_set_interface: static void __exit sysman_exit(void) { release_attributes_data(); - device_destroy(&firmware_attributes_class, MKDEV(0, 0)); + device_unregister(wmi_priv.class_dev); exit_bios_attr_set_interface(); exit_bios_attr_pass_interface(); } From 968a419c95131e420f12bbdba19e96e2f6b071c4 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 27 Jun 2025 07:13:46 +0200 Subject: [PATCH 883/971] net: usb: lan78xx: fix WARN in __netif_napi_del_locked on disconnect [ Upstream commit 6c7ffc9af7186ed79403a3ffee9a1e5199fc7450 ] Remove redundant netif_napi_del() call from disconnect path. A WARN may be triggered in __netif_napi_del_locked() during USB device disconnect: WARNING: CPU: 0 PID: 11 at net/core/dev.c:7417 __netif_napi_del_locked+0x2b4/0x350 This happens because netif_napi_del() is called in the disconnect path while NAPI is still enabled. However, it is not necessary to call netif_napi_del() explicitly, since unregister_netdev() will handle NAPI teardown automatically and safely. Removing the redundant call avoids triggering the warning. Full trace: lan78xx 1-1:1.0 enu1: Failed to read register index 0x000000c4. ret = -ENODEV lan78xx 1-1:1.0 enu1: Failed to set MAC down with error -ENODEV lan78xx 1-1:1.0 enu1: Link is Down lan78xx 1-1:1.0 enu1: Failed to read register index 0x00000120. ret = -ENODEV ------------[ cut here ]------------ WARNING: CPU: 0 PID: 11 at net/core/dev.c:7417 __netif_napi_del_locked+0x2b4/0x350 Modules linked in: flexcan can_dev fuse CPU: 0 UID: 0 PID: 11 Comm: kworker/0:1 Not tainted 6.16.0-rc2-00624-ge926949dab03 #9 PREEMPT Hardware name: SKOV IMX8MP CPU revC - bd500 (DT) Workqueue: usb_hub_wq hub_event pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : __netif_napi_del_locked+0x2b4/0x350 lr : __netif_napi_del_locked+0x7c/0x350 sp : ffffffc085b673c0 x29: ffffffc085b673c0 x28: ffffff800b7f2000 x27: ffffff800b7f20d8 x26: ffffff80110bcf58 x25: ffffff80110bd978 x24: 1ffffff0022179eb x23: ffffff80110bc000 x22: ffffff800b7f5000 x21: ffffff80110bc000 x20: ffffff80110bcf38 x19: ffffff80110bcf28 x18: dfffffc000000000 x17: ffffffc081578940 x16: ffffffc08284cee0 x15: 0000000000000028 x14: 0000000000000006 x13: 0000000000040000 x12: ffffffb0022179e8 x11: 1ffffff0022179e7 x10: ffffffb0022179e7 x9 : dfffffc000000000 x8 : 0000004ffdde8619 x7 : ffffff80110bcf3f x6 : 0000000000000001 x5 : ffffff80110bcf38 x4 : ffffff80110bcf38 x3 : 0000000000000000 x2 : 0000000000000000 x1 : 1ffffff0022179e7 x0 : 0000000000000000 Call trace: __netif_napi_del_locked+0x2b4/0x350 (P) lan78xx_disconnect+0xf4/0x360 usb_unbind_interface+0x158/0x718 device_remove+0x100/0x150 device_release_driver_internal+0x308/0x478 device_release_driver+0x1c/0x30 bus_remove_device+0x1a8/0x368 device_del+0x2e0/0x7b0 usb_disable_device+0x244/0x540 usb_disconnect+0x220/0x758 hub_event+0x105c/0x35e0 process_one_work+0x760/0x17b0 worker_thread+0x768/0xce8 kthread+0x3bc/0x690 ret_from_fork+0x10/0x20 irq event stamp: 211604 hardirqs last enabled at (211603): [] _raw_spin_unlock_irqrestore+0x84/0x98 hardirqs last disabled at (211604): [] el1_dbg+0x24/0x80 softirqs last enabled at (211296): [] handle_softirqs+0x820/0xbc8 softirqs last disabled at (210993): [] __do_softirq+0x18/0x20 ---[ end trace 0000000000000000 ]--- lan78xx 1-1:1.0 enu1: failed to kill vid 0081/0 Fixes: ec4c7e12396b ("lan78xx: Introduce NAPI polling support") Suggested-by: Jakub Kicinski Signed-off-by: Oleksij Rempel Link: https://patch.msgid.link/20250627051346.276029-1-o.rempel@pengutronix.de Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/usb/lan78xx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 09173d7b87ed..ec5689cd240a 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -4229,8 +4229,6 @@ static void lan78xx_disconnect(struct usb_interface *intf) if (!dev) return; - netif_napi_del(&dev->napi); - udev = interface_to_usbdev(intf); net = dev->net; From 33713f7cda3d541d7eee43b18e712acfa75cdf60 Mon Sep 17 00:00:00 2001 From: Alok Tiwari Date: Mon, 30 Jun 2025 03:58:08 -0700 Subject: [PATCH 884/971] platform/mellanox: mlxreg-lc: Fix logic error in power state check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 644bec18e705ca41d444053407419a21832fcb2f ] Fixes a logic issue in mlxreg_lc_completion_notify() where the intention was to check if MLXREG_LC_POWERED flag is not set before powering on the device. The original code used "state & ~MLXREG_LC_POWERED" to check for the absence of the POWERED bit. However this condition evaluates to true even when other bits are set, leading to potentially incorrect behavior. Corrected the logic to explicitly check for the absence of MLXREG_LC_POWERED using !(state & MLXREG_LC_POWERED). Fixes: 62f9529b8d5c ("platform/mellanox: mlxreg-lc: Add initial support for Nvidia line card devices") Suggested-by: Vadim Pasternak Signed-off-by: Alok Tiwari Link: https://lore.kernel.org/r/20250630105812.601014-1-alok.a.tiwari@oracle.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin --- drivers/platform/mellanox/mlxreg-lc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/mellanox/mlxreg-lc.c b/drivers/platform/mellanox/mlxreg-lc.c index 8d833836a6d3..74e9d78ff01e 100644 --- a/drivers/platform/mellanox/mlxreg-lc.c +++ b/drivers/platform/mellanox/mlxreg-lc.c @@ -688,7 +688,7 @@ static int mlxreg_lc_completion_notify(void *handle, struct i2c_adapter *parent, if (regval & mlxreg_lc->data->mask) { mlxreg_lc->state |= MLXREG_LC_SYNCED; mlxreg_lc_state_update_locked(mlxreg_lc, MLXREG_LC_SYNCED, 1); - if (mlxreg_lc->state & ~MLXREG_LC_POWERED) { + if (!(mlxreg_lc->state & MLXREG_LC_POWERED)) { err = mlxreg_lc_power_on_off(mlxreg_lc, 1); if (err) goto mlxreg_lc_regmap_power_on_off_fail; From 40e09506aea1fde1f3e0e04eca531bbb23404baf Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Wed, 11 Jun 2025 12:42:13 +0200 Subject: [PATCH 885/971] drm/i915/gt: Fix timeline left held on VMA alloc error [ Upstream commit a5aa7bc1fca78c7fa127d9e33aa94a0c9066c1d6 ] The following error has been reported sporadically by CI when a test unbinds the i915 driver on a ring submission platform: <4> [239.330153] ------------[ cut here ]------------ <4> [239.330166] i915 0000:00:02.0: [drm] drm_WARN_ON(dev_priv->mm.shrink_count) <4> [239.330196] WARNING: CPU: 1 PID: 18570 at drivers/gpu/drm/i915/i915_gem.c:1309 i915_gem_cleanup_early+0x13e/0x150 [i915] ... <4> [239.330640] RIP: 0010:i915_gem_cleanup_early+0x13e/0x150 [i915] ... <4> [239.330942] Call Trace: <4> [239.330944] <4> [239.330949] i915_driver_late_release+0x2b/0xa0 [i915] <4> [239.331202] i915_driver_release+0x86/0xa0 [i915] <4> [239.331482] devm_drm_dev_init_release+0x61/0x90 <4> [239.331494] devm_action_release+0x15/0x30 <4> [239.331504] release_nodes+0x3d/0x120 <4> [239.331517] devres_release_all+0x96/0xd0 <4> [239.331533] device_unbind_cleanup+0x12/0x80 <4> [239.331543] device_release_driver_internal+0x23a/0x280 <4> [239.331550] ? bus_find_device+0xa5/0xe0 <4> [239.331563] device_driver_detach+0x14/0x20 ... <4> [357.719679] ---[ end trace 0000000000000000 ]--- If the test also unloads the i915 module then that's followed with: <3> [357.787478] ============================================================================= <3> [357.788006] BUG i915_vma (Tainted: G U W N ): Objects remaining on __kmem_cache_shutdown() <3> [357.788031] ----------------------------------------------------------------------------- <3> [357.788204] Object 0xffff888109e7f480 @offset=29824 <3> [357.788670] Allocated in i915_vma_instance+0xee/0xc10 [i915] age=292729 cpu=4 pid=2244 <4> [357.788994] i915_vma_instance+0xee/0xc10 [i915] <4> [357.789290] init_status_page+0x7b/0x420 [i915] <4> [357.789532] intel_engines_init+0x1d8/0x980 [i915] <4> [357.789772] intel_gt_init+0x175/0x450 [i915] <4> [357.790014] i915_gem_init+0x113/0x340 [i915] <4> [357.790281] i915_driver_probe+0x847/0xed0 [i915] <4> [357.790504] i915_pci_probe+0xe6/0x220 [i915] ... Closer analysis of CI results history has revealed a dependency of the error on a few IGT tests, namely: - igt@api_intel_allocator@fork-simple-stress-signal, - igt@api_intel_allocator@two-level-inception-interruptible, - igt@gem_linear_blits@interruptible, - igt@prime_mmap_coherency@ioctl-errors, which invisibly trigger the issue, then exhibited with first driver unbind attempt. All of the above tests perform actions which are actively interrupted with signals. Further debugging has allowed to narrow that scope down to DRM_IOCTL_I915_GEM_EXECBUFFER2, and ring_context_alloc(), specific to ring submission, in particular. If successful then that function, or its execlists or GuC submission equivalent, is supposed to be called only once per GEM context engine, followed by raise of a flag that prevents the function from being called again. The function is expected to unwind its internal errors itself, so it may be safely called once more after it returns an error. In case of ring submission, the function first gets a reference to the engine's legacy timeline and then allocates a VMA. If the VMA allocation fails, e.g. when i915_vma_instance() called from inside is interrupted with a signal, then ring_context_alloc() fails, leaving the timeline held referenced. On next I915_GEM_EXECBUFFER2 IOCTL, another reference to the timeline is got, and only that last one is put on successful completion. As a consequence, the legacy timeline, with its underlying engine status page's VMA object, is still held and not released on driver unbind. Get the legacy timeline only after successful allocation of the context engine's VMA. v2: Add a note on other submission methods (Krzysztof Karas): Both execlists and GuC submission use lrc_alloc() which seems free from a similar issue. Fixes: 75d0a7f31eec ("drm/i915: Lift timeline into intel_context") Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12061 Cc: Chris Wilson Cc: Matthew Auld Cc: Krzysztof Karas Reviewed-by: Sebastian Brzezinka Reviewed-by: Krzysztof Niemiec Signed-off-by: Janusz Krzysztofik Reviewed-by: Nitin Gote Reviewed-by: Andi Shyti Signed-off-by: Andi Shyti Link: https://lore.kernel.org/r/20250611104352.1014011-2-janusz.krzysztofik@linux.intel.com (cherry picked from commit cc43422b3cc79eacff4c5a8ba0d224688ca9dd4f) Signed-off-by: Joonas Lahtinen Signed-off-by: Sasha Levin --- drivers/gpu/drm/i915/gt/intel_ring_submission.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c b/drivers/gpu/drm/i915/gt/intel_ring_submission.c index 92085ffd23de..4eb78895773f 100644 --- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c +++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c @@ -573,7 +573,6 @@ static int ring_context_alloc(struct intel_context *ce) /* One ringbuffer to rule them all */ GEM_BUG_ON(!engine->legacy.ring); ce->ring = engine->legacy.ring; - ce->timeline = intel_timeline_get(engine->legacy.timeline); GEM_BUG_ON(ce->state); if (engine->context_size) { @@ -586,6 +585,8 @@ static int ring_context_alloc(struct intel_context *ce) ce->state = vma; } + ce->timeline = intel_timeline_get(engine->legacy.timeline); + return 0; } From 832058110a1d3392814ded96057a7eb93f170251 Mon Sep 17 00:00:00 2001 From: Junxiao Chang Date: Fri, 25 Apr 2025 23:11:07 +0800 Subject: [PATCH 886/971] drm/i915/gsc: mei interrupt top half should be in irq disabled context [ Upstream commit 8cadce97bf264ed478669c6f32d5603b34608335 ] MEI GSC interrupt comes from i915. It has top half and bottom half. Top half is called from i915 interrupt handler. It should be in irq disabled context. With RT kernel, by default i915 IRQ handler is in threaded IRQ. MEI GSC top half might be in threaded IRQ context. generic_handle_irq_safe API could be called from either IRQ or process context, it disables local IRQ then calls MEI GSC interrupt top half. This change fixes A380/A770 GPU boot hang issue with RT kernel. Fixes: 1e3dc1d8622b ("drm/i915/gsc: add gsc as a mei auxiliary device") Tested-by: Furong Zhou Suggested-by: Sebastian Andrzej Siewior Acked-by: Sebastian Andrzej Siewior Signed-off-by: Junxiao Chang Link: https://lore.kernel.org/r/20250425151108.643649-1-junxiao.chang@intel.com Reviewed-by: Rodrigo Vivi Signed-off-by: Rodrigo Vivi (cherry picked from commit dccf655f69002d496a527ba441b4f008aa5bebbf) Signed-off-by: Joonas Lahtinen Signed-off-by: Sasha Levin --- drivers/gpu/drm/i915/gt/intel_gsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/intel_gsc.c b/drivers/gpu/drm/i915/gt/intel_gsc.c index bcc3605158db..27420ed631d8 100644 --- a/drivers/gpu/drm/i915/gt/intel_gsc.c +++ b/drivers/gpu/drm/i915/gt/intel_gsc.c @@ -298,7 +298,7 @@ static void gsc_irq_handler(struct intel_gt *gt, unsigned int intf_id) if (gt->gsc.intf[intf_id].irq < 0) return; - ret = generic_handle_irq(gt->gsc.intf[intf_id].irq); + ret = generic_handle_irq_safe(gt->gsc.intf[intf_id].irq); if (ret) drm_err_ratelimited(>->i915->drm, "error handling GSC irq: %d\n", ret); } From 8f4652848b36508394d0ce9eee27afeab5698a19 Mon Sep 17 00:00:00 2001 From: Vitaly Lifshits Date: Wed, 11 Jun 2025 15:52:54 +0300 Subject: [PATCH 887/971] igc: disable L1.2 PCI-E link substate to avoid performance issue [ Upstream commit 0325143b59c6c6d79987afc57d2456e7a20d13b7 ] I226 devices advertise support for the PCI-E link L1.2 substate. However, due to a hardware limitation, the exit latency from this low-power state is longer than the packet buffer can tolerate under high traffic conditions. This can lead to packet loss and degraded performance. To mitigate this, disable the L1.2 substate. The increased power draw between L1.1 and L1.2 is insignificant. Fixes: 43546211738e ("igc: Add new device ID's") Link: https://lore.kernel.org/intel-wired-lan/15248b4f-3271-42dd-8e35-02bfc92b25e1@intel.com Signed-off-by: Vitaly Lifshits Reviewed-by: Aleksandr Loktionov Tested-by: Mor Bar-Gabay Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/igc/igc_main.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index e2f5c4384455..11543db4c47f 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -6772,6 +6772,10 @@ static int igc_probe(struct pci_dev *pdev, adapter->port_num = hw->bus.func; adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); + /* Disable ASPM L1.2 on I226 devices to avoid packet loss */ + if (igc_is_device_id_i226(hw)) + pci_disable_link_state(pdev, PCIE_LINK_STATE_L1_2); + err = pci_save_state(pdev); if (err) goto err_ioremap; @@ -7144,6 +7148,9 @@ static int __maybe_unused igc_resume(struct device *dev) pci_enable_wake(pdev, PCI_D3hot, 0); pci_enable_wake(pdev, PCI_D3cold, 0); + if (igc_is_device_id_i226(hw)) + pci_disable_link_state(pdev, PCIE_LINK_STATE_L1_2); + if (igc_init_interrupt_scheme(adapter, true)) { netdev_err(netdev, "Unable to allocate memory for queues\n"); return -ENOMEM; @@ -7259,6 +7266,9 @@ static pci_ers_result_t igc_io_slot_reset(struct pci_dev *pdev) pci_enable_wake(pdev, PCI_D3hot, 0); pci_enable_wake(pdev, PCI_D3cold, 0); + if (igc_is_device_id_i226(hw)) + pci_disable_link_state_locked(pdev, PCIE_LINK_STATE_L1_2); + /* In case of PCI error, adapter loses its HW address * so we should re-assign it here. */ From f2ca04cbf01db8cf56cdc9b14edd1042024a2dcf Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 30 Jun 2025 14:36:40 -0500 Subject: [PATCH 888/971] lib: test_objagg: Set error message in check_expect_hints_stats() [ Upstream commit e6ed134a4ef592fe1fd0cafac9683813b3c8f3e8 ] Smatch complains that the error message isn't set in the caller: lib/test_objagg.c:923 test_hints_case2() error: uninitialized symbol 'errmsg'. This static checker warning only showed up after a recent refactoring but the bug dates back to when the code was originally added. This likely doesn't affect anything in real life. Reported-by: kernel test robot Closes: https://lore.kernel.org/r/202506281403.DsuyHFTZ-lkp@intel.com/ Fixes: 0a020d416d0a ("lib: introduce initial implementation of object aggregation manager") Signed-off-by: Dan Carpenter Reviewed-by: Ido Schimmel Reviewed-by: Simon Horman Link: https://patch.msgid.link/8548f423-2e3b-4bb7-b816-5041de2762aa@sabinyo.mountain Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- lib/test_objagg.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/test_objagg.c b/lib/test_objagg.c index c0c957c50635..c0f7bb53db8d 100644 --- a/lib/test_objagg.c +++ b/lib/test_objagg.c @@ -899,8 +899,10 @@ static int check_expect_hints_stats(struct objagg_hints *objagg_hints, int err; stats = objagg_hints_stats_get(objagg_hints); - if (IS_ERR(stats)) + if (IS_ERR(stats)) { + *errmsg = "objagg_hints_stats_get() failed."; return PTR_ERR(stats); + } err = __check_expect_stats(stats, expect_stats, errmsg); objagg_stats_put(stats); return err; From a133683c05677c8ade96d85d6c0027c4d535dc81 Mon Sep 17 00:00:00 2001 From: Raju Rangoju Date: Tue, 1 Jul 2025 00:56:36 +0530 Subject: [PATCH 889/971] amd-xgbe: align CL37 AN sequence as per databook [ Upstream commit 42fd432fe6d320323215ebdf4de4d0d7e56e6792 ] Update the Clause 37 Auto-Negotiation implementation to properly align with the PCS hardware specifications: - Fix incorrect bit settings in Link Status and Link Duplex fields - Implement missing sequence steps 2 and 7 These changes ensure CL37 auto-negotiation protocol follows the exact sequence patterns as specified in the hardware databook. Fixes: 1bf40ada6290 ("amd-xgbe: Add support for clause 37 auto-negotiation") Signed-off-by: Raju Rangoju Link: https://patch.msgid.link/20250630192636.3838291-1-Raju.Rangoju@amd.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/amd/xgbe/xgbe-common.h | 2 ++ drivers/net/ethernet/amd/xgbe/xgbe-mdio.c | 9 +++++++++ drivers/net/ethernet/amd/xgbe/xgbe.h | 4 ++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h index 3b70f6737633..aa25a8a0a106 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h @@ -1373,6 +1373,8 @@ #define MDIO_VEND2_CTRL1_SS13 BIT(13) #endif +#define XGBE_VEND2_MAC_AUTO_SW BIT(9) + /* MDIO mask values */ #define XGBE_AN_CL73_INT_CMPLT BIT(0) #define XGBE_AN_CL73_INC_LINK BIT(1) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c index 4a2dc705b528..154e7598a32b 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c @@ -375,6 +375,10 @@ static void xgbe_an37_set(struct xgbe_prv_data *pdata, bool enable, reg |= MDIO_VEND2_CTRL1_AN_RESTART; XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_CTRL1, reg); + + reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_PCS_DIG_CTRL); + reg |= XGBE_VEND2_MAC_AUTO_SW; + XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_PCS_DIG_CTRL, reg); } static void xgbe_an37_restart(struct xgbe_prv_data *pdata) @@ -1003,6 +1007,11 @@ static void xgbe_an37_init(struct xgbe_prv_data *pdata) netif_dbg(pdata, link, pdata->netdev, "CL37 AN (%s) initialized\n", (pdata->an_mode == XGBE_AN_MODE_CL37) ? "BaseX" : "SGMII"); + + reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_CTRL1); + reg &= ~MDIO_AN_CTRL1_ENABLE; + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_CTRL1, reg); + } static void xgbe_an73_init(struct xgbe_prv_data *pdata) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h index 173f4dad470f..a596cd08124f 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe.h @@ -292,12 +292,12 @@ #define XGBE_LINK_TIMEOUT 5 #define XGBE_KR_TRAINING_WAIT_ITER 50 -#define XGBE_SGMII_AN_LINK_STATUS BIT(1) +#define XGBE_SGMII_AN_LINK_DUPLEX BIT(1) #define XGBE_SGMII_AN_LINK_SPEED (BIT(2) | BIT(3)) #define XGBE_SGMII_AN_LINK_SPEED_10 0x00 #define XGBE_SGMII_AN_LINK_SPEED_100 0x04 #define XGBE_SGMII_AN_LINK_SPEED_1000 0x08 -#define XGBE_SGMII_AN_LINK_DUPLEX BIT(4) +#define XGBE_SGMII_AN_LINK_STATUS BIT(4) /* ECC correctable error notification window (seconds) */ #define XGBE_ECC_LIMIT 60 From 744cd8baffe8e241bb20e5c8aaa6ac106746fabd Mon Sep 17 00:00:00 2001 From: Alok Tiwari Date: Sat, 28 Jun 2025 07:56:05 -0700 Subject: [PATCH 890/971] enic: fix incorrect MTU comparison in enic_change_mtu() [ Upstream commit aaf2b2480375099c022a82023e1cd772bf1c6a5d ] The comparison in enic_change_mtu() incorrectly used the current netdev->mtu instead of the new new_mtu value when warning about an MTU exceeding the port MTU. This could suppress valid warnings or issue incorrect ones. Fix the condition and log to properly reflect the new_mtu. Fixes: ab123fe071c9 ("enic: handle mtu change for vf properly") Signed-off-by: Alok Tiwari Acked-by: John Daley Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250628145612.476096-1-alok.a.tiwari@oracle.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/cisco/enic/enic_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index cccf0db2fb4e..48701032c20c 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -2057,10 +2057,10 @@ static int enic_change_mtu(struct net_device *netdev, int new_mtu) if (enic_is_dynamic(enic) || enic_is_sriov_vf(enic)) return -EOPNOTSUPP; - if (netdev->mtu > enic->port_mtu) + if (new_mtu > enic->port_mtu) netdev_warn(netdev, "interface MTU (%d) set higher than port MTU (%d)\n", - netdev->mtu, enic->port_mtu); + new_mtu, enic->port_mtu); return _enic_change_mtu(netdev, new_mtu); } From 7a1841c9609377e989ec41c16551309ce79c39e4 Mon Sep 17 00:00:00 2001 From: Kohei Enju Date: Sun, 29 Jun 2025 12:06:31 +0900 Subject: [PATCH 891/971] rose: fix dangling neighbour pointers in rose_rt_device_down() [ Upstream commit 34a500caf48c47d5171f4aa1f237da39b07c6157 ] There are two bugs in rose_rt_device_down() that can cause use-after-free: 1. The loop bound `t->count` is modified within the loop, which can cause the loop to terminate early and miss some entries. 2. When removing an entry from the neighbour array, the subsequent entries are moved up to fill the gap, but the loop index `i` is still incremented, causing the next entry to be skipped. For example, if a node has three neighbours (A, A, B) with count=3 and A is being removed, the second A is not checked. i=0: (A, A, B) -> (A, B) with count=2 ^ checked i=1: (A, B) -> (A, B) with count=2 ^ checked (B, not A!) i=2: (doesn't occur because i < count is false) This leaves the second A in the array with count=2, but the rose_neigh structure has been freed. Code that accesses these entries assumes that the first `count` entries are valid pointers, causing a use-after-free when it accesses the dangling pointer. Fix both issues by iterating over the array in reverse order with a fixed loop bound. This ensures that all entries are examined and that the removal of an entry doesn't affect subsequent iterations. Reported-by: syzbot+e04e2c007ba2c80476cb@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=e04e2c007ba2c80476cb Tested-by: syzbot+e04e2c007ba2c80476cb@syzkaller.appspotmail.com Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Kohei Enju Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250629030833.6680-1-enjuk@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/rose/rose_route.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index fee772b4637c..a7054546f52d 100644 --- a/net/rose/rose_route.c +++ b/net/rose/rose_route.c @@ -497,22 +497,15 @@ void rose_rt_device_down(struct net_device *dev) t = rose_node; rose_node = rose_node->next; - for (i = 0; i < t->count; i++) { + for (i = t->count - 1; i >= 0; i--) { if (t->neighbour[i] != s) continue; t->count--; - switch (i) { - case 0: - t->neighbour[0] = t->neighbour[1]; - fallthrough; - case 1: - t->neighbour[1] = t->neighbour[2]; - break; - case 2: - break; - } + memmove(&t->neighbour[i], &t->neighbour[i + 1], + sizeof(t->neighbour[0]) * + (t->count - i)); } if (t->count <= 0) From 5ea2a10be7d7e8ac959e3f8b094ede8a4dc5fef1 Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Mon, 30 Jun 2025 10:36:43 +0200 Subject: [PATCH 892/971] nui: Fix dma_mapping_error() check [ Upstream commit 561aa0e22b70a5e7246b73d62a824b3aef3fc375 ] dma_map_XXX() functions return values DMA_MAPPING_ERROR as error values which is often ~0. The error value should be tested with dma_mapping_error(). This patch creates a new function in niu_ops to test if the mapping failed. The test is fixed in niu_rbr_add_page(), added in niu_start_xmit() and the successfully mapped pages are unmaped upon error. Fixes: ec2deec1f352 ("niu: Fix to check for dma mapping errors.") Signed-off-by: Thomas Fourier Reviewed-by: Simon Horman Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/sun/niu.c | 31 ++++++++++++++++++++++++++++++- drivers/net/ethernet/sun/niu.h | 4 ++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index 011d74087f86..fc6217917fc2 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c @@ -3336,7 +3336,7 @@ static int niu_rbr_add_page(struct niu *np, struct rx_ring_info *rp, addr = np->ops->map_page(np->device, page, 0, PAGE_SIZE, DMA_FROM_DEVICE); - if (!addr) { + if (np->ops->mapping_error(np->device, addr)) { __free_page(page); return -ENOMEM; } @@ -6672,6 +6672,8 @@ static netdev_tx_t niu_start_xmit(struct sk_buff *skb, len = skb_headlen(skb); mapping = np->ops->map_single(np->device, skb->data, len, DMA_TO_DEVICE); + if (np->ops->mapping_error(np->device, mapping)) + goto out_drop; prod = rp->prod; @@ -6713,6 +6715,8 @@ static netdev_tx_t niu_start_xmit(struct sk_buff *skb, mapping = np->ops->map_page(np->device, skb_frag_page(frag), skb_frag_off(frag), len, DMA_TO_DEVICE); + if (np->ops->mapping_error(np->device, mapping)) + goto out_unmap; rp->tx_buffs[prod].skb = NULL; rp->tx_buffs[prod].mapping = mapping; @@ -6737,6 +6741,19 @@ static netdev_tx_t niu_start_xmit(struct sk_buff *skb, out: return NETDEV_TX_OK; +out_unmap: + while (i--) { + const skb_frag_t *frag; + + prod = PREVIOUS_TX(rp, prod); + frag = &skb_shinfo(skb)->frags[i]; + np->ops->unmap_page(np->device, rp->tx_buffs[prod].mapping, + skb_frag_size(frag), DMA_TO_DEVICE); + } + + np->ops->unmap_single(np->device, rp->tx_buffs[rp->prod].mapping, + skb_headlen(skb), DMA_TO_DEVICE); + out_drop: rp->tx_errors++; kfree_skb(skb); @@ -9636,6 +9653,11 @@ static void niu_pci_unmap_single(struct device *dev, u64 dma_address, dma_unmap_single(dev, dma_address, size, direction); } +static int niu_pci_mapping_error(struct device *dev, u64 addr) +{ + return dma_mapping_error(dev, addr); +} + static const struct niu_ops niu_pci_ops = { .alloc_coherent = niu_pci_alloc_coherent, .free_coherent = niu_pci_free_coherent, @@ -9643,6 +9665,7 @@ static const struct niu_ops niu_pci_ops = { .unmap_page = niu_pci_unmap_page, .map_single = niu_pci_map_single, .unmap_single = niu_pci_unmap_single, + .mapping_error = niu_pci_mapping_error, }; static void niu_driver_version(void) @@ -10009,6 +10032,11 @@ static void niu_phys_unmap_single(struct device *dev, u64 dma_address, /* Nothing to do. */ } +static int niu_phys_mapping_error(struct device *dev, u64 dma_address) +{ + return false; +} + static const struct niu_ops niu_phys_ops = { .alloc_coherent = niu_phys_alloc_coherent, .free_coherent = niu_phys_free_coherent, @@ -10016,6 +10044,7 @@ static const struct niu_ops niu_phys_ops = { .unmap_page = niu_phys_unmap_page, .map_single = niu_phys_map_single, .unmap_single = niu_phys_unmap_single, + .mapping_error = niu_phys_mapping_error, }; static int niu_of_probe(struct platform_device *op) diff --git a/drivers/net/ethernet/sun/niu.h b/drivers/net/ethernet/sun/niu.h index 04c215f91fc0..0b169c08b0f2 100644 --- a/drivers/net/ethernet/sun/niu.h +++ b/drivers/net/ethernet/sun/niu.h @@ -2879,6 +2879,9 @@ struct tx_ring_info { #define NEXT_TX(tp, index) \ (((index) + 1) < (tp)->pending ? ((index) + 1) : 0) +#define PREVIOUS_TX(tp, index) \ + (((index) - 1) >= 0 ? ((index) - 1) : (((tp)->pending) - 1)) + static inline u32 niu_tx_avail(struct tx_ring_info *tp) { return (tp->pending - @@ -3140,6 +3143,7 @@ struct niu_ops { enum dma_data_direction direction); void (*unmap_single)(struct device *dev, u64 dma_address, size_t size, enum dma_data_direction direction); + int (*mapping_error)(struct device *dev, u64 dma_address); }; struct niu_link_config { From f680a4643c6f71e758d8fe0431a958e9a6a4f59d Mon Sep 17 00:00:00 2001 From: Lion Ackermann Date: Mon, 30 Jun 2025 15:27:30 +0200 Subject: [PATCH 893/971] net/sched: Always pass notifications when child class becomes empty [ Upstream commit 103406b38c600fec1fe375a77b27d87e314aea09 ] Certain classful qdiscs may invoke their classes' dequeue handler on an enqueue operation. This may unexpectedly empty the child qdisc and thus make an in-flight class passive via qlen_notify(). Most qdiscs do not expect such behaviour at this point in time and may re-activate the class eventually anyways which will lead to a use-after-free. The referenced fix commit attempted to fix this behavior for the HFSC case by moving the backlog accounting around, though this turned out to be incomplete since the parent's parent may run into the issue too. The following reproducer demonstrates this use-after-free: tc qdisc add dev lo root handle 1: drr tc filter add dev lo parent 1: basic classid 1:1 tc class add dev lo parent 1: classid 1:1 drr tc qdisc add dev lo parent 1:1 handle 2: hfsc def 1 tc class add dev lo parent 2: classid 2:1 hfsc rt m1 8 d 1 m2 0 tc qdisc add dev lo parent 2:1 handle 3: netem tc qdisc add dev lo parent 3:1 handle 4: blackhole echo 1 | socat -u STDIN UDP4-DATAGRAM:127.0.0.1:8888 tc class delete dev lo classid 1:1 echo 1 | socat -u STDIN UDP4-DATAGRAM:127.0.0.1:8888 Since backlog accounting issues leading to a use-after-frees on stale class pointers is a recurring pattern at this point, this patch takes a different approach. Instead of trying to fix the accounting, the patch ensures that qdisc_tree_reduce_backlog always calls qlen_notify when the child qdisc is empty. This solves the problem because deletion of qdiscs always involves a call to qdisc_reset() and / or qdisc_purge_queue() which ultimately resets its qlen to 0 thus causing the following qdisc_tree_reduce_backlog() to report to the parent. Note that this may call qlen_notify on passive classes multiple times. This is not a problem after the recent patch series that made all the classful qdiscs qlen_notify() handlers idempotent. Fixes: 3f981138109f ("sch_hfsc: Fix qlen accounting bug when using peek in hfsc_enqueue()") Signed-off-by: Lion Ackermann Reviewed-by: Jamal Hadi Salim Acked-by: Cong Wang Acked-by: Jamal Hadi Salim Link: https://patch.msgid.link/d912cbd7-193b-4269-9857-525bee8bbb6a@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/sched/sch_api.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index df89790c459a..282423106f15 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -779,15 +779,12 @@ static u32 qdisc_alloc_handle(struct net_device *dev) void qdisc_tree_reduce_backlog(struct Qdisc *sch, int n, int len) { - bool qdisc_is_offloaded = sch->flags & TCQ_F_OFFLOADED; const struct Qdisc_class_ops *cops; unsigned long cl; u32 parentid; bool notify; int drops; - if (n == 0 && len == 0) - return; drops = max_t(int, n, 0); rcu_read_lock(); while ((parentid = sch->parent)) { @@ -796,17 +793,8 @@ void qdisc_tree_reduce_backlog(struct Qdisc *sch, int n, int len) if (sch->flags & TCQ_F_NOPARENT) break; - /* Notify parent qdisc only if child qdisc becomes empty. - * - * If child was empty even before update then backlog - * counter is screwed and we skip notification because - * parent class is already passive. - * - * If the original child was offloaded then it is allowed - * to be seem as empty, so the parent is notified anyway. - */ - notify = !sch->q.qlen && !WARN_ON_ONCE(!n && - !qdisc_is_offloaded); + /* Notify parent qdisc only if child qdisc becomes empty. */ + notify = !sch->q.qlen; /* TODO: perform the search on a per txq basis */ sch = qdisc_lookup_rcu(qdisc_dev(sch), TC_H_MAJ(parentid)); if (sch == NULL) { @@ -815,6 +803,9 @@ void qdisc_tree_reduce_backlog(struct Qdisc *sch, int n, int len) } cops = sch->ops->cl_ops; if (notify && cops->qlen_notify) { + /* Note that qlen_notify must be idempotent as it may get called + * multiple times. + */ cl = cops->find(sch, parentid); cops->qlen_notify(sch, cl); } From 70b32cba5cfdec26c0d323a750259643c6326d2b Mon Sep 17 00:00:00 2001 From: Raju Rangoju Date: Tue, 1 Jul 2025 12:20:16 +0530 Subject: [PATCH 894/971] amd-xgbe: do not double read link status [ Upstream commit 16ceda2ef683a50cd0783006c0504e1931cd8879 ] The link status is latched low so that momentary link drops can be detected. Always double-reading the status defeats this design feature. Only double read if link was already down This prevents unnecessary duplicate readings of the link status. Fixes: 4f3b20bfbb75 ("amd-xgbe: add support for rx-adaptation") Signed-off-by: Raju Rangoju Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250701065016.4140707-1-Raju.Rangoju@amd.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/amd/xgbe/xgbe-mdio.c | 4 ++++ drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c | 24 +++++++++++++-------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c index 154e7598a32b..8345d439184e 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c @@ -1413,6 +1413,10 @@ static void xgbe_phy_status(struct xgbe_prv_data *pdata) pdata->phy.link = pdata->phy_if.phy_impl.link_status(pdata, &an_restart); + /* bail out if the link status register read fails */ + if (pdata->phy.link < 0) + return; + if (an_restart) { xgbe_phy_config_aneg(pdata); goto adjust_link; diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c index 268399dfcf22..32e633d11348 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c @@ -2855,8 +2855,7 @@ static bool xgbe_phy_valid_speed(struct xgbe_prv_data *pdata, int speed) static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart) { struct xgbe_phy_data *phy_data = pdata->phy_data; - unsigned int reg; - int ret; + int reg, ret; *an_restart = 0; @@ -2890,11 +2889,20 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart) return 0; } - /* Link status is latched low, so read once to clear - * and then read again to get current state + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); + if (reg < 0) + return reg; + + /* Link status is latched low so that momentary link drops + * can be detected. If link was already down read again + * to get the latest state. */ - reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); - reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); + + if (!pdata->phy.link && !(reg & MDIO_STAT1_LSTATUS)) { + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); + if (reg < 0) + return reg; + } if (pdata->en_rx_adap) { /* if the link is available and adaptation is done, @@ -2913,9 +2921,7 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart) xgbe_phy_set_mode(pdata, phy_data->cur_mode); } - /* check again for the link and adaptation status */ - reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); - if ((reg & MDIO_STAT1_LSTATUS) && pdata->rx_adapt_done) + if (pdata->rx_adapt_done) return 1; } else if (reg & MDIO_STAT1_LSTATUS) return 1; From ca7d5aa7ccf0af1a40d56ed2df05ed17ed0ce5d3 Mon Sep 17 00:00:00 2001 From: Wang Zhaolong Date: Thu, 3 Jul 2025 21:29:52 +0800 Subject: [PATCH 895/971] smb: client: fix race condition in negotiate timeout by using more precise timing [ Upstream commit 266b5d02e14f3a0e07414e11f239397de0577a1d ] When the SMB server reboots and the client immediately accesses the mount point, a race condition can occur that causes operations to fail with "Host is down" error. Reproduction steps: # Mount SMB share mount -t cifs //192.168.245.109/TEST /mnt/ -o xxxx ls /mnt # Reboot server ssh root@192.168.245.109 reboot ssh root@192.168.245.109 /path/to/cifs_server_setup.sh ssh root@192.168.245.109 systemctl stop firewalld # Immediate access fails ls /mnt ls: cannot access '/mnt': Host is down # But works if there is a delay The issue is caused by a race condition between negotiate and reconnect. The 20-second negotiate timeout mechanism can interfere with the normal recovery process when both are triggered simultaneously. ls cifsd --------------------------------------------------- cifs_getattr cifs_revalidate_dentry cifs_get_inode_info cifs_get_fattr smb2_query_path_info smb2_compound_op SMB2_open_init smb2_reconnect cifs_negotiate_protocol smb2_negotiate cifs_send_recv smb_send_rqst wait_for_response cifs_demultiplex_thread cifs_read_from_socket cifs_readv_from_socket server_unresponsive cifs_reconnect __cifs_reconnect cifs_abort_connection mid->mid_state = MID_RETRY_NEEDED cifs_wake_up_task cifs_sync_mid_result // case MID_RETRY_NEEDED rc = -EAGAIN; // In smb2_negotiate() rc = -EHOSTDOWN; The server_unresponsive() timeout triggers cifs_reconnect(), which aborts ongoing mid requests and causes the ls command to receive -EAGAIN, leading to -EHOSTDOWN. Fix this by introducing a dedicated `neg_start` field to precisely tracks when the negotiate process begins. The timeout check now uses this accurate timestamp instead of `lstrp`, ensuring that: 1. Timeout is only triggered after negotiate has actually run for 20s 2. The mechanism doesn't interfere with concurrent recovery processes 3. Uninitialized timestamps (value 0) don't trigger false timeouts Fixes: 7ccc1465465d ("smb: client: fix hang in wait_for_response() for negproto") Signed-off-by: Wang Zhaolong Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/smb/client/cifsglob.h | 1 + fs/smb/client/connect.c | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index a6020f7408fe..5c856adf7be9 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -743,6 +743,7 @@ struct TCP_Server_Info { __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 */ + unsigned long neg_start; /* when negotiate started (jiffies) */ struct cifs_secmech secmech; /* crypto sec mech functs, descriptors */ #define CIFS_NEGFLAVOR_UNENCAP 1 /* wct == 17, but no ext_sec */ #define CIFS_NEGFLAVOR_EXTENDED 2 /* wct == 17, ext_sec bit set */ diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c index 454420aa0222..8298d1745f9b 100644 --- a/fs/smb/client/connect.c +++ b/fs/smb/client/connect.c @@ -677,12 +677,12 @@ server_unresponsive(struct TCP_Server_Info *server) /* * If we're in the process of mounting a share or reconnecting a session * and the server abruptly shut down (e.g. socket wasn't closed, packet - * had been ACK'ed but no SMB response), don't wait longer than 20s to - * negotiate protocol. + * had been ACK'ed but no SMB response), don't wait longer than 20s from + * when negotiate actually started. */ spin_lock(&server->srv_lock); if (server->tcpStatus == CifsInNegotiate && - time_after(jiffies, server->lstrp + 20 * HZ)) { + time_after(jiffies, server->neg_start + 20 * HZ)) { spin_unlock(&server->srv_lock); cifs_reconnect(server, false); return true; @@ -3998,6 +3998,7 @@ retry: server->lstrp = jiffies; server->tcpStatus = CifsInNegotiate; + server->neg_start = jiffies; spin_unlock(&server->srv_lock); rc = server->ops->negotiate(xid, ses, server); From ccdd3eaec689cc166f18ae9d091a570d291bbacb Mon Sep 17 00:00:00 2001 From: Joonas Lahtinen Date: Thu, 22 May 2025 09:41:27 +0300 Subject: [PATCH 896/971] Revert "drm/i915/gem: Allow EXEC_CAPTURE on recoverable contexts on DG1" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit ed5915cfce2abb9a553c3737badebd4a11d6c9c7 ] This reverts commit d6e020819612a4a06207af858e0978be4d3e3140. The IS_DGFX check was put in place because error capture of buffer objects is expected to be broken on devices with VRAM. Userspace fix[1] to the impacted media driver has been submitted, merged and a new driver release is out as 25.2.3 where the capture flag is dropped on DG1 thus unblocking the usage of media driver on DG1. [1] https://github.com/intel/media-driver/commit/93c07d9b4b96a78bab21f6acd4eb863f4313ea4a Cc: stable@vger.kernel.org # v6.0+ Cc: Ville Syrjälä Cc: Andi Shyti Cc: Matthew Auld Cc: Thomas Hellström Cc: Tvrtko Ursulin Acked-by: Tvrtko Ursulin Reviewed-by: Andi Shyti Link: https://lore.kernel.org/r/20250522064127.24293-1-joonas.lahtinen@linux.intel.com [Joonas: Update message to point out the merged userspace fix] Signed-off-by: Joonas Lahtinen (cherry picked from commit d2dc30e0aa252830f908c8e793d3139d51321370) Signed-off-by: Joonas Lahtinen Signed-off-by: Sasha Levin --- drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 023b2ea74c36..5a687a3686bd 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -2013,7 +2013,7 @@ static int eb_capture_stage(struct i915_execbuffer *eb) continue; if (i915_gem_context_is_recoverable(eb->gem_context) && - GRAPHICS_VER_FULL(eb->i915) > IP_VER(12, 10)) + (IS_DGFX(eb->i915) || GRAPHICS_VER_FULL(eb->i915) > IP_VER(12, 0))) return -EINVAL; for_each_batch_create_order(eb, j) { From 3499dcb6c507d378b1b75ff40d602da6e1991b8d Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Wed, 7 May 2025 13:05:36 +0100 Subject: [PATCH 897/971] btrfs: fix qgroup reservation leak on failure to allocate ordered extent [ Upstream commit 1f2889f5594a2bc4c6a52634c4a51b93e785def5 ] If we fail to allocate an ordered extent for a COW write we end up leaking a qgroup data reservation since we called btrfs_qgroup_release_data() but we didn't call btrfs_qgroup_free_refroot() (which would happen when running the respective data delayed ref created by ordered extent completion or when finishing the ordered extent in case an error happened). So make sure we call btrfs_qgroup_free_refroot() if we fail to allocate an ordered extent for a COW write. Fixes: 7dbeaad0af7d ("btrfs: change timing for qgroup reserved space for ordered extents to fix reserved space leak") CC: stable@vger.kernel.org # 6.1+ Reviewed-by: Boris Burkov Reviewed-by: Qu Wenruo Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/ordered-data.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 86d846eb5ed4..c68e9ecbc438 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -154,9 +154,10 @@ static struct btrfs_ordered_extent *alloc_ordered_extent( struct btrfs_ordered_extent *entry; int ret; u64 qgroup_rsv = 0; + const bool is_nocow = (flags & + ((1U << BTRFS_ORDERED_NOCOW) | (1U << BTRFS_ORDERED_PREALLOC))); - if (flags & - ((1 << BTRFS_ORDERED_NOCOW) | (1 << BTRFS_ORDERED_PREALLOC))) { + if (is_nocow) { /* For nocow write, we can release the qgroup rsv right now */ ret = btrfs_qgroup_free_data(inode, NULL, file_offset, num_bytes, &qgroup_rsv); if (ret < 0) @@ -171,8 +172,13 @@ static struct btrfs_ordered_extent *alloc_ordered_extent( return ERR_PTR(ret); } entry = kmem_cache_zalloc(btrfs_ordered_extent_cache, GFP_NOFS); - if (!entry) + if (!entry) { + if (!is_nocow) + btrfs_qgroup_free_refroot(inode->root->fs_info, + btrfs_root_id(inode->root), + qgroup_rsv, BTRFS_QGROUP_RSV_DATA); return ERR_PTR(-ENOMEM); + } entry->file_offset = file_offset; entry->num_bytes = num_bytes; From 64d07a40f853a1d31dd0b51596e8ca1bfb432451 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 6 Jul 2025 05:03:16 -0400 Subject: [PATCH 898/971] smb: client: remove \t from TP_printk statements [ Upstream commit e97f9540ce001503a4539f337da742c1dfa7d86a ] The generate '[FAILED TO PARSE]' strings in trace-cmd report output like this: rm-5298 [001] 6084.533748493: smb3_exit_err: [FAILED TO PARSE] xid=972 func_name=cifs_rmdir rc=-39 rm-5298 [001] 6084.533959234: smb3_enter: [FAILED TO PARSE] xid=973 func_name=cifs_closedir rm-5298 [001] 6084.533967630: smb3_close_enter: [FAILED TO PARSE] xid=973 fid=94489281833 tid=1 sesid=96758029877361 rm-5298 [001] 6084.534004008: smb3_cmd_enter: [FAILED TO PARSE] tid=1 sesid=96758029877361 cmd=6 mid=566 rm-5298 [001] 6084.552248232: smb3_cmd_done: [FAILED TO PARSE] tid=1 sesid=96758029877361 cmd=6 mid=566 rm-5298 [001] 6084.552280542: smb3_close_done: [FAILED TO PARSE] xid=973 fid=94489281833 tid=1 sesid=96758029877361 rm-5298 [001] 6084.552316034: smb3_exit_done: [FAILED TO PARSE] xid=973 func_name=cifs_closedir Cc: stable@vger.kernel.org Signed-off-by: Stefan Metzmacher Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/smb/client/trace.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/fs/smb/client/trace.h b/fs/smb/client/trace.h index 563cb4d8edf0..4dfdc521c5c9 100644 --- a/fs/smb/client/trace.h +++ b/fs/smb/client/trace.h @@ -114,7 +114,7 @@ DECLARE_EVENT_CLASS(smb3_rw_err_class, __entry->len = len; __entry->rc = rc; ), - TP_printk("\txid=%u sid=0x%llx tid=0x%x fid=0x%llx offset=0x%llx len=0x%x rc=%d", + TP_printk("xid=%u sid=0x%llx tid=0x%x fid=0x%llx offset=0x%llx len=0x%x rc=%d", __entry->xid, __entry->sesid, __entry->tid, __entry->fid, __entry->offset, __entry->len, __entry->rc) ) @@ -247,7 +247,7 @@ DECLARE_EVENT_CLASS(smb3_fd_class, __entry->tid = tid; __entry->sesid = sesid; ), - TP_printk("\txid=%u sid=0x%llx tid=0x%x fid=0x%llx", + TP_printk("xid=%u sid=0x%llx tid=0x%x fid=0x%llx", __entry->xid, __entry->sesid, __entry->tid, __entry->fid) ) @@ -286,7 +286,7 @@ DECLARE_EVENT_CLASS(smb3_fd_err_class, __entry->sesid = sesid; __entry->rc = rc; ), - TP_printk("\txid=%u sid=0x%llx tid=0x%x fid=0x%llx rc=%d", + TP_printk("xid=%u sid=0x%llx tid=0x%x fid=0x%llx rc=%d", __entry->xid, __entry->sesid, __entry->tid, __entry->fid, __entry->rc) ) @@ -558,7 +558,7 @@ DECLARE_EVENT_CLASS(smb3_cmd_err_class, __entry->status = status; __entry->rc = rc; ), - TP_printk("\tsid=0x%llx tid=0x%x cmd=%u mid=%llu status=0x%x rc=%d", + TP_printk("sid=0x%llx tid=0x%x cmd=%u mid=%llu status=0x%x rc=%d", __entry->sesid, __entry->tid, __entry->cmd, __entry->mid, __entry->status, __entry->rc) ) @@ -593,7 +593,7 @@ DECLARE_EVENT_CLASS(smb3_cmd_done_class, __entry->cmd = cmd; __entry->mid = mid; ), - TP_printk("\tsid=0x%llx tid=0x%x cmd=%u mid=%llu", + TP_printk("sid=0x%llx tid=0x%x cmd=%u mid=%llu", __entry->sesid, __entry->tid, __entry->cmd, __entry->mid) ) @@ -631,7 +631,7 @@ DECLARE_EVENT_CLASS(smb3_mid_class, __entry->when_sent = when_sent; __entry->when_received = when_received; ), - TP_printk("\tcmd=%u mid=%llu pid=%u, when_sent=%lu when_rcv=%lu", + TP_printk("cmd=%u mid=%llu pid=%u, when_sent=%lu when_rcv=%lu", __entry->cmd, __entry->mid, __entry->pid, __entry->when_sent, __entry->when_received) ) @@ -662,7 +662,7 @@ DECLARE_EVENT_CLASS(smb3_exit_err_class, __assign_str(func_name, func_name); __entry->rc = rc; ), - TP_printk("\t%s: xid=%u rc=%d", + TP_printk("%s: xid=%u rc=%d", __get_str(func_name), __entry->xid, __entry->rc) ) @@ -688,7 +688,7 @@ DECLARE_EVENT_CLASS(smb3_sync_err_class, __entry->ino = ino; __entry->rc = rc; ), - TP_printk("\tino=%lu rc=%d", + TP_printk("ino=%lu rc=%d", __entry->ino, __entry->rc) ) @@ -714,7 +714,7 @@ DECLARE_EVENT_CLASS(smb3_enter_exit_class, __entry->xid = xid; __assign_str(func_name, func_name); ), - TP_printk("\t%s: xid=%u", + TP_printk("%s: xid=%u", __get_str(func_name), __entry->xid) ) From bc0819a25e04cd68ef3568cfa51b63118fea39a7 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Sun, 6 Jul 2025 05:34:31 -0400 Subject: [PATCH 899/971] Bluetooth: hci_core: Fix use-after-free in vhci_flush() [ Upstream commit 1d6123102e9fbedc8d25bf4731da6d513173e49e ] syzbot reported use-after-free in vhci_flush() without repro. [0] From the splat, a thread close()d a vhci file descriptor while its device was being used by iotcl() on another thread. Once the last fd refcnt is released, vhci_release() calls hci_unregister_dev(), hci_free_dev(), and kfree() for struct vhci_data, which is set to hci_dev->dev->driver_data. The problem is that there is no synchronisation after unlinking hdev from hci_dev_list in hci_unregister_dev(). There might be another thread still accessing the hdev which was fetched before the unlink operation. We can use SRCU for such synchronisation. Let's run hci_dev_reset() under SRCU and wait for its completion in hci_unregister_dev(). Another option would be to restore hci_dev->destruct(), which was removed in commit 587ae086f6e4 ("Bluetooth: Remove unused hci-destruct cb"). However, this would not be a good solution, as we should not run hci_unregister_dev() while there are in-flight ioctl() requests, which could lead to another data-race KCSAN splat. Note that other drivers seem to have the same problem, for exmaple, virtbt_remove(). [0]: BUG: KASAN: slab-use-after-free in skb_queue_empty_lockless include/linux/skbuff.h:1891 [inline] BUG: KASAN: slab-use-after-free in skb_queue_purge_reason+0x99/0x360 net/core/skbuff.c:3937 Read of size 8 at addr ffff88807cb8d858 by task syz.1.219/6718 CPU: 1 UID: 0 PID: 6718 Comm: syz.1.219 Not tainted 6.16.0-rc1-syzkaller-00196-g08207f42d3ff #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/07/2025 Call Trace: dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:408 [inline] print_report+0xd2/0x2b0 mm/kasan/report.c:521 kasan_report+0x118/0x150 mm/kasan/report.c:634 skb_queue_empty_lockless include/linux/skbuff.h:1891 [inline] skb_queue_purge_reason+0x99/0x360 net/core/skbuff.c:3937 skb_queue_purge include/linux/skbuff.h:3368 [inline] vhci_flush+0x44/0x50 drivers/bluetooth/hci_vhci.c:69 hci_dev_do_reset net/bluetooth/hci_core.c:552 [inline] hci_dev_reset+0x420/0x5c0 net/bluetooth/hci_core.c:592 sock_do_ioctl+0xd9/0x300 net/socket.c:1190 sock_ioctl+0x576/0x790 net/socket.c:1311 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:907 [inline] __se_sys_ioctl+0xf9/0x170 fs/ioctl.c:893 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7fcf5b98e929 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fcf5c7b9038 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007fcf5bbb6160 RCX: 00007fcf5b98e929 RDX: 0000000000000000 RSI: 00000000400448cb RDI: 0000000000000009 RBP: 00007fcf5ba10b39 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000000000 R14: 00007fcf5bbb6160 R15: 00007ffd6353d528 Allocated by task 6535: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x3e/0x80 mm/kasan/common.c:68 poison_kmalloc_redzone mm/kasan/common.c:377 [inline] __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:394 kasan_kmalloc include/linux/kasan.h:260 [inline] __kmalloc_cache_noprof+0x230/0x3d0 mm/slub.c:4359 kmalloc_noprof include/linux/slab.h:905 [inline] kzalloc_noprof include/linux/slab.h:1039 [inline] vhci_open+0x57/0x360 drivers/bluetooth/hci_vhci.c:635 misc_open+0x2bc/0x330 drivers/char/misc.c:161 chrdev_open+0x4c9/0x5e0 fs/char_dev.c:414 do_dentry_open+0xdf0/0x1970 fs/open.c:964 vfs_open+0x3b/0x340 fs/open.c:1094 do_open fs/namei.c:3887 [inline] path_openat+0x2ee5/0x3830 fs/namei.c:4046 do_filp_open+0x1fa/0x410 fs/namei.c:4073 do_sys_openat2+0x121/0x1c0 fs/open.c:1437 do_sys_open fs/open.c:1452 [inline] __do_sys_openat fs/open.c:1468 [inline] __se_sys_openat fs/open.c:1463 [inline] __x64_sys_openat+0x138/0x170 fs/open.c:1463 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 6535: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x3e/0x80 mm/kasan/common.c:68 kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:576 poison_slab_object mm/kasan/common.c:247 [inline] __kasan_slab_free+0x62/0x70 mm/kasan/common.c:264 kasan_slab_free include/linux/kasan.h:233 [inline] slab_free_hook mm/slub.c:2381 [inline] slab_free mm/slub.c:4643 [inline] kfree+0x18e/0x440 mm/slub.c:4842 vhci_release+0xbc/0xd0 drivers/bluetooth/hci_vhci.c:671 __fput+0x44c/0xa70 fs/file_table.c:465 task_work_run+0x1d1/0x260 kernel/task_work.c:227 exit_task_work include/linux/task_work.h:40 [inline] do_exit+0x6ad/0x22e0 kernel/exit.c:955 do_group_exit+0x21c/0x2d0 kernel/exit.c:1104 __do_sys_exit_group kernel/exit.c:1115 [inline] __se_sys_exit_group kernel/exit.c:1113 [inline] __x64_sys_exit_group+0x3f/0x40 kernel/exit.c:1113 x64_sys_call+0x21ba/0x21c0 arch/x86/include/generated/asm/syscalls_64.h:232 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f The buggy address belongs to the object at ffff88807cb8d800 which belongs to the cache kmalloc-1k of size 1024 The buggy address is located 88 bytes inside of freed 1024-byte region [ffff88807cb8d800, ffff88807cb8dc00) Fixes: bf18c7118cf8 ("Bluetooth: vhci: Free driver_data on file release") Reported-by: syzbot+2faa4825e556199361f9@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=f62d64848fc4c7c30cd6 Signed-off-by: Kuniyuki Iwashima Acked-by: Paul Menzel Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- include/net/bluetooth/hci_core.h | 2 ++ net/bluetooth/hci_core.c | 34 ++++++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index d63af08c6cdc..4f067599e6e9 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -339,6 +340,7 @@ struct adv_monitor { struct hci_dev { struct list_head list; + struct srcu_struct srcu; struct mutex lock; struct ida unset_handle_ida; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 32f7bd0e8916..824208a53c25 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -65,7 +65,7 @@ static DEFINE_IDA(hci_index_ida); /* Get HCI device by index. * Device is held on return. */ -struct hci_dev *hci_dev_get(int index) +static struct hci_dev *__hci_dev_get(int index, int *srcu_index) { struct hci_dev *hdev = NULL, *d; @@ -78,6 +78,8 @@ struct hci_dev *hci_dev_get(int index) list_for_each_entry(d, &hci_dev_list, list) { if (d->id == index) { hdev = hci_dev_hold(d); + if (srcu_index) + *srcu_index = srcu_read_lock(&d->srcu); break; } } @@ -85,6 +87,22 @@ struct hci_dev *hci_dev_get(int index) return hdev; } +struct hci_dev *hci_dev_get(int index) +{ + return __hci_dev_get(index, NULL); +} + +static struct hci_dev *hci_dev_get_srcu(int index, int *srcu_index) +{ + return __hci_dev_get(index, srcu_index); +} + +static void hci_dev_put_srcu(struct hci_dev *hdev, int srcu_index) +{ + srcu_read_unlock(&hdev->srcu, srcu_index); + hci_dev_put(hdev); +} + /* ---- Inquiry support ---- */ bool hci_discovery_active(struct hci_dev *hdev) @@ -590,9 +608,9 @@ static int hci_dev_do_reset(struct hci_dev *hdev) int hci_dev_reset(__u16 dev) { struct hci_dev *hdev; - int err; + int err, srcu_index; - hdev = hci_dev_get(dev); + hdev = hci_dev_get_srcu(dev, &srcu_index); if (!hdev) return -ENODEV; @@ -614,7 +632,7 @@ int hci_dev_reset(__u16 dev) err = hci_dev_do_reset(hdev); done: - hci_dev_put(hdev); + hci_dev_put_srcu(hdev, srcu_index); return err; } @@ -2424,6 +2442,11 @@ struct hci_dev *hci_alloc_dev_priv(int sizeof_priv) if (!hdev) return NULL; + if (init_srcu_struct(&hdev->srcu)) { + kfree(hdev); + return NULL; + } + hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); hdev->esco_type = (ESCO_HV1); hdev->link_mode = (HCI_LM_ACCEPT); @@ -2670,6 +2693,9 @@ void hci_unregister_dev(struct hci_dev *hdev) list_del(&hdev->list); write_unlock(&hci_dev_list_lock); + synchronize_srcu(&hdev->srcu); + cleanup_srcu_struct(&hdev->srcu); + cancel_work_sync(&hdev->rx_work); cancel_work_sync(&hdev->cmd_work); cancel_work_sync(&hdev->tx_work); From 32d0b58079eda1019c0c6d012d8a13f74852b532 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 29 Jan 2024 19:34:39 +0100 Subject: [PATCH 900/971] wifi: mac80211: chan: chandef is non-NULL for reserved [ Upstream commit 9bf7079bc2271321fac467cae981c44e495b76b9 ] The last caller of this with a NULL argument was related to the non-chanctx code, so we can now remove this odd logic. Reviewed-by: Miriam Rachel Korenblit Link: https://msgid.link/20240129194108.bad8ec1e76c8.I12287452f42c54baf75821e75491cf6d021af20a@changeid Signed-off-by: Johannes Berg Stable-dep-of: d87c3ca0f8f1 ("wifi: mac80211: finish link init before RCU publish") Signed-off-by: Sasha Levin --- net/mac80211/chan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 68952752b599..31c4f112345e 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -89,11 +89,11 @@ ieee80211_chanctx_reserved_chandef(struct ieee80211_local *local, lockdep_assert_held(&local->chanctx_mtx); + if (WARN_ON(!compat)) + return NULL; + list_for_each_entry(link, &ctx->reserved_links, reserved_chanctx_list) { - if (!compat) - compat = &link->reserved_chandef; - compat = cfg80211_chandef_compatible(&link->reserved_chandef, compat); if (!compat) From ebca4264c648dc69f0b5a8deb8d797bca4be33d9 Mon Sep 17 00:00:00 2001 From: Muna Sinada Date: Tue, 25 Mar 2025 14:31:23 -0700 Subject: [PATCH 901/971] wifi: mac80211: Add link iteration macro for link data [ Upstream commit f61c7b3d442bef91dd432d468d08f72eadcc3209 ] Currently before iterating through valid links we are utilizing open-coding when checking if vif valid_links is a non-zero value. Add new macro, for_each_link_data(), which iterates through link_id and checks if it is set on vif valid_links. If it is a valid link then access link data for that link id. Signed-off-by: Muna Sinada Link: https://patch.msgid.link/20250325213125.1509362-2-muna.sinada@oss.qualcomm.com Signed-off-by: Johannes Berg Stable-dep-of: d87c3ca0f8f1 ("wifi: mac80211: finish link init before RCU publish") Signed-off-by: Sasha Levin --- net/mac80211/ieee80211_i.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 04c876d78d3b..44aad3394084 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1186,6 +1186,15 @@ ieee80211_vif_get_shift(struct ieee80211_vif *vif) return shift; } +#define for_each_link_data(sdata, __link) \ + struct ieee80211_sub_if_data *__sdata = sdata; \ + for (int __link_id = 0; \ + __link_id < ARRAY_SIZE((__sdata)->link); __link_id++) \ + if ((!(__sdata)->vif.valid_links || \ + (__sdata)->vif.valid_links & BIT(__link_id)) && \ + ((__link) = sdata_dereference((__sdata)->link[__link_id], \ + (__sdata)))) + static inline int ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems, struct cfg80211_rnr_elems *rnr_elems, From 6310aafd42674e162b9f996ddd76f6fe0d8bf321 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 24 Jun 2025 13:07:49 +0200 Subject: [PATCH 902/971] wifi: mac80211: finish link init before RCU publish [ Upstream commit d87c3ca0f8f1ca4c25f2ed819e954952f4d8d709 ] Since the link/conf pointers can be accessed without any protection other than RCU, make sure the data is actually set up before publishing the structures. Fixes: b2e8434f1829 ("wifi: mac80211: set up/tear down client vif links properly") Link: https://patch.msgid.link/20250624130749.9a308b713c74.I4a80f5eead112a38730939ea591d2e275c721256@changeid Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- net/mac80211/link.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/net/mac80211/link.c b/net/mac80211/link.c index 16cbaea93fc3..af4d2b2e9a26 100644 --- a/net/mac80211/link.c +++ b/net/mac80211/link.c @@ -28,8 +28,16 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata, if (link_id < 0) link_id = 0; - rcu_assign_pointer(sdata->vif.link_conf[link_id], link_conf); - rcu_assign_pointer(sdata->link[link_id], link); + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { + struct ieee80211_sub_if_data *ap_bss; + struct ieee80211_bss_conf *ap_bss_conf; + + ap_bss = container_of(sdata->bss, + struct ieee80211_sub_if_data, u.ap); + ap_bss_conf = sdata_dereference(ap_bss->vif.link_conf[link_id], + ap_bss); + memcpy(link_conf, ap_bss_conf, sizeof(*link_conf)); + } link->sdata = sdata; link->link_id = link_id; @@ -65,6 +73,9 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata, ieee80211_link_debugfs_add(link); } + + rcu_assign_pointer(sdata->vif.link_conf[link_id], link_conf); + rcu_assign_pointer(sdata->link[link_id], link); } void ieee80211_link_stop(struct ieee80211_link_data *link) From 16254aa985d14dee050564c4a3936f3dc096e1f7 Mon Sep 17 00:00:00 2001 From: Yan Zhai Date: Mon, 23 Jun 2025 09:06:38 -0700 Subject: [PATCH 903/971] bnxt: properly flush XDP redirect lists [ Upstream commit 9caca6ac0e26cd20efd490d8b3b2ffb1c7c00f6f ] We encountered following crash when testing a XDP_REDIRECT feature in production: [56251.579676] list_add corruption. next->prev should be prev (ffff93120dd40f30), but was ffffb301ef3a6740. (next=ffff93120dd 40f30). [56251.601413] ------------[ cut here ]------------ [56251.611357] kernel BUG at lib/list_debug.c:29! [56251.621082] Oops: invalid opcode: 0000 [#1] PREEMPT SMP NOPTI [56251.632073] CPU: 111 UID: 0 PID: 0 Comm: swapper/111 Kdump: loaded Tainted: P O 6.12.33-cloudflare-2025.6. 3 #1 [56251.653155] Tainted: [P]=PROPRIETARY_MODULE, [O]=OOT_MODULE [56251.663877] Hardware name: MiTAC GC68B-B8032-G11P6-GPU/S8032GM-HE-CFR, BIOS V7.020.B10-sig 01/22/2025 [56251.682626] RIP: 0010:__list_add_valid_or_report+0x4b/0xa0 [56251.693203] Code: 0e 48 c7 c7 68 e7 d9 97 e8 42 16 fe ff 0f 0b 48 8b 52 08 48 39 c2 74 14 48 89 f1 48 c7 c7 90 e7 d9 97 48 89 c6 e8 25 16 fe ff <0f> 0b 4c 8b 02 49 39 f0 74 14 48 89 d1 48 c7 c7 e8 e7 d9 97 4c 89 [56251.725811] RSP: 0018:ffff93120dd40b80 EFLAGS: 00010246 [56251.736094] RAX: 0000000000000075 RBX: ffffb301e6bba9d8 RCX: 0000000000000000 [56251.748260] RDX: 0000000000000000 RSI: ffff9149afda0b80 RDI: ffff9149afda0b80 [56251.760349] RBP: ffff9131e49c8000 R08: 0000000000000000 R09: ffff93120dd40a18 [56251.772382] R10: ffff9159cf2ce1a8 R11: 0000000000000003 R12: ffff911a80850000 [56251.784364] R13: ffff93120fbc7000 R14: 0000000000000010 R15: ffff9139e7510e40 [56251.796278] FS: 0000000000000000(0000) GS:ffff9149afd80000(0000) knlGS:0000000000000000 [56251.809133] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [56251.819561] CR2: 00007f5e85e6f300 CR3: 00000038b85e2006 CR4: 0000000000770ef0 [56251.831365] PKRU: 55555554 [56251.838653] Call Trace: [56251.845560] [56251.851943] cpu_map_enqueue.cold+0x5/0xa [56251.860243] xdp_do_redirect+0x2d9/0x480 [56251.868388] bnxt_rx_xdp+0x1d8/0x4c0 [bnxt_en] [56251.877028] bnxt_rx_pkt+0x5f7/0x19b0 [bnxt_en] [56251.885665] ? cpu_max_write+0x1e/0x100 [56251.893510] ? srso_alias_return_thunk+0x5/0xfbef5 [56251.902276] __bnxt_poll_work+0x190/0x340 [bnxt_en] [56251.911058] bnxt_poll+0xab/0x1b0 [bnxt_en] [56251.919041] ? srso_alias_return_thunk+0x5/0xfbef5 [56251.927568] ? srso_alias_return_thunk+0x5/0xfbef5 [56251.935958] ? srso_alias_return_thunk+0x5/0xfbef5 [56251.944250] __napi_poll+0x2b/0x160 [56251.951155] bpf_trampoline_6442548651+0x79/0x123 [56251.959262] __napi_poll+0x5/0x160 [56251.966037] net_rx_action+0x3d2/0x880 [56251.973133] ? srso_alias_return_thunk+0x5/0xfbef5 [56251.981265] ? srso_alias_return_thunk+0x5/0xfbef5 [56251.989262] ? __hrtimer_run_queues+0x162/0x2a0 [56251.996967] ? srso_alias_return_thunk+0x5/0xfbef5 [56252.004875] ? srso_alias_return_thunk+0x5/0xfbef5 [56252.012673] ? bnxt_msix+0x62/0x70 [bnxt_en] [56252.019903] handle_softirqs+0xcf/0x270 [56252.026650] irq_exit_rcu+0x67/0x90 [56252.032933] common_interrupt+0x85/0xa0 [56252.039498] [56252.044246] [56252.048935] asm_common_interrupt+0x26/0x40 [56252.055727] RIP: 0010:cpuidle_enter_state+0xb8/0x420 [56252.063305] Code: dc 01 00 00 e8 f9 79 3b ff e8 64 f7 ff ff 49 89 c5 0f 1f 44 00 00 31 ff e8 a5 32 3a ff 45 84 ff 0f 85 ae 01 00 00 fb 45 85 f6 <0f> 88 88 01 00 00 48 8b 04 24 49 63 ce 4c 89 ea 48 6b f1 68 48 29 [56252.088911] RSP: 0018:ffff93120c97fe98 EFLAGS: 00000202 [56252.096912] RAX: ffff9149afd80000 RBX: ffff9141d3a72800 RCX: 0000000000000000 [56252.106844] RDX: 00003329176c6b98 RSI: ffffffe36db3fdc7 RDI: 0000000000000000 [56252.116733] RBP: 0000000000000002 R08: 0000000000000002 R09: 000000000000004e [56252.126652] R10: ffff9149afdb30c4 R11: 071c71c71c71c71c R12: ffffffff985ff860 [56252.136637] R13: 00003329176c6b98 R14: 0000000000000002 R15: 0000000000000000 [56252.146667] ? cpuidle_enter_state+0xab/0x420 [56252.153909] cpuidle_enter+0x2d/0x40 [56252.160360] do_idle+0x176/0x1c0 [56252.166456] cpu_startup_entry+0x29/0x30 [56252.173248] start_secondary+0xf7/0x100 [56252.179941] common_startup_64+0x13e/0x141 [56252.186886] From the crash dump, we found that the cpu_map_flush_list inside redirect info is partially corrupted: its list_head->next points to itself, but list_head->prev points to a valid list of unflushed bq entries. This turned out to be a result of missed XDP flush on redirect lists. By digging in the actual source code, we found that commit 7f0a168b0441 ("bnxt_en: Add completion ring pointer in TX and RX ring structures") incorrectly overwrites the event mask for XDP_REDIRECT in bnxt_rx_xdp. We can stably reproduce this crash by returning XDP_TX and XDP_REDIRECT randomly for incoming packets in a naive XDP program. Properly propagate the XDP_REDIRECT events back fixes the crash. Fixes: a7559bc8c17c ("bnxt: support transmit and free of aggregation buffers") Tested-by: Andrew Rzeznik Signed-off-by: Yan Zhai Acked-by: Jesper Dangaard Brouer Reviewed-by: Michael Chan Reviewed-by: Andy Gospodarek Link: https://patch.msgid.link/aFl7jpCNzscumuN2@debian.debian Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 6bf4a2185385..8e4e8291d8c6 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -2491,6 +2491,7 @@ static int __bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, { struct bnxt_napi *bnapi = cpr->bnapi; u32 raw_cons = cpr->cp_raw_cons; + bool flush_xdp = false; u32 cons; int tx_pkts = 0; int rx_pkts = 0; @@ -2528,6 +2529,8 @@ static int __bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, else rc = bnxt_force_rx_discard(bp, cpr, &raw_cons, &event); + if (event & BNXT_REDIRECT_EVENT) + flush_xdp = true; if (likely(rc >= 0)) rx_pkts += rc; /* Increment rx_pkts when rc is -ENOMEM to count towards @@ -2555,8 +2558,10 @@ static int __bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, } } - if (event & BNXT_REDIRECT_EVENT) + if (flush_xdp) { xdp_do_flush(); + event &= ~BNXT_REDIRECT_EVENT; + } if (event & BNXT_TX_EVENT) { struct bnxt_tx_ring_info *txr = bnapi->tx_ring; From b43c3050d21196e5e7024872e3048dba83e31751 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Sun, 10 Dec 2023 17:20:40 +0800 Subject: [PATCH 904/971] f2fs: add tracepoint for f2fs_vm_page_mkwrite() [ Upstream commit 87f3afd366f7c668be0269efda8a89741a3ea6b3 ] This patch adds to support tracepoint for f2fs_vm_page_mkwrite(), meanwhile it prints more details for trace_f2fs_filemap_fault(). Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Stable-dep-of: ba8dac350faf ("f2fs: fix to zero post-eof page") Signed-off-by: Sasha Levin --- fs/f2fs/file.c | 25 ++++++++++++++---------- include/trace/events/f2fs.h | 39 ++++++++++++++++++++++++------------- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index ae129044c52f..3e3822115d1e 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -46,7 +46,7 @@ static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf) f2fs_update_iostat(F2FS_I_SB(inode), inode, APP_MAPPED_READ_IO, F2FS_BLKSIZE); - trace_f2fs_filemap_fault(inode, vmf->pgoff, (unsigned long)ret); + trace_f2fs_filemap_fault(inode, vmf->pgoff, vmf->vma->vm_flags, ret); return ret; } @@ -59,26 +59,29 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf) struct dnode_of_data dn; bool need_alloc = true; int err = 0; + vm_fault_t ret; if (unlikely(IS_IMMUTABLE(inode))) return VM_FAULT_SIGBUS; - if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) - return VM_FAULT_SIGBUS; + if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) { + err = -EIO; + goto out; + } if (unlikely(f2fs_cp_error(sbi))) { err = -EIO; - goto err; + goto out; } if (!f2fs_is_checkpoint_ready(sbi)) { err = -ENOSPC; - goto err; + goto out; } err = f2fs_convert_inline_inode(inode); if (err) - goto err; + goto out; #ifdef CONFIG_F2FS_FS_COMPRESSION if (f2fs_compressed_file(inode)) { @@ -86,7 +89,7 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf) if (ret < 0) { err = ret; - goto err; + goto out; } else if (ret) { need_alloc = false; } @@ -153,13 +156,15 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf) f2fs_update_iostat(sbi, inode, APP_MAPPED_IO, F2FS_BLKSIZE); f2fs_update_time(sbi, REQ_TIME); - trace_f2fs_vm_page_mkwrite(page, DATA); out_sem: filemap_invalidate_unlock_shared(inode->i_mapping); sb_end_pagefault(inode->i_sb); -err: - return vmf_fs_error(err); +out: + ret = vmf_fs_error(err); + + trace_f2fs_vm_page_mkwrite(inode, page->index, vmf->vma->vm_flags, ret); + return ret; } static const struct vm_operations_struct f2fs_file_vm_ops = { diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h index b6ffae01a8cd..f2ce7f6da879 100644 --- a/include/trace/events/f2fs.h +++ b/include/trace/events/f2fs.h @@ -1284,13 +1284,6 @@ DEFINE_EVENT(f2fs__page, f2fs_set_page_dirty, TP_ARGS(page, type) ); -DEFINE_EVENT(f2fs__page, f2fs_vm_page_mkwrite, - - TP_PROTO(struct page *page, int type), - - TP_ARGS(page, type) -); - TRACE_EVENT(f2fs_replace_atomic_write_block, TP_PROTO(struct inode *inode, struct inode *cow_inode, pgoff_t index, @@ -1328,30 +1321,50 @@ TRACE_EVENT(f2fs_replace_atomic_write_block, __entry->recovery) ); -TRACE_EVENT(f2fs_filemap_fault, +DECLARE_EVENT_CLASS(f2fs_mmap, - TP_PROTO(struct inode *inode, pgoff_t index, unsigned long ret), + TP_PROTO(struct inode *inode, pgoff_t index, + vm_flags_t flags, vm_fault_t ret), - TP_ARGS(inode, index, ret), + TP_ARGS(inode, index, flags, ret), TP_STRUCT__entry( __field(dev_t, dev) __field(ino_t, ino) __field(pgoff_t, index) - __field(unsigned long, ret) + __field(vm_flags_t, flags) + __field(vm_fault_t, ret) ), TP_fast_assign( __entry->dev = inode->i_sb->s_dev; __entry->ino = inode->i_ino; __entry->index = index; + __entry->flags = flags; __entry->ret = ret; ), - TP_printk("dev = (%d,%d), ino = %lu, index = %lu, ret = %lx", + TP_printk("dev = (%d,%d), ino = %lu, index = %lu, flags: %s, ret: %s", show_dev_ino(__entry), (unsigned long)__entry->index, - __entry->ret) + __print_flags(__entry->flags, "|", FAULT_FLAG_TRACE), + __print_flags(__entry->ret, "|", VM_FAULT_RESULT_TRACE)) +); + +DEFINE_EVENT(f2fs_mmap, f2fs_filemap_fault, + + TP_PROTO(struct inode *inode, pgoff_t index, + vm_flags_t flags, vm_fault_t ret), + + TP_ARGS(inode, index, flags, ret) +); + +DEFINE_EVENT(f2fs_mmap, f2fs_vm_page_mkwrite, + + TP_PROTO(struct inode *inode, pgoff_t index, + vm_flags_t flags, vm_fault_t ret), + + TP_ARGS(inode, index, flags, ret) ); TRACE_EVENT(f2fs_writepages, From bceae1daf3029326dc8e1f5a7a497f3e9691352f Mon Sep 17 00:00:00 2001 From: "Xin Li (Intel)" Date: Sun, 6 Jul 2025 07:43:08 -0400 Subject: [PATCH 905/971] x86/traps: Initialize DR6 by writing its architectural reset value [ Upstream commit 5f465c148c61e876b6d6eacd8e8e365f2d47758f ] Initialize DR6 by writing its architectural reset value to avoid incorrectly zeroing DR6 to clear DR6.BLD at boot time, which leads to a false bus lock detected warning. The Intel SDM says: 1) Certain debug exceptions may clear bits 0-3 of DR6. 2) BLD induced #DB clears DR6.BLD and any other debug exception doesn't modify DR6.BLD. 3) RTM induced #DB clears DR6.RTM and any other debug exception sets DR6.RTM. To avoid confusion in identifying debug exceptions, debug handlers should set DR6.BLD and DR6.RTM, and clear other DR6 bits before returning. The DR6 architectural reset value 0xFFFF0FF0, already defined as macro DR6_RESERVED, satisfies these requirements, so just use it to reinitialize DR6 whenever needed. Since clear_all_debug_regs() no longer zeros all debug registers, rename it to initialize_debug_regs() to better reflect its current behavior. Since debug_read_clear_dr6() no longer clears DR6, rename it to debug_read_reset_dr6() to better reflect its current behavior. Fixes: ebb1064e7c2e9 ("x86/traps: Handle #DB for bus lock") Reported-by: Sohil Mehta Suggested-by: H. Peter Anvin (Intel) Signed-off-by: Xin Li (Intel) Signed-off-by: Dave Hansen Reviewed-by: H. Peter Anvin (Intel) Reviewed-by: Sohil Mehta Acked-by: Peter Zijlstra (Intel) Tested-by: Sohil Mehta Link: https://lore.kernel.org/lkml/06e68373-a92b-472e-8fd9-ba548119770c@intel.com/ Cc:stable@vger.kernel.org Link: https://lore.kernel.org/all/20250620231504.2676902-2-xin%40zytor.com Signed-off-by: Sasha Levin --- arch/x86/include/uapi/asm/debugreg.h | 21 +++++++++++++++++- arch/x86/kernel/cpu/common.c | 21 +++++++++--------- arch/x86/kernel/traps.c | 32 +++++++++++++++++----------- 3 files changed, 50 insertions(+), 24 deletions(-) diff --git a/arch/x86/include/uapi/asm/debugreg.h b/arch/x86/include/uapi/asm/debugreg.h index 0007ba077c0c..41da492dfb01 100644 --- a/arch/x86/include/uapi/asm/debugreg.h +++ b/arch/x86/include/uapi/asm/debugreg.h @@ -15,7 +15,26 @@ which debugging register was responsible for the trap. The other bits are either reserved or not of interest to us. */ -/* Define reserved bits in DR6 which are always set to 1 */ +/* + * Define bits in DR6 which are set to 1 by default. + * + * This is also the DR6 architectural value following Power-up, Reset or INIT. + * + * Note, with the introduction of Bus Lock Detection (BLD) and Restricted + * Transactional Memory (RTM), the DR6 register has been modified: + * + * 1) BLD flag (bit 11) is no longer reserved to 1 if the CPU supports + * Bus Lock Detection. The assertion of a bus lock could clear it. + * + * 2) RTM flag (bit 16) is no longer reserved to 1 if the CPU supports + * restricted transactional memory. #DB occurred inside an RTM region + * could clear it. + * + * Apparently, DR6.BLD and DR6.RTM are active low bits. + * + * As a result, DR6_RESERVED is an incorrect name now, but it is kept for + * compatibility. + */ #define DR6_RESERVED (0xFFFF0FF0) #define DR_TRAP0 (0x1) /* db0 */ diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index b6e43dad577a..3390814de0a5 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -2218,17 +2218,16 @@ EXPORT_PER_CPU_SYMBOL(__stack_chk_guard); /* * Clear all 6 debug registers: */ -static void clear_all_debug_regs(void) +static void initialize_debug_regs(void) { - int i; - - for (i = 0; i < 8; i++) { - /* Ignore db4, db5 */ - if ((i == 4) || (i == 5)) - continue; - - set_debugreg(0, i); - } + /* Control register first -- to make sure everything is disabled. */ + set_debugreg(0, 7); + set_debugreg(DR6_RESERVED, 6); + /* dr5 and dr4 don't exist */ + set_debugreg(0, 3); + set_debugreg(0, 2); + set_debugreg(0, 1); + set_debugreg(0, 0); } #ifdef CONFIG_KGDB @@ -2371,7 +2370,7 @@ void cpu_init(void) load_mm_ldt(&init_mm); - clear_all_debug_regs(); + initialize_debug_regs(); dbg_restore_debug_regs(); doublefault_init_cpu_tss(); diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 8718d58dd0fb..a52db362a65d 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -975,24 +975,32 @@ static bool is_sysenter_singlestep(struct pt_regs *regs) #endif } -static __always_inline unsigned long debug_read_clear_dr6(void) +static __always_inline unsigned long debug_read_reset_dr6(void) { unsigned long dr6; + get_debugreg(dr6, 6); + dr6 ^= DR6_RESERVED; /* Flip to positive polarity */ + /* * The Intel SDM says: * - * Certain debug exceptions may clear bits 0-3. The remaining - * contents of the DR6 register are never cleared by the - * processor. To avoid confusion in identifying debug - * exceptions, debug handlers should clear the register before - * returning to the interrupted task. + * Certain debug exceptions may clear bits 0-3 of DR6. * - * Keep it simple: clear DR6 immediately. + * BLD induced #DB clears DR6.BLD and any other debug + * exception doesn't modify DR6.BLD. + * + * RTM induced #DB clears DR6.RTM and any other debug + * exception sets DR6.RTM. + * + * To avoid confusion in identifying debug exceptions, + * debug handlers should set DR6.BLD and DR6.RTM, and + * clear other DR6 bits before returning. + * + * Keep it simple: write DR6 with its architectural reset + * value 0xFFFF0FF0, defined as DR6_RESERVED, immediately. */ - get_debugreg(dr6, 6); set_debugreg(DR6_RESERVED, 6); - dr6 ^= DR6_RESERVED; /* Flip to positive polarity */ return dr6; } @@ -1188,19 +1196,19 @@ out: /* IST stack entry */ DEFINE_IDTENTRY_DEBUG(exc_debug) { - exc_debug_kernel(regs, debug_read_clear_dr6()); + exc_debug_kernel(regs, debug_read_reset_dr6()); } /* User entry, runs on regular task stack */ DEFINE_IDTENTRY_DEBUG_USER(exc_debug) { - exc_debug_user(regs, debug_read_clear_dr6()); + exc_debug_user(regs, debug_read_reset_dr6()); } #else /* 32 bit does not have separate entry points. */ DEFINE_IDTENTRY_RAW(exc_debug) { - unsigned long dr6 = debug_read_clear_dr6(); + unsigned long dr6 = debug_read_reset_dr6(); if (user_mode(regs)) exc_debug_user(regs, dr6); From 7ac8a61e5503d3c06fe2524e0099719a9d0dafa7 Mon Sep 17 00:00:00 2001 From: Daeho Jeong Date: Thu, 11 Apr 2024 10:54:10 -0700 Subject: [PATCH 906/971] f2fs: prevent writing without fallocate() for pinned files [ Upstream commit 3fdd89b452c2ea5e2195d6e315bef122769584c9 ] In a case writing without fallocate(), we can't guarantee it's allocated in the conventional area for zoned stroage. To make it consistent across storage devices, we disallow it regardless of storage device types. Signed-off-by: Daeho Jeong Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Stable-dep-of: ba8dac350faf ("f2fs: fix to zero post-eof page") Signed-off-by: Sasha Levin --- fs/f2fs/file.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 3e3822115d1e..2eff37cc3760 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -57,7 +57,7 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf) struct inode *inode = file_inode(vmf->vma->vm_file); struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct dnode_of_data dn; - bool need_alloc = true; + bool need_alloc = !f2fs_is_pinned_file(inode); int err = 0; vm_fault_t ret; @@ -114,19 +114,18 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf) goto out_sem; } + set_new_dnode(&dn, inode, NULL, NULL, 0); if (need_alloc) { /* block allocation */ - set_new_dnode(&dn, inode, NULL, NULL, 0); err = f2fs_get_block_locked(&dn, page->index); - } - -#ifdef CONFIG_F2FS_FS_COMPRESSION - if (!need_alloc) { - set_new_dnode(&dn, inode, NULL, NULL, 0); + } else { err = f2fs_get_dnode_of_data(&dn, page->index, LOOKUP_NODE); f2fs_put_dnode(&dn); + if (f2fs_is_pinned_file(inode) && + !__is_valid_data_blkaddr(dn.data_blkaddr)) + err = -EIO; } -#endif + if (err) { unlock_page(page); goto out_sem; @@ -3332,7 +3331,7 @@ static int f2fs_ioc_set_pin_file(struct file *filp, unsigned long arg) goto done; } - if (f2fs_sb_has_blkzoned(sbi) && F2FS_HAS_BLOCKS(inode)) { + if (F2FS_HAS_BLOCKS(inode)) { ret = -EFBIG; goto out; } @@ -4919,6 +4918,8 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) bool dio; bool may_need_sync = true; int preallocated; + const loff_t pos = iocb->ki_pos; + const ssize_t count = iov_iter_count(from); ssize_t ret; if (unlikely(f2fs_cp_error(F2FS_I_SB(inode)))) { @@ -4940,6 +4941,12 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) inode_lock(inode); } + if (f2fs_is_pinned_file(inode) && + !f2fs_overwrite_io(inode, pos, count)) { + ret = -EIO; + goto out_unlock; + } + ret = f2fs_write_checks(iocb, from); if (ret <= 0) goto out_unlock; From d1ccd98eddbac70739cc072d2440aae2b79fa391 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 13 Aug 2024 22:13:24 +0800 Subject: [PATCH 907/971] f2fs: convert f2fs_vm_page_mkwrite() to use folio [ Upstream commit aec5755951b74e3bbb5ddee39ac142a788547854 ] Convert to use folio, so that we can get rid of 'page->index' to prepare for removal of 'index' field in structure page [1]. [1] https://lore.kernel.org/all/Zp8fgUSIBGQ1TN0D@casper.infradead.org/ Cc: Matthew Wilcox Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Stable-dep-of: ba8dac350faf ("f2fs: fix to zero post-eof page") Signed-off-by: Sasha Levin --- fs/f2fs/file.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 2eff37cc3760..121849a4dcfd 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -53,7 +53,7 @@ static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf) static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf) { - struct page *page = vmf->page; + struct folio *folio = page_folio(vmf->page); struct inode *inode = file_inode(vmf->vma->vm_file); struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct dnode_of_data dn; @@ -85,7 +85,7 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf) #ifdef CONFIG_F2FS_FS_COMPRESSION if (f2fs_compressed_file(inode)) { - int ret = f2fs_is_compressed_cluster(inode, page->index); + int ret = f2fs_is_compressed_cluster(inode, folio->index); if (ret < 0) { err = ret; @@ -105,11 +105,11 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf) file_update_time(vmf->vma->vm_file); filemap_invalidate_lock_shared(inode->i_mapping); - lock_page(page); - if (unlikely(page->mapping != inode->i_mapping || - page_offset(page) > i_size_read(inode) || - !PageUptodate(page))) { - unlock_page(page); + folio_lock(folio); + if (unlikely(folio->mapping != inode->i_mapping || + folio_pos(folio) > i_size_read(inode) || + !folio_test_uptodate(folio))) { + folio_unlock(folio); err = -EFAULT; goto out_sem; } @@ -117,9 +117,9 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf) set_new_dnode(&dn, inode, NULL, NULL, 0); if (need_alloc) { /* block allocation */ - err = f2fs_get_block_locked(&dn, page->index); + err = f2fs_get_block_locked(&dn, folio->index); } else { - err = f2fs_get_dnode_of_data(&dn, page->index, LOOKUP_NODE); + err = f2fs_get_dnode_of_data(&dn, folio->index, LOOKUP_NODE); f2fs_put_dnode(&dn); if (f2fs_is_pinned_file(inode) && !__is_valid_data_blkaddr(dn.data_blkaddr)) @@ -127,11 +127,11 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf) } if (err) { - unlock_page(page); + folio_unlock(folio); goto out_sem; } - f2fs_wait_on_page_writeback(page, DATA, false, true); + f2fs_wait_on_page_writeback(folio_page(folio, 0), DATA, false, true); /* wait for GCed page writeback via META_MAPPING */ f2fs_wait_on_block_writeback(inode, dn.data_blkaddr); @@ -139,18 +139,18 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf) /* * check to see if the page is mapped already (no holes) */ - if (PageMappedToDisk(page)) + if (folio_test_mappedtodisk(folio)) goto out_sem; /* page is wholly or partially inside EOF */ - if (((loff_t)(page->index + 1) << PAGE_SHIFT) > + if (((loff_t)(folio->index + 1) << PAGE_SHIFT) > i_size_read(inode)) { loff_t offset; offset = i_size_read(inode) & ~PAGE_MASK; - zero_user_segment(page, offset, PAGE_SIZE); + folio_zero_segment(folio, offset, folio_size(folio)); } - set_page_dirty(page); + folio_mark_dirty(folio); f2fs_update_iostat(sbi, inode, APP_MAPPED_IO, F2FS_BLKSIZE); f2fs_update_time(sbi, REQ_TIME); @@ -162,7 +162,7 @@ out_sem: out: ret = vmf_fs_error(err); - trace_f2fs_vm_page_mkwrite(inode, page->index, vmf->vma->vm_flags, ret); + trace_f2fs_vm_page_mkwrite(inode, folio->index, vmf->vma->vm_flags, ret); return ret; } From 9e67044aa9a79f9334132ddc18cf5f71587fa5ae Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Thu, 5 Jun 2025 11:26:33 +0800 Subject: [PATCH 908/971] f2fs: fix to zero post-eof page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit ba8dac350faf16afc129ce6303ca4feaf083ccb1 ] fstest reports a f2fs bug: #generic/363 42s ... [failed, exit status 1]- output mismatch (see /share/git/fstests/results//generic/363.out.bad) # --- tests/generic/363.out 2025-01-12 21:57:40.271440542 +0800 # +++ /share/git/fstests/results//generic/363.out.bad 2025-05-19 19:55:58.000000000 +0800 # @@ -1,2 +1,78 @@ # QA output created by 363 # fsx -q -S 0 -e 1 -N 100000 # +READ BAD DATA: offset = 0xd6fb, size = 0xf044, fname = /mnt/f2fs/junk # +OFFSET GOOD BAD RANGE # +0x1540d 0x0000 0x2a25 0x0 # +operation# (mod 256) for the bad data may be 37 # +0x1540e 0x0000 0x2527 0x1 # ... # (Run 'diff -u /share/git/fstests/tests/generic/363.out /share/git/fstests/results//generic/363.out.bad' to see the entire diff) Ran: generic/363 Failures: generic/363 Failed 1 of 1 tests The root cause is user can update post-eof page via mmap [1], however, f2fs missed to zero post-eof page in below operations, so, once it expands i_size, then it will include dummy data locates previous post-eof page, so during below operations, we need to zero post-eof page. Operations which can include dummy data after previous i_size after expanding i_size: - write - mapwrite [1] - truncate - fallocate * preallocate * zero_range * insert_range * collapse_range - clone_range (doesn’t support in f2fs) - copy_range (doesn’t support in f2fs) [1] https://man7.org/linux/man-pages/man2/mmap.2.html 'BUG section' Cc: stable@kernel.org Signed-off-by: Chao Yu Reviewed-by: Zhiguo Niu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- fs/f2fs/file.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 121849a4dcfd..b73d40f98191 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -36,6 +36,17 @@ #include #include +static void f2fs_zero_post_eof_page(struct inode *inode, loff_t new_size) +{ + loff_t old_size = i_size_read(inode); + + if (old_size >= new_size) + return; + + /* zero or drop pages only in range of [old_size, new_size] */ + truncate_pagecache(inode, old_size); +} + static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf) { struct inode *inode = file_inode(vmf->vma->vm_file); @@ -103,8 +114,13 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf) f2fs_bug_on(sbi, f2fs_has_inline_data(inode)); + filemap_invalidate_lock(inode->i_mapping); + f2fs_zero_post_eof_page(inode, (folio->index + 1) << PAGE_SHIFT); + filemap_invalidate_unlock(inode->i_mapping); + file_update_time(vmf->vma->vm_file); filemap_invalidate_lock_shared(inode->i_mapping); + folio_lock(folio); if (unlikely(folio->mapping != inode->i_mapping || folio_pos(folio) > i_size_read(inode) || @@ -1051,6 +1067,8 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); filemap_invalidate_lock(inode->i_mapping); + if (attr->ia_size > old_size) + f2fs_zero_post_eof_page(inode, attr->ia_size); truncate_setsize(inode, attr->ia_size); if (attr->ia_size <= old_size) @@ -1169,6 +1187,10 @@ static int f2fs_punch_hole(struct inode *inode, loff_t offset, loff_t len) if (ret) return ret; + filemap_invalidate_lock(inode->i_mapping); + f2fs_zero_post_eof_page(inode, offset + len); + filemap_invalidate_unlock(inode->i_mapping); + pg_start = ((unsigned long long) offset) >> PAGE_SHIFT; pg_end = ((unsigned long long) offset + len) >> PAGE_SHIFT; @@ -1453,6 +1475,8 @@ static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len) f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); filemap_invalidate_lock(inode->i_mapping); + f2fs_zero_post_eof_page(inode, offset + len); + f2fs_lock_op(sbi); f2fs_drop_extent_tree(inode); truncate_pagecache(inode, offset); @@ -1575,6 +1599,10 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len, if (ret) return ret; + filemap_invalidate_lock(mapping); + f2fs_zero_post_eof_page(inode, offset + len); + filemap_invalidate_unlock(mapping); + pg_start = ((unsigned long long) offset) >> PAGE_SHIFT; pg_end = ((unsigned long long) offset + len) >> PAGE_SHIFT; @@ -1706,6 +1734,8 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len) /* avoid gc operation during block exchange */ f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); filemap_invalidate_lock(mapping); + + f2fs_zero_post_eof_page(inode, offset + len); truncate_pagecache(inode, offset); while (!ret && idx > pg_start) { @@ -1761,6 +1791,10 @@ static int f2fs_expand_inode_data(struct inode *inode, loff_t offset, if (err) return err; + filemap_invalidate_lock(inode->i_mapping); + f2fs_zero_post_eof_page(inode, offset + len); + filemap_invalidate_unlock(inode->i_mapping); + f2fs_balance_fs(sbi, true); pg_start = ((unsigned long long)offset) >> PAGE_SHIFT; @@ -4674,6 +4708,10 @@ static ssize_t f2fs_write_checks(struct kiocb *iocb, struct iov_iter *from) err = file_modified(file); if (err) return err; + + filemap_invalidate_lock(inode->i_mapping); + f2fs_zero_post_eof_page(inode, iocb->ki_pos + iov_iter_count(from)); + filemap_invalidate_unlock(inode->i_mapping); return count; } From 95ffe734518d99647409010046ea2d8a6f9c6f7f Mon Sep 17 00:00:00 2001 From: Peter Wang Date: Thu, 31 Aug 2023 21:08:25 +0800 Subject: [PATCH 909/971] scsi: ufs: core: Fix abnormal scale up after last cmd finish [ Upstream commit 6fd53da45bbc834b9cfdf707d2f7ebe666667943 ] When ufshcd_clk_scaling_suspend_work (thread A) running and new command coming, ufshcd_clk_scaling_start_busy (thread B) may get host_lock after thread A first time release host_lock. Then thread A second time get host_lock will set clk_scaling.window_start_t = 0 which scale up clock abnormal next polling_ms time. Also inlines another __ufshcd_suspend_clkscaling calls. Below is racing step: 1 hba->clk_scaling.suspend_work (Thread A) ufshcd_clk_scaling_suspend_work 2 spin_lock_irqsave(hba->host->host_lock, irq_flags); 3 hba->clk_scaling.is_suspended = true; 4 spin_unlock_irqrestore(hba->host->host_lock, irq_flags); __ufshcd_suspend_clkscaling 7 spin_lock_irqsave(hba->host->host_lock, flags); 8 hba->clk_scaling.window_start_t = 0; 9 spin_unlock_irqrestore(hba->host->host_lock, flags); ufshcd_send_command (Thread B) ufshcd_clk_scaling_start_busy 5 spin_lock_irqsave(hba->host->host_lock, flags); .... 6 spin_unlock_irqrestore(hba->host->host_lock, flags); Signed-off-by: Peter Wang Link: https://lore.kernel.org/r/20230831130826.5592-3-peter.wang@mediatek.com Reviewed-by: Bart Van Assche Signed-off-by: Martin K. Petersen Stable-dep-of: 2e083cd80229 ("scsi: ufs: core: Fix clk scaling to be conditional in reset and restore") Signed-off-by: Sasha Levin --- drivers/ufs/core/ufshcd.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 412931cf240f..08c46fefb32b 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -289,7 +289,6 @@ static inline void ufshcd_add_delay_before_dme_cmd(struct ufs_hba *hba); static int ufshcd_host_reset_and_restore(struct ufs_hba *hba); static void ufshcd_resume_clkscaling(struct ufs_hba *hba); static void ufshcd_suspend_clkscaling(struct ufs_hba *hba); -static void __ufshcd_suspend_clkscaling(struct ufs_hba *hba); static int ufshcd_scale_clks(struct ufs_hba *hba, bool scale_up); static irqreturn_t ufshcd_intr(int irq, void *__hba); static int ufshcd_change_power_mode(struct ufs_hba *hba, @@ -1377,9 +1376,10 @@ static void ufshcd_clk_scaling_suspend_work(struct work_struct *work) return; } hba->clk_scaling.is_suspended = true; + hba->clk_scaling.window_start_t = 0; spin_unlock_irqrestore(hba->host->host_lock, irq_flags); - __ufshcd_suspend_clkscaling(hba); + devfreq_suspend_device(hba->devfreq); } static void ufshcd_clk_scaling_resume_work(struct work_struct *work) @@ -1556,16 +1556,6 @@ static void ufshcd_devfreq_remove(struct ufs_hba *hba) dev_pm_opp_remove(hba->dev, clki->max_freq); } -static void __ufshcd_suspend_clkscaling(struct ufs_hba *hba) -{ - unsigned long flags; - - devfreq_suspend_device(hba->devfreq); - spin_lock_irqsave(hba->host->host_lock, flags); - hba->clk_scaling.window_start_t = 0; - spin_unlock_irqrestore(hba->host->host_lock, flags); -} - static void ufshcd_suspend_clkscaling(struct ufs_hba *hba) { unsigned long flags; @@ -1578,11 +1568,12 @@ static void ufshcd_suspend_clkscaling(struct ufs_hba *hba) if (!hba->clk_scaling.is_suspended) { suspend = true; hba->clk_scaling.is_suspended = true; + hba->clk_scaling.window_start_t = 0; } spin_unlock_irqrestore(hba->host->host_lock, flags); if (suspend) - __ufshcd_suspend_clkscaling(hba); + devfreq_suspend_device(hba->devfreq); } static void ufshcd_resume_clkscaling(struct ufs_hba *hba) From 847af89aa1635f42dac2f40ae042eb5d368b23d4 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Thu, 12 Oct 2023 22:51:26 +0530 Subject: [PATCH 910/971] scsi: ufs: core: Add OPP support for scaling clocks and regulators [ Upstream commit 930bd77ebe3dc23b18aa49e55e6a515d5663d67a ] UFS core is only scaling the clocks during devfreq scaling and initialization. But for an optimum power saving, regulators should also be scaled along with the clocks. So let's use the OPP framework which supports scaling clocks, regulators, and performance state using OPP table defined in devicetree. For accomodating the OPP support, the existing APIs (ufshcd_scale_clks, ufshcd_is_devfreq_scaling_required and ufshcd_devfreq_scale) are modified to accept "freq" as an argument which in turn used by the OPP helpers. The OPP support is added along with the old freq-table based clock scaling so that the existing platforms work as expected. Co-developed-by: Krzysztof Kozlowski Signed-off-by: Krzysztof Kozlowski Signed-off-by: Manivannan Sadhasivam Link: https://lore.kernel.org/r/20231012172129.65172-3-manivannan.sadhasivam@linaro.org Signed-off-by: Martin K. Petersen Stable-dep-of: 2e083cd80229 ("scsi: ufs: core: Fix clk scaling to be conditional in reset and restore") Signed-off-by: Sasha Levin --- drivers/ufs/core/ufshcd.c | 144 +++++++++++++++++++++++++++++--------- include/ufs/ufshcd.h | 4 ++ 2 files changed, 115 insertions(+), 33 deletions(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 08c46fefb32b..fa86942efd11 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -289,7 +290,8 @@ static inline void ufshcd_add_delay_before_dme_cmd(struct ufs_hba *hba); static int ufshcd_host_reset_and_restore(struct ufs_hba *hba); static void ufshcd_resume_clkscaling(struct ufs_hba *hba); static void ufshcd_suspend_clkscaling(struct ufs_hba *hba); -static int ufshcd_scale_clks(struct ufs_hba *hba, bool scale_up); +static int ufshcd_scale_clks(struct ufs_hba *hba, unsigned long freq, + bool scale_up); static irqreturn_t ufshcd_intr(int irq, void *__hba); static int ufshcd_change_power_mode(struct ufs_hba *hba, struct ufs_pa_layer_attr *pwr_mode); @@ -1078,14 +1080,32 @@ out: return ret; } +static int ufshcd_opp_set_rate(struct ufs_hba *hba, unsigned long freq) +{ + struct dev_pm_opp *opp; + int ret; + + opp = dev_pm_opp_find_freq_floor_indexed(hba->dev, + &freq, 0); + if (IS_ERR(opp)) + return PTR_ERR(opp); + + ret = dev_pm_opp_set_opp(hba->dev, opp); + dev_pm_opp_put(opp); + + return ret; +} + /** * ufshcd_scale_clks - scale up or scale down UFS controller clocks * @hba: per adapter instance + * @freq: frequency to scale * @scale_up: True if scaling up and false if scaling down * * Return: 0 if successful; < 0 upon failure. */ -static int ufshcd_scale_clks(struct ufs_hba *hba, bool scale_up) +static int ufshcd_scale_clks(struct ufs_hba *hba, unsigned long freq, + bool scale_up) { int ret = 0; ktime_t start = ktime_get(); @@ -1094,13 +1114,21 @@ static int ufshcd_scale_clks(struct ufs_hba *hba, bool scale_up) if (ret) goto out; - ret = ufshcd_set_clk_freq(hba, scale_up); + if (hba->use_pm_opp) + ret = ufshcd_opp_set_rate(hba, freq); + else + ret = ufshcd_set_clk_freq(hba, scale_up); if (ret) goto out; ret = ufshcd_vops_clk_scale_notify(hba, scale_up, POST_CHANGE); - if (ret) - ufshcd_set_clk_freq(hba, !scale_up); + if (ret) { + if (hba->use_pm_opp) + ufshcd_opp_set_rate(hba, + hba->devfreq->previous_freq); + else + ufshcd_set_clk_freq(hba, !scale_up); + } out: trace_ufshcd_profile_clk_scaling(dev_name(hba->dev), @@ -1112,12 +1140,13 @@ out: /** * ufshcd_is_devfreq_scaling_required - check if scaling is required or not * @hba: per adapter instance + * @freq: frequency to scale * @scale_up: True if scaling up and false if scaling down * * Return: true if scaling is required, false otherwise. */ static bool ufshcd_is_devfreq_scaling_required(struct ufs_hba *hba, - bool scale_up) + unsigned long freq, bool scale_up) { struct ufs_clk_info *clki; struct list_head *head = &hba->clk_list_head; @@ -1125,6 +1154,9 @@ static bool ufshcd_is_devfreq_scaling_required(struct ufs_hba *hba, if (list_empty(head)) return false; + if (hba->use_pm_opp) + return freq != hba->clk_scaling.target_freq; + list_for_each_entry(clki, head, list) { if (!IS_ERR_OR_NULL(clki->clk)) { if (scale_up && clki->max_freq) { @@ -1323,12 +1355,14 @@ static void ufshcd_clock_scaling_unprepare(struct ufs_hba *hba, int err, bool sc /** * ufshcd_devfreq_scale - scale up/down UFS clocks and gear * @hba: per adapter instance + * @freq: frequency to scale * @scale_up: True for scaling up and false for scalin down * * Return: 0 for success; -EBUSY if scaling can't happen at this time; non-zero * for any other errors. */ -static int ufshcd_devfreq_scale(struct ufs_hba *hba, bool scale_up) +static int ufshcd_devfreq_scale(struct ufs_hba *hba, unsigned long freq, + bool scale_up) { int ret = 0; @@ -1343,7 +1377,7 @@ static int ufshcd_devfreq_scale(struct ufs_hba *hba, bool scale_up) goto out_unprepare; } - ret = ufshcd_scale_clks(hba, scale_up); + ret = ufshcd_scale_clks(hba, freq, scale_up); if (ret) { if (!scale_up) ufshcd_scale_gear(hba, true); @@ -1354,7 +1388,8 @@ static int ufshcd_devfreq_scale(struct ufs_hba *hba, bool scale_up) if (scale_up) { ret = ufshcd_scale_gear(hba, true); if (ret) { - ufshcd_scale_clks(hba, false); + ufshcd_scale_clks(hba, hba->devfreq->previous_freq, + false); goto out_unprepare; } } @@ -1413,9 +1448,22 @@ static int ufshcd_devfreq_target(struct device *dev, if (!ufshcd_is_clkscaling_supported(hba)) return -EINVAL; - clki = list_first_entry(&hba->clk_list_head, struct ufs_clk_info, list); - /* Override with the closest supported frequency */ - *freq = (unsigned long) clk_round_rate(clki->clk, *freq); + if (hba->use_pm_opp) { + struct dev_pm_opp *opp; + + /* Get the recommended frequency from OPP framework */ + opp = devfreq_recommended_opp(dev, freq, flags); + if (IS_ERR(opp)) + return PTR_ERR(opp); + + dev_pm_opp_put(opp); + } else { + /* Override with the closest supported frequency */ + clki = list_first_entry(&hba->clk_list_head, struct ufs_clk_info, + list); + *freq = (unsigned long) clk_round_rate(clki->clk, *freq); + } + spin_lock_irqsave(hba->host->host_lock, irq_flags); if (ufshcd_eh_in_progress(hba)) { spin_unlock_irqrestore(hba->host->host_lock, irq_flags); @@ -1430,12 +1478,17 @@ static int ufshcd_devfreq_target(struct device *dev, goto out; } - /* Decide based on the rounded-off frequency and update */ - scale_up = *freq == clki->max_freq; - if (!scale_up) + /* Decide based on the target or rounded-off frequency and update */ + if (hba->use_pm_opp) + scale_up = *freq > hba->clk_scaling.target_freq; + else + scale_up = *freq == clki->max_freq; + + if (!hba->use_pm_opp && !scale_up) *freq = clki->min_freq; + /* Update the frequency */ - if (!ufshcd_is_devfreq_scaling_required(hba, scale_up)) { + if (!ufshcd_is_devfreq_scaling_required(hba, *freq, scale_up)) { spin_unlock_irqrestore(hba->host->host_lock, irq_flags); ret = 0; goto out; /* no state change required */ @@ -1443,7 +1496,9 @@ static int ufshcd_devfreq_target(struct device *dev, spin_unlock_irqrestore(hba->host->host_lock, irq_flags); start = ktime_get(); - ret = ufshcd_devfreq_scale(hba, scale_up); + ret = ufshcd_devfreq_scale(hba, *freq, scale_up); + if (!ret) + hba->clk_scaling.target_freq = *freq; trace_ufshcd_profile_clk_scaling(dev_name(hba->dev), (scale_up ? "up" : "down"), @@ -1463,8 +1518,6 @@ static int ufshcd_devfreq_get_dev_status(struct device *dev, struct ufs_hba *hba = dev_get_drvdata(dev); struct ufs_clk_scaling *scaling = &hba->clk_scaling; unsigned long flags; - struct list_head *clk_list = &hba->clk_list_head; - struct ufs_clk_info *clki; ktime_t curr_t; if (!ufshcd_is_clkscaling_supported(hba)) @@ -1477,17 +1530,24 @@ static int ufshcd_devfreq_get_dev_status(struct device *dev, if (!scaling->window_start_t) goto start_window; - clki = list_first_entry(clk_list, struct ufs_clk_info, list); /* * If current frequency is 0, then the ondemand governor considers * there's no initial frequency set. And it always requests to set * to max. frequency. */ - stat->current_frequency = clki->curr_freq; + if (hba->use_pm_opp) { + stat->current_frequency = hba->clk_scaling.target_freq; + } else { + struct list_head *clk_list = &hba->clk_list_head; + struct ufs_clk_info *clki; + + clki = list_first_entry(clk_list, struct ufs_clk_info, list); + stat->current_frequency = clki->curr_freq; + } + if (scaling->is_busy_started) scaling->tot_busy_t += ktime_us_delta(curr_t, scaling->busy_start_t); - stat->total_time = ktime_us_delta(curr_t, scaling->window_start_t); stat->busy_time = scaling->tot_busy_t; start_window: @@ -1516,9 +1576,11 @@ static int ufshcd_devfreq_init(struct ufs_hba *hba) if (list_empty(clk_list)) return 0; - clki = list_first_entry(clk_list, struct ufs_clk_info, list); - dev_pm_opp_add(hba->dev, clki->min_freq, 0); - dev_pm_opp_add(hba->dev, clki->max_freq, 0); + if (!hba->use_pm_opp) { + clki = list_first_entry(clk_list, struct ufs_clk_info, list); + dev_pm_opp_add(hba->dev, clki->min_freq, 0); + dev_pm_opp_add(hba->dev, clki->max_freq, 0); + } ufshcd_vops_config_scaling_param(hba, &hba->vps->devfreq_profile, &hba->vps->ondemand_data); @@ -1530,8 +1592,10 @@ static int ufshcd_devfreq_init(struct ufs_hba *hba) ret = PTR_ERR(devfreq); dev_err(hba->dev, "Unable to register with devfreq %d\n", ret); - dev_pm_opp_remove(hba->dev, clki->min_freq); - dev_pm_opp_remove(hba->dev, clki->max_freq); + if (!hba->use_pm_opp) { + dev_pm_opp_remove(hba->dev, clki->min_freq); + dev_pm_opp_remove(hba->dev, clki->max_freq); + } return ret; } @@ -1543,7 +1607,6 @@ static int ufshcd_devfreq_init(struct ufs_hba *hba) static void ufshcd_devfreq_remove(struct ufs_hba *hba) { struct list_head *clk_list = &hba->clk_list_head; - struct ufs_clk_info *clki; if (!hba->devfreq) return; @@ -1551,9 +1614,13 @@ static void ufshcd_devfreq_remove(struct ufs_hba *hba) devfreq_remove_device(hba->devfreq); hba->devfreq = NULL; - clki = list_first_entry(clk_list, struct ufs_clk_info, list); - dev_pm_opp_remove(hba->dev, clki->min_freq); - dev_pm_opp_remove(hba->dev, clki->max_freq); + if (!hba->use_pm_opp) { + struct ufs_clk_info *clki; + + clki = list_first_entry(clk_list, struct ufs_clk_info, list); + dev_pm_opp_remove(hba->dev, clki->min_freq); + dev_pm_opp_remove(hba->dev, clki->max_freq); + } } static void ufshcd_suspend_clkscaling(struct ufs_hba *hba) @@ -1629,7 +1696,7 @@ static ssize_t ufshcd_clkscale_enable_store(struct device *dev, ufshcd_resume_clkscaling(hba); } else { ufshcd_suspend_clkscaling(hba); - err = ufshcd_devfreq_scale(hba, true); + err = ufshcd_devfreq_scale(hba, ULONG_MAX, true); if (err) dev_err(hba->dev, "%s: failed to scale clocks up %d\n", __func__, err); @@ -7713,7 +7780,7 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba) hba->silence_err_logs = false; /* scale up clocks to max frequency before full reinitialization */ - ufshcd_scale_clks(hba, true); + ufshcd_scale_clks(hba, ULONG_MAX, true); err = ufshcd_hba_enable(hba); @@ -9351,6 +9418,17 @@ static int ufshcd_init_clocks(struct ufs_hba *hba) dev_dbg(dev, "%s: clk: %s, rate: %lu\n", __func__, clki->name, clk_get_rate(clki->clk)); } + + /* Set Max. frequency for all clocks */ + if (hba->use_pm_opp) { + ret = ufshcd_opp_set_rate(hba, ULONG_MAX); + if (ret) { + dev_err(hba->dev, "%s: failed to set OPP: %d", __func__, + ret); + goto out; + } + } + out: return ret; } diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index d5aa832f8dba..e9db9682316a 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -430,6 +430,7 @@ struct ufs_clk_gating { * @workq: workqueue to schedule devfreq suspend/resume work * @suspend_work: worker to suspend devfreq * @resume_work: worker to resume devfreq + * @target_freq: frequency requested by devfreq framework * @min_gear: lowest HS gear to scale down to * @is_enabled: tracks if scaling is currently enabled or not, controlled by * clkscale_enable sysfs node @@ -449,6 +450,7 @@ struct ufs_clk_scaling { struct workqueue_struct *workq; struct work_struct suspend_work; struct work_struct resume_work; + unsigned long target_freq; u32 min_gear; bool is_enabled; bool is_allowed; @@ -862,6 +864,7 @@ enum ufshcd_mcq_opr { * @auto_bkops_enabled: to track whether bkops is enabled in device * @vreg_info: UFS device voltage regulator information * @clk_list_head: UFS host controller clocks list node head + * @use_pm_opp: Indicates whether OPP based scaling is used or not * @req_abort_count: number of times ufshcd_abort() has been called * @lanes_per_direction: number of lanes per data direction between the UFS * controller and the UFS device. @@ -1014,6 +1017,7 @@ struct ufs_hba { bool auto_bkops_enabled; struct ufs_vreg_info vreg_info; struct list_head clk_list_head; + bool use_pm_opp; /* Number of requests aborts */ int req_abort_count; From 51ba65860457b67e7905fe16690df0fecf1a29d2 Mon Sep 17 00:00:00 2001 From: anvithdosapati Date: Mon, 16 Jun 2025 08:57:34 +0000 Subject: [PATCH 911/971] scsi: ufs: core: Fix clk scaling to be conditional in reset and restore [ Upstream commit 2e083cd802294693a5414e4557a183dd7e442e71 ] In ufshcd_host_reset_and_restore(), scale up clocks only when clock scaling is supported. Without this change CPU latency is voted for 0 (ufshcd_pm_qos_update) during resume unconditionally. Signed-off-by: anvithdosapati Link: https://lore.kernel.org/r/20250616085734.2133581-1-anvithdosapati@google.com Fixes: a3cd5ec55f6c ("scsi: ufs: add load based scaling of UFS gear") Cc: stable@vger.kernel.org Reviewed-by: Bart Van Assche Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/ufs/core/ufshcd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index fa86942efd11..da20bd3d46bc 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -7780,7 +7780,8 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba) hba->silence_err_logs = false; /* scale up clocks to max frequency before full reinitialization */ - ufshcd_scale_clks(hba, ULONG_MAX, true); + if (ufshcd_is_clkscaling_supported(hba)) + ufshcd_scale_clks(hba, ULONG_MAX, true); err = ufshcd_hba_enable(hba); From ad09bb7cbd14ae6571c14f2352f79eeca86a8161 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 7 Apr 2025 15:47:24 +0200 Subject: [PATCH 912/971] drm/simpledrm: Do not upcast in release helpers [ Upstream commit d231cde7c84359fb18fb268cf6cff03b5bce48ff ] The res pointer passed to simpledrm_device_release_clocks() and simpledrm_device_release_regulators() points to an instance of struct simpledrm_device. No need to upcast from struct drm_device. The upcast is harmless, as DRM device is the first field in struct simpledrm_device. Signed-off-by: Thomas Zimmermann Fixes: 11e8f5fd223b ("drm: Add simpledrm driver") Cc: # v5.14+ Reviewed-by: Javier Martinez Canillas Reviewed-by: Jocelyn Falempe Link: https://lore.kernel.org/r/20250407134753.985925-2-tzimmermann@suse.de Signed-off-by: Sasha Levin --- drivers/gpu/drm/tiny/simpledrm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c index 8ea120eb8674..30676b107303 100644 --- a/drivers/gpu/drm/tiny/simpledrm.c +++ b/drivers/gpu/drm/tiny/simpledrm.c @@ -276,7 +276,7 @@ static struct simpledrm_device *simpledrm_device_of_dev(struct drm_device *dev) static void simpledrm_device_release_clocks(void *res) { - struct simpledrm_device *sdev = simpledrm_device_of_dev(res); + struct simpledrm_device *sdev = res; unsigned int i; for (i = 0; i < sdev->clk_count; ++i) { @@ -374,7 +374,7 @@ static int simpledrm_device_init_clocks(struct simpledrm_device *sdev) static void simpledrm_device_release_regulators(void *res) { - struct simpledrm_device *sdev = simpledrm_device_of_dev(res); + struct simpledrm_device *sdev = res; unsigned int i; for (i = 0; i < sdev->regulator_count; ++i) { From 5df2087c9a1e127eaacb257b9e064d534b1f1443 Mon Sep 17 00:00:00 2001 From: "Xin Li (Intel)" Date: Fri, 20 Jun 2025 16:15:03 -0700 Subject: [PATCH 913/971] drm/i915/dp_mst: Work around Thunderbolt sink disconnect after SINK_COUNT_ESI read [ Upstream commit 9cb15478916e849d62a6ec44b10c593b9663328c ] Due to a problem in the iTBT DP-in adapter's firmware the sink on a TBT link may get disconnected inadvertently if the SINK_COUNT_ESI and the DP_LINK_SERVICE_IRQ_VECTOR_ESI0 registers are read in a single AUX transaction. Work around the issue by reading these registers in separate transactions. The issue affects MTL+ platforms and will be fixed in the DP-in adapter firmware, however releasing that firmware fix may take some time and is not guaranteed to be available for all systems. Based on this apply the workaround on affected platforms. See HSD #13013007775. v2: Cc'ing Mika Westerberg. Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13760 Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14147 Cc: Mika Westerberg Cc: stable@vger.kernel.org Reviewed-by: Mika Westerberg Signed-off-by: Imre Deak Link: https://lore.kernel.org/r/20250519133417.1469181-1-imre.deak@intel.com (cherry picked from commit c3a48363cf1f76147088b1adb518136ac5df86a0) Signed-off-by: Joonas Lahtinen Signed-off-by: Sasha Levin --- arch/x86/kernel/cpu/common.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 3390814de0a5..cc1bbf70477b 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -2215,9 +2215,6 @@ EXPORT_PER_CPU_SYMBOL(__stack_chk_guard); #endif /* CONFIG_X86_64 */ -/* - * Clear all 6 debug registers: - */ static void initialize_debug_regs(void) { /* Control register first -- to make sure everything is disabled. */ From fe2695b2f63bd77e0e03bc0fc779164115bb4699 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 14 May 2025 09:33:32 -0700 Subject: [PATCH 914/971] drm/msm: Fix a fence leak in submit error path [ Upstream commit 5d319f75ccf7f0927425a7545aa1a22b3eedc189 ] In error paths, we could unref the submit without calling drm_sched_entity_push_job(), so msm_job_free() will never get called. Since drm_sched_job_cleanup() will NULL out the s_fence, we can use that to detect this case. Signed-off-by: Rob Clark Patchwork: https://patchwork.freedesktop.org/patch/653584/ Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/msm_gem_submit.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 018b39546fc1..27366304f5d5 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -85,6 +85,15 @@ void __msm_gem_submit_destroy(struct kref *kref) container_of(kref, struct msm_gem_submit, ref); unsigned i; + /* + * In error paths, we could unref the submit without calling + * drm_sched_entity_push_job(), so msm_job_free() will never + * get called. Since drm_sched_job_cleanup() will NULL out + * s_fence, we can use that to detect this case. + */ + if (submit->base.s_fence) + drm_sched_job_cleanup(&submit->base); + if (submit->fence_id) { spin_lock(&submit->queue->idr_lock); idr_remove(&submit->queue->fence_idr, submit->fence_id); From c40ad1c04d306f7fde26337fdcf8a5979657d93f Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 14 May 2025 09:33:33 -0700 Subject: [PATCH 915/971] drm/msm: Fix another leak in the submit error path [ Upstream commit f681c2aa8676a890eacc84044717ab0fd26e058f ] put_unused_fd() doesn't free the installed file, if we've already done fd_install(). So we need to also free the sync_file. Signed-off-by: Rob Clark Patchwork: https://patchwork.freedesktop.org/patch/653583/ Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/msm_gem_submit.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 27366304f5d5..bbe4f1665b60 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -763,6 +763,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, struct msm_ringbuffer *ring; struct msm_submit_post_dep *post_deps = NULL; struct drm_syncobj **syncobjs_to_reset = NULL; + struct sync_file *sync_file = NULL; int out_fence_fd = -1; bool has_ww_ticket = false; unsigned i; @@ -979,7 +980,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, } if (ret == 0 && args->flags & MSM_SUBMIT_FENCE_FD_OUT) { - struct sync_file *sync_file = sync_file_create(submit->user_fence); + sync_file = sync_file_create(submit->user_fence); if (!sync_file) { ret = -ENOMEM; } else { @@ -1012,8 +1013,11 @@ out: out_unlock: mutex_unlock(&queue->lock); out_post_unlock: - if (ret && (out_fence_fd >= 0)) + if (ret && (out_fence_fd >= 0)) { put_unused_fd(out_fence_fd); + if (sync_file) + fput(sync_file->file); + } if (!IS_ERR_OR_NULL(submit)) { msm_gem_submit_put(submit); From c7922052c6f26e69e6361a1604b6828ddaac4be3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Jun 2025 08:43:19 +0200 Subject: [PATCH 916/971] ALSA: sb: Don't allow changing the DMA mode during operations [ Upstream commit ed29e073ba93f2d52832804cabdd831d5d357d33 ] When a PCM stream is already running, one shouldn't change the DMA mode via kcontrol, which may screw up the hardware. Return -EBUSY instead. Link: https://bugzilla.kernel.org/show_bug.cgi?id=218185 Link: https://patch.msgid.link/20250610064322.26787-1-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/isa/sb/sb16_main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c index a9b87e159b2d..5efbd0a41312 100644 --- a/sound/isa/sb/sb16_main.c +++ b/sound/isa/sb/sb16_main.c @@ -703,6 +703,9 @@ static int snd_sb16_dma_control_put(struct snd_kcontrol *kcontrol, struct snd_ct unsigned char nval, oval; int change; + if (chip->mode & (SB_MODE_PLAYBACK | SB_MODE_CAPTURE)) + return -EBUSY; + nval = ucontrol->value.enumerated.item[0]; if (nval > 2) return -EINVAL; From 6766316c1a9f7168480357a35f0cb61a446e8336 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Jun 2025 08:43:20 +0200 Subject: [PATCH 917/971] ALSA: sb: Force to disable DMAs once when DMA mode is changed [ Upstream commit 4c267ae2ef349639b4d9ebf00dd28586a82fdbe6 ] When the DMA mode is changed on the (still real!) SB AWE32 after playing a stream and closing, the previous DMA setup was still silently kept, and it can confuse the hardware, resulting in the unexpected noises. As a workaround, enforce the disablement of DMA setups when the DMA setup is changed by the kcontrol. https://bugzilla.kernel.org/show_bug.cgi?id=218185 Link: https://patch.msgid.link/20250610064322.26787-2-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/isa/sb/sb16_main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c index 5efbd0a41312..1497a7822eee 100644 --- a/sound/isa/sb/sb16_main.c +++ b/sound/isa/sb/sb16_main.c @@ -714,6 +714,10 @@ static int snd_sb16_dma_control_put(struct snd_kcontrol *kcontrol, struct snd_ct change = nval != oval; snd_sb16_set_dma_mode(chip, nval); spin_unlock_irqrestore(&chip->reg_lock, flags); + if (change) { + snd_dma_disable(chip->dma8); + snd_dma_disable(chip->dma16); + } return change; } From 71f89fab5cc95d8069eb5b2aaea802f3bdb71c29 Mon Sep 17 00:00:00 2001 From: Tasos Sahanidis Date: Mon, 19 May 2025 11:56:55 +0300 Subject: [PATCH 918/971] ata: libata-acpi: Do not assume 40 wire cable if no devices are enabled [ Upstream commit 33877220b8641b4cde474a4229ea92c0e3637883 ] On at least an ASRock 990FX Extreme 4 with a VIA VT6330, the devices have not yet been enabled by the first time ata_acpi_cbl_80wire() is called. This means that the ata_for_each_dev loop is never entered, and a 40 wire cable is assumed. The VIA controller on this board does not report the cable in the PCI config space, thus having to fall back to ACPI even though no SATA bridge is present. The _GTM values are correctly reported by the firmware through ACPI, which has already set up faster transfer modes, but due to the above the controller is forced down to a maximum of UDMA/33. Resolve this by modifying ata_acpi_cbl_80wire() to directly return the cable type. First, an unknown cable is assumed which preserves the mode set by the firmware, and then on subsequent calls when the devices have been enabled, an 80 wire cable is correctly detected. Since the function now directly returns the cable type, it is renamed to ata_acpi_cbl_pata_type(). Signed-off-by: Tasos Sahanidis Link: https://lore.kernel.org/r/20250519085945.1399466-1-tasos@tasossah.com Signed-off-by: Niklas Cassel Signed-off-by: Sasha Levin --- drivers/ata/libata-acpi.c | 24 ++++++++++++++++-------- drivers/ata/pata_via.c | 6 ++---- include/linux/libata.h | 7 +++---- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index d36e71f475ab..39a350755a1b 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -514,15 +514,19 @@ unsigned int ata_acpi_gtm_xfermask(struct ata_device *dev, EXPORT_SYMBOL_GPL(ata_acpi_gtm_xfermask); /** - * ata_acpi_cbl_80wire - Check for 80 wire cable + * ata_acpi_cbl_pata_type - Return PATA cable type * @ap: Port to check - * @gtm: GTM data to use * - * Return 1 if the @gtm indicates the BIOS selected an 80wire mode. + * Return ATA_CBL_PATA* according to the transfer mode selected by BIOS */ -int ata_acpi_cbl_80wire(struct ata_port *ap, const struct ata_acpi_gtm *gtm) +int ata_acpi_cbl_pata_type(struct ata_port *ap) { struct ata_device *dev; + int ret = ATA_CBL_PATA_UNK; + const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap); + + if (!gtm) + return ATA_CBL_PATA40; ata_for_each_dev(dev, &ap->link, ENABLED) { unsigned int xfer_mask, udma_mask; @@ -530,13 +534,17 @@ int ata_acpi_cbl_80wire(struct ata_port *ap, const struct ata_acpi_gtm *gtm) xfer_mask = ata_acpi_gtm_xfermask(dev, gtm); ata_unpack_xfermask(xfer_mask, NULL, NULL, &udma_mask); - if (udma_mask & ~ATA_UDMA_MASK_40C) - return 1; + ret = ATA_CBL_PATA40; + + if (udma_mask & ~ATA_UDMA_MASK_40C) { + ret = ATA_CBL_PATA80; + break; + } } - return 0; + return ret; } -EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire); +EXPORT_SYMBOL_GPL(ata_acpi_cbl_pata_type); static void ata_acpi_gtf_to_tf(struct ata_device *dev, const struct ata_acpi_gtf *gtf, diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index d82728a01832..bb80e7800dcb 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -201,11 +201,9 @@ static int via_cable_detect(struct ata_port *ap) { two drives */ if (ata66 & (0x10100000 >> (16 * ap->port_no))) return ATA_CBL_PATA80; + /* Check with ACPI so we can spot BIOS reported SATA bridges */ - if (ata_acpi_init_gtm(ap) && - ata_acpi_cbl_80wire(ap, ata_acpi_init_gtm(ap))) - return ATA_CBL_PATA80; - return ATA_CBL_PATA40; + return ata_acpi_cbl_pata_type(ap); } static int via_pre_reset(struct ata_link *link, unsigned long deadline) diff --git a/include/linux/libata.h b/include/linux/libata.h index 91c4e11cb6ab..285d709cbbde 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1305,7 +1305,7 @@ int ata_acpi_stm(struct ata_port *ap, const struct ata_acpi_gtm *stm); int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *stm); unsigned int ata_acpi_gtm_xfermask(struct ata_device *dev, const struct ata_acpi_gtm *gtm); -int ata_acpi_cbl_80wire(struct ata_port *ap, const struct ata_acpi_gtm *gtm); +int ata_acpi_cbl_pata_type(struct ata_port *ap); #else static inline const struct ata_acpi_gtm *ata_acpi_init_gtm(struct ata_port *ap) { @@ -1330,10 +1330,9 @@ static inline unsigned int ata_acpi_gtm_xfermask(struct ata_device *dev, return 0; } -static inline int ata_acpi_cbl_80wire(struct ata_port *ap, - const struct ata_acpi_gtm *gtm) +static inline int ata_acpi_cbl_pata_type(struct ata_port *ap) { - return 0; + return ATA_CBL_PATA40; } #endif From 69283b3fd463edb3001c32242a2dde3b00dd8756 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 6 Jun 2025 11:01:11 +0200 Subject: [PATCH 919/971] ata: pata_cs5536: fix build on 32-bit UML [ Upstream commit fe5b391fc56f77cf3c22a9dd4f0ce20db0e3533f ] On 32-bit ARCH=um, CONFIG_X86_32 is still defined, so it doesn't indicate building on real X86 machines. There's no MSR on UML though, so add a check for CONFIG_X86. Reported-by: Arnd Bergmann Signed-off-by: Johannes Berg Link: https://lore.kernel.org/r/20250606090110.15784-2-johannes@sipsolutions.net Signed-off-by: Niklas Cassel Signed-off-by: Sasha Levin --- drivers/ata/pata_cs5536.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c index b811efd2cc34..73e81e160c91 100644 --- a/drivers/ata/pata_cs5536.c +++ b/drivers/ata/pata_cs5536.c @@ -27,7 +27,7 @@ #include #include -#ifdef CONFIG_X86_32 +#if defined(CONFIG_X86) && defined(CONFIG_X86_32) #include static int use_msr; module_param_named(msr, use_msr, int, 0644); From 785200516552ac87c3ade196e3a0bf35254d1e79 Mon Sep 17 00:00:00 2001 From: Gabriel Santese Date: Fri, 30 May 2025 02:52:32 +0200 Subject: [PATCH 920/971] ASoC: amd: yc: Add quirk for MSI Bravo 17 D7VF internal mic [ Upstream commit ba06528ad5a31923efc24324706116ccd17e12d8 ] MSI Bravo 17 (D7VF), like other laptops from the family, has broken ACPI tables and needs a quirk for internal mic to work properly. Signed-off-by: Gabriel Santese Link: https://patch.msgid.link/20250530005444.23398-1-santesegabriel@gmail.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index 40e2b5a87916..1547cf8b46b1 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -451,6 +451,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Bravo 17 D7VEK"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Micro-Star International Co., Ltd."), + DMI_MATCH(DMI_PRODUCT_NAME, "Bravo 17 D7VF"), + } + }, { .driver_data = &acp6x_card, .matches = { From ba9117312795efa07b487d378a7ebff247f48dc5 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Wed, 11 Jun 2025 15:33:40 -0500 Subject: [PATCH 921/971] platform/x86/amd/pmc: Add PCSpecialist Lafite Pro V 14M to 8042 quirks list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 9ba75ccad85708c5a484637dccc1fc59295b0a83 ] Every other s2idle cycle fails to reach hardware sleep when keyboard wakeup is enabled. This appears to be an EC bug, but the vendor refuses to fix it. It was confirmed that turning off i8042 wakeup avoids ths issue (albeit keyboard wakeup is disabled). Take the lesser of two evils and add it to the i8042 quirk list. Reported-by: Raoul Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220116 Tested-by: Raoul Signed-off-by: Mario Limonciello Link: https://lore.kernel.org/r/20250611203341.3733478-1-superm1@kernel.org Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin --- drivers/platform/x86/amd/pmc/pmc-quirks.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/platform/x86/amd/pmc/pmc-quirks.c b/drivers/platform/x86/amd/pmc/pmc-quirks.c index 2e3f6fc67c56..7ed12c1d3b34 100644 --- a/drivers/platform/x86/amd/pmc/pmc-quirks.c +++ b/drivers/platform/x86/amd/pmc/pmc-quirks.c @@ -224,6 +224,15 @@ static const struct dmi_system_id fwbug_list[] = { DMI_MATCH(DMI_BOARD_NAME, "WUJIE14-GX4HRXL"), } }, + /* https://bugzilla.kernel.org/show_bug.cgi?id=220116 */ + { + .ident = "PCSpecialist Lafite Pro V 14M", + .driver_data = &quirk_spurious_8042, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "PCSpecialist"), + DMI_MATCH(DMI_PRODUCT_NAME, "Lafite Pro V 14M"), + } + }, {} }; From 871beab5b4f9618b4d58266abffa9be2891f914b Mon Sep 17 00:00:00 2001 From: Madhavan Srinivasan Date: Sat, 17 May 2025 19:52:37 +0530 Subject: [PATCH 922/971] powerpc: Fix struct termio related ioctl macros [ Upstream commit ab107276607af90b13a5994997e19b7b9731e251 ] Since termio interface is now obsolete, include/uapi/asm/ioctls.h has some constant macros referring to "struct termio", this caused build failure at userspace. In file included from /usr/include/asm/ioctl.h:12, from /usr/include/asm/ioctls.h:5, from tst-ioctls.c:3: tst-ioctls.c: In function 'get_TCGETA': tst-ioctls.c:12:10: error: invalid application of 'sizeof' to incomplete type 'struct termio' 12 | return TCGETA; | ^~~~~~ Even though termios.h provides "struct termio", trying to juggle definitions around to make it compile could introduce regressions. So better to open code it. Reported-by: Tulio Magno Suggested-by: Nicholas Piggin Tested-by: Justin M. Forbes Reviewed-by: Michael Ellerman Closes: https://lore.kernel.org/linuxppc-dev/8734dji5wl.fsf@ascii.art.br/ Signed-off-by: Madhavan Srinivasan Link: https://patch.msgid.link/20250517142237.156665-1-maddy@linux.ibm.com Signed-off-by: Sasha Levin --- arch/powerpc/include/uapi/asm/ioctls.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/include/uapi/asm/ioctls.h b/arch/powerpc/include/uapi/asm/ioctls.h index 2c145da3b774..b5211e413829 100644 --- a/arch/powerpc/include/uapi/asm/ioctls.h +++ b/arch/powerpc/include/uapi/asm/ioctls.h @@ -23,10 +23,10 @@ #define TCSETSW _IOW('t', 21, struct termios) #define TCSETSF _IOW('t', 22, struct termios) -#define TCGETA _IOR('t', 23, struct termio) -#define TCSETA _IOW('t', 24, struct termio) -#define TCSETAW _IOW('t', 25, struct termio) -#define TCSETAF _IOW('t', 28, struct termio) +#define TCGETA 0x40147417 /* _IOR('t', 23, struct termio) */ +#define TCSETA 0x80147418 /* _IOW('t', 24, struct termio) */ +#define TCSETAW 0x80147419 /* _IOW('t', 25, struct termio) */ +#define TCSETAF 0x8014741c /* _IOW('t', 28, struct termio) */ #define TCSBRK _IO('t', 29) #define TCXONC _IO('t', 30) From a1d10fee0783de5ba4fea473eb9e026369d1eab9 Mon Sep 17 00:00:00 2001 From: Raven Black Date: Fri, 13 Jun 2025 07:51:25 -0400 Subject: [PATCH 923/971] ASoC: amd: yc: update quirk data for HP Victus [ Upstream commit 13b86ea92ebf0fa587fbadfb8a60ca2e9993203f ] Make the internal microphone work on HP Victus laptops. Signed-off-by: Raven Black Link: https://patch.msgid.link/20250613-support-hp-victus-microphone-v1-1-bebc4c3a2041@gmail.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index 1547cf8b46b1..429e61d47ffb 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -521,6 +521,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16z-n000"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "Victus by HP Gaming Laptop 15-fb2xxx"), + } + }, { .driver_data = &acp6x_card, .matches = { From 7b9203afeb37e52a49a4e1f9042f5d679d8a8f81 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Fri, 6 Jun 2025 21:04:18 +0200 Subject: [PATCH 924/971] regulator: fan53555: add enable_time support and soft-start times [ Upstream commit 8acfb165a492251a08a22a4fa6497a131e8c2609 ] The datasheets for all the fan53555 variants (and clones using the same interface) define so called soft start times, from enabling the regulator until at least some percentage of the output (i.e. 92% for the rk860x types) are available. The regulator framework supports this with the enable_time property but currently the fan53555 driver does not define enable_times for any variant. I ran into a problem with this while testing the new driver for the Rockchip NPUs (rocket), which does runtime-pm including disabling and enabling a rk8602 as needed. When reenabling the regulator while running a load, fatal hangs could be observed while enabling the associated power-domain, which the regulator supplies. Experimentally setting the regulator to always-on, made the issue disappear, leading to the missing delay to let power stabilize. And as expected, setting the enable-time to a non-zero value according to the datasheet also resolved the regulator-issue. The datasheets in nearly all cases only specify "typical" values, except for the fan53555 type 08. There both a typical and maximum value are listed - 40uS apart. For all typical values I've added 100uS to be on the safe side. Individual details for the relevant regulators below: - fan53526: The datasheet for all variants lists a typical value of 150uS, so make that 250uS with safety margin. - fan53555: types 08 and 18 (unsupported) are given a typical enable time of 135uS but also a maximum of 175uS so use that value. All the other types only have a typical time in the datasheet of 300uS, so give a bit margin by setting it to 400uS. - rk8600 + rk8602: Datasheet reports a typical value of 260us, so use 360uS to be safe. - syr82x + syr83x: All datasheets report typical soft-start values of 300uS for these regulators, so use 400uS. - tcs452x: Datasheet sadly does not report a soft-start time, so I've not set an enable-time Signed-off-by: Heiko Stuebner Link: https://patch.msgid.link/20250606190418.478633-1-heiko@sntech.de Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/regulator/fan53555.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c index 48f312167e53..8912f5be7270 100644 --- a/drivers/regulator/fan53555.c +++ b/drivers/regulator/fan53555.c @@ -147,6 +147,7 @@ struct fan53555_device_info { unsigned int slew_mask; const unsigned int *ramp_delay_table; unsigned int n_ramp_values; + unsigned int enable_time; unsigned int slew_rate; }; @@ -282,6 +283,7 @@ static int fan53526_voltages_setup_fairchild(struct fan53555_device_info *di) di->slew_mask = CTL_SLEW_MASK; di->ramp_delay_table = slew_rates; di->n_ramp_values = ARRAY_SIZE(slew_rates); + di->enable_time = 250; di->vsel_count = FAN53526_NVOLTAGES; return 0; @@ -296,10 +298,12 @@ static int fan53555_voltages_setup_fairchild(struct fan53555_device_info *di) case FAN53555_CHIP_REV_00: di->vsel_min = 600000; di->vsel_step = 10000; + di->enable_time = 400; break; case FAN53555_CHIP_REV_13: di->vsel_min = 800000; di->vsel_step = 10000; + di->enable_time = 400; break; default: dev_err(di->dev, @@ -311,13 +315,19 @@ static int fan53555_voltages_setup_fairchild(struct fan53555_device_info *di) case FAN53555_CHIP_ID_01: case FAN53555_CHIP_ID_03: case FAN53555_CHIP_ID_05: + di->vsel_min = 600000; + di->vsel_step = 10000; + di->enable_time = 400; + break; case FAN53555_CHIP_ID_08: di->vsel_min = 600000; di->vsel_step = 10000; + di->enable_time = 175; break; case FAN53555_CHIP_ID_04: di->vsel_min = 603000; di->vsel_step = 12826; + di->enable_time = 400; break; default: dev_err(di->dev, @@ -350,6 +360,7 @@ static int fan53555_voltages_setup_rockchip(struct fan53555_device_info *di) di->slew_mask = CTL_SLEW_MASK; di->ramp_delay_table = slew_rates; di->n_ramp_values = ARRAY_SIZE(slew_rates); + di->enable_time = 360; di->vsel_count = FAN53555_NVOLTAGES; return 0; @@ -372,6 +383,7 @@ static int rk8602_voltages_setup_rockchip(struct fan53555_device_info *di) di->slew_mask = CTL_SLEW_MASK; di->ramp_delay_table = slew_rates; di->n_ramp_values = ARRAY_SIZE(slew_rates); + di->enable_time = 360; di->vsel_count = RK8602_NVOLTAGES; return 0; @@ -395,6 +407,7 @@ static int fan53555_voltages_setup_silergy(struct fan53555_device_info *di) di->slew_mask = CTL_SLEW_MASK; di->ramp_delay_table = slew_rates; di->n_ramp_values = ARRAY_SIZE(slew_rates); + di->enable_time = 400; di->vsel_count = FAN53555_NVOLTAGES; return 0; @@ -594,6 +607,7 @@ static int fan53555_regulator_register(struct fan53555_device_info *di, rdesc->ramp_mask = di->slew_mask; rdesc->ramp_delay_table = di->ramp_delay_table; rdesc->n_ramp_values = di->n_ramp_values; + rdesc->enable_time = di->enable_time; rdesc->owner = THIS_MODULE; rdev = devm_regulator_register(di->dev, &di->desc, config); From 55dfffc5e94730370b08de02c0cf3b7c951bbe9e Mon Sep 17 00:00:00 2001 From: Maurizio Lombardi Date: Thu, 12 Jun 2025 12:15:56 +0200 Subject: [PATCH 925/971] scsi: target: Fix NULL pointer dereference in core_scsi3_decode_spec_i_port() [ Upstream commit d8ab68bdb294b09a761e967dad374f2965e1913f ] The function core_scsi3_decode_spec_i_port(), in its error code path, unconditionally calls core_scsi3_lunacl_undepend_item() passing the dest_se_deve pointer, which may be NULL. This can lead to a NULL pointer dereference if dest_se_deve remains unset. SPC-3 PR SPEC_I_PT: Unable to locate dest_tpg Unable to handle kernel paging request at virtual address dfff800000000012 Call trace: core_scsi3_lunacl_undepend_item+0x2c/0xf0 [target_core_mod] (P) core_scsi3_decode_spec_i_port+0x120c/0x1c30 [target_core_mod] core_scsi3_emulate_pro_register+0x6b8/0xcd8 [target_core_mod] target_scsi3_emulate_pr_out+0x56c/0x840 [target_core_mod] Fix this by adding a NULL check before calling core_scsi3_lunacl_undepend_item() Signed-off-by: Maurizio Lombardi Link: https://lore.kernel.org/r/20250612101556.24829-1-mlombard@redhat.com Reviewed-by: Mike Christie Reviewed-by: John Meneghini Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/target/target_core_pr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 49d9167bb263..a9eb6a3e8383 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -1841,7 +1841,9 @@ out: } kmem_cache_free(t10_pr_reg_cache, dest_pr_reg); - core_scsi3_lunacl_undepend_item(dest_se_deve); + + if (dest_se_deve) + core_scsi3_lunacl_undepend_item(dest_se_deve); if (is_local) continue; From 270d637100f9ffbaea29b343333e7cb8416a2fed Mon Sep 17 00:00:00 2001 From: Justin Sanders Date: Tue, 10 Jun 2025 17:06:00 +0000 Subject: [PATCH 926/971] aoe: defer rexmit timer downdev work to workqueue [ Upstream commit cffc873d68ab09a0432b8212008c5613f8a70a2c ] When aoe's rexmit_timer() notices that an aoe target fails to respond to commands for more than aoe_deadsecs, it calls aoedev_downdev() which cleans the outstanding aoe and block queues. This can involve sleeping, such as in blk_mq_freeze_queue(), which should not occur in irq context. This patch defers that aoedev_downdev() call to the aoe device's workqueue. Link: https://bugzilla.kernel.org/show_bug.cgi?id=212665 Signed-off-by: Justin Sanders Link: https://lore.kernel.org/r/20250610170600.869-2-jsanders.devel@gmail.com Tested-By: Valentin Kleibel Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- drivers/block/aoe/aoe.h | 1 + drivers/block/aoe/aoecmd.c | 8 ++++++-- drivers/block/aoe/aoedev.c | 5 ++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h index 749ae1246f4c..d35caa3c69e1 100644 --- a/drivers/block/aoe/aoe.h +++ b/drivers/block/aoe/aoe.h @@ -80,6 +80,7 @@ enum { DEVFL_NEWSIZE = (1<<6), /* need to update dev size in block layer */ DEVFL_FREEING = (1<<7), /* set when device is being cleaned up */ DEVFL_FREED = (1<<8), /* device has been cleaned up */ + DEVFL_DEAD = (1<<9), /* device has timed out of aoe_deadsecs */ }; enum { diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index d1f4ddc57645..c4c5cf1ec71b 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -754,7 +754,7 @@ rexmit_timer(struct timer_list *timer) utgts = count_targets(d, NULL); - if (d->flags & DEVFL_TKILL) { + if (d->flags & (DEVFL_TKILL | DEVFL_DEAD)) { spin_unlock_irqrestore(&d->lock, flags); return; } @@ -786,7 +786,8 @@ rexmit_timer(struct timer_list *timer) * to clean up. */ list_splice(&flist, &d->factive[0]); - aoedev_downdev(d); + d->flags |= DEVFL_DEAD; + queue_work(aoe_wq, &d->work); goto out; } @@ -898,6 +899,9 @@ aoecmd_sleepwork(struct work_struct *work) { struct aoedev *d = container_of(work, struct aoedev, work); + if (d->flags & DEVFL_DEAD) + aoedev_downdev(d); + if (d->flags & DEVFL_GDALLOC) aoeblk_gdalloc(d); diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c index 280679bde3a5..4240e11adfb7 100644 --- a/drivers/block/aoe/aoedev.c +++ b/drivers/block/aoe/aoedev.c @@ -200,8 +200,11 @@ aoedev_downdev(struct aoedev *d) struct list_head *head, *pos, *nx; struct request *rq, *rqnext; int i; + unsigned long flags; - d->flags &= ~DEVFL_UP; + spin_lock_irqsave(&d->lock, flags); + d->flags &= ~(DEVFL_UP | DEVFL_DEAD); + spin_unlock_irqrestore(&d->lock, flags); /* clean out active and to-be-retransmitted buffers */ for (i = 0; i < NFACTIVE; i++) { From 5aebb9aa538a7a241a4db84a41540703c62bec11 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 16 Jun 2025 17:18:38 +0200 Subject: [PATCH 927/971] wifi: mac80211: drop invalid source address OCB frames [ Upstream commit d1b1a5eb27c4948e8811cf4dbb05aaf3eb10700c ] In OCB, don't accept frames from invalid source addresses (and in particular don't try to create stations for them), drop the frames instead. Reported-by: syzbot+8b512026a7ec10dcbdd9@syzkaller.appspotmail.com Closes: https://lore.kernel.org/r/6788d2d9.050a0220.20d369.0028.GAE@google.com/ Signed-off-by: Johannes Berg Tested-by: syzbot+8b512026a7ec10dcbdd9@syzkaller.appspotmail.com Link: https://patch.msgid.link/20250616171838.7433379cab5d.I47444d63c72a0bd58d2e2b67bb99e1fea37eec6f@changeid Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- net/mac80211/rx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 5eb233f61981..58665b6ae635 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -4419,6 +4419,10 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx) if (!multicast && !ether_addr_equal(sdata->dev->dev_addr, hdr->addr1)) return false; + /* reject invalid/our STA address */ + if (!is_valid_ether_addr(hdr->addr2) || + ether_addr_equal(sdata->dev->dev_addr, hdr->addr2)) + return false; if (!rx->sta) { int rate_idx; if (status->encoding != RX_ENC_LEGACY) From 347827bd0c5680dac2dd59674616840c4d5154f1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 17 Jun 2025 11:45:29 +0200 Subject: [PATCH 928/971] wifi: ath6kl: remove WARN on bad firmware input [ Upstream commit e7417421d89358da071fd2930f91e67c7128fbff ] If the firmware gives bad input, that's nothing to do with the driver's stack at this point etc., so the WARN_ON() doesn't add any value. Additionally, this is one of the top syzbot reports now. Just print a message, and as an added bonus, print the sizes too. Reported-by: syzbot+92c6dd14aaa230be6855@syzkaller.appspotmail.com Tested-by: syzbot+92c6dd14aaa230be6855@syzkaller.appspotmail.com Acked-by: Jeff Johnson Link: https://patch.msgid.link/20250617114529.031a677a348e.I58bf1eb4ac16a82c546725ff010f3f0d2b0cca49@changeid Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath6kl/bmi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c index af98e871199d..5a9e93fd1ef4 100644 --- a/drivers/net/wireless/ath/ath6kl/bmi.c +++ b/drivers/net/wireless/ath/ath6kl/bmi.c @@ -87,7 +87,9 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar, * We need to do some backwards compatibility to make this work. */ if (le32_to_cpu(targ_info->byte_count) != sizeof(*targ_info)) { - WARN_ON(1); + ath6kl_err("mismatched byte count %d vs. expected %zd\n", + le32_to_cpu(targ_info->byte_count), + sizeof(*targ_info)); return -EINVAL; } From d547779e72cea9865b732cd45393c4cd02b3598e Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 18 Jun 2025 14:17:45 +0200 Subject: [PATCH 929/971] ACPICA: Refuse to evaluate a method if arguments are missing [ Upstream commit 6fcab2791543924d438e7fa49276d0998b0a069f ] As reported in [1], a platform firmware update that increased the number of method parameters and forgot to update a least one of its callers, caused ACPICA to crash due to use-after-free. Since this a result of a clear AML issue that arguably cannot be fixed up by the interpreter (it cannot produce missing data out of thin air), address it by making ACPICA refuse to evaluate a method if the caller attempts to pass fewer arguments than expected to it. Closes: https://github.com/acpica/acpica/issues/1027 [1] Reported-by: Peter Williams Signed-off-by: Rafael J. Wysocki Reviewed-by: Hans de Goede Tested-by: Hans de Goede # Dell XPS 9640 with BIOS 1.12.0 Link: https://patch.msgid.link/5909446.DvuYhMxLoT@rjwysocki.net Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/acpica/dsmethod.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index e809c2aed78a..a232746d150a 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c @@ -483,6 +483,13 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, return_ACPI_STATUS(AE_NULL_OBJECT); } + if (this_walk_state->num_operands < obj_desc->method.param_count) { + ACPI_ERROR((AE_INFO, "Missing argument for method [%4.4s]", + acpi_ut_get_node_name(method_node))); + + return_ACPI_STATUS(AE_AML_UNINITIALIZED_ARG); + } + /* Init for new method, possibly wait on method mutex */ status = From d5c1e3f32902ab518519d05515ee6030fd6c59ae Mon Sep 17 00:00:00 2001 From: Pablo Martin-Gomez Date: Wed, 18 Jun 2025 13:35:16 +0200 Subject: [PATCH 930/971] mtd: spinand: fix memory leak of ECC engine conf [ Upstream commit 6463cbe08b0cbf9bba8763306764f5fd643023e1 ] Memory allocated for the ECC engine conf is not released during spinand cleanup. Below kmemleak trace is seen for this memory leak: unreferenced object 0xffffff80064f00e0 (size 8): comm "swapper/0", pid 1, jiffies 4294937458 hex dump (first 8 bytes): 00 00 00 00 00 00 00 00 ........ backtrace (crc 0): kmemleak_alloc+0x30/0x40 __kmalloc_cache_noprof+0x208/0x3c0 spinand_ondie_ecc_init_ctx+0x114/0x200 nand_ecc_init_ctx+0x70/0xa8 nanddev_ecc_engine_init+0xec/0x27c spinand_probe+0xa2c/0x1620 spi_mem_probe+0x130/0x21c spi_probe+0xf0/0x170 really_probe+0x17c/0x6e8 __driver_probe_device+0x17c/0x21c driver_probe_device+0x58/0x180 __device_attach_driver+0x15c/0x1f8 bus_for_each_drv+0xec/0x150 __device_attach+0x188/0x24c device_initial_probe+0x10/0x20 bus_probe_device+0x11c/0x160 Fix the leak by calling nanddev_ecc_engine_cleanup() inside spinand_cleanup(). Signed-off-by: Pablo Martin-Gomez Signed-off-by: Miquel Raynal Signed-off-by: Sasha Levin --- drivers/mtd/nand/spi/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 393ff37f0d23..cd21bf8f254a 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -1316,6 +1316,7 @@ static void spinand_cleanup(struct spinand_device *spinand) { struct nand_device *nand = spinand_to_nand(spinand); + nanddev_ecc_engine_cleanup(nand); nanddev_cleanup(nand); spinand_manufacturer_cleanup(spinand); kfree(spinand->databuf); From 817662f9bdf81fb5c040aa94b44669f3d345a07d Mon Sep 17 00:00:00 2001 From: "Uladzislau Rezki (Sony)" Date: Tue, 10 Jun 2025 19:34:48 +0200 Subject: [PATCH 931/971] rcu: Return early if callback is not specified [ Upstream commit 33b6a1f155d627f5bd80c7485c598ce45428f74f ] Currently the call_rcu() API does not check whether a callback pointer is NULL. If NULL is passed, rcu_core() will try to invoke it, resulting in NULL pointer dereference and a kernel crash. To prevent this and improve debuggability, this patch adds a check for NULL and emits a kernel stack trace to help identify a faulty caller. Signed-off-by: Uladzislau Rezki (Sony) Reviewed-by: Joel Fernandes Signed-off-by: Joel Fernandes Signed-off-by: Sasha Levin --- kernel/rcu/tree.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 1fb3b7a0ed5d..536acebf22b0 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -2699,6 +2699,10 @@ __call_rcu_common(struct rcu_head *head, rcu_callback_t func, bool lazy_in) /* Misaligned rcu_head! */ WARN_ON_ONCE((unsigned long)head & (sizeof(void *) - 1)); + /* Avoid NULL dereference if callback is NULL. */ + if (WARN_ON_ONCE(!func)) + return; + if (debug_rcu_head_queue(head)) { /* * Probable double call_rcu(), so leak the callback. From 387da3b6d1a90e3210bc9a7fb56703bdad2ac18a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ADra=20Canal?= Date: Sat, 28 Jun 2025 19:42:42 -0300 Subject: [PATCH 932/971] drm/v3d: Disable interrupts before resetting the GPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 226862f50a7a88e4e4de9abbf36c64d19acd6fd0 ] Currently, an interrupt can be triggered during a GPU reset, which can lead to GPU hangs and NULL pointer dereference in an interrupt context as shown in the following trace: [ 314.035040] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000c0 [ 314.043822] Mem abort info: [ 314.046606] ESR = 0x0000000096000005 [ 314.050347] EC = 0x25: DABT (current EL), IL = 32 bits [ 314.055651] SET = 0, FnV = 0 [ 314.058695] EA = 0, S1PTW = 0 [ 314.061826] FSC = 0x05: level 1 translation fault [ 314.066694] Data abort info: [ 314.069564] ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000 [ 314.075039] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 [ 314.080080] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 [ 314.085382] user pgtable: 4k pages, 39-bit VAs, pgdp=0000000102728000 [ 314.091814] [00000000000000c0] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000 [ 314.100511] Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP [ 314.106770] Modules linked in: v3d i2c_brcmstb vc4 snd_soc_hdmi_codec gpu_sched drm_shmem_helper drm_display_helper cec drm_dma_helper drm_kms_helper drm drm_panel_orientation_quirks snd_soc_core snd_compress snd_pcm_dmaengine snd_pcm snd_timer snd backlight [ 314.129654] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.12.25+rpt-rpi-v8 #1 Debian 1:6.12.25-1+rpt1 [ 314.139388] Hardware name: Raspberry Pi 4 Model B Rev 1.4 (DT) [ 314.145211] pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 314.152165] pc : v3d_irq+0xec/0x2e0 [v3d] [ 314.156187] lr : v3d_irq+0xe0/0x2e0 [v3d] [ 314.160198] sp : ffffffc080003ea0 [ 314.163502] x29: ffffffc080003ea0 x28: ffffffec1f184980 x27: 021202b000000000 [ 314.170633] x26: ffffffec1f17f630 x25: ffffff8101372000 x24: ffffffec1f17d9f0 [ 314.177764] x23: 000000000000002a x22: 000000000000002a x21: ffffff8103252000 [ 314.184895] x20: 0000000000000001 x19: 00000000deadbeef x18: 0000000000000000 [ 314.192026] x17: ffffff94e51d2000 x16: ffffffec1dac3cb0 x15: c306000000000000 [ 314.199156] x14: 0000000000000000 x13: b2fc982e03cc5168 x12: 0000000000000001 [ 314.206286] x11: ffffff8103f8bcc0 x10: ffffffec1f196868 x9 : ffffffec1dac3874 [ 314.213416] x8 : 0000000000000000 x7 : 0000000000042a3a x6 : ffffff810017a180 [ 314.220547] x5 : ffffffec1ebad400 x4 : ffffffec1ebad320 x3 : 00000000000bebeb [ 314.227677] x2 : 0000000000000000 x1 : 0000000000000000 x0 : 0000000000000000 [ 314.234807] Call trace: [ 314.237243] v3d_irq+0xec/0x2e0 [v3d] [ 314.240906] __handle_irq_event_percpu+0x58/0x218 [ 314.245609] handle_irq_event+0x54/0xb8 [ 314.249439] handle_fasteoi_irq+0xac/0x240 [ 314.253527] handle_irq_desc+0x48/0x68 [ 314.257269] generic_handle_domain_irq+0x24/0x38 [ 314.261879] gic_handle_irq+0x48/0xd8 [ 314.265533] call_on_irq_stack+0x24/0x58 [ 314.269448] do_interrupt_handler+0x88/0x98 [ 314.273624] el1_interrupt+0x34/0x68 [ 314.277193] el1h_64_irq_handler+0x18/0x28 [ 314.281281] el1h_64_irq+0x64/0x68 [ 314.284673] default_idle_call+0x3c/0x168 [ 314.288675] do_idle+0x1fc/0x230 [ 314.291895] cpu_startup_entry+0x3c/0x50 [ 314.295810] rest_init+0xe4/0xf0 [ 314.299030] start_kernel+0x5e8/0x790 [ 314.302684] __primary_switched+0x80/0x90 [ 314.306691] Code: 940029eb 360ffc13 f9442ea0 52800001 (f9406017) [ 314.312775] ---[ end trace 0000000000000000 ]--- [ 314.317384] Kernel panic - not syncing: Oops: Fatal exception in interrupt [ 314.324249] SMP: stopping secondary CPUs [ 314.328167] Kernel Offset: 0x2b9da00000 from 0xffffffc080000000 [ 314.334076] PHYS_OFFSET: 0x0 [ 314.336946] CPU features: 0x08,00002013,c0200000,0200421b [ 314.342337] Memory Limit: none [ 314.345382] ---[ end Kernel panic - not syncing: Oops: Fatal exception in interrupt ]--- Before resetting the GPU, it's necessary to disable all interrupts and deal with any interrupt handler still in-flight. Otherwise, the GPU might reset with jobs still running, or yet, an interrupt could be handled during the reset. Cc: stable@vger.kernel.org Fixes: 57692c94dcbe ("drm/v3d: Introduce a new DRM driver for Broadcom V3D V3.x+") Reviewed-by: Juan A. Suarez Reviewed-by: Iago Toral Quiroga Link: https://lore.kernel.org/r/20250628224243.47599-1-mcanal@igalia.com Signed-off-by: Maíra Canal Signed-off-by: Sasha Levin --- drivers/gpu/drm/v3d/v3d_drv.h | 8 ++++++++ drivers/gpu/drm/v3d/v3d_gem.c | 2 ++ drivers/gpu/drm/v3d/v3d_irq.c | 37 +++++++++++++++++++++++++---------- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h index 7f664a4b2a75..bcef978ba9c4 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.h +++ b/drivers/gpu/drm/v3d/v3d_drv.h @@ -62,6 +62,12 @@ struct v3d_perfmon { u64 values[]; }; +enum v3d_irq { + V3D_CORE_IRQ, + V3D_HUB_IRQ, + V3D_MAX_IRQS, +}; + struct v3d_dev { struct drm_device drm; @@ -71,6 +77,8 @@ struct v3d_dev { int ver; bool single_irq_line; + int irq[V3D_MAX_IRQS]; + void __iomem *hub_regs; void __iomem *core_regs[3]; void __iomem *bridge_regs; diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c index 2e94ce788c71..ef991a9b1c6c 100644 --- a/drivers/gpu/drm/v3d/v3d_gem.c +++ b/drivers/gpu/drm/v3d/v3d_gem.c @@ -120,6 +120,8 @@ v3d_reset(struct v3d_dev *v3d) if (false) v3d_idle_axi(v3d, 0); + v3d_irq_disable(v3d); + v3d_idle_gca(v3d); v3d_reset_v3d(v3d); diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c index b2d59a168697..641315dbee8b 100644 --- a/drivers/gpu/drm/v3d/v3d_irq.c +++ b/drivers/gpu/drm/v3d/v3d_irq.c @@ -215,7 +215,7 @@ v3d_hub_irq(int irq, void *arg) int v3d_irq_init(struct v3d_dev *v3d) { - int irq1, ret, core; + int irq, ret, core; INIT_WORK(&v3d->overflow_mem_work, v3d_overflow_mem_work); @@ -226,17 +226,24 @@ v3d_irq_init(struct v3d_dev *v3d) V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS); V3D_WRITE(V3D_HUB_INT_CLR, V3D_HUB_IRQS); - irq1 = platform_get_irq_optional(v3d_to_pdev(v3d), 1); - if (irq1 == -EPROBE_DEFER) - return irq1; - if (irq1 > 0) { - ret = devm_request_irq(v3d->drm.dev, irq1, + irq = platform_get_irq_optional(v3d_to_pdev(v3d), 1); + if (irq == -EPROBE_DEFER) + return irq; + if (irq > 0) { + v3d->irq[V3D_CORE_IRQ] = irq; + + ret = devm_request_irq(v3d->drm.dev, v3d->irq[V3D_CORE_IRQ], v3d_irq, IRQF_SHARED, "v3d_core0", v3d); if (ret) goto fail; - ret = devm_request_irq(v3d->drm.dev, - platform_get_irq(v3d_to_pdev(v3d), 0), + + irq = platform_get_irq(v3d_to_pdev(v3d), 0); + if (irq < 0) + return irq; + v3d->irq[V3D_HUB_IRQ] = irq; + + ret = devm_request_irq(v3d->drm.dev, v3d->irq[V3D_HUB_IRQ], v3d_hub_irq, IRQF_SHARED, "v3d_hub", v3d); if (ret) @@ -244,8 +251,12 @@ v3d_irq_init(struct v3d_dev *v3d) } else { v3d->single_irq_line = true; - ret = devm_request_irq(v3d->drm.dev, - platform_get_irq(v3d_to_pdev(v3d), 0), + irq = platform_get_irq(v3d_to_pdev(v3d), 0); + if (irq < 0) + return irq; + v3d->irq[V3D_CORE_IRQ] = irq; + + ret = devm_request_irq(v3d->drm.dev, v3d->irq[V3D_CORE_IRQ], v3d_irq, IRQF_SHARED, "v3d", v3d); if (ret) @@ -286,6 +297,12 @@ v3d_irq_disable(struct v3d_dev *v3d) V3D_CORE_WRITE(core, V3D_CTL_INT_MSK_SET, ~0); V3D_WRITE(V3D_HUB_INT_MSK_SET, ~0); + /* Finish any interrupt handler still in flight. */ + for (int i = 0; i < V3D_MAX_IRQS; i++) { + if (v3d->irq[i]) + synchronize_irq(v3d->irq[i]); + } + /* Clear any pending interrupts we might have left. */ for (core = 0; core < v3d->cores; core++) V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS); From 8570c219cd59d01c109ff798f6a8d57c28c222d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Sat, 4 Jan 2025 00:05:12 +0100 Subject: [PATCH 933/971] platform/x86: hp-bioscfg: Directly use firmware_attributes_class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 63f8c058036057644f095123a35895cd11639b88 ] The usage of the lifecycle functions is not necessary anymore. Signed-off-by: Thomas Weißschuh Reviewed-by: Armin Wolf Reviewed-by: Mario Limonciello Reviewed-by: Mark Pearson Tested-by: Mark Pearson Link: https://lore.kernel.org/r/20250104-firmware-attributes-simplify-v1-4-949f9709e405@weissschuh.net Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Stable-dep-of: 11cba4793b95 ("platform/x86: hp-bioscfg: Fix class device unregistration") Signed-off-by: Sasha Levin --- drivers/platform/x86/hp/hp-bioscfg/bioscfg.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c index b8bac35ebd42..049851e469f6 100644 --- a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c +++ b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c @@ -24,8 +24,6 @@ struct bioscfg_priv bioscfg_drv = { .mutex = __MUTEX_INITIALIZER(bioscfg_drv.mutex), }; -static const struct class *fw_attr_class; - ssize_t display_name_language_code_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) @@ -974,11 +972,7 @@ static int __init hp_init(void) if (ret) return ret; - ret = fw_attributes_class_get(&fw_attr_class); - if (ret) - goto err_unregister_class; - - bioscfg_drv.class_dev = device_create(fw_attr_class, NULL, MKDEV(0, 0), + bioscfg_drv.class_dev = device_create(&firmware_attributes_class, NULL, MKDEV(0, 0), NULL, "%s", DRIVER_NAME); if (IS_ERR(bioscfg_drv.class_dev)) { ret = PTR_ERR(bioscfg_drv.class_dev); @@ -1045,10 +1039,9 @@ err_release_attributes_data: release_attributes_data(); err_destroy_classdev: - device_destroy(fw_attr_class, MKDEV(0, 0)); + device_destroy(&firmware_attributes_class, MKDEV(0, 0)); err_unregister_class: - fw_attributes_class_put(); hp_exit_attr_set_interface(); return ret; @@ -1057,9 +1050,8 @@ err_unregister_class: static void __exit hp_exit(void) { release_attributes_data(); - device_destroy(fw_attr_class, MKDEV(0, 0)); + device_destroy(&firmware_attributes_class, MKDEV(0, 0)); - fw_attributes_class_put(); hp_exit_attr_set_interface(); } From a6069306f4e18b9a0bb4d778726a451ea96dbff2 Mon Sep 17 00:00:00 2001 From: Kurt Borja Date: Wed, 25 Jun 2025 22:17:35 -0300 Subject: [PATCH 934/971] platform/x86: hp-bioscfg: Fix class device unregistration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 11cba4793b95df3bc192149a6eb044f69aa0b99e ] Devices under the firmware_attributes_class do not have unique a dev_t. Therefore, device_unregister() should be used instead of device_destroy(), since the latter may match any device with a given dev_t. Fixes: a34fc329b189 ("platform/x86: hp-bioscfg: bioscfg") Signed-off-by: Kurt Borja Link: https://lore.kernel.org/r/20250625-dest-fix-v1-1-3a0f342312bb@gmail.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin --- drivers/platform/x86/hp/hp-bioscfg/bioscfg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c index 049851e469f6..b62b158cffd8 100644 --- a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c +++ b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c @@ -1039,7 +1039,7 @@ err_release_attributes_data: release_attributes_data(); err_destroy_classdev: - device_destroy(&firmware_attributes_class, MKDEV(0, 0)); + device_unregister(bioscfg_drv.class_dev); err_unregister_class: hp_exit_attr_set_interface(); @@ -1050,7 +1050,7 @@ err_unregister_class: static void __exit hp_exit(void) { release_attributes_data(); - device_destroy(&firmware_attributes_class, MKDEV(0, 0)); + device_unregister(bioscfg_drv.class_dev); hp_exit_attr_set_interface(); } From adb29b437fe58d41bd5d4a5c3d63bf1bb02f0877 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 2 May 2025 16:12:09 +0200 Subject: [PATCH 935/971] module: Provide EXPORT_SYMBOL_GPL_FOR_MODULES() helper [ Upstream commit 707f853d7fa3ce323a6875487890c213e34d81a0 ] Helper macro to more easily limit the export of a symbol to a given list of modules. Eg: EXPORT_SYMBOL_GPL_FOR_MODULES(preempt_notifier_inc, "kvm"); will limit the use of said function to kvm.ko, any other module trying to use this symbol will refure to load (and get modpost build failures). Requested-by: Masahiro Yamada Requested-by: Christoph Hellwig Signed-off-by: Peter Zijlstra Reviewed-by: Petr Pavlu Signed-off-by: Masahiro Yamada Stable-dep-of: cbe4134ea4bc ("fs: export anon_inode_make_secure_inode() and fix secretmem LSM bypass") Signed-off-by: Sasha Levin --- Documentation/core-api/symbol-namespaces.rst | 22 ++++++++++++++++++++ include/linux/export.h | 12 +++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Documentation/core-api/symbol-namespaces.rst b/Documentation/core-api/symbol-namespaces.rst index 12e4aecdae94..29875e25e376 100644 --- a/Documentation/core-api/symbol-namespaces.rst +++ b/Documentation/core-api/symbol-namespaces.rst @@ -28,6 +28,9 @@ kernel. As of today, modules that make use of symbols exported into namespaces, are required to import the namespace. Otherwise the kernel will, depending on its configuration, reject loading the module or warn about a missing import. +Additionally, it is possible to put symbols into a module namespace, strictly +limiting which modules are allowed to use these symbols. + 2. How to define Symbol Namespaces ================================== @@ -84,6 +87,22 @@ unit as preprocessor statement. The above example would then read:: within the corresponding compilation unit before any EXPORT_SYMBOL macro is used. +2.3 Using the EXPORT_SYMBOL_GPL_FOR_MODULES() macro +=================================================== + +Symbols exported using this macro are put into a module namespace. This +namespace cannot be imported. + +The macro takes a comma separated list of module names, allowing only those +modules to access this symbol. Simple tail-globs are supported. + +For example: + + EXPORT_SYMBOL_GPL_FOR_MODULES(preempt_notifier_inc, "kvm,kvm-*") + +will limit usage of this symbol to modules whoes name matches the given +patterns. + 3. How to use Symbols exported in Namespaces ============================================ @@ -155,3 +174,6 @@ in-tree modules:: You can also run nsdeps for external module builds. A typical usage is:: $ make -C M=$PWD nsdeps + +Note: it will happily generate an import statement for the module namespace; +which will not work and generates build and runtime failures. diff --git a/include/linux/export.h b/include/linux/export.h index 9911508a9604..06f7a4eb6492 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -42,11 +42,17 @@ extern struct module __this_module; .long sym #endif -#define ___EXPORT_SYMBOL(sym, license, ns) \ +/* + * LLVM integrated assembler cam merge adjacent string literals (like + * C and GNU-as) passed to '.ascii', but not to '.asciz' and chokes on: + * + * .asciz "MODULE_" "kvm" ; + */ +#define ___EXPORT_SYMBOL(sym, license, ns...) \ .section ".export_symbol","a" ASM_NL \ __export_symbol_##sym: ASM_NL \ .asciz license ASM_NL \ - .asciz ns ASM_NL \ + .ascii ns "\0" ASM_NL \ __EXPORT_SYMBOL_REF(sym) ASM_NL \ .previous @@ -88,4 +94,6 @@ extern struct module __this_module; #define EXPORT_SYMBOL_NS(sym, ns) __EXPORT_SYMBOL(sym, "", __stringify(ns)) #define EXPORT_SYMBOL_NS_GPL(sym, ns) __EXPORT_SYMBOL(sym, "GPL", __stringify(ns)) +#define EXPORT_SYMBOL_GPL_FOR_MODULES(sym, mods) __EXPORT_SYMBOL(sym, "GPL", "module:" mods) + #endif /* _LINUX_EXPORT_H */ From e3eed01347721cd7a8819568161c91d538fbf229 Mon Sep 17 00:00:00 2001 From: Shivank Garg Date: Fri, 20 Jun 2025 07:03:30 +0000 Subject: [PATCH 936/971] fs: export anon_inode_make_secure_inode() and fix secretmem LSM bypass [ Upstream commit cbe4134ea4bc493239786220bd69cb8a13493190 ] Export anon_inode_make_secure_inode() to allow KVM guest_memfd to create anonymous inodes with proper security context. This replaces the current pattern of calling alloc_anon_inode() followed by inode_init_security_anon() for creating security context manually. This change also fixes a security regression in secretmem where the S_PRIVATE flag was not cleared after alloc_anon_inode(), causing LSM/SELinux checks to be bypassed for secretmem file descriptors. As guest_memfd currently resides in the KVM module, we need to export this symbol for use outside the core kernel. In the future, guest_memfd might be moved to core-mm, at which point the symbols no longer would have to be exported. When/if that happens is still unclear. Fixes: 2bfe15c52612 ("mm: create security context for memfd_secret inodes") Suggested-by: David Hildenbrand Suggested-by: Mike Rapoport Signed-off-by: Shivank Garg Link: https://lore.kernel.org/20250620070328.803704-3-shivankg@amd.com Acked-by: "Mike Rapoport (Microsoft)" Signed-off-by: Christian Brauner Signed-off-by: Sasha Levin --- fs/anon_inodes.c | 23 ++++++++++++++++++----- include/linux/fs.h | 2 ++ mm/secretmem.c | 11 +---------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index 24192a7667ed..a25766e90f0a 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c @@ -55,15 +55,26 @@ static struct file_system_type anon_inode_fs_type = { .kill_sb = kill_anon_super, }; -static struct inode *anon_inode_make_secure_inode( - const char *name, - const struct inode *context_inode) +/** + * anon_inode_make_secure_inode - allocate an anonymous inode with security context + * @sb: [in] Superblock to allocate from + * @name: [in] Name of the class of the newfile (e.g., "secretmem") + * @context_inode: + * [in] Optional parent inode for security inheritance + * + * The function ensures proper security initialization through the LSM hook + * security_inode_init_security_anon(). + * + * Return: Pointer to new inode on success, ERR_PTR on failure. + */ +struct inode *anon_inode_make_secure_inode(struct super_block *sb, const char *name, + const struct inode *context_inode) { struct inode *inode; const struct qstr qname = QSTR_INIT(name, strlen(name)); int error; - inode = alloc_anon_inode(anon_inode_mnt->mnt_sb); + inode = alloc_anon_inode(sb); if (IS_ERR(inode)) return inode; inode->i_flags &= ~S_PRIVATE; @@ -74,6 +85,7 @@ static struct inode *anon_inode_make_secure_inode( } return inode; } +EXPORT_SYMBOL_GPL_FOR_MODULES(anon_inode_make_secure_inode, "kvm"); static struct file *__anon_inode_getfile(const char *name, const struct file_operations *fops, @@ -88,7 +100,8 @@ static struct file *__anon_inode_getfile(const char *name, return ERR_PTR(-ENOENT); if (secure) { - inode = anon_inode_make_secure_inode(name, context_inode); + inode = anon_inode_make_secure_inode(anon_inode_mnt->mnt_sb, + name, context_inode); if (IS_ERR(inode)) { file = ERR_CAST(inode); goto err; diff --git a/include/linux/fs.h b/include/linux/fs.h index 81edfa1e66b6..b641a01512fb 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3170,6 +3170,8 @@ extern int simple_write_begin(struct file *file, struct address_space *mapping, extern const struct address_space_operations ram_aops; extern int always_delete_dentry(const struct dentry *); extern struct inode *alloc_anon_inode(struct super_block *); +struct inode *anon_inode_make_secure_inode(struct super_block *sb, const char *name, + const struct inode *context_inode); extern int simple_nosetlease(struct file *, int, struct file_lock **, void **); extern const struct dentry_operations simple_dentry_operations; diff --git a/mm/secretmem.c b/mm/secretmem.c index 399552814fd0..4bedf491a8a7 100644 --- a/mm/secretmem.c +++ b/mm/secretmem.c @@ -195,19 +195,10 @@ static struct file *secretmem_file_create(unsigned long flags) struct file *file; struct inode *inode; const char *anon_name = "[secretmem]"; - const struct qstr qname = QSTR_INIT(anon_name, strlen(anon_name)); - int err; - inode = alloc_anon_inode(secretmem_mnt->mnt_sb); + inode = anon_inode_make_secure_inode(secretmem_mnt->mnt_sb, anon_name, NULL); if (IS_ERR(inode)) return ERR_CAST(inode); - - err = security_inode_init_security_anon(inode, &qname, NULL); - if (err) { - file = ERR_PTR(err); - goto err_free_inode; - } - file = alloc_file_pseudo(inode, secretmem_mnt, "secretmem", O_RDWR, &secretmem_fops); if (IS_ERR(file)) From 204bdc7a8b7b7b7fcfc500f1402762a1f99e00bc Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 19 Jun 2025 15:16:11 -0400 Subject: [PATCH 937/971] NFSv4/flexfiles: Fix handling of NFS level errors in I/O [ Upstream commit 38074de35b015df5623f524d6f2b49a0cd395c40 ] Allow the flexfiles error handling to recognise NFS level errors (as opposed to RPC level errors) and handle them separately. The main motivator is the NFSERR_PERM errors that get returned if the NFS client connects to the data server through a port number that is lower than 1024. In that case, the client should disconnect and retry a READ on a different data server, or it should retry a WRITE after reconnecting. Reviewed-by: Tigran Mkrtchyan Fixes: d67ae825a59d ("pnfs/flexfiles: Add the FlexFile Layout Driver") Signed-off-by: Trond Myklebust Signed-off-by: Anna Schumaker Signed-off-by: Sasha Levin --- fs/nfs/flexfilelayout/flexfilelayout.c | 121 ++++++++++++++++++------- 1 file changed, 87 insertions(+), 34 deletions(-) diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index 0bc537de1b29..0a26444fe202 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c @@ -1096,6 +1096,7 @@ static void ff_layout_reset_read(struct nfs_pgio_header *hdr) } static int ff_layout_async_handle_error_v4(struct rpc_task *task, + u32 op_status, struct nfs4_state *state, struct nfs_client *clp, struct pnfs_layout_segment *lseg, @@ -1106,32 +1107,42 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task, struct nfs4_deviceid_node *devid = FF_LAYOUT_DEVID_NODE(lseg, idx); struct nfs4_slot_table *tbl = &clp->cl_session->fc_slot_table; - switch (task->tk_status) { - case -NFS4ERR_BADSESSION: - case -NFS4ERR_BADSLOT: - case -NFS4ERR_BAD_HIGH_SLOT: - case -NFS4ERR_DEADSESSION: - case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: - case -NFS4ERR_SEQ_FALSE_RETRY: - case -NFS4ERR_SEQ_MISORDERED: + switch (op_status) { + case NFS4_OK: + case NFS4ERR_NXIO: + break; + case NFSERR_PERM: + if (!task->tk_xprt) + break; + xprt_force_disconnect(task->tk_xprt); + goto out_retry; + case NFS4ERR_BADSESSION: + case NFS4ERR_BADSLOT: + case NFS4ERR_BAD_HIGH_SLOT: + case NFS4ERR_DEADSESSION: + case NFS4ERR_CONN_NOT_BOUND_TO_SESSION: + case NFS4ERR_SEQ_FALSE_RETRY: + case NFS4ERR_SEQ_MISORDERED: dprintk("%s ERROR %d, Reset session. Exchangeid " "flags 0x%x\n", __func__, task->tk_status, clp->cl_exchange_flags); nfs4_schedule_session_recovery(clp->cl_session, task->tk_status); - break; - case -NFS4ERR_DELAY: - case -NFS4ERR_GRACE: + goto out_retry; + case NFS4ERR_DELAY: + nfs_inc_stats(lseg->pls_layout->plh_inode, NFSIOS_DELAY); + fallthrough; + case NFS4ERR_GRACE: rpc_delay(task, FF_LAYOUT_POLL_RETRY_MAX); - break; - case -NFS4ERR_RETRY_UNCACHED_REP: - break; + goto out_retry; + case NFS4ERR_RETRY_UNCACHED_REP: + goto out_retry; /* Invalidate Layout errors */ - case -NFS4ERR_PNFS_NO_LAYOUT: - case -ESTALE: /* mapped NFS4ERR_STALE */ - case -EBADHANDLE: /* mapped NFS4ERR_BADHANDLE */ - case -EISDIR: /* mapped NFS4ERR_ISDIR */ - case -NFS4ERR_FHEXPIRED: - case -NFS4ERR_WRONG_TYPE: + case NFS4ERR_PNFS_NO_LAYOUT: + case NFS4ERR_STALE: + case NFS4ERR_BADHANDLE: + case NFS4ERR_ISDIR: + case NFS4ERR_FHEXPIRED: + case NFS4ERR_WRONG_TYPE: dprintk("%s Invalid layout error %d\n", __func__, task->tk_status); /* @@ -1144,6 +1155,11 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task, pnfs_destroy_layout(NFS_I(inode)); rpc_wake_up(&tbl->slot_tbl_waitq); goto reset; + default: + break; + } + + switch (task->tk_status) { /* RPC connection errors */ case -ECONNREFUSED: case -EHOSTDOWN: @@ -1159,26 +1175,56 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task, nfs4_delete_deviceid(devid->ld, devid->nfs_client, &devid->deviceid); rpc_wake_up(&tbl->slot_tbl_waitq); - fallthrough; + break; default: - if (ff_layout_avoid_mds_available_ds(lseg)) - return -NFS4ERR_RESET_TO_PNFS; -reset: - dprintk("%s Retry through MDS. Error %d\n", __func__, - task->tk_status); - return -NFS4ERR_RESET_TO_MDS; + break; } + + if (ff_layout_avoid_mds_available_ds(lseg)) + return -NFS4ERR_RESET_TO_PNFS; +reset: + dprintk("%s Retry through MDS. Error %d\n", __func__, + task->tk_status); + return -NFS4ERR_RESET_TO_MDS; + +out_retry: task->tk_status = 0; return -EAGAIN; } /* Retry all errors through either pNFS or MDS except for -EJUKEBOX */ static int ff_layout_async_handle_error_v3(struct rpc_task *task, + u32 op_status, + struct nfs_client *clp, struct pnfs_layout_segment *lseg, u32 idx) { struct nfs4_deviceid_node *devid = FF_LAYOUT_DEVID_NODE(lseg, idx); + switch (op_status) { + case NFS_OK: + case NFSERR_NXIO: + break; + case NFSERR_PERM: + if (!task->tk_xprt) + break; + xprt_force_disconnect(task->tk_xprt); + goto out_retry; + case NFSERR_ACCES: + case NFSERR_BADHANDLE: + case NFSERR_FBIG: + case NFSERR_IO: + case NFSERR_NOSPC: + case NFSERR_ROFS: + case NFSERR_STALE: + goto out_reset_to_pnfs; + case NFSERR_JUKEBOX: + nfs_inc_stats(lseg->pls_layout->plh_inode, NFSIOS_DELAY); + goto out_retry; + default: + break; + } + switch (task->tk_status) { /* File access problems. Don't mark the device as unavailable */ case -EACCES: @@ -1197,6 +1243,7 @@ static int ff_layout_async_handle_error_v3(struct rpc_task *task, nfs4_delete_deviceid(devid->ld, devid->nfs_client, &devid->deviceid); } +out_reset_to_pnfs: /* FIXME: Need to prevent infinite looping here. */ return -NFS4ERR_RESET_TO_PNFS; out_retry: @@ -1207,6 +1254,7 @@ out_retry: } static int ff_layout_async_handle_error(struct rpc_task *task, + u32 op_status, struct nfs4_state *state, struct nfs_client *clp, struct pnfs_layout_segment *lseg, @@ -1225,10 +1273,11 @@ static int ff_layout_async_handle_error(struct rpc_task *task, switch (vers) { case 3: - return ff_layout_async_handle_error_v3(task, lseg, idx); - case 4: - return ff_layout_async_handle_error_v4(task, state, clp, + return ff_layout_async_handle_error_v3(task, op_status, clp, lseg, idx); + case 4: + return ff_layout_async_handle_error_v4(task, op_status, state, + clp, lseg, idx); default: /* should never happen */ WARN_ON_ONCE(1); @@ -1281,6 +1330,7 @@ static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg, switch (status) { case NFS4ERR_DELAY: case NFS4ERR_GRACE: + case NFS4ERR_PERM: break; case NFS4ERR_NXIO: ff_layout_mark_ds_unreachable(lseg, idx); @@ -1313,7 +1363,8 @@ static int ff_layout_read_done_cb(struct rpc_task *task, trace_ff_layout_read_error(hdr); } - err = ff_layout_async_handle_error(task, hdr->args.context->state, + err = ff_layout_async_handle_error(task, hdr->res.op_status, + hdr->args.context->state, hdr->ds_clp, hdr->lseg, hdr->pgio_mirror_idx); @@ -1483,7 +1534,8 @@ static int ff_layout_write_done_cb(struct rpc_task *task, trace_ff_layout_write_error(hdr); } - err = ff_layout_async_handle_error(task, hdr->args.context->state, + err = ff_layout_async_handle_error(task, hdr->res.op_status, + hdr->args.context->state, hdr->ds_clp, hdr->lseg, hdr->pgio_mirror_idx); @@ -1529,8 +1581,9 @@ static int ff_layout_commit_done_cb(struct rpc_task *task, trace_ff_layout_commit_error(data); } - err = ff_layout_async_handle_error(task, NULL, data->ds_clp, - data->lseg, data->ds_commit_index); + err = ff_layout_async_handle_error(task, data->res.op_status, + NULL, data->ds_clp, data->lseg, + data->ds_commit_index); trace_nfs4_pnfs_commit_ds(data, err); switch (err) { From 7609899eb6b70b536123eb58eeab27c764752b82 Mon Sep 17 00:00:00 2001 From: Raju Rangoju Date: Fri, 27 Jun 2025 17:41:19 +0300 Subject: [PATCH 938/971] usb: xhci: quirk for data loss in ISOC transfers commit cbc889ab0122366f6cdbe3c28d477c683ebcebc2 upstream. During the High-Speed Isochronous Audio transfers, xHCI controller on certain AMD platforms experiences momentary data loss. This results in Missed Service Errors (MSE) being generated by the xHCI. The root cause of the MSE is attributed to the ISOC OUT endpoint being omitted from scheduling. This can happen when an IN endpoint with a 64ms service interval either is pre-scheduled prior to the ISOC OUT endpoint or the interval of the ISOC OUT endpoint is shorter than that of the IN endpoint. Consequently, the OUT service is neglected when an IN endpoint with a service interval exceeding 32ms is scheduled concurrently (every 64ms in this scenario). This issue is particularly seen on certain older AMD platforms. To mitigate this problem, it is recommended to adjust the service interval of the IN endpoint to not exceed 32ms (interval 8). This adjustment ensures that the OUT endpoint will not be bypassed, even if a smaller interval value is utilized. Cc: stable Signed-off-by: Raju Rangoju Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20250627144127.3889714-2-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mem.c | 4 ++++ drivers/usb/host/xhci-pci.c | 25 +++++++++++++++++++++++++ drivers/usb/host/xhci.h | 1 + 3 files changed, 30 insertions(+) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 22cca89efbfd..cceb69d4f61e 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1436,6 +1436,10 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, /* Periodic endpoint bInterval limit quirk */ if (usb_endpoint_xfer_int(&ep->desc) || usb_endpoint_xfer_isoc(&ep->desc)) { + if ((xhci->quirks & XHCI_LIMIT_ENDPOINT_INTERVAL_9) && + interval >= 9) { + interval = 8; + } if ((xhci->quirks & XHCI_LIMIT_ENDPOINT_INTERVAL_7) && udev->speed >= USB_SPEED_HIGH && interval >= 7) { diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index c1a172b6feae..5abc48f148dc 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -65,12 +65,22 @@ #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI 0x51ed #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_PCH_XHCI 0x54ed +#define PCI_DEVICE_ID_AMD_ARIEL_TYPEC_XHCI 0x13ed +#define PCI_DEVICE_ID_AMD_ARIEL_TYPEA_XHCI 0x13ee +#define PCI_DEVICE_ID_AMD_STARSHIP_XHCI 0x148c +#define PCI_DEVICE_ID_AMD_FIREFLIGHT_15D4_XHCI 0x15d4 +#define PCI_DEVICE_ID_AMD_FIREFLIGHT_15D5_XHCI 0x15d5 +#define PCI_DEVICE_ID_AMD_RAVEN_15E0_XHCI 0x15e0 +#define PCI_DEVICE_ID_AMD_RAVEN_15E1_XHCI 0x15e1 +#define PCI_DEVICE_ID_AMD_RAVEN2_XHCI 0x15e5 #define PCI_DEVICE_ID_AMD_RENOIR_XHCI 0x1639 #define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9 #define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba #define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb #define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc +#define PCI_DEVICE_ID_ATI_NAVI10_7316_XHCI 0x7316 + #define PCI_DEVICE_ID_ASMEDIA_1042_XHCI 0x1042 #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 #define PCI_DEVICE_ID_ASMEDIA_1142_XHCI 0x1242 @@ -348,6 +358,21 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) if (pdev->vendor == PCI_VENDOR_ID_NEC) xhci->quirks |= XHCI_NEC_HOST; + if (pdev->vendor == PCI_VENDOR_ID_AMD && + (pdev->device == PCI_DEVICE_ID_AMD_ARIEL_TYPEC_XHCI || + pdev->device == PCI_DEVICE_ID_AMD_ARIEL_TYPEA_XHCI || + pdev->device == PCI_DEVICE_ID_AMD_STARSHIP_XHCI || + pdev->device == PCI_DEVICE_ID_AMD_FIREFLIGHT_15D4_XHCI || + pdev->device == PCI_DEVICE_ID_AMD_FIREFLIGHT_15D5_XHCI || + pdev->device == PCI_DEVICE_ID_AMD_RAVEN_15E0_XHCI || + pdev->device == PCI_DEVICE_ID_AMD_RAVEN_15E1_XHCI || + pdev->device == PCI_DEVICE_ID_AMD_RAVEN2_XHCI)) + xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_9; + + if (pdev->vendor == PCI_VENDOR_ID_ATI && + pdev->device == PCI_DEVICE_ID_ATI_NAVI10_7316_XHCI) + xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_9; + if (pdev->vendor == PCI_VENDOR_ID_AMD && xhci->hci_version == 0x96) xhci->quirks |= XHCI_AMD_0x96_HOST; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 74bdd035d756..159cdfc71290 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1659,6 +1659,7 @@ struct xhci_hcd { #define XHCI_WRITE_64_HI_LO BIT_ULL(47) #define XHCI_CDNS_SCTX_QUIRK BIT_ULL(48) #define XHCI_ETRON_HOST BIT_ULL(49) +#define XHCI_LIMIT_ENDPOINT_INTERVAL_9 BIT_ULL(50) unsigned int num_active_eps; unsigned int limit_active_eps; From 897d1170c24900fdfb54f941b480a4459d45f043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Bartosik?= Date: Fri, 27 Jun 2025 17:41:21 +0300 Subject: [PATCH 939/971] xhci: dbctty: disable ECHO flag by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 2b857d69a5e116150639a0c6c39c86cc329939ee upstream. When /dev/ttyDBC0 device is created then by default ECHO flag is set for the terminal device. However if data arrives from a peer before application using /dev/ttyDBC0 applies its set of terminal flags then the arriving data will be echoed which might not be desired behavior. Fixes: 4521f1613940 ("xhci: dbctty: split dbc tty driver registration and unregistration functions.") Cc: stable Signed-off-by: Łukasz Bartosik Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/stable/20250610111802.18742-1-ukaszb%40chromium.org Link: https://lore.kernel.org/r/20250627144127.3889714-4-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-dbgtty.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/host/xhci-dbgtty.c b/drivers/usb/host/xhci-dbgtty.c index 0266c2f5bc0d..aa689fbd3dce 100644 --- a/drivers/usb/host/xhci-dbgtty.c +++ b/drivers/usb/host/xhci-dbgtty.c @@ -585,6 +585,7 @@ int dbc_tty_init(void) dbc_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; dbc_tty_driver->subtype = SERIAL_TYPE_NORMAL; dbc_tty_driver->init_termios = tty_std_termios; + dbc_tty_driver->init_termios.c_lflag &= ~ECHO; dbc_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; dbc_tty_driver->init_termios.c_ispeed = 9600; From 881c9274246c69f742a06c87a361f0e285d6b14d Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Fri, 27 Jun 2025 17:41:22 +0300 Subject: [PATCH 940/971] xhci: dbc: Flush queued requests before stopping dbc commit efe3e3ae5a66cb38ef29c909e951b4039044bae9 upstream. Flush dbc requests when dbc is stopped and transfer rings are freed. Failure to flush them lead to leaking memory and dbc completing odd requests after resuming from suspend, leading to error messages such as: [ 95.344392] xhci_hcd 0000:00:0d.0: no matched request Cc: stable Fixes: dfba2174dc42 ("usb: xhci: Add DbC support in xHCI driver") Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20250627144127.3889714-5-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-dbgcap.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c index fab9e6be4e27..2cd8c757c653 100644 --- a/drivers/usb/host/xhci-dbgcap.c +++ b/drivers/usb/host/xhci-dbgcap.c @@ -639,6 +639,10 @@ static void xhci_dbc_stop(struct xhci_dbc *dbc) case DS_DISABLED: return; case DS_CONFIGURED: + spin_lock(&dbc->lock); + xhci_dbc_flush_requests(dbc); + spin_unlock(&dbc->lock); + if (dbc->driver->disconnect) dbc->driver->disconnect(dbc); break; From c16b75aa6fb619e5256636963e4812dd6e9d20c3 Mon Sep 17 00:00:00 2001 From: Hongyu Xie Date: Fri, 27 Jun 2025 17:41:20 +0300 Subject: [PATCH 941/971] xhci: Disable stream for xHC controller with XHCI_BROKEN_STREAMS commit cd65ee81240e8bc3c3119b46db7f60c80864b90b upstream. Disable stream for platform xHC controller with broken stream. Fixes: 14aec589327a6 ("storage: accept some UAS devices if streams are unavailable") Cc: stable Signed-off-by: Hongyu Xie Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20250627144127.3889714-3-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-plat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 8832e0cedada..749ba3596c2b 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -313,7 +313,8 @@ int xhci_plat_probe(struct platform_device *pdev, struct device *sysdev, const s } usb3_hcd = xhci_get_usb3_hcd(xhci); - if (usb3_hcd && HCC_MAX_PSA(xhci->hcc_params) >= 4) + if (usb3_hcd && HCC_MAX_PSA(xhci->hcc_params) >= 4 && + !(xhci->quirks & XHCI_BROKEN_STREAMS)) usb3_hcd->can_do_streams = 1; if (xhci->shared_hcd) { From 2cd5e7c16942786d05eef79647569698a4648630 Mon Sep 17 00:00:00 2001 From: Nilton Perim Neto Date: Fri, 27 Jun 2025 16:29:40 -0700 Subject: [PATCH 942/971] Input: xpad - support Acer NGR 200 Controller commit 22c69d786ef8fb789c61ca75492a272774221324 upstream. Add the NGR 200 Xbox 360 to the list of recognized controllers. Signed-off-by: Nilton Perim Neto Link: https://lore.kernel.org/r/20250608060517.14967-1-niltonperimneto@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/joystick/xpad.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index e6fed973ea74..05c00421ff2b 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -174,6 +174,7 @@ static const struct xpad_device { { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", 0, XTYPE_XBOX }, { 0x05fe, 0x3030, "Chic Controller", 0, XTYPE_XBOX }, { 0x05fe, 0x3031, "Chic Controller", 0, XTYPE_XBOX }, + { 0x0502, 0x1305, "Acer NGR200", 0, XTYPE_XBOX }, { 0x062a, 0x0020, "Logic3 Xbox GamePad", 0, XTYPE_XBOX }, { 0x062a, 0x0033, "Competition Pro Steering Wheel", 0, XTYPE_XBOX }, { 0x06a3, 0x0200, "Saitek Racing Wheel", 0, XTYPE_XBOX }, @@ -514,6 +515,7 @@ static const struct usb_device_id xpad_table[] = { XPAD_XBOX360_VENDOR(0x045e), /* Microsoft Xbox 360 controllers */ XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft Xbox One controllers */ XPAD_XBOX360_VENDOR(0x046d), /* Logitech Xbox 360-style controllers */ + XPAD_XBOX360_VENDOR(0x0502), /* Acer Inc. Xbox 360 style controllers */ XPAD_XBOX360_VENDOR(0x056e), /* Elecom JC-U3613M */ XPAD_XBOX360_VENDOR(0x06a3), /* Saitek P3600 */ XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz Xbox 360 controllers */ From c9a841fd2ec2e0147585a5c9cfcfaaa8dd67d47b Mon Sep 17 00:00:00 2001 From: Jeff LaBundy Date: Sun, 29 Jun 2025 18:33:30 -0700 Subject: [PATCH 943/971] Input: iqs7222 - explicitly define number of external channels commit 63f4970a1219b5256e8ea952096c86dab666d312 upstream. The number of external channels is assumed to be a multiple of 10, but this is not the case for IQS7222D. As a result, some CRx pins are wrongly prevented from being assigned to some channels. Address this problem by explicitly defining the number of external channels for cases in which the number of external channels is not equal to the total number of available channels. Fixes: dd24e202ac72 ("Input: iqs7222 - add support for Azoteq IQS7222D") Signed-off-by: Jeff LaBundy Link: https://lore.kernel.org/r/aGHVf6HkyFZrzTPy@nixie71 Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/misc/iqs7222.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/input/misc/iqs7222.c b/drivers/input/misc/iqs7222.c index b98529568eeb..ce7e977cc8a7 100644 --- a/drivers/input/misc/iqs7222.c +++ b/drivers/input/misc/iqs7222.c @@ -301,6 +301,7 @@ struct iqs7222_dev_desc { int allow_offset; int event_offset; int comms_offset; + int ext_chan; bool legacy_gesture; struct iqs7222_reg_grp_desc reg_grps[IQS7222_NUM_REG_GRPS]; }; @@ -315,6 +316,7 @@ static const struct iqs7222_dev_desc iqs7222_devs[] = { .allow_offset = 9, .event_offset = 10, .comms_offset = 12, + .ext_chan = 10, .reg_grps = { [IQS7222_REG_GRP_STAT] = { .base = IQS7222_SYS_STATUS, @@ -373,6 +375,7 @@ static const struct iqs7222_dev_desc iqs7222_devs[] = { .allow_offset = 9, .event_offset = 10, .comms_offset = 12, + .ext_chan = 10, .legacy_gesture = true, .reg_grps = { [IQS7222_REG_GRP_STAT] = { @@ -2244,7 +2247,7 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, const struct iqs7222_dev_desc *dev_desc = iqs7222->dev_desc; struct i2c_client *client = iqs7222->client; int num_chan = dev_desc->reg_grps[IQS7222_REG_GRP_CHAN].num_row; - int ext_chan = rounddown(num_chan, 10); + int ext_chan = dev_desc->ext_chan ? : num_chan; int error, i; u16 *chan_setup = iqs7222->chan_setup[chan_index]; u16 *sys_setup = iqs7222->sys_setup; @@ -2448,7 +2451,7 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, const struct iqs7222_dev_desc *dev_desc = iqs7222->dev_desc; struct i2c_client *client = iqs7222->client; int num_chan = dev_desc->reg_grps[IQS7222_REG_GRP_CHAN].num_row; - int ext_chan = rounddown(num_chan, 10); + int ext_chan = dev_desc->ext_chan ? : num_chan; int count, error, reg_offset, i; u16 *event_mask = &iqs7222->sys_setup[dev_desc->event_offset]; u16 *sldr_setup = iqs7222->sldr_setup[sldr_index]; From afbec8c34428b65b572dde64c871251e6e9be278 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 19 Jun 2025 09:34:13 +0800 Subject: [PATCH 944/971] usb: cdnsp: do not disable slot for disabled slot commit 7e2c421ef88e9da9c39e01496b7f5b0b354b42bc upstream. It doesn't need to do it, and the related command event returns 'Slot Not Enabled Error' status. Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver") Cc: stable Suggested-by: Hongliang Yang Reviewed-by: Fugang Duan Signed-off-by: Peter Chen Link: https://lore.kernel.org/r/20250619013413.35817-1-peter.chen@cixtech.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/cdns3/cdnsp-ring.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/cdns3/cdnsp-ring.c b/drivers/usb/cdns3/cdnsp-ring.c index 080a3f17a35d..3b17d9e4b07d 100644 --- a/drivers/usb/cdns3/cdnsp-ring.c +++ b/drivers/usb/cdns3/cdnsp-ring.c @@ -772,7 +772,9 @@ static int cdnsp_update_port_id(struct cdnsp_device *pdev, u32 port_id) } if (port_id != old_port) { - cdnsp_disable_slot(pdev); + if (pdev->slot_id) + cdnsp_disable_slot(pdev); + pdev->active_port = port; cdnsp_enable_slot(pdev); } From 937f49be49d6ee696eb5457c21ff89c135c9b5ae Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Sat, 14 Jun 2025 20:49:14 +0800 Subject: [PATCH 945/971] usb: chipidea: udc: disconnect/reconnect from host when do suspend/resume commit 31a6afbe86e8e9deba9ab53876ec49eafc7fd901 upstream. Shawn and John reported a hang issue during system suspend as below: - USB gadget is enabled as Ethernet - There is data transfer over USB Ethernet (scp a big file between host and device) - Device is going in/out suspend (echo mem > /sys/power/state) The root cause is the USB device controller is suspended but the USB bus is still active which caused the USB host continues to transfer data with device and the device continues to queue USB requests (in this case, a delayed TCP ACK packet trigger the issue) after controller is suspended, however the USB controller clock is already gated off. Then if udc driver access registers after that point, the system will hang. The correct way to avoid such issue is to disconnect device from host when the USB bus is not at suspend state. Then the host will receive disconnect event and stop data transfer in time. To continue make USB gadget device work after system resume, this will reconnect device automatically. To make usb wakeup work if USB bus is already at suspend state, this will keep connection for it only when USB device controller has enabled wakeup capability. Reported-by: Shawn Guo Reported-by: John Ernberg Closes: https://lore.kernel.org/linux-usb/aEZxmlHmjeWcXiF3@dragon/ Tested-by: John Ernberg # iMX8QXP Fixes: 235ffc17d014 ("usb: chipidea: udc: add suspend/resume support for device controller") Cc: stable Reviewed-by: Jun Li Signed-off-by: Xu Yang Acked-by: Peter Chen Link: https://lore.kernel.org/r/20250614124914.207540-1-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/udc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index f2ae5f4c5828..0bee561420af 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -2213,6 +2213,10 @@ static void udc_suspend(struct ci_hdrc *ci) */ if (hw_read(ci, OP_ENDPTLISTADDR, ~0) == 0) hw_write(ci, OP_ENDPTLISTADDR, ~0, ~0); + + if (ci->gadget.connected && + (!ci->suspended || !device_may_wakeup(ci->dev))) + usb_gadget_disconnect(&ci->gadget); } static void udc_resume(struct ci_hdrc *ci, bool power_lost) @@ -2223,6 +2227,9 @@ static void udc_resume(struct ci_hdrc *ci, bool power_lost) OTGSC_BSVIS | OTGSC_BSVIE); if (ci->vbus_active) usb_gadget_vbus_disconnect(&ci->gadget); + } else if (ci->vbus_active && ci->driver && + !ci->gadget.connected) { + usb_gadget_connect(&ci->gadget); } /* Restore value 0 if it was set for power lost check */ From 59205a3e93ef2cb96443fa0dcb7b8bb0e528eb42 Mon Sep 17 00:00:00 2001 From: Philipp Kerling Date: Sun, 29 Jun 2025 19:05:05 +0200 Subject: [PATCH 946/971] smb: client: fix readdir returning wrong type with POSIX extensions commit b8f89cb723b9e66f5dbd7199e4036fee34fb0de0 upstream. When SMB 3.1.1 POSIX Extensions are negotiated, userspace applications using readdir() or getdents() calls without stat() on each individual file (such as a simple "ls" or "find") would misidentify file types and exhibit strange behavior such as not descending into directories. The reason for this behavior is an oversight in the cifs_posix_to_fattr conversion function. Instead of extracting the entry type for cf_dtype from the properly converted cf_mode field, it tries to extract the type from the PDU. While the wire representation of the entry mode is similar in structure to POSIX stat(), the assignments of the entry types are different. Applying the S_DT macro to cf_mode instead yields the correct result. This is also what the equivalent function smb311_posix_info_to_fattr in inode.c already does for stat() etc.; which is why "ls -l" would give the correct file type but "ls" would not (as identified by the colors). Cc: stable@vger.kernel.org Signed-off-by: Philipp Kerling Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/smb/client/readdir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/smb/client/readdir.c b/fs/smb/client/readdir.c index 222348ae6258..0be16f8acd9a 100644 --- a/fs/smb/client/readdir.c +++ b/fs/smb/client/readdir.c @@ -263,7 +263,7 @@ cifs_posix_to_fattr(struct cifs_fattr *fattr, struct smb2_posix_info *info, /* The Mode field in the response can now include the file type as well */ fattr->cf_mode = wire_mode_to_posix(le32_to_cpu(info->Mode), fattr->cf_cifsattrs & ATTR_DIRECTORY); - fattr->cf_dtype = S_DT(le32_to_cpu(info->Mode)); + fattr->cf_dtype = S_DT(fattr->cf_mode); switch (fattr->cf_mode & S_IFMT) { case S_IFLNK: From d8eab407c08d40908345174f27c306483c894c7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 28 Jan 2025 10:47:48 +0100 Subject: [PATCH 947/971] dma-buf: fix timeout handling in dma_resv_wait_timeout v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 2b95a7db6e0f75587bffddbb490399cbb87e4985 upstream. Even the kerneldoc says that with a zero timeout the function should not wait for anything, but still return 1 to indicate that the fences are signaled now. Unfortunately that isn't what was implemented, instead of only returning 1 we also waited for at least one jiffies. Fix that by adjusting the handling to what the function is actually documented to do. v2: improve code readability Reported-by: Marek Olšák Reported-by: Lucas Stach Signed-off-by: Christian König Reviewed-by: Lucas Stach Cc: Link: https://lore.kernel.org/r/20250129105841.1806-1-christian.koenig@amd.com Signed-off-by: Greg Kroah-Hartman --- drivers/dma-buf/dma-resv.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c index 9093f751f133..8f3fa149a76d 100644 --- a/drivers/dma-buf/dma-resv.c +++ b/drivers/dma-buf/dma-resv.c @@ -678,11 +678,13 @@ long dma_resv_wait_timeout(struct dma_resv *obj, enum dma_resv_usage usage, dma_resv_iter_begin(&cursor, obj, usage); dma_resv_for_each_fence_unlocked(&cursor, fence) { - ret = dma_fence_wait_timeout(fence, intr, ret); - if (ret <= 0) { - dma_resv_iter_end(&cursor); - return ret; - } + ret = dma_fence_wait_timeout(fence, intr, timeout); + if (ret <= 0) + break; + + /* Even for zero timeout the return value is 1 */ + if (timeout) + timeout = ret; } dma_resv_iter_end(&cursor); From 6358cb9c2a31e23b6b51bfcd7fe2b7becaf6b149 Mon Sep 17 00:00:00 2001 From: "Michael J. Ruhl" Date: Fri, 27 Jun 2025 10:35:11 -0400 Subject: [PATCH 948/971] i2c/designware: Fix an initialization issue commit 3d30048958e0d43425f6d4e76565e6249fa71050 upstream. The i2c_dw_xfer_init() function requires msgs and msg_write_idx from the dev context to be initialized. amd_i2c_dw_xfer_quirk() inits msgs and msgs_num, but not msg_write_idx. This could allow an out of bounds access (of msgs). Initialize msg_write_idx before calling i2c_dw_xfer_init(). Reviewed-by: Andy Shevchenko Fixes: 17631e8ca2d3 ("i2c: designware: Add driver support for AMD NAVI GPU") Cc: # v5.13+ Signed-off-by: Michael J. Ruhl Signed-off-by: Andi Shyti Link: https://lore.kernel.org/r/20250627143511.489570-1-michael.j.ruhl@intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-designware-master.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index 51f5491648c0..e865869ccc50 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c @@ -327,6 +327,7 @@ static int amd_i2c_dw_xfer_quirk(struct i2c_adapter *adap, struct i2c_msg *msgs, dev->msgs = msgs; dev->msgs_num = num_msgs; + dev->msg_write_idx = 0; i2c_dw_xfer_init(dev); regmap_write(dev->map, DW_IC_INTR_MASK, 0); From 6052862ba31ca96c425711c9bacc491ff5860c27 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 5 Jun 2025 14:28:45 +0200 Subject: [PATCH 949/971] Logitech C-270 even more broken commit cee4392a57e14a799fbdee193bc4c0de65b29521 upstream. Some varieties of this device don't work with RESET_RESUME alone. Signed-off-by: Oliver Neukum Cc: stable Link: https://lore.kernel.org/r/20250605122852.1440382-1-oneukum@suse.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index c979ecd0169a..46db600fdd82 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -227,7 +227,8 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x046a, 0x0023), .driver_info = USB_QUIRK_RESET_RESUME }, /* Logitech HD Webcam C270 */ - { USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME }, + { USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME | + USB_QUIRK_NO_LPM}, /* Logitech HD Pro Webcams C920, C920-C, C922, C925e and C930e */ { USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT }, From 73d43c215007e7ee995828548c9b8fd961759f9c Mon Sep 17 00:00:00 2001 From: Simon Xue Date: Mon, 23 Jun 2025 10:00:18 +0800 Subject: [PATCH 950/971] iommu/rockchip: prevent iommus dead loop when two masters share one IOMMU commit 62e062a29ad5133f67c20b333ba0a952a99161ae upstream. When two masters share an IOMMU, calling ops->of_xlate during the second master's driver init may overwrite iommu->domain set by the first. This causes the check if (iommu->domain == domain) in rk_iommu_attach_device() to fail, resulting in the same iommu->node being added twice to &rk_domain->iommus, which can lead to an infinite loop in subsequent &rk_domain->iommus operations. Cc: Fixes: 25c2325575cc ("iommu/rockchip: Add missing set_platform_dma_ops callback") Signed-off-by: Simon Xue Reviewed-by: Robin Murphy Link: https://lore.kernel.org/r/20250623020018.584802-1-xxm@rock-chips.com Signed-off-by: Joerg Roedel Signed-off-by: Greg Kroah-Hartman --- drivers/iommu/rockchip-iommu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index 8ff69fbf9f65..36fec26d2a04 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c @@ -1177,7 +1177,6 @@ static int rk_iommu_of_xlate(struct device *dev, iommu_dev = of_find_device_by_node(args->np); data->iommu = platform_get_drvdata(iommu_dev); - data->iommu->domain = &rk_identity_domain; dev_iommu_priv_set(dev, data); platform_device_put(iommu_dev); @@ -1217,6 +1216,8 @@ static int rk_iommu_probe(struct platform_device *pdev) if (!iommu) return -ENOMEM; + iommu->domain = &rk_identity_domain; + platform_set_drvdata(pdev, iommu); iommu->dev = dev; iommu->num_mmu = 0; From 36054636286584ba22ce3cbc47c749b758b278e8 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 19 Jun 2025 15:13:40 +0800 Subject: [PATCH 951/971] powercap: intel_rapl: Do not change CLAMPING bit if ENABLE bit cannot be changed commit 964209202ebe1569c858337441e87ef0f9d71416 upstream. PL1 cannot be disabled on some platforms. The ENABLE bit is still set after software clears it. This behavior leads to a scenario where, upon user request to disable the Power Limit through the powercap sysfs, the ENABLE bit remains set while the CLAMPING bit is inadvertently cleared. According to the Intel Software Developer's Manual, the CLAMPING bit, "When set, allows the processor to go below the OS requested P states in order to maintain the power below specified Platform Power Limit value." Thus this means the system may operate at higher power levels than intended on such platforms. Enhance the code to check ENABLE bit after writing to it, and stop further processing if ENABLE bit cannot be changed. Reported-by: Srinivas Pandruvada Fixes: 2d281d8196e3 ("PowerCap: Introduce Intel RAPL power capping driver") Cc: All applicable Signed-off-by: Zhang Rui Link: https://patch.msgid.link/20250619071340.384782-1-rui.zhang@intel.com [ rjw: Use str_enabled_disabled() instead of open-coded equivalent ] Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/powercap/intel_rapl_common.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/powercap/intel_rapl_common.c b/drivers/powercap/intel_rapl_common.c index f1de4111e98d..5a09a56698f4 100644 --- a/drivers/powercap/intel_rapl_common.c +++ b/drivers/powercap/intel_rapl_common.c @@ -338,12 +338,28 @@ static int set_domain_enable(struct powercap_zone *power_zone, bool mode) { struct rapl_domain *rd = power_zone_to_rapl_domain(power_zone); struct rapl_defaults *defaults = get_defaults(rd->rp); + u64 val; int ret; cpus_read_lock(); ret = rapl_write_pl_data(rd, POWER_LIMIT1, PL_ENABLE, mode); - if (!ret && defaults->set_floor_freq) + if (ret) + goto end; + + ret = rapl_read_pl_data(rd, POWER_LIMIT1, PL_ENABLE, false, &val); + if (ret) + goto end; + + if (mode != val) { + pr_debug("%s cannot be %s\n", power_zone->name, + str_enabled_disabled(mode)); + goto end; + } + + if (defaults->set_floor_freq) defaults->set_floor_freq(rd, mode); + +end: cpus_read_unlock(); return ret; From cb3e3244d88da68864f1699f61b357e611319c8f Mon Sep 17 00:00:00 2001 From: Kurt Borja Date: Mon, 30 Jun 2025 14:31:19 -0300 Subject: [PATCH 952/971] platform/x86: think-lmi: Create ksets consecutively MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 8dab34ca77293b409c3223636dde915a22656748 upstream. Avoid entering tlmi_release_attr() in error paths if both ksets are not yet created. This is accomplished by initializing them side by side. Reviewed-by: Mark Pearson Reviewed-by: Ilpo Järvinen Cc: stable@vger.kernel.org Signed-off-by: Kurt Borja Link: https://lore.kernel.org/r/20250630-lmi-fix-v3-1-ce4f81c9c481@gmail.com Signed-off-by: Ilpo Järvinen Signed-off-by: Greg Kroah-Hartman --- drivers/platform/x86/think-lmi.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index 626990d103e3..62f03a66a619 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -1285,6 +1285,14 @@ static int tlmi_sysfs_init(void) goto fail_device_created; } + tlmi_priv.authentication_kset = kset_create_and_add("authentication", NULL, + &tlmi_priv.class_dev->kobj); + if (!tlmi_priv.authentication_kset) { + kset_unregister(tlmi_priv.attribute_kset); + ret = -ENOMEM; + goto fail_device_created; + } + for (i = 0; i < TLMI_SETTINGS_COUNT; i++) { /* Check if index is a valid setting - skip if it isn't */ if (!tlmi_priv.setting[i]) @@ -1322,12 +1330,6 @@ static int tlmi_sysfs_init(void) } /* Create authentication entries */ - tlmi_priv.authentication_kset = kset_create_and_add("authentication", NULL, - &tlmi_priv.class_dev->kobj); - if (!tlmi_priv.authentication_kset) { - ret = -ENOMEM; - goto fail_create_attr; - } tlmi_priv.pwd_admin->kobj.kset = tlmi_priv.authentication_kset; ret = kobject_add(&tlmi_priv.pwd_admin->kobj, NULL, "%s", "Admin"); if (ret) From 98002f1ac947f63f8eda0f3d1f576a50a4daa91f Mon Sep 17 00:00:00 2001 From: Kurt Borja Date: Mon, 30 Jun 2025 14:31:20 -0300 Subject: [PATCH 953/971] platform/x86: think-lmi: Fix kobject cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 9110056fe10b0519529bdbbac37311a5037ea0c2 upstream. In tlmi_analyze(), allocated structs with an embedded kobject are freed in error paths after the they were already initialized. Fix this by first by avoiding the initialization of kobjects in tlmi_analyze() and then by correctly cleaning them up in tlmi_release_attr() using their kset's kobject list. Fixes: a40cd7ef22fb ("platform/x86: think-lmi: Add WMI interface support on Lenovo platforms") Fixes: 30e78435d3bf ("platform/x86: think-lmi: Split kobject_init() and kobject_add() calls") Cc: stable@vger.kernel.org Reviewed-by: Mark Pearson Reviewed-by: Ilpo Järvinen Signed-off-by: Kurt Borja Link: https://lore.kernel.org/r/20250630-lmi-fix-v3-2-ce4f81c9c481@gmail.com Signed-off-by: Ilpo Järvinen Signed-off-by: Greg Kroah-Hartman --- drivers/platform/x86/think-lmi.c | 35 +++++++++++++++++--------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index 62f03a66a619..c3f1735a5551 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -1212,19 +1212,22 @@ static struct kobj_attribute debug_cmd = __ATTR_WO(debug_cmd); /* ---- Initialisation --------------------------------------------------------- */ static void tlmi_release_attr(void) { + struct kobject *pos, *n; int i; /* Attribute structures */ for (i = 0; i < TLMI_SETTINGS_COUNT; i++) { if (tlmi_priv.setting[i]) { sysfs_remove_group(&tlmi_priv.setting[i]->kobj, &tlmi_attr_group); - kobject_put(&tlmi_priv.setting[i]->kobj); } } sysfs_remove_file(&tlmi_priv.attribute_kset->kobj, &pending_reboot.attr); if (tlmi_priv.can_debug_cmd && debug_support) sysfs_remove_file(&tlmi_priv.attribute_kset->kobj, &debug_cmd.attr); + list_for_each_entry_safe(pos, n, &tlmi_priv.attribute_kset->list, entry) + kobject_put(pos); + kset_unregister(tlmi_priv.attribute_kset); /* Free up any saved signatures */ @@ -1233,19 +1236,17 @@ static void tlmi_release_attr(void) /* Authentication structures */ sysfs_remove_group(&tlmi_priv.pwd_admin->kobj, &auth_attr_group); - kobject_put(&tlmi_priv.pwd_admin->kobj); sysfs_remove_group(&tlmi_priv.pwd_power->kobj, &auth_attr_group); - kobject_put(&tlmi_priv.pwd_power->kobj); if (tlmi_priv.opcode_support) { sysfs_remove_group(&tlmi_priv.pwd_system->kobj, &auth_attr_group); - kobject_put(&tlmi_priv.pwd_system->kobj); sysfs_remove_group(&tlmi_priv.pwd_hdd->kobj, &auth_attr_group); - kobject_put(&tlmi_priv.pwd_hdd->kobj); sysfs_remove_group(&tlmi_priv.pwd_nvme->kobj, &auth_attr_group); - kobject_put(&tlmi_priv.pwd_nvme->kobj); } + list_for_each_entry_safe(pos, n, &tlmi_priv.authentication_kset->list, entry) + kobject_put(pos); + kset_unregister(tlmi_priv.authentication_kset); } @@ -1309,8 +1310,8 @@ static int tlmi_sysfs_init(void) /* Build attribute */ tlmi_priv.setting[i]->kobj.kset = tlmi_priv.attribute_kset; - ret = kobject_add(&tlmi_priv.setting[i]->kobj, NULL, - "%s", tlmi_priv.setting[i]->display_name); + ret = kobject_init_and_add(&tlmi_priv.setting[i]->kobj, &tlmi_attr_setting_ktype, + NULL, "%s", tlmi_priv.setting[i]->display_name); if (ret) goto fail_create_attr; @@ -1331,7 +1332,8 @@ static int tlmi_sysfs_init(void) /* Create authentication entries */ tlmi_priv.pwd_admin->kobj.kset = tlmi_priv.authentication_kset; - ret = kobject_add(&tlmi_priv.pwd_admin->kobj, NULL, "%s", "Admin"); + ret = kobject_init_and_add(&tlmi_priv.pwd_admin->kobj, &tlmi_pwd_setting_ktype, + NULL, "%s", "Admin"); if (ret) goto fail_create_attr; @@ -1340,7 +1342,8 @@ static int tlmi_sysfs_init(void) goto fail_create_attr; tlmi_priv.pwd_power->kobj.kset = tlmi_priv.authentication_kset; - ret = kobject_add(&tlmi_priv.pwd_power->kobj, NULL, "%s", "Power-on"); + ret = kobject_init_and_add(&tlmi_priv.pwd_power->kobj, &tlmi_pwd_setting_ktype, + NULL, "%s", "Power-on"); if (ret) goto fail_create_attr; @@ -1350,7 +1353,8 @@ static int tlmi_sysfs_init(void) if (tlmi_priv.opcode_support) { tlmi_priv.pwd_system->kobj.kset = tlmi_priv.authentication_kset; - ret = kobject_add(&tlmi_priv.pwd_system->kobj, NULL, "%s", "System"); + ret = kobject_init_and_add(&tlmi_priv.pwd_system->kobj, &tlmi_pwd_setting_ktype, + NULL, "%s", "System"); if (ret) goto fail_create_attr; @@ -1359,7 +1363,8 @@ static int tlmi_sysfs_init(void) goto fail_create_attr; tlmi_priv.pwd_hdd->kobj.kset = tlmi_priv.authentication_kset; - ret = kobject_add(&tlmi_priv.pwd_hdd->kobj, NULL, "%s", "HDD"); + ret = kobject_init_and_add(&tlmi_priv.pwd_hdd->kobj, &tlmi_pwd_setting_ktype, + NULL, "%s", "HDD"); if (ret) goto fail_create_attr; @@ -1368,7 +1373,8 @@ static int tlmi_sysfs_init(void) goto fail_create_attr; tlmi_priv.pwd_nvme->kobj.kset = tlmi_priv.authentication_kset; - ret = kobject_add(&tlmi_priv.pwd_nvme->kobj, NULL, "%s", "NVMe"); + ret = kobject_init_and_add(&tlmi_priv.pwd_nvme->kobj, &tlmi_pwd_setting_ktype, + NULL, "%s", "NVMe"); if (ret) goto fail_create_attr; @@ -1405,8 +1411,6 @@ static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type, new_pwd->maxlen = tlmi_priv.pwdcfg.core.max_length; new_pwd->index = 0; - kobject_init(&new_pwd->kobj, &tlmi_pwd_setting_ktype); - return new_pwd; } @@ -1510,7 +1514,6 @@ static int tlmi_analyze(void) if (setting->possible_values) strreplace(setting->possible_values, ',', ';'); - kobject_init(&setting->kobj, &tlmi_attr_setting_ktype); tlmi_priv.setting[i] = setting; kfree(item); } From 4b91b77af24c4a2d9f1d68cf7d3e2bf55474195b Mon Sep 17 00:00:00 2001 From: Kurt Borja Date: Mon, 30 Jun 2025 14:31:21 -0300 Subject: [PATCH 954/971] platform/x86: think-lmi: Fix sysfs group cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 4f30f946f27b7f044cf8f3f1f353dee1dcd3517a upstream. Many error paths in tlmi_sysfs_init() lead to sysfs groups being removed when they were not even created. Fix this by letting the kobject core manage these groups through their kobj_type's defult_groups. Fixes: a40cd7ef22fb ("platform/x86: think-lmi: Add WMI interface support on Lenovo platforms") Cc: stable@vger.kernel.org Reviewed-by: Mark Pearson Reviewed-by: Ilpo Järvinen Signed-off-by: Kurt Borja Link: https://lore.kernel.org/r/20250630-lmi-fix-v3-3-ce4f81c9c481@gmail.com Signed-off-by: Ilpo Järvinen Signed-off-by: Greg Kroah-Hartman --- drivers/platform/x86/think-lmi.c | 43 +++----------------------------- 1 file changed, 4 insertions(+), 39 deletions(-) diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index c3f1735a5551..d5319b4637e1 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -916,6 +916,7 @@ static const struct attribute_group auth_attr_group = { .is_visible = auth_attr_is_visible, .attrs = auth_attrs, }; +__ATTRIBUTE_GROUPS(auth_attr); /* ---- Attributes sysfs --------------------------------------------------------- */ static ssize_t display_name_show(struct kobject *kobj, struct kobj_attribute *attr, @@ -1119,6 +1120,7 @@ static const struct attribute_group tlmi_attr_group = { .is_visible = attr_is_visible, .attrs = tlmi_attrs, }; +__ATTRIBUTE_GROUPS(tlmi_attr); static void tlmi_attr_setting_release(struct kobject *kobj) { @@ -1138,11 +1140,13 @@ static void tlmi_pwd_setting_release(struct kobject *kobj) static const struct kobj_type tlmi_attr_setting_ktype = { .release = &tlmi_attr_setting_release, .sysfs_ops = &kobj_sysfs_ops, + .default_groups = tlmi_attr_groups, }; static const struct kobj_type tlmi_pwd_setting_ktype = { .release = &tlmi_pwd_setting_release, .sysfs_ops = &kobj_sysfs_ops, + .default_groups = auth_attr_groups, }; static ssize_t pending_reboot_show(struct kobject *kobj, struct kobj_attribute *attr, @@ -1213,14 +1217,8 @@ static struct kobj_attribute debug_cmd = __ATTR_WO(debug_cmd); static void tlmi_release_attr(void) { struct kobject *pos, *n; - int i; /* Attribute structures */ - for (i = 0; i < TLMI_SETTINGS_COUNT; i++) { - if (tlmi_priv.setting[i]) { - sysfs_remove_group(&tlmi_priv.setting[i]->kobj, &tlmi_attr_group); - } - } sysfs_remove_file(&tlmi_priv.attribute_kset->kobj, &pending_reboot.attr); if (tlmi_priv.can_debug_cmd && debug_support) sysfs_remove_file(&tlmi_priv.attribute_kset->kobj, &debug_cmd.attr); @@ -1235,15 +1233,6 @@ static void tlmi_release_attr(void) kfree(tlmi_priv.pwd_admin->save_signature); /* Authentication structures */ - sysfs_remove_group(&tlmi_priv.pwd_admin->kobj, &auth_attr_group); - sysfs_remove_group(&tlmi_priv.pwd_power->kobj, &auth_attr_group); - - if (tlmi_priv.opcode_support) { - sysfs_remove_group(&tlmi_priv.pwd_system->kobj, &auth_attr_group); - sysfs_remove_group(&tlmi_priv.pwd_hdd->kobj, &auth_attr_group); - sysfs_remove_group(&tlmi_priv.pwd_nvme->kobj, &auth_attr_group); - } - list_for_each_entry_safe(pos, n, &tlmi_priv.authentication_kset->list, entry) kobject_put(pos); @@ -1314,10 +1303,6 @@ static int tlmi_sysfs_init(void) NULL, "%s", tlmi_priv.setting[i]->display_name); if (ret) goto fail_create_attr; - - ret = sysfs_create_group(&tlmi_priv.setting[i]->kobj, &tlmi_attr_group); - if (ret) - goto fail_create_attr; } ret = sysfs_create_file(&tlmi_priv.attribute_kset->kobj, &pending_reboot.attr); @@ -1337,20 +1322,12 @@ static int tlmi_sysfs_init(void) if (ret) goto fail_create_attr; - ret = sysfs_create_group(&tlmi_priv.pwd_admin->kobj, &auth_attr_group); - if (ret) - goto fail_create_attr; - tlmi_priv.pwd_power->kobj.kset = tlmi_priv.authentication_kset; ret = kobject_init_and_add(&tlmi_priv.pwd_power->kobj, &tlmi_pwd_setting_ktype, NULL, "%s", "Power-on"); if (ret) goto fail_create_attr; - ret = sysfs_create_group(&tlmi_priv.pwd_power->kobj, &auth_attr_group); - if (ret) - goto fail_create_attr; - if (tlmi_priv.opcode_support) { tlmi_priv.pwd_system->kobj.kset = tlmi_priv.authentication_kset; ret = kobject_init_and_add(&tlmi_priv.pwd_system->kobj, &tlmi_pwd_setting_ktype, @@ -1358,29 +1335,17 @@ static int tlmi_sysfs_init(void) if (ret) goto fail_create_attr; - ret = sysfs_create_group(&tlmi_priv.pwd_system->kobj, &auth_attr_group); - if (ret) - goto fail_create_attr; - tlmi_priv.pwd_hdd->kobj.kset = tlmi_priv.authentication_kset; ret = kobject_init_and_add(&tlmi_priv.pwd_hdd->kobj, &tlmi_pwd_setting_ktype, NULL, "%s", "HDD"); if (ret) goto fail_create_attr; - ret = sysfs_create_group(&tlmi_priv.pwd_hdd->kobj, &auth_attr_group); - if (ret) - goto fail_create_attr; - tlmi_priv.pwd_nvme->kobj.kset = tlmi_priv.authentication_kset; ret = kobject_init_and_add(&tlmi_priv.pwd_nvme->kobj, &tlmi_pwd_setting_ktype, NULL, "%s", "NVMe"); if (ret) goto fail_create_attr; - - ret = sysfs_create_group(&tlmi_priv.pwd_nvme->kobj, &auth_attr_group); - if (ret) - goto fail_create_attr; } return ret; From 63cff9f57e86b2dc25d7487ca0118df89a665296 Mon Sep 17 00:00:00 2001 From: Andrei Kuchynski Date: Tue, 24 Jun 2025 13:32:46 +0000 Subject: [PATCH 955/971] usb: typec: displayport: Fix potential deadlock commit 099cf1fbb8afc3771f408109f62bdec66f85160e upstream. The deadlock can occur due to a recursive lock acquisition of `cros_typec_altmode_data::mutex`. The call chain is as follows: 1. cros_typec_altmode_work() acquires the mutex 2. typec_altmode_vdm() -> dp_altmode_vdm() -> 3. typec_altmode_exit() -> cros_typec_altmode_exit() 4. cros_typec_altmode_exit() attempts to acquire the mutex again To prevent this, defer the `typec_altmode_exit()` call by scheduling it rather than calling it directly from within the mutex-protected context. Cc: stable Fixes: b4b38ffb38c9 ("usb: typec: displayport: Receive DP Status Update NAK request exit dp altmode") Signed-off-by: Andrei Kuchynski Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20250624133246.3936737-1-akuchynski@chromium.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/altmodes/displayport.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c index 2f8d3ed01d5b..7eb78885fa2b 100644 --- a/drivers/usb/typec/altmodes/displayport.c +++ b/drivers/usb/typec/altmodes/displayport.c @@ -324,8 +324,7 @@ static int dp_altmode_vdm(struct typec_altmode *alt, 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"); + dp->state = DP_STATE_EXIT; break; case DP_CMD_CONFIGURE: dp->data.conf = 0; From 8a7ac2737211451b8b98657b919c4c4e0a4c0c2f Mon Sep 17 00:00:00 2001 From: Madhavan Srinivasan Date: Sun, 11 May 2025 09:41:11 +0530 Subject: [PATCH 956/971] powerpc/kernel: Fix ppc_save_regs inclusion in build commit 93bd4a80efeb521314485a06d8c21157240497bb upstream. Recent patch fixed an old commit 'fc2a5a6161a2 ("powerpc/64s: ppc_save_regs is now needed for all 64s builds")' which is to include building of ppc_save_reg.c only when XMON and KEXEC_CORE and PPC_BOOK3S are enabled. This was valid, since ppc_save_regs was called only in replay_system_reset() of old irq.c which was under BOOK3S. But there has been multiple refactoring of irq.c and have added call to ppc_save_regs() from __replay_soft_interrupts -> replay_soft_interrupts which is part of irq_64.c included under CONFIG_PPC64. And since ppc_save_regs is called in CRASH_DUMP path as part of crash_setup_regs in kexec.h, CONFIG_PPC32 also needs it. So with this recent patch which enabled the building of ppc_save_regs.c caused a build break when none of these (XMON, KEXEC_CORE, BOOK3S) where enabled as part of config. Patch to enable building of ppc_save_regs.c by defaults. Signed-off-by: Madhavan Srinivasan Link: https://patch.msgid.link/20250511041111.841158-1-maddy@linux.ibm.com Cc: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/kernel/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index b7629122680b..131c859b2467 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -165,9 +165,7 @@ endif obj64-$(CONFIG_PPC_TRANSACTIONAL_MEM) += tm.o -ifneq ($(CONFIG_XMON)$(CONFIG_KEXEC_CORE)$(CONFIG_PPC_BOOK3S),) obj-y += ppc_save_regs.o -endif obj-$(CONFIG_EPAPR_PARAVIRT) += epapr_paravirt.o epapr_hcalls.o obj-$(CONFIG_KVM_GUEST) += kvm.o kvm_emul.o From 2b6a5fbe9dc1842e3485557a057c8e6311b6fd72 Mon Sep 17 00:00:00 2001 From: "Borislav Petkov (AMD)" Date: Wed, 11 Sep 2024 05:13:46 +0200 Subject: [PATCH 957/971] x86/bugs: Rename MDS machinery to something more generic Commit f9af88a3d384c8b55beb5dc5483e5da0135fadbd upstream. It will be used by other x86 mitigations. No functional changes. Signed-off-by: Borislav Petkov (AMD) Reviewed-by: Pawan Gupta Signed-off-by: Greg Kroah-Hartman --- .../hw-vuln/processor_mmio_stale_data.rst | 4 +-- Documentation/arch/x86/mds.rst | 8 ++--- arch/x86/entry/entry.S | 8 ++--- arch/x86/include/asm/irqflags.h | 4 +-- arch/x86/include/asm/mwait.h | 5 ++-- arch/x86/include/asm/nospec-branch.h | 29 ++++++++++--------- arch/x86/kernel/cpu/bugs.c | 12 ++++---- arch/x86/kvm/vmx/vmx.c | 2 +- 8 files changed, 36 insertions(+), 36 deletions(-) diff --git a/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst b/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst index c98fd11907cc..e916dc232b0f 100644 --- a/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst +++ b/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst @@ -157,9 +157,7 @@ This is achieved by using the otherwise unused and obsolete VERW instruction in combination with a microcode update. The microcode clears the affected CPU buffers when the VERW instruction is executed. -Kernel reuses the MDS function to invoke the buffer clearing: - - mds_clear_cpu_buffers() +Kernel does the buffer clearing with x86_clear_cpu_buffers(). On MDS affected CPUs, the kernel already invokes CPU buffer clear on kernel/userspace, hypervisor/guest and C-state (idle) transitions. No diff --git a/Documentation/arch/x86/mds.rst b/Documentation/arch/x86/mds.rst index c58c72362911..43106f349cc3 100644 --- a/Documentation/arch/x86/mds.rst +++ b/Documentation/arch/x86/mds.rst @@ -93,7 +93,7 @@ enters a C-state. The kernel provides a function to invoke the buffer clearing: - mds_clear_cpu_buffers() + x86_clear_cpu_buffers() Also macro CLEAR_CPU_BUFFERS can be used in ASM late in exit-to-user path. Other than CFLAGS.ZF, this macro doesn't clobber any registers. @@ -185,9 +185,9 @@ Mitigation points idle clearing would be a window dressing exercise and is therefore not activated. - The invocation is controlled by the static key mds_idle_clear which is - switched depending on the chosen mitigation mode and the SMT state of - the system. + The invocation is controlled by the static key cpu_buf_idle_clear which is + switched depending on the chosen mitigation mode and the SMT state of the + system. The buffer clear is only invoked before entering the C-State to prevent that stale data from the idling CPU from spilling to the Hyper-Thread diff --git a/arch/x86/entry/entry.S b/arch/x86/entry/entry.S index ad292c0d971a..4e7ecffee762 100644 --- a/arch/x86/entry/entry.S +++ b/arch/x86/entry/entry.S @@ -31,20 +31,20 @@ EXPORT_SYMBOL_GPL(entry_ibpb); /* * Define the VERW operand that is disguised as entry code so that - * it can be referenced with KPTI enabled. This ensure VERW can be + * it can be referenced with KPTI enabled. This ensures VERW can be * used late in exit-to-user path after page tables are switched. */ .pushsection .entry.text, "ax" .align L1_CACHE_BYTES, 0xcc -SYM_CODE_START_NOALIGN(mds_verw_sel) +SYM_CODE_START_NOALIGN(x86_verw_sel) UNWIND_HINT_UNDEFINED ANNOTATE_NOENDBR .word __KERNEL_DS .align L1_CACHE_BYTES, 0xcc -SYM_CODE_END(mds_verw_sel); +SYM_CODE_END(x86_verw_sel); /* For KVM */ -EXPORT_SYMBOL_GPL(mds_verw_sel); +EXPORT_SYMBOL_GPL(x86_verw_sel); .popsection diff --git a/arch/x86/include/asm/irqflags.h b/arch/x86/include/asm/irqflags.h index 9acfe2bcf1fd..9bfb7b90e299 100644 --- a/arch/x86/include/asm/irqflags.h +++ b/arch/x86/include/asm/irqflags.h @@ -44,13 +44,13 @@ static __always_inline void native_irq_enable(void) static __always_inline void native_safe_halt(void) { - mds_idle_clear_cpu_buffers(); + x86_idle_clear_cpu_buffers(); asm volatile("sti; hlt": : :"memory"); } static __always_inline void native_halt(void) { - mds_idle_clear_cpu_buffers(); + x86_idle_clear_cpu_buffers(); asm volatile("hlt": : :"memory"); } diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h index a541411d9226..748c02179a87 100644 --- a/arch/x86/include/asm/mwait.h +++ b/arch/x86/include/asm/mwait.h @@ -44,7 +44,7 @@ static __always_inline void __monitorx(const void *eax, unsigned long ecx, static __always_inline void __mwait(unsigned long eax, unsigned long ecx) { - mds_idle_clear_cpu_buffers(); + x86_idle_clear_cpu_buffers(); /* "mwait %eax, %ecx;" */ asm volatile(".byte 0x0f, 0x01, 0xc9;" @@ -89,7 +89,8 @@ static __always_inline void __mwaitx(unsigned long eax, unsigned long ebx, static __always_inline void __sti_mwait(unsigned long eax, unsigned long ecx) { - mds_idle_clear_cpu_buffers(); + x86_idle_clear_cpu_buffers(); + /* "mwait %eax, %ecx;" */ asm volatile("sti; .byte 0x0f, 0x01, 0xc9;" :: "a" (eax), "c" (ecx)); diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h index bc4fa6d09d29..c9444ede6761 100644 --- a/arch/x86/include/asm/nospec-branch.h +++ b/arch/x86/include/asm/nospec-branch.h @@ -324,22 +324,22 @@ .endm /* - * Macro to execute VERW instruction that mitigate transient data sampling - * attacks such as MDS. On affected systems a microcode update overloaded VERW - * instruction to also clear the CPU buffers. VERW clobbers CFLAGS.ZF. - * + * Macro to execute VERW insns that mitigate transient data sampling + * attacks such as MDS or TSA. On affected systems a microcode update + * overloaded VERW insns to also clear the CPU buffers. VERW clobbers + * CFLAGS.ZF. * Note: Only the memory operand variant of VERW clears the CPU buffers. */ .macro CLEAR_CPU_BUFFERS #ifdef CONFIG_X86_64 - ALTERNATIVE "", "verw mds_verw_sel(%rip)", X86_FEATURE_CLEAR_CPU_BUF + ALTERNATIVE "", "verw x86_verw_sel(%rip)", X86_FEATURE_CLEAR_CPU_BUF #else /* * In 32bit mode, the memory operand must be a %cs reference. The data * segments may not be usable (vm86 mode), and the stack segment may not * be flat (ESPFIX32). */ - ALTERNATIVE "", "verw %cs:mds_verw_sel", X86_FEATURE_CLEAR_CPU_BUF + ALTERNATIVE "", "verw %cs:x86_verw_sel", X86_FEATURE_CLEAR_CPU_BUF #endif .endm @@ -592,24 +592,24 @@ DECLARE_STATIC_KEY_FALSE(switch_to_cond_stibp); DECLARE_STATIC_KEY_FALSE(switch_mm_cond_ibpb); DECLARE_STATIC_KEY_FALSE(switch_mm_always_ibpb); -DECLARE_STATIC_KEY_FALSE(mds_idle_clear); +DECLARE_STATIC_KEY_FALSE(cpu_buf_idle_clear); DECLARE_STATIC_KEY_FALSE(switch_mm_cond_l1d_flush); DECLARE_STATIC_KEY_FALSE(mmio_stale_data_clear); -extern u16 mds_verw_sel; +extern u16 x86_verw_sel; #include /** - * mds_clear_cpu_buffers - Mitigation for MDS and TAA vulnerability + * x86_clear_cpu_buffers - Buffer clearing support for different x86 CPU vulns * * This uses the otherwise unused and obsolete VERW instruction in * combination with microcode which triggers a CPU buffer flush when the * instruction is executed. */ -static __always_inline void mds_clear_cpu_buffers(void) +static __always_inline void x86_clear_cpu_buffers(void) { static const u16 ds = __KERNEL_DS; @@ -626,14 +626,15 @@ static __always_inline void mds_clear_cpu_buffers(void) } /** - * mds_idle_clear_cpu_buffers - Mitigation for MDS vulnerability + * x86_idle_clear_cpu_buffers - Buffer clearing support in idle for the MDS + * vulnerability * * Clear CPU buffers if the corresponding static key is enabled */ -static __always_inline void mds_idle_clear_cpu_buffers(void) +static __always_inline void x86_idle_clear_cpu_buffers(void) { - if (static_branch_likely(&mds_idle_clear)) - mds_clear_cpu_buffers(); + if (static_branch_likely(&cpu_buf_idle_clear)) + x86_clear_cpu_buffers(); } #endif /* __ASSEMBLY__ */ diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 07b45bbf6348..35df0e86326a 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -122,9 +122,9 @@ DEFINE_STATIC_KEY_FALSE(switch_mm_cond_ibpb); /* Control unconditional IBPB in switch_mm() */ DEFINE_STATIC_KEY_FALSE(switch_mm_always_ibpb); -/* Control MDS CPU buffer clear before idling (halt, mwait) */ -DEFINE_STATIC_KEY_FALSE(mds_idle_clear); -EXPORT_SYMBOL_GPL(mds_idle_clear); +/* Control CPU buffer clear before idling (halt, mwait) */ +DEFINE_STATIC_KEY_FALSE(cpu_buf_idle_clear); +EXPORT_SYMBOL_GPL(cpu_buf_idle_clear); /* * Controls whether l1d flush based mitigations are enabled, @@ -445,7 +445,7 @@ static void __init mmio_select_mitigation(void) * is required irrespective of SMT state. */ if (!(x86_arch_cap_msr & ARCH_CAP_FBSDP_NO)) - static_branch_enable(&mds_idle_clear); + static_branch_enable(&cpu_buf_idle_clear); /* * Check if the system has the right microcode. @@ -2082,10 +2082,10 @@ static void update_mds_branch_idle(void) return; if (sched_smt_active()) { - static_branch_enable(&mds_idle_clear); + static_branch_enable(&cpu_buf_idle_clear); } else if (mmio_mitigation == MMIO_MITIGATION_OFF || (x86_arch_cap_msr & ARCH_CAP_FBSDP_NO)) { - static_branch_disable(&mds_idle_clear); + static_branch_disable(&cpu_buf_idle_clear); } } diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index e7f3b70f9114..e53620e18925 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -7263,7 +7263,7 @@ static noinstr void vmx_vcpu_enter_exit(struct kvm_vcpu *vcpu, vmx_l1d_flush(vcpu); else if (static_branch_unlikely(&mmio_stale_data_clear) && kvm_arch_has_assigned_device(vcpu->kvm)) - mds_clear_cpu_buffers(); + x86_clear_cpu_buffers(); vmx_disable_fb_clear(vmx); From 90293047df18caf7ed0fe566d89af0720f2dc98a Mon Sep 17 00:00:00 2001 From: "Borislav Petkov (AMD)" Date: Wed, 11 Sep 2024 10:53:08 +0200 Subject: [PATCH 958/971] x86/bugs: Add a Transient Scheduler Attacks mitigation Commit d8010d4ba43e9f790925375a7de100604a5e2dba upstream. Add the required features detection glue to bugs.c et all in order to support the TSA mitigation. Co-developed-by: Kim Phillips Signed-off-by: Kim Phillips Signed-off-by: Borislav Petkov (AMD) Reviewed-by: Pawan Gupta Signed-off-by: Greg Kroah-Hartman --- .../ABI/testing/sysfs-devices-system-cpu | 1 + .../admin-guide/kernel-parameters.txt | 13 ++ arch/x86/Kconfig | 9 ++ arch/x86/include/asm/cpu.h | 12 ++ arch/x86/include/asm/cpufeatures.h | 6 + arch/x86/include/asm/mwait.h | 2 +- arch/x86/include/asm/nospec-branch.h | 14 +- arch/x86/kernel/cpu/amd.c | 60 +++++++++ arch/x86/kernel/cpu/bugs.c | 121 ++++++++++++++++++ arch/x86/kernel/cpu/common.c | 14 +- arch/x86/kernel/cpu/microcode/amd.c | 12 -- arch/x86/kernel/cpu/scattered.c | 2 + arch/x86/kvm/svm/vmenter.S | 6 + drivers/base/cpu.c | 3 + include/linux/cpu.h | 1 + 15 files changed, 258 insertions(+), 18 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index 0426ec112155..868ec736a9d2 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu @@ -526,6 +526,7 @@ What: /sys/devices/system/cpu/vulnerabilities /sys/devices/system/cpu/vulnerabilities/spectre_v1 /sys/devices/system/cpu/vulnerabilities/spectre_v2 /sys/devices/system/cpu/vulnerabilities/srbds + /sys/devices/system/cpu/vulnerabilities/tsa /sys/devices/system/cpu/vulnerabilities/tsx_async_abort Date: January 2018 Contact: Linux kernel mailing list diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index f95734ceb82b..bcfa49019c3f 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -6645,6 +6645,19 @@ If not specified, "default" is used. In this case, the RNG's choice is left to each individual trust source. + tsa= [X86] Control mitigation for Transient Scheduler + Attacks on AMD CPUs. Search the following in your + favourite search engine for more details: + + "Technical guidance for mitigating transient scheduler + attacks". + + off - disable the mitigation + on - enable the mitigation (default) + user - mitigate only user/kernel transitions + vm - mitigate only guest/host transitions + + tsc= Disable clocksource stability checks for TSC. Format: [x86] reliable: mark tsc clocksource as reliable, this diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 4372657ab0d6..caa6adcedc18 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2621,6 +2621,15 @@ config MITIGATION_ITS disabled, mitigation cannot be enabled via cmdline. See +config MITIGATION_TSA + bool "Mitigate Transient Scheduler Attacks" + depends on CPU_SUP_AMD + default y + help + Enable mitigation for Transient Scheduler Attacks. TSA is a hardware + security vulnerability on AMD CPUs which can lead to forwarding of + invalid info to subsequent instructions and thus can affect their + timing and thereby cause a leakage. endif config ARCH_HAS_ADD_PAGES diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index fecc4fe1d68a..9c67f8b4c919 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h @@ -81,4 +81,16 @@ int intel_microcode_sanity_check(void *mc, bool print_err, int hdr_type); extern struct cpumask cpus_stop_mask; +union zen_patch_rev { + struct { + __u32 rev : 8, + stepping : 4, + model : 4, + __reserved : 4, + ext_model : 4, + ext_fam : 8; + }; + __u32 ucode_rev; +}; + #endif /* _ASM_X86_CPU_H */ diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h index 8a2482651a6f..311cc58f2958 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -449,6 +449,7 @@ /* AMD-defined Extended Feature 2 EAX, CPUID level 0x80000021 (EAX), word 20 */ #define X86_FEATURE_NO_NESTED_DATA_BP (20*32+ 0) /* "" No Nested Data Breakpoints */ #define X86_FEATURE_LFENCE_RDTSC (20*32+ 2) /* "" LFENCE always serializing / synchronizes RDTSC */ +#define X86_FEATURE_VERW_CLEAR (20*32+ 5) /* "" The memory form of VERW mitigates TSA */ #define X86_FEATURE_NULL_SEL_CLR_BASE (20*32+ 6) /* "" Null Selector Clears Base */ #define X86_FEATURE_AUTOIBRS (20*32+ 8) /* "" Automatic IBRS */ #define X86_FEATURE_NO_SMM_CTL_MSR (20*32+ 9) /* "" SMM_CTL MSR is not present */ @@ -470,6 +471,10 @@ #define X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT (21*32+ 4) /* "" Clear branch history at vmexit using SW loop */ #define X86_FEATURE_INDIRECT_THUNK_ITS (21*32 + 5) /* "" Use thunk for indirect branches in lower half of cacheline */ +#define X86_FEATURE_TSA_SQ_NO (21*32+11) /* "" AMD CPU not vulnerable to TSA-SQ */ +#define X86_FEATURE_TSA_L1_NO (21*32+12) /* "" AMD CPU not vulnerable to TSA-L1 */ +#define X86_FEATURE_CLEAR_CPU_BUF_VM (21*32+13) /* "" Clear CPU buffers using VERW before VMRUN */ + /* * BUG word(s) */ @@ -521,4 +526,5 @@ #define X86_BUG_IBPB_NO_RET X86_BUG(1*32 + 4) /* "ibpb_no_ret" IBPB omits return target predictions */ #define X86_BUG_ITS X86_BUG(1*32 + 5) /* CPU is affected by Indirect Target Selection */ #define X86_BUG_ITS_NATIVE_ONLY X86_BUG(1*32 + 6) /* CPU is affected by ITS, VMX is not affected */ +#define X86_BUG_TSA X86_BUG(1*32+ 9) /* "tsa" CPU is affected by Transient Scheduler Attacks */ #endif /* _ASM_X86_CPUFEATURES_H */ diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h index 748c02179a87..e45d0dac7bb7 100644 --- a/arch/x86/include/asm/mwait.h +++ b/arch/x86/include/asm/mwait.h @@ -80,7 +80,7 @@ static __always_inline void __mwait(unsigned long eax, unsigned long ecx) static __always_inline void __mwaitx(unsigned long eax, unsigned long ebx, unsigned long ecx) { - /* No MDS buffer clear as this is AMD/HYGON only */ + /* No need for TSA buffer clearing on AMD */ /* "mwaitx %eax, %ebx, %ecx;" */ asm volatile(".byte 0x0f, 0x01, 0xfb;" diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h index c9444ede6761..04f5a41c3a04 100644 --- a/arch/x86/include/asm/nospec-branch.h +++ b/arch/x86/include/asm/nospec-branch.h @@ -330,19 +330,25 @@ * CFLAGS.ZF. * Note: Only the memory operand variant of VERW clears the CPU buffers. */ -.macro CLEAR_CPU_BUFFERS +.macro __CLEAR_CPU_BUFFERS feature #ifdef CONFIG_X86_64 - ALTERNATIVE "", "verw x86_verw_sel(%rip)", X86_FEATURE_CLEAR_CPU_BUF + ALTERNATIVE "", "verw x86_verw_sel(%rip)", \feature #else /* * In 32bit mode, the memory operand must be a %cs reference. The data * segments may not be usable (vm86 mode), and the stack segment may not * be flat (ESPFIX32). */ - ALTERNATIVE "", "verw %cs:x86_verw_sel", X86_FEATURE_CLEAR_CPU_BUF + ALTERNATIVE "", "verw %cs:x86_verw_sel", \feature #endif .endm +#define CLEAR_CPU_BUFFERS \ + __CLEAR_CPU_BUFFERS X86_FEATURE_CLEAR_CPU_BUF + +#define VM_CLEAR_CPU_BUFFERS \ + __CLEAR_CPU_BUFFERS X86_FEATURE_CLEAR_CPU_BUF_VM + #ifdef CONFIG_X86_64 .macro CLEAR_BRANCH_HISTORY ALTERNATIVE "", "call clear_bhb_loop", X86_FEATURE_CLEAR_BHB_LOOP @@ -627,7 +633,7 @@ static __always_inline void x86_clear_cpu_buffers(void) /** * x86_idle_clear_cpu_buffers - Buffer clearing support in idle for the MDS - * vulnerability + * and TSA vulnerabilities. * * Clear CPU buffers if the corresponding static key is enabled */ diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 498f27537772..1180689a2390 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -539,6 +539,63 @@ static void early_init_amd_mc(struct cpuinfo_x86 *c) #endif } +static bool amd_check_tsa_microcode(void) +{ + struct cpuinfo_x86 *c = &boot_cpu_data; + union zen_patch_rev p; + u32 min_rev = 0; + + p.ext_fam = c->x86 - 0xf; + p.model = c->x86_model; + p.stepping = c->x86_stepping; + + if (cpu_has(c, X86_FEATURE_ZEN3) || + cpu_has(c, X86_FEATURE_ZEN4)) { + switch (p.ucode_rev >> 8) { + case 0xa0011: min_rev = 0x0a0011d7; break; + case 0xa0012: min_rev = 0x0a00123b; break; + case 0xa0082: min_rev = 0x0a00820d; break; + case 0xa1011: min_rev = 0x0a10114c; break; + case 0xa1012: min_rev = 0x0a10124c; break; + case 0xa1081: min_rev = 0x0a108109; break; + case 0xa2010: min_rev = 0x0a20102e; break; + case 0xa2012: min_rev = 0x0a201211; break; + case 0xa4041: min_rev = 0x0a404108; break; + case 0xa5000: min_rev = 0x0a500012; break; + case 0xa6012: min_rev = 0x0a60120a; break; + case 0xa7041: min_rev = 0x0a704108; break; + case 0xa7052: min_rev = 0x0a705208; break; + case 0xa7080: min_rev = 0x0a708008; break; + case 0xa70c0: min_rev = 0x0a70c008; break; + case 0xaa002: min_rev = 0x0aa00216; break; + default: + pr_debug("%s: ucode_rev: 0x%x, current revision: 0x%x\n", + __func__, p.ucode_rev, c->microcode); + return false; + } + } + + if (!min_rev) + return false; + + return c->microcode >= min_rev; +} + +static void tsa_init(struct cpuinfo_x86 *c) +{ + if (cpu_has(c, X86_FEATURE_HYPERVISOR)) + return; + + if (cpu_has(c, X86_FEATURE_ZEN3) || + cpu_has(c, X86_FEATURE_ZEN4)) { + if (amd_check_tsa_microcode()) + setup_force_cpu_cap(X86_FEATURE_VERW_CLEAR); + } else { + setup_force_cpu_cap(X86_FEATURE_TSA_SQ_NO); + setup_force_cpu_cap(X86_FEATURE_TSA_L1_NO); + } +} + static void bsp_init_amd(struct cpuinfo_x86 *c) { if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) { @@ -645,6 +702,9 @@ static void bsp_init_amd(struct cpuinfo_x86 *c) break; } + + tsa_init(c); + return; warn: diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 35df0e86326a..c4d5ac99c6af 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -50,6 +50,7 @@ static void __init l1d_flush_select_mitigation(void); static void __init srso_select_mitigation(void); static void __init gds_select_mitigation(void); static void __init its_select_mitigation(void); +static void __init tsa_select_mitigation(void); /* The base value of the SPEC_CTRL MSR without task-specific bits set */ u64 x86_spec_ctrl_base; @@ -185,6 +186,7 @@ void __init cpu_select_mitigations(void) srso_select_mitigation(); gds_select_mitigation(); its_select_mitigation(); + tsa_select_mitigation(); } /* @@ -2093,6 +2095,94 @@ static void update_mds_branch_idle(void) #define TAA_MSG_SMT "TAA CPU bug present and SMT on, data leak possible. See https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/tsx_async_abort.html for more details.\n" #define MMIO_MSG_SMT "MMIO Stale Data CPU bug present and SMT on, data leak possible. See https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/processor_mmio_stale_data.html for more details.\n" +#undef pr_fmt +#define pr_fmt(fmt) "Transient Scheduler Attacks: " fmt + +enum tsa_mitigations { + TSA_MITIGATION_NONE, + TSA_MITIGATION_UCODE_NEEDED, + TSA_MITIGATION_USER_KERNEL, + TSA_MITIGATION_VM, + TSA_MITIGATION_FULL, +}; + +static const char * const tsa_strings[] = { + [TSA_MITIGATION_NONE] = "Vulnerable", + [TSA_MITIGATION_UCODE_NEEDED] = "Vulnerable: Clear CPU buffers attempted, no microcode", + [TSA_MITIGATION_USER_KERNEL] = "Mitigation: Clear CPU buffers: user/kernel boundary", + [TSA_MITIGATION_VM] = "Mitigation: Clear CPU buffers: VM", + [TSA_MITIGATION_FULL] = "Mitigation: Clear CPU buffers", +}; + +static enum tsa_mitigations tsa_mitigation __ro_after_init = + IS_ENABLED(CONFIG_MITIGATION_TSA) ? TSA_MITIGATION_FULL : TSA_MITIGATION_NONE; + +static int __init tsa_parse_cmdline(char *str) +{ + if (!str) + return -EINVAL; + + if (!strcmp(str, "off")) + tsa_mitigation = TSA_MITIGATION_NONE; + else if (!strcmp(str, "on")) + tsa_mitigation = TSA_MITIGATION_FULL; + else if (!strcmp(str, "user")) + tsa_mitigation = TSA_MITIGATION_USER_KERNEL; + else if (!strcmp(str, "vm")) + tsa_mitigation = TSA_MITIGATION_VM; + else + pr_err("Ignoring unknown tsa=%s option.\n", str); + + return 0; +} +early_param("tsa", tsa_parse_cmdline); + +static void __init tsa_select_mitigation(void) +{ + if (tsa_mitigation == TSA_MITIGATION_NONE) + return; + + if (cpu_mitigations_off() || !boot_cpu_has_bug(X86_BUG_TSA)) { + tsa_mitigation = TSA_MITIGATION_NONE; + return; + } + + if (!boot_cpu_has(X86_FEATURE_VERW_CLEAR)) + tsa_mitigation = TSA_MITIGATION_UCODE_NEEDED; + + switch (tsa_mitigation) { + case TSA_MITIGATION_USER_KERNEL: + setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF); + break; + + case TSA_MITIGATION_VM: + setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF_VM); + break; + + case TSA_MITIGATION_UCODE_NEEDED: + if (!boot_cpu_has(X86_FEATURE_HYPERVISOR)) + goto out; + + pr_notice("Forcing mitigation on in a VM\n"); + + /* + * On the off-chance that microcode has been updated + * on the host, enable the mitigation in the guest just + * in case. + */ + fallthrough; + case TSA_MITIGATION_FULL: + setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF); + setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF_VM); + break; + default: + break; + } + +out: + pr_info("%s\n", tsa_strings[tsa_mitigation]); +} + void cpu_bugs_smt_update(void) { mutex_lock(&spec_ctrl_mutex); @@ -2146,6 +2236,24 @@ void cpu_bugs_smt_update(void) break; } + switch (tsa_mitigation) { + case TSA_MITIGATION_USER_KERNEL: + case TSA_MITIGATION_VM: + case TSA_MITIGATION_FULL: + case TSA_MITIGATION_UCODE_NEEDED: + /* + * TSA-SQ can potentially lead to info leakage between + * SMT threads. + */ + if (sched_smt_active()) + static_branch_enable(&cpu_buf_idle_clear); + else + static_branch_disable(&cpu_buf_idle_clear); + break; + case TSA_MITIGATION_NONE: + break; + } + mutex_unlock(&spec_ctrl_mutex); } @@ -3075,6 +3183,11 @@ static ssize_t gds_show_state(char *buf) return sysfs_emit(buf, "%s\n", gds_strings[gds_mitigation]); } +static ssize_t tsa_show_state(char *buf) +{ + return sysfs_emit(buf, "%s\n", tsa_strings[tsa_mitigation]); +} + static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr, char *buf, unsigned int bug) { @@ -3136,6 +3249,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr case X86_BUG_ITS: return its_show_state(buf); + case X86_BUG_TSA: + return tsa_show_state(buf); + default: break; } @@ -3220,4 +3336,9 @@ ssize_t cpu_show_indirect_target_selection(struct device *dev, struct device_att { return cpu_show_common(dev, attr, buf, X86_BUG_ITS); } + +ssize_t cpu_show_tsa(struct device *dev, struct device_attribute *attr, char *buf) +{ + return cpu_show_common(dev, attr, buf, X86_BUG_TSA); +} #endif diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index cc1bbf70477b..f66c71bffa6d 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1277,6 +1277,8 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { #define ITS BIT(8) /* CPU is affected by Indirect Target Selection, but guest-host isolation is not affected */ #define ITS_NATIVE_ONLY BIT(9) +/* CPU is affected by Transient Scheduler Attacks */ +#define TSA BIT(10) static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { VULNBL_INTEL_STEPPINGS(IVYBRIDGE, X86_STEPPING_ANY, SRBDS), @@ -1324,7 +1326,7 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { VULNBL_AMD(0x16, RETBLEED), VULNBL_AMD(0x17, RETBLEED | SMT_RSB | SRSO), VULNBL_HYGON(0x18, RETBLEED | SMT_RSB | SRSO), - VULNBL_AMD(0x19, SRSO), + VULNBL_AMD(0x19, SRSO | TSA), {} }; @@ -1529,6 +1531,16 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) setup_force_cpu_bug(X86_BUG_ITS_NATIVE_ONLY); } + if (c->x86_vendor == X86_VENDOR_AMD) { + if (!cpu_has(c, X86_FEATURE_TSA_SQ_NO) || + !cpu_has(c, X86_FEATURE_TSA_L1_NO)) { + if (cpu_matches(cpu_vuln_blacklist, TSA) || + /* Enable bug on Zen guests to allow for live migration. */ + (cpu_has(c, X86_FEATURE_HYPERVISOR) && cpu_has(c, X86_FEATURE_ZEN))) + setup_force_cpu_bug(X86_BUG_TSA); + } + } + if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) return; diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index 9b0570f769eb..7444fe0e3d08 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -96,18 +96,6 @@ static struct equiv_cpu_table { struct equiv_cpu_entry *entry; } equiv_table; -union zen_patch_rev { - struct { - __u32 rev : 8, - stepping : 4, - model : 4, - __reserved : 4, - ext_model : 4, - ext_fam : 8; - }; - __u32 ucode_rev; -}; - union cpuid_1_eax { struct { __u32 stepping : 4, diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c index af5aa2c754c2..7a42e699f6e3 100644 --- a/arch/x86/kernel/cpu/scattered.c +++ b/arch/x86/kernel/cpu/scattered.c @@ -48,6 +48,8 @@ static const struct cpuid_bit cpuid_bits[] = { { X86_FEATURE_MBA, CPUID_EBX, 6, 0x80000008, 0 }, { X86_FEATURE_SMBA, CPUID_EBX, 2, 0x80000020, 0 }, { X86_FEATURE_BMEC, CPUID_EBX, 3, 0x80000020, 0 }, + { X86_FEATURE_TSA_SQ_NO, CPUID_ECX, 1, 0x80000021, 0 }, + { X86_FEATURE_TSA_L1_NO, CPUID_ECX, 2, 0x80000021, 0 }, { X86_FEATURE_PERFMON_V2, CPUID_EAX, 0, 0x80000022, 0 }, { X86_FEATURE_AMD_LBR_V2, CPUID_EAX, 1, 0x80000022, 0 }, { X86_FEATURE_AMD_LBR_PMC_FREEZE, CPUID_EAX, 2, 0x80000022, 0 }, diff --git a/arch/x86/kvm/svm/vmenter.S b/arch/x86/kvm/svm/vmenter.S index ef2ebabb059c..56fe34d9397f 100644 --- a/arch/x86/kvm/svm/vmenter.S +++ b/arch/x86/kvm/svm/vmenter.S @@ -167,6 +167,9 @@ SYM_FUNC_START(__svm_vcpu_run) #endif mov VCPU_RDI(%_ASM_DI), %_ASM_DI + /* Clobbers EFLAGS.ZF */ + VM_CLEAR_CPU_BUFFERS + /* Enter guest mode */ sti @@ -334,6 +337,9 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run) mov SVM_current_vmcb(%_ASM_DI), %_ASM_AX mov KVM_VMCB_pa(%_ASM_AX), %_ASM_AX + /* Clobbers EFLAGS.ZF */ + VM_CLEAR_CPU_BUFFERS + /* Enter guest mode */ sti diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index a5cfc1bfad51..a3aea3c1431a 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -567,6 +567,7 @@ CPU_SHOW_VULN_FALLBACK(spec_rstack_overflow); CPU_SHOW_VULN_FALLBACK(gds); CPU_SHOW_VULN_FALLBACK(reg_file_data_sampling); CPU_SHOW_VULN_FALLBACK(indirect_target_selection); +CPU_SHOW_VULN_FALLBACK(tsa); static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); @@ -583,6 +584,7 @@ static DEVICE_ATTR(spec_rstack_overflow, 0444, cpu_show_spec_rstack_overflow, NU static DEVICE_ATTR(gather_data_sampling, 0444, cpu_show_gds, NULL); static DEVICE_ATTR(reg_file_data_sampling, 0444, cpu_show_reg_file_data_sampling, NULL); static DEVICE_ATTR(indirect_target_selection, 0444, cpu_show_indirect_target_selection, NULL); +static DEVICE_ATTR(tsa, 0444, cpu_show_tsa, NULL); static struct attribute *cpu_root_vulnerabilities_attrs[] = { &dev_attr_meltdown.attr, @@ -600,6 +602,7 @@ static struct attribute *cpu_root_vulnerabilities_attrs[] = { &dev_attr_gather_data_sampling.attr, &dev_attr_reg_file_data_sampling.attr, &dev_attr_indirect_target_selection.attr, + &dev_attr_tsa.attr, NULL }; diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 20db7fc0651f..6b4f9f169688 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -79,6 +79,7 @@ extern ssize_t cpu_show_reg_file_data_sampling(struct device *dev, struct device_attribute *attr, char *buf); extern ssize_t cpu_show_indirect_target_selection(struct device *dev, struct device_attribute *attr, char *buf); +extern ssize_t cpu_show_tsa(struct device *dev, struct device_attribute *attr, char *buf); extern __printf(4, 5) struct device *cpu_device_create(struct device *parent, void *drvdata, From 276499bb6944c5300ee79439302529c3b28564dd Mon Sep 17 00:00:00 2001 From: "Borislav Petkov (AMD)" Date: Wed, 11 Sep 2024 11:00:50 +0200 Subject: [PATCH 959/971] KVM: SVM: Advertise TSA CPUID bits to guests Commit 31272abd5974b38ba312e9cf2ec2f09f9dd7dcba upstream. Synthesize the TSA CPUID feature bits for guests. Set TSA_{SQ,L1}_NO on unaffected machines. Signed-off-by: Borislav Petkov (AMD) Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/cpuid.c | 8 +++++++- arch/x86/kvm/reverse_cpuid.h | 8 ++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index a6cffeff75d4..288db3516772 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -780,6 +780,7 @@ void kvm_set_cpu_caps(void) kvm_cpu_cap_mask(CPUID_8000_0021_EAX, F(NO_NESTED_DATA_BP) | F(LFENCE_RDTSC) | 0 /* SmmPgCfgLock */ | + F(VERW_CLEAR) | F(NULL_SEL_CLR_BASE) | F(AUTOIBRS) | 0 /* PrefetchCtlMsr */ ); @@ -790,6 +791,10 @@ void kvm_set_cpu_caps(void) F(PERFMON_V2) ); + kvm_cpu_cap_init_kvm_defined(CPUID_8000_0021_ECX, + F(TSA_SQ_NO) | F(TSA_L1_NO) + ); + /* * Synthesize "LFENCE is serializing" into the AMD-defined entry in * KVM's supported CPUID if the feature is reported as supported by the @@ -1296,8 +1301,9 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) entry->eax = entry->ebx = entry->ecx = entry->edx = 0; break; case 0x80000021: - entry->ebx = entry->ecx = entry->edx = 0; + entry->ebx = entry->edx = 0; cpuid_entry_override(entry, CPUID_8000_0021_EAX); + cpuid_entry_override(entry, CPUID_8000_0021_ECX); break; /* AMD Extended Performance Monitoring and Debug */ case 0x80000022: { diff --git a/arch/x86/kvm/reverse_cpuid.h b/arch/x86/kvm/reverse_cpuid.h index 2f4e155080ba..be23712354bd 100644 --- a/arch/x86/kvm/reverse_cpuid.h +++ b/arch/x86/kvm/reverse_cpuid.h @@ -17,6 +17,7 @@ enum kvm_only_cpuid_leafs { CPUID_8000_0007_EDX, CPUID_8000_0022_EAX, CPUID_7_2_EDX, + CPUID_8000_0021_ECX, NR_KVM_CPU_CAPS, NKVMCAPINTS = NR_KVM_CPU_CAPS - NCAPINTS, @@ -61,6 +62,10 @@ enum kvm_only_cpuid_leafs { /* CPUID level 0x80000022 (EAX) */ #define KVM_X86_FEATURE_PERFMON_V2 KVM_X86_FEATURE(CPUID_8000_0022_EAX, 0) +/* CPUID level 0x80000021 (ECX) */ +#define KVM_X86_FEATURE_TSA_SQ_NO KVM_X86_FEATURE(CPUID_8000_0021_ECX, 1) +#define KVM_X86_FEATURE_TSA_L1_NO KVM_X86_FEATURE(CPUID_8000_0021_ECX, 2) + struct cpuid_reg { u32 function; u32 index; @@ -90,6 +95,7 @@ static const struct cpuid_reg reverse_cpuid[] = { [CPUID_8000_0021_EAX] = {0x80000021, 0, CPUID_EAX}, [CPUID_8000_0022_EAX] = {0x80000022, 0, CPUID_EAX}, [CPUID_7_2_EDX] = { 7, 2, CPUID_EDX}, + [CPUID_8000_0021_ECX] = {0x80000021, 0, CPUID_ECX}, }; /* @@ -129,6 +135,8 @@ static __always_inline u32 __feature_translate(int x86_feature) KVM_X86_TRANSLATE_FEATURE(PERFMON_V2); KVM_X86_TRANSLATE_FEATURE(RRSBA_CTRL); KVM_X86_TRANSLATE_FEATURE(BHI_CTRL); + KVM_X86_TRANSLATE_FEATURE(TSA_SQ_NO); + KVM_X86_TRANSLATE_FEATURE(TSA_L1_NO); default: return x86_feature; } From 6fb766d53f613e23c60fb91b6fdbc10d522cccc6 Mon Sep 17 00:00:00 2001 From: "Borislav Petkov (AMD)" Date: Thu, 27 Mar 2025 12:23:55 +0100 Subject: [PATCH 960/971] x86/microcode/AMD: Add TSA microcode SHAs Commit 2329f250e04d3b8e78b36a68b9880ca7750a07ef upstream. Signed-off-by: Borislav Petkov (AMD) Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/cpu/microcode/amd_shas.c | 112 +++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/arch/x86/kernel/cpu/microcode/amd_shas.c b/arch/x86/kernel/cpu/microcode/amd_shas.c index 2a1655b1fdd8..1fd349cfc802 100644 --- a/arch/x86/kernel/cpu/microcode/amd_shas.c +++ b/arch/x86/kernel/cpu/microcode/amd_shas.c @@ -231,6 +231,13 @@ static const struct patch_digest phashes[] = { 0x0d,0x5b,0x65,0x34,0x69,0xb2,0x62,0x21, } }, + { 0xa0011d7, { + 0x35,0x07,0xcd,0x40,0x94,0xbc,0x81,0x6b, + 0xfc,0x61,0x56,0x1a,0xe2,0xdb,0x96,0x12, + 0x1c,0x1c,0x31,0xb1,0x02,0x6f,0xe5,0xd2, + 0xfe,0x1b,0x04,0x03,0x2c,0x8f,0x4c,0x36, + } + }, { 0xa001223, { 0xfb,0x32,0x5f,0xc6,0x83,0x4f,0x8c,0xb8, 0xa4,0x05,0xf9,0x71,0x53,0x01,0x16,0xc4, @@ -294,6 +301,13 @@ static const struct patch_digest phashes[] = { 0xc0,0xcd,0x33,0xf2,0x8d,0xf9,0xef,0x59, } }, + { 0xa00123b, { + 0xef,0xa1,0x1e,0x71,0xf1,0xc3,0x2c,0xe2, + 0xc3,0xef,0x69,0x41,0x7a,0x54,0xca,0xc3, + 0x8f,0x62,0x84,0xee,0xc2,0x39,0xd9,0x28, + 0x95,0xa7,0x12,0x49,0x1e,0x30,0x71,0x72, + } + }, { 0xa00820c, { 0xa8,0x0c,0x81,0xc0,0xa6,0x00,0xe7,0xf3, 0x5f,0x65,0xd3,0xb9,0x6f,0xea,0x93,0x63, @@ -301,6 +315,13 @@ static const struct patch_digest phashes[] = { 0xe1,0x3b,0x8d,0xb2,0xf8,0x22,0x03,0xe2, } }, + { 0xa00820d, { + 0xf9,0x2a,0xc0,0xf4,0x9e,0xa4,0x87,0xa4, + 0x7d,0x87,0x00,0xfd,0xab,0xda,0x19,0xca, + 0x26,0x51,0x32,0xc1,0x57,0x91,0xdf,0xc1, + 0x05,0xeb,0x01,0x7c,0x5a,0x95,0x21,0xb7, + } + }, { 0xa10113e, { 0x05,0x3c,0x66,0xd7,0xa9,0x5a,0x33,0x10, 0x1b,0xf8,0x9c,0x8f,0xed,0xfc,0xa7,0xa0, @@ -322,6 +343,13 @@ static const struct patch_digest phashes[] = { 0xf1,0x5e,0xb0,0xde,0xb4,0x98,0xae,0xc4, } }, + { 0xa10114c, { + 0x9e,0xb6,0xa2,0xd9,0x87,0x38,0xc5,0x64, + 0xd8,0x88,0xfa,0x78,0x98,0xf9,0x6f,0x74, + 0x39,0x90,0x1b,0xa5,0xcf,0x5e,0xb4,0x2a, + 0x02,0xff,0xd4,0x8c,0x71,0x8b,0xe2,0xc0, + } + }, { 0xa10123e, { 0x03,0xb9,0x2c,0x76,0x48,0x93,0xc9,0x18, 0xfb,0x56,0xfd,0xf7,0xe2,0x1d,0xca,0x4d, @@ -343,6 +371,13 @@ static const struct patch_digest phashes[] = { 0x1b,0x7d,0x64,0x9d,0x4b,0x53,0x13,0x75, } }, + { 0xa10124c, { + 0x29,0xea,0xf1,0x2c,0xb2,0xe4,0xef,0x90, + 0xa4,0xcd,0x1d,0x86,0x97,0x17,0x61,0x46, + 0xfc,0x22,0xcb,0x57,0x75,0x19,0xc8,0xcc, + 0x0c,0xf5,0xbc,0xac,0x81,0x9d,0x9a,0xd2, + } + }, { 0xa108108, { 0xed,0xc2,0xec,0xa1,0x15,0xc6,0x65,0xe9, 0xd0,0xef,0x39,0xaa,0x7f,0x55,0x06,0xc6, @@ -350,6 +385,13 @@ static const struct patch_digest phashes[] = { 0x28,0x1e,0x9c,0x59,0x69,0x99,0x4d,0x16, } }, + { 0xa108109, { + 0x85,0xb4,0xbd,0x7c,0x49,0xa7,0xbd,0xfa, + 0x49,0x36,0x80,0x81,0xc5,0xb7,0x39,0x1b, + 0x9a,0xaa,0x50,0xde,0x9b,0xe9,0x32,0x35, + 0x42,0x7e,0x51,0x4f,0x52,0x2c,0x28,0x59, + } + }, { 0xa20102d, { 0xf9,0x6e,0xf2,0x32,0xd3,0x0f,0x5f,0x11, 0x59,0xa1,0xfe,0xcc,0xcd,0x9b,0x42,0x89, @@ -357,6 +399,13 @@ static const struct patch_digest phashes[] = { 0x8c,0xe9,0x19,0x3e,0xcc,0x3f,0x7b,0xb4, } }, + { 0xa20102e, { + 0xbe,0x1f,0x32,0x04,0x0d,0x3c,0x9c,0xdd, + 0xe1,0xa4,0xbf,0x76,0x3a,0xec,0xc2,0xf6, + 0x11,0x00,0xa7,0xaf,0x0f,0xe5,0x02,0xc5, + 0x54,0x3a,0x1f,0x8c,0x16,0xb5,0xff,0xbe, + } + }, { 0xa201210, { 0xe8,0x6d,0x51,0x6a,0x8e,0x72,0xf3,0xfe, 0x6e,0x16,0xbc,0x62,0x59,0x40,0x17,0xe9, @@ -364,6 +413,13 @@ static const struct patch_digest phashes[] = { 0xf7,0x55,0xf0,0x13,0xbb,0x22,0xf6,0x41, } }, + { 0xa201211, { + 0x69,0xa1,0x17,0xec,0xd0,0xf6,0x6c,0x95, + 0xe2,0x1e,0xc5,0x59,0x1a,0x52,0x0a,0x27, + 0xc4,0xed,0xd5,0x59,0x1f,0xbf,0x00,0xff, + 0x08,0x88,0xb5,0xe1,0x12,0xb6,0xcc,0x27, + } + }, { 0xa404107, { 0xbb,0x04,0x4e,0x47,0xdd,0x5e,0x26,0x45, 0x1a,0xc9,0x56,0x24,0xa4,0x4c,0x82,0xb0, @@ -371,6 +427,13 @@ static const struct patch_digest phashes[] = { 0x13,0xbc,0xc5,0x25,0xe4,0xc5,0xc3,0x99, } }, + { 0xa404108, { + 0x69,0x67,0x43,0x06,0xf8,0x0c,0x62,0xdc, + 0xa4,0x21,0x30,0x4f,0x0f,0x21,0x2c,0xcb, + 0xcc,0x37,0xf1,0x1c,0xc3,0xf8,0x2f,0x19, + 0xdf,0x53,0x53,0x46,0xb1,0x15,0xea,0x00, + } + }, { 0xa500011, { 0x23,0x3d,0x70,0x7d,0x03,0xc3,0xc4,0xf4, 0x2b,0x82,0xc6,0x05,0xda,0x80,0x0a,0xf1, @@ -378,6 +441,13 @@ static const struct patch_digest phashes[] = { 0x11,0x5e,0x96,0x7e,0x71,0xe9,0xfc,0x74, } }, + { 0xa500012, { + 0xeb,0x74,0x0d,0x47,0xa1,0x8e,0x09,0xe4, + 0x93,0x4c,0xad,0x03,0x32,0x4c,0x38,0x16, + 0x10,0x39,0xdd,0x06,0xaa,0xce,0xd6,0x0f, + 0x62,0x83,0x9d,0x8e,0x64,0x55,0xbe,0x63, + } + }, { 0xa601209, { 0x66,0x48,0xd4,0x09,0x05,0xcb,0x29,0x32, 0x66,0xb7,0x9a,0x76,0xcd,0x11,0xf3,0x30, @@ -385,6 +455,13 @@ static const struct patch_digest phashes[] = { 0xe8,0x73,0xe2,0xd6,0xdb,0xd2,0x77,0x1d, } }, + { 0xa60120a, { + 0x0c,0x8b,0x3d,0xfd,0x52,0x52,0x85,0x7d, + 0x20,0x3a,0xe1,0x7e,0xa4,0x21,0x3b,0x7b, + 0x17,0x86,0xae,0xac,0x13,0xb8,0x63,0x9d, + 0x06,0x01,0xd0,0xa0,0x51,0x9a,0x91,0x2c, + } + }, { 0xa704107, { 0xf3,0xc6,0x58,0x26,0xee,0xac,0x3f,0xd6, 0xce,0xa1,0x72,0x47,0x3b,0xba,0x2b,0x93, @@ -392,6 +469,13 @@ static const struct patch_digest phashes[] = { 0x64,0x39,0x71,0x8c,0xce,0xe7,0x41,0x39, } }, + { 0xa704108, { + 0xd7,0x55,0x15,0x2b,0xfe,0xc4,0xbc,0x93, + 0xec,0x91,0xa0,0xae,0x45,0xb7,0xc3,0x98, + 0x4e,0xff,0x61,0x77,0x88,0xc2,0x70,0x49, + 0xe0,0x3a,0x1d,0x84,0x38,0x52,0xbf,0x5a, + } + }, { 0xa705206, { 0x8d,0xc0,0x76,0xbd,0x58,0x9f,0x8f,0xa4, 0x12,0x9d,0x21,0xfb,0x48,0x21,0xbc,0xe7, @@ -399,6 +483,13 @@ static const struct patch_digest phashes[] = { 0x03,0x35,0xe9,0xbe,0xfb,0x06,0xdf,0xfc, } }, + { 0xa705208, { + 0x30,0x1d,0x55,0x24,0xbc,0x6b,0x5a,0x19, + 0x0c,0x7d,0x1d,0x74,0xaa,0xd1,0xeb,0xd2, + 0x16,0x62,0xf7,0x5b,0xe1,0x1f,0x18,0x11, + 0x5c,0xf0,0x94,0x90,0x26,0xec,0x69,0xff, + } + }, { 0xa708007, { 0x6b,0x76,0xcc,0x78,0xc5,0x8a,0xa3,0xe3, 0x32,0x2d,0x79,0xe4,0xc3,0x80,0xdb,0xb2, @@ -406,6 +497,13 @@ static const struct patch_digest phashes[] = { 0xdf,0x92,0x73,0x84,0x87,0x3c,0x73,0x93, } }, + { 0xa708008, { + 0x08,0x6e,0xf0,0x22,0x4b,0x8e,0xc4,0x46, + 0x58,0x34,0xe6,0x47,0xa2,0x28,0xfd,0xab, + 0x22,0x3d,0xdd,0xd8,0x52,0x9e,0x1d,0x16, + 0xfa,0x01,0x68,0x14,0x79,0x3e,0xe8,0x6b, + } + }, { 0xa70c005, { 0x88,0x5d,0xfb,0x79,0x64,0xd8,0x46,0x3b, 0x4a,0x83,0x8e,0x77,0x7e,0xcf,0xb3,0x0f, @@ -413,6 +511,13 @@ static const struct patch_digest phashes[] = { 0xee,0x49,0xac,0xe1,0x8b,0x13,0xc5,0x13, } }, + { 0xa70c008, { + 0x0f,0xdb,0x37,0xa1,0x10,0xaf,0xd4,0x21, + 0x94,0x0d,0xa4,0xa2,0xe9,0x86,0x6c,0x0e, + 0x85,0x7c,0x36,0x30,0xa3,0x3a,0x78,0x66, + 0x18,0x10,0x60,0x0d,0x78,0x3d,0x44,0xd0, + } + }, { 0xaa00116, { 0xe8,0x4c,0x2c,0x88,0xa1,0xac,0x24,0x63, 0x65,0xe5,0xaa,0x2d,0x16,0xa9,0xc3,0xf5, @@ -441,4 +546,11 @@ static const struct patch_digest phashes[] = { 0x68,0x2f,0x46,0xee,0xfe,0xc6,0x6d,0xef, } }, + { 0xaa00216, { + 0x79,0xfb,0x5b,0x9f,0xb6,0xe6,0xa8,0xf5, + 0x4e,0x7c,0x4f,0x8e,0x1d,0xad,0xd0,0x08, + 0xc2,0x43,0x7c,0x8b,0xe6,0xdb,0xd0,0xd2, + 0xe8,0x39,0x26,0xc1,0xe5,0x5a,0x48,0xf1, + } + }, }; From 8c1944905855c2ea56dbd21915dce6b802af49be Mon Sep 17 00:00:00 2001 From: "Borislav Petkov (AMD)" Date: Mon, 14 Apr 2025 15:33:19 +0200 Subject: [PATCH 961/971] x86/process: Move the buffer clearing before MONITOR Commit 8e786a85c0a3c0fffae6244733fb576eeabd9dec upstream. Move the VERW clearing before the MONITOR so that VERW doesn't disarm it and the machine never enters C1. Original idea by Kim Phillips . Suggested-by: Andrew Cooper Signed-off-by: Borislav Petkov (AMD) Signed-off-by: Greg Kroah-Hartman --- arch/x86/include/asm/mwait.h | 25 +++++++++++++++---------- arch/x86/kernel/process.c | 16 ++++++++++++---- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h index e45d0dac7bb7..ae7a83e3f743 100644 --- a/arch/x86/include/asm/mwait.h +++ b/arch/x86/include/asm/mwait.h @@ -44,8 +44,6 @@ static __always_inline void __monitorx(const void *eax, unsigned long ecx, static __always_inline void __mwait(unsigned long eax, unsigned long ecx) { - x86_idle_clear_cpu_buffers(); - /* "mwait %eax, %ecx;" */ asm volatile(".byte 0x0f, 0x01, 0xc9;" :: "a" (eax), "c" (ecx)); @@ -89,7 +87,6 @@ static __always_inline void __mwaitx(unsigned long eax, unsigned long ebx, static __always_inline void __sti_mwait(unsigned long eax, unsigned long ecx) { - x86_idle_clear_cpu_buffers(); /* "mwait %eax, %ecx;" */ asm volatile("sti; .byte 0x0f, 0x01, 0xc9;" @@ -108,21 +105,29 @@ static __always_inline void __sti_mwait(unsigned long eax, unsigned long ecx) */ static __always_inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) { + if (need_resched()) + return; + + x86_idle_clear_cpu_buffers(); + if (static_cpu_has_bug(X86_BUG_MONITOR) || !current_set_polling_and_test()) { const void *addr = ¤t_thread_info()->flags; alternative_input("", "clflush (%[addr])", X86_BUG_CLFLUSH_MONITOR, [addr] "a" (addr)); __monitor(addr, 0, 0); - if (!need_resched()) { - if (ecx & 1) { - __mwait(eax, ecx); - } else { - __sti_mwait(eax, ecx); - raw_local_irq_disable(); - } + if (need_resched()) + goto out; + + if (ecx & 1) { + __mwait(eax, ecx); + } else { + __sti_mwait(eax, ecx); + raw_local_irq_disable(); } } + +out: current_clr_polling(); } diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 33c235e9d0d3..e3c26cc45f70 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -928,16 +928,24 @@ static int prefer_mwait_c1_over_halt(const struct cpuinfo_x86 *c) */ static __cpuidle void mwait_idle(void) { + if (need_resched()) + return; + + x86_idle_clear_cpu_buffers(); + if (!current_set_polling_and_test()) { const void *addr = ¤t_thread_info()->flags; alternative_input("", "clflush (%[addr])", X86_BUG_CLFLUSH_MONITOR, [addr] "a" (addr)); __monitor(addr, 0, 0); - if (!need_resched()) { - __sti_mwait(0, 0); - raw_local_irq_disable(); - } + if (need_resched()) + goto out; + + __sti_mwait(0, 0); + raw_local_irq_disable(); } + +out: __current_clr_polling(); } From 897761d16564e899faecb9381b4818858705081f Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Thu, 14 Mar 2024 10:05:28 +0800 Subject: [PATCH 962/971] f2fs: fix to avoid use-after-free issue in f2fs_filemap_fault commit eb70d5a6c932d9d23f4bb3e7b83782c21ac4b064 upstream. syzbot reports a f2fs bug as below: BUG: KASAN: slab-use-after-free in f2fs_filemap_fault+0xd1/0x2c0 fs/f2fs/file.c:49 Read of size 8 at addr ffff88807bb22680 by task syz-executor184/5058 CPU: 0 PID: 5058 Comm: syz-executor184 Not tainted 6.7.0-syzkaller-09928-g052d534373b7 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/17/2023 Call Trace: __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x1e7/0x2d0 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:377 [inline] print_report+0x163/0x540 mm/kasan/report.c:488 kasan_report+0x142/0x170 mm/kasan/report.c:601 f2fs_filemap_fault+0xd1/0x2c0 fs/f2fs/file.c:49 __do_fault+0x131/0x450 mm/memory.c:4376 do_shared_fault mm/memory.c:4798 [inline] do_fault mm/memory.c:4872 [inline] do_pte_missing mm/memory.c:3745 [inline] handle_pte_fault mm/memory.c:5144 [inline] __handle_mm_fault+0x23b7/0x72b0 mm/memory.c:5285 handle_mm_fault+0x27e/0x770 mm/memory.c:5450 do_user_addr_fault arch/x86/mm/fault.c:1364 [inline] handle_page_fault arch/x86/mm/fault.c:1507 [inline] exc_page_fault+0x456/0x870 arch/x86/mm/fault.c:1563 asm_exc_page_fault+0x26/0x30 arch/x86/include/asm/idtentry.h:570 The root cause is: in f2fs_filemap_fault(), vmf->vma may be not alive after filemap_fault(), so it may cause use-after-free issue when accessing vmf->vma->vm_flags in trace_f2fs_filemap_fault(). So it needs to keep vm_flags in separated temporary variable for tracepoint use. Fixes: 87f3afd366f7 ("f2fs: add tracepoint for f2fs_vm_page_mkwrite()") Reported-and-tested-by: syzbot+763afad57075d3f862f2@syzkaller.appspotmail.com Closes: https://lore.kernel.org/lkml/000000000000e8222b060f00db3b@google.com Cc: Ed Tsai Suggested-by: Hillf Danton Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Greg Kroah-Hartman --- fs/f2fs/file.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index b73d40f98191..8f0cb7c7eede 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -50,6 +50,7 @@ static void f2fs_zero_post_eof_page(struct inode *inode, loff_t new_size) static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf) { struct inode *inode = file_inode(vmf->vma->vm_file); + vm_flags_t flags = vmf->vma->vm_flags; vm_fault_t ret; ret = filemap_fault(vmf); @@ -57,7 +58,7 @@ static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf) f2fs_update_iostat(F2FS_I_SB(inode), inode, APP_MAPPED_READ_IO, F2FS_BLKSIZE); - trace_f2fs_filemap_fault(inode, vmf->pgoff, vmf->vma->vm_flags, ret); + trace_f2fs_filemap_fault(inode, vmf->pgoff, flags, ret); return ret; } From 59a2de10b81ae4765d73142acde15106028b1571 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 10 Jul 2025 16:03:22 +0200 Subject: [PATCH 963/971] Linux 6.6.97 Link: https://lore.kernel.org/r/20250708162230.765762963@linuxfoundation.org Tested-by: Shuah Khan Link: https://lore.kernel.org/r/20250708183253.753837521@linuxfoundation.org Tested-by: Florian Fainelli Tested-by: Mark Brown Tested-by: Harshit Mogalapalli Tested-by: Ron Economos Tested-by: Jon Hunter Tested-by: Miguel Ojeda Tested-by: Linux Kernel Functional Testing Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 038fc8e0982b..9d5c08363637 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 6 PATCHLEVEL = 6 -SUBLEVEL = 96 +SUBLEVEL = 97 EXTRAVERSION = NAME = Pinguïn Aangedreven From 06215a57456593a19000afe99c61b4a2093bebbe Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 10 Jul 2025 18:47:22 +0000 Subject: [PATCH 964/971] ANDROID: GKI: add devm_regulator_bulk_get_enable to db845c symbol list In commit 9830ef1803a5 ("ASoC: codecs: wcd9335: Fix missing free of regulator supplies"), the wcd9335 driver adds a use of devm_regulator_bulk_get_enable. Add this symbol to the db845c symbol list as it now requires it to build properly. Fixes: 9830ef1803a5 ("ASoC: codecs: wcd9335: Fix missing free of regulator supplies") Change-Id: I371b04a656e8a61f64ca0fc770efe85b04f97d91 Signed-off-by: Greg Kroah-Hartman --- android/abi_gki_aarch64_db845c | 1 + 1 file changed, 1 insertion(+) diff --git a/android/abi_gki_aarch64_db845c b/android/abi_gki_aarch64_db845c index 8351fadf505c..13bb001d6bd2 100644 --- a/android/abi_gki_aarch64_db845c +++ b/android/abi_gki_aarch64_db845c @@ -153,6 +153,7 @@ __devm_regmap_init_i2c __devm_regmap_init_mmio_clk devm_regulator_bulk_get + devm_regulator_bulk_get_enable devm_regulator_get devm_regulator_get_optional devm_regulator_register From 170440ba3c39eedceb5659ec529b3addbfd362bf Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 13 Jul 2025 13:44:57 +0000 Subject: [PATCH 965/971] Revert "Bluetooth: hci_core: Fix use-after-free in vhci_flush()" This reverts commit bc0819a25e04cd68ef3568cfa51b63118fea39a7 which is commit 1d6123102e9fbedc8d25bf4731da6d513173e49e upstream. It breaks the Android kernel abi and can be brought back in the future in an abi-safe way if it is really needed. Bug: 161946584 Change-Id: Id182067e3ab35d3c51f9a114af331cea5589e0ac Signed-off-by: Greg Kroah-Hartman --- include/net/bluetooth/hci_core.h | 2 -- net/bluetooth/hci_core.c | 34 ++++---------------------------- 2 files changed, 4 insertions(+), 32 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 67c6e7c95e26..46f40cb391c6 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -350,7 +349,6 @@ struct amp_assoc { struct hci_dev { struct list_head list; - struct srcu_struct srcu; struct mutex lock; struct ida unset_handle_ida; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 98576baf9cf4..023ad47a385b 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -65,7 +65,7 @@ static DEFINE_IDA(hci_index_ida); /* Get HCI device by index. * Device is held on return. */ -static struct hci_dev *__hci_dev_get(int index, int *srcu_index) +struct hci_dev *hci_dev_get(int index) { struct hci_dev *hdev = NULL, *d; @@ -78,8 +78,6 @@ static struct hci_dev *__hci_dev_get(int index, int *srcu_index) list_for_each_entry(d, &hci_dev_list, list) { if (d->id == index) { hdev = hci_dev_hold(d); - if (srcu_index) - *srcu_index = srcu_read_lock(&d->srcu); break; } } @@ -87,22 +85,6 @@ static struct hci_dev *__hci_dev_get(int index, int *srcu_index) return hdev; } -struct hci_dev *hci_dev_get(int index) -{ - return __hci_dev_get(index, NULL); -} - -static struct hci_dev *hci_dev_get_srcu(int index, int *srcu_index) -{ - return __hci_dev_get(index, srcu_index); -} - -static void hci_dev_put_srcu(struct hci_dev *hdev, int srcu_index) -{ - srcu_read_unlock(&hdev->srcu, srcu_index); - hci_dev_put(hdev); -} - /* ---- Inquiry support ---- */ bool hci_discovery_active(struct hci_dev *hdev) @@ -608,9 +590,9 @@ static int hci_dev_do_reset(struct hci_dev *hdev) int hci_dev_reset(__u16 dev) { struct hci_dev *hdev; - int err, srcu_index; + int err; - hdev = hci_dev_get_srcu(dev, &srcu_index); + hdev = hci_dev_get(dev); if (!hdev) return -ENODEV; @@ -632,7 +614,7 @@ int hci_dev_reset(__u16 dev) err = hci_dev_do_reset(hdev); done: - hci_dev_put_srcu(hdev, srcu_index); + hci_dev_put(hdev); return err; } @@ -2442,11 +2424,6 @@ struct hci_dev *hci_alloc_dev_priv(int sizeof_priv) if (!hdev) return NULL; - if (init_srcu_struct(&hdev->srcu)) { - kfree(hdev); - return NULL; - } - hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); hdev->esco_type = (ESCO_HV1); hdev->link_mode = (HCI_LM_ACCEPT); @@ -2692,9 +2669,6 @@ void hci_unregister_dev(struct hci_dev *hdev) list_del(&hdev->list); write_unlock(&hci_dev_list_lock); - synchronize_srcu(&hdev->srcu); - cleanup_srcu_struct(&hdev->srcu); - cancel_work_sync(&hdev->rx_work); cancel_work_sync(&hdev->cmd_work); cancel_work_sync(&hdev->tx_work); From 881548d5903788122a58c1683f38a6ae636cca8e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 13 Jul 2025 11:49:39 +0000 Subject: [PATCH 966/971] ANDROID: GKI: add fput() to db854c symbol list In commit c40ad1c04d30 ("drm/msm: Fix another leak in the submit error path"), the msm drm module adds a call to fput(). Add that symbol to the db845c build target to fix the build issue. Fixes: c40ad1c04d30 ("drm/msm: Fix another leak in the submit error path") Change-Id: I0495084d45cc4d1325e8504ab2b422ec59a4e1b8 Signed-off-by: Greg Kroah-Hartman --- android/abi_gki_aarch64_db845c | 1 + 1 file changed, 1 insertion(+) diff --git a/android/abi_gki_aarch64_db845c b/android/abi_gki_aarch64_db845c index 13bb001d6bd2..8a1438070389 100644 --- a/android/abi_gki_aarch64_db845c +++ b/android/abi_gki_aarch64_db845c @@ -270,6 +270,7 @@ flush_work __flush_workqueue fortify_panic + fput free_io_pgtable_ops free_irq fwnode_handle_put From b3d28c180f2a6af60de9fcd8604c2b55536f225c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 13 Jul 2025 13:46:16 +0000 Subject: [PATCH 967/971] Revert "scsi: ufs: core: Fix clk scaling to be conditional in reset and restore" This reverts commit 51ba65860457b67e7905fe16690df0fecf1a29d2 which is commit 2e083cd802294693a5414e4557a183dd7e442e71 upstream. It breaks the Android kernel abi and can be brought back in the future in an abi-safe way if it is really needed. Bug: 161946584 Change-Id: Ic044e2024ec360ae2dcd930bd9f8ee8e0f71a75b Signed-off-by: Greg Kroah-Hartman --- drivers/ufs/core/ufshcd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index bf5109f3c730..4fdeec819833 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -7839,8 +7839,7 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba) hba->silence_err_logs = false; /* scale up clocks to max frequency before full reinitialization */ - if (ufshcd_is_clkscaling_supported(hba)) - ufshcd_scale_clks(hba, ULONG_MAX, true); + ufshcd_scale_clks(hba, ULONG_MAX, true); err = ufshcd_hba_enable(hba); From 0b225c3d7eef7a65d055fa8751304e3f061bf8da Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 13 Jul 2025 13:46:21 +0000 Subject: [PATCH 968/971] Revert "scsi: ufs: core: Add OPP support for scaling clocks and regulators" This reverts commit 847af89aa1635f42dac2f40ae042eb5d368b23d4 which is commit 930bd77ebe3dc23b18aa49e55e6a515d5663d67a upstream. It breaks the Android kernel abi and can be brought back in the future in an abi-safe way if it is really needed. Bug: 161946584 Change-Id: If1498686628b8d9a8c29f15d7c51dfa2f0cb2db5 Signed-off-by: Greg Kroah-Hartman --- drivers/ufs/core/ufshcd.c | 144 +++++++++----------------------------- include/ufs/ufshcd.h | 4 -- 2 files changed, 33 insertions(+), 115 deletions(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 4fdeec819833..1ec9e901aa22 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -324,8 +323,7 @@ static inline void ufshcd_add_delay_before_dme_cmd(struct ufs_hba *hba); static int ufshcd_host_reset_and_restore(struct ufs_hba *hba); static void ufshcd_resume_clkscaling(struct ufs_hba *hba); static void ufshcd_suspend_clkscaling(struct ufs_hba *hba); -static int ufshcd_scale_clks(struct ufs_hba *hba, unsigned long freq, - bool scale_up); +static int ufshcd_scale_clks(struct ufs_hba *hba, bool scale_up); static irqreturn_t ufshcd_intr(int irq, void *__hba); static int ufshcd_change_power_mode(struct ufs_hba *hba, struct ufs_pa_layer_attr *pwr_mode); @@ -1116,32 +1114,14 @@ out: return ret; } -static int ufshcd_opp_set_rate(struct ufs_hba *hba, unsigned long freq) -{ - struct dev_pm_opp *opp; - int ret; - - opp = dev_pm_opp_find_freq_floor_indexed(hba->dev, - &freq, 0); - if (IS_ERR(opp)) - return PTR_ERR(opp); - - ret = dev_pm_opp_set_opp(hba->dev, opp); - dev_pm_opp_put(opp); - - return ret; -} - /** * ufshcd_scale_clks - scale up or scale down UFS controller clocks * @hba: per adapter instance - * @freq: frequency to scale * @scale_up: True if scaling up and false if scaling down * * Return: 0 if successful; < 0 upon failure. */ -static int ufshcd_scale_clks(struct ufs_hba *hba, unsigned long freq, - bool scale_up) +static int ufshcd_scale_clks(struct ufs_hba *hba, bool scale_up) { int ret = 0; ktime_t start = ktime_get(); @@ -1150,21 +1130,13 @@ static int ufshcd_scale_clks(struct ufs_hba *hba, unsigned long freq, if (ret) goto out; - if (hba->use_pm_opp) - ret = ufshcd_opp_set_rate(hba, freq); - else - ret = ufshcd_set_clk_freq(hba, scale_up); + ret = ufshcd_set_clk_freq(hba, scale_up); if (ret) goto out; ret = ufshcd_vops_clk_scale_notify(hba, scale_up, POST_CHANGE); - if (ret) { - if (hba->use_pm_opp) - ufshcd_opp_set_rate(hba, - hba->devfreq->previous_freq); - else - ufshcd_set_clk_freq(hba, !scale_up); - } + if (ret) + ufshcd_set_clk_freq(hba, !scale_up); out: trace_ufshcd_profile_clk_scaling(dev_name(hba->dev), @@ -1176,13 +1148,12 @@ out: /** * ufshcd_is_devfreq_scaling_required - check if scaling is required or not * @hba: per adapter instance - * @freq: frequency to scale * @scale_up: True if scaling up and false if scaling down * * Return: true if scaling is required, false otherwise. */ static bool ufshcd_is_devfreq_scaling_required(struct ufs_hba *hba, - unsigned long freq, bool scale_up) + bool scale_up) { struct ufs_clk_info *clki; struct list_head *head = &hba->clk_list_head; @@ -1190,9 +1161,6 @@ static bool ufshcd_is_devfreq_scaling_required(struct ufs_hba *hba, if (list_empty(head)) return false; - if (hba->use_pm_opp) - return freq != hba->clk_scaling.target_freq; - list_for_each_entry(clki, head, list) { if (!IS_ERR_OR_NULL(clki->clk)) { if (scale_up && clki->max_freq) { @@ -1391,14 +1359,12 @@ static void ufshcd_clock_scaling_unprepare(struct ufs_hba *hba, int err, bool sc /** * ufshcd_devfreq_scale - scale up/down UFS clocks and gear * @hba: per adapter instance - * @freq: frequency to scale * @scale_up: True for scaling up and false for scalin down * * Return: 0 for success; -EBUSY if scaling can't happen at this time; non-zero * for any other errors. */ -static int ufshcd_devfreq_scale(struct ufs_hba *hba, unsigned long freq, - bool scale_up) +static int ufshcd_devfreq_scale(struct ufs_hba *hba, bool scale_up) { int ret = 0; @@ -1413,7 +1379,7 @@ static int ufshcd_devfreq_scale(struct ufs_hba *hba, unsigned long freq, goto out_unprepare; } - ret = ufshcd_scale_clks(hba, freq, scale_up); + ret = ufshcd_scale_clks(hba, scale_up); if (ret) { if (!scale_up) ufshcd_scale_gear(hba, true); @@ -1424,8 +1390,7 @@ static int ufshcd_devfreq_scale(struct ufs_hba *hba, unsigned long freq, if (scale_up) { ret = ufshcd_scale_gear(hba, true); if (ret) { - ufshcd_scale_clks(hba, hba->devfreq->previous_freq, - false); + ufshcd_scale_clks(hba, false); goto out_unprepare; } } @@ -1484,22 +1449,9 @@ static int ufshcd_devfreq_target(struct device *dev, if (!ufshcd_is_clkscaling_supported(hba)) return -EINVAL; - if (hba->use_pm_opp) { - struct dev_pm_opp *opp; - - /* Get the recommended frequency from OPP framework */ - opp = devfreq_recommended_opp(dev, freq, flags); - if (IS_ERR(opp)) - return PTR_ERR(opp); - - dev_pm_opp_put(opp); - } else { - /* Override with the closest supported frequency */ - clki = list_first_entry(&hba->clk_list_head, struct ufs_clk_info, - list); - *freq = (unsigned long) clk_round_rate(clki->clk, *freq); - } - + clki = list_first_entry(&hba->clk_list_head, struct ufs_clk_info, list); + /* Override with the closest supported frequency */ + *freq = (unsigned long) clk_round_rate(clki->clk, *freq); spin_lock_irqsave(hba->host->host_lock, irq_flags); if (ufshcd_eh_in_progress(hba)) { spin_unlock_irqrestore(hba->host->host_lock, irq_flags); @@ -1521,17 +1473,12 @@ static int ufshcd_devfreq_target(struct device *dev, goto out; } - /* Decide based on the target or rounded-off frequency and update */ - if (hba->use_pm_opp) - scale_up = *freq > hba->clk_scaling.target_freq; - else - scale_up = *freq == clki->max_freq; - - if (!hba->use_pm_opp && !scale_up) + /* Decide based on the rounded-off frequency and update */ + scale_up = *freq == clki->max_freq; + if (!scale_up) *freq = clki->min_freq; - /* Update the frequency */ - if (!ufshcd_is_devfreq_scaling_required(hba, *freq, scale_up)) { + if (!ufshcd_is_devfreq_scaling_required(hba, scale_up)) { spin_unlock_irqrestore(hba->host->host_lock, irq_flags); ret = 0; goto out; /* no state change required */ @@ -1539,9 +1486,7 @@ static int ufshcd_devfreq_target(struct device *dev, spin_unlock_irqrestore(hba->host->host_lock, irq_flags); start = ktime_get(); - ret = ufshcd_devfreq_scale(hba, *freq, scale_up); - if (!ret) - hba->clk_scaling.target_freq = *freq; + ret = ufshcd_devfreq_scale(hba, scale_up); trace_ufshcd_profile_clk_scaling(dev_name(hba->dev), (scale_up ? "up" : "down"), @@ -1562,6 +1507,8 @@ static int ufshcd_devfreq_get_dev_status(struct device *dev, struct ufs_hba *hba = dev_get_drvdata(dev); struct ufs_clk_scaling *scaling = &hba->clk_scaling; unsigned long flags; + struct list_head *clk_list = &hba->clk_list_head; + struct ufs_clk_info *clki; ktime_t curr_t; if (!ufshcd_is_clkscaling_supported(hba)) @@ -1574,24 +1521,17 @@ static int ufshcd_devfreq_get_dev_status(struct device *dev, if (!scaling->window_start_t) goto start_window; + clki = list_first_entry(clk_list, struct ufs_clk_info, list); /* * If current frequency is 0, then the ondemand governor considers * there's no initial frequency set. And it always requests to set * to max. frequency. */ - if (hba->use_pm_opp) { - stat->current_frequency = hba->clk_scaling.target_freq; - } else { - struct list_head *clk_list = &hba->clk_list_head; - struct ufs_clk_info *clki; - - clki = list_first_entry(clk_list, struct ufs_clk_info, list); - stat->current_frequency = clki->curr_freq; - } - + stat->current_frequency = clki->curr_freq; if (scaling->is_busy_started) scaling->tot_busy_t += ktime_us_delta(curr_t, scaling->busy_start_t); + stat->total_time = ktime_us_delta(curr_t, scaling->window_start_t); stat->busy_time = scaling->tot_busy_t; start_window: @@ -1620,11 +1560,9 @@ static int ufshcd_devfreq_init(struct ufs_hba *hba) if (list_empty(clk_list)) return 0; - if (!hba->use_pm_opp) { - clki = list_first_entry(clk_list, struct ufs_clk_info, list); - dev_pm_opp_add(hba->dev, clki->min_freq, 0); - dev_pm_opp_add(hba->dev, clki->max_freq, 0); - } + clki = list_first_entry(clk_list, struct ufs_clk_info, list); + dev_pm_opp_add(hba->dev, clki->min_freq, 0); + dev_pm_opp_add(hba->dev, clki->max_freq, 0); ufshcd_vops_config_scaling_param(hba, &hba->vps->devfreq_profile, &hba->vps->ondemand_data); @@ -1636,10 +1574,8 @@ static int ufshcd_devfreq_init(struct ufs_hba *hba) ret = PTR_ERR(devfreq); dev_err(hba->dev, "Unable to register with devfreq %d\n", ret); - if (!hba->use_pm_opp) { - dev_pm_opp_remove(hba->dev, clki->min_freq); - dev_pm_opp_remove(hba->dev, clki->max_freq); - } + dev_pm_opp_remove(hba->dev, clki->min_freq); + dev_pm_opp_remove(hba->dev, clki->max_freq); return ret; } @@ -1651,6 +1587,7 @@ static int ufshcd_devfreq_init(struct ufs_hba *hba) static void ufshcd_devfreq_remove(struct ufs_hba *hba) { struct list_head *clk_list = &hba->clk_list_head; + struct ufs_clk_info *clki; if (!hba->devfreq) return; @@ -1658,13 +1595,9 @@ static void ufshcd_devfreq_remove(struct ufs_hba *hba) devfreq_remove_device(hba->devfreq); hba->devfreq = NULL; - if (!hba->use_pm_opp) { - struct ufs_clk_info *clki; - - clki = list_first_entry(clk_list, struct ufs_clk_info, list); - dev_pm_opp_remove(hba->dev, clki->min_freq); - dev_pm_opp_remove(hba->dev, clki->max_freq); - } + clki = list_first_entry(clk_list, struct ufs_clk_info, list); + dev_pm_opp_remove(hba->dev, clki->min_freq); + dev_pm_opp_remove(hba->dev, clki->max_freq); } static void ufshcd_suspend_clkscaling(struct ufs_hba *hba) @@ -1740,7 +1673,7 @@ static ssize_t ufshcd_clkscale_enable_store(struct device *dev, ufshcd_resume_clkscaling(hba); } else { ufshcd_suspend_clkscaling(hba); - err = ufshcd_devfreq_scale(hba, ULONG_MAX, true); + err = ufshcd_devfreq_scale(hba, true); if (err) dev_err(hba->dev, "%s: failed to scale clocks up %d\n", __func__, err); @@ -7839,7 +7772,7 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba) hba->silence_err_logs = false; /* scale up clocks to max frequency before full reinitialization */ - ufshcd_scale_clks(hba, ULONG_MAX, true); + ufshcd_scale_clks(hba, true); err = ufshcd_hba_enable(hba); @@ -9449,17 +9382,6 @@ static int ufshcd_init_clocks(struct ufs_hba *hba) dev_dbg(dev, "%s: clk: %s, rate: %lu\n", __func__, clki->name, clk_get_rate(clki->clk)); } - - /* Set Max. frequency for all clocks */ - if (hba->use_pm_opp) { - ret = ufshcd_opp_set_rate(hba, ULONG_MAX); - if (ret) { - dev_err(hba->dev, "%s: failed to set OPP: %d", __func__, - ret); - goto out; - } - } - out: return ret; } diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index 213a85f93267..66bd5c15375e 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -445,7 +445,6 @@ struct ufs_clk_gating { * @workq: workqueue to schedule devfreq suspend/resume work * @suspend_work: worker to suspend devfreq * @resume_work: worker to resume devfreq - * @target_freq: frequency requested by devfreq framework * @min_gear: lowest HS gear to scale down to * @is_enabled: tracks if scaling is currently enabled or not, controlled by * clkscale_enable sysfs node @@ -466,7 +465,6 @@ struct ufs_clk_scaling { struct workqueue_struct *workq; struct work_struct suspend_work; struct work_struct resume_work; - unsigned long target_freq; u32 min_gear; bool is_enabled; bool is_allowed; @@ -928,7 +926,6 @@ enum ufshcd_mcq_opr { * @auto_bkops_enabled: to track whether bkops is enabled in device * @vreg_info: UFS device voltage regulator information * @clk_list_head: UFS host controller clocks list node head - * @use_pm_opp: Indicates whether OPP based scaling is used or not * @req_abort_count: number of times ufshcd_abort() has been called * @lanes_per_direction: number of lanes per data direction between the UFS * controller and the UFS device. @@ -1081,7 +1078,6 @@ struct ufs_hba { bool auto_bkops_enabled; struct ufs_vreg_info vreg_info; struct list_head clk_list_head; - bool use_pm_opp; /* Number of requests aborts */ int req_abort_count; From 81020b228773cdbb9c3236172201f9c05a3b855f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 13 Jul 2025 13:46:43 +0000 Subject: [PATCH 969/971] Revert "scsi: ufs: core: Fix abnormal scale up after last cmd finish" This reverts commit 95ffe734518d99647409010046ea2d8a6f9c6f7f which is commit 6fd53da45bbc834b9cfdf707d2f7ebe666667943 upstream. It breaks the Android kernel abi and can be brought back in the future in an abi-safe way if it is really needed. Bug: 161946584 Change-Id: I72021c6bddafc49cd50bc98f1d07de210e324ed1 Signed-off-by: Greg Kroah-Hartman --- drivers/ufs/core/ufshcd.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 1ec9e901aa22..a3a7ecd53901 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -323,6 +323,7 @@ static inline void ufshcd_add_delay_before_dme_cmd(struct ufs_hba *hba); static int ufshcd_host_reset_and_restore(struct ufs_hba *hba); static void ufshcd_resume_clkscaling(struct ufs_hba *hba); static void ufshcd_suspend_clkscaling(struct ufs_hba *hba); +static void __ufshcd_suspend_clkscaling(struct ufs_hba *hba); static int ufshcd_scale_clks(struct ufs_hba *hba, bool scale_up); static irqreturn_t ufshcd_intr(int irq, void *__hba); static int ufshcd_change_power_mode(struct ufs_hba *hba, @@ -1412,10 +1413,9 @@ static void ufshcd_clk_scaling_suspend_work(struct work_struct *work) return; } hba->clk_scaling.is_suspended = true; - hba->clk_scaling.window_start_t = 0; spin_unlock_irqrestore(hba->host->host_lock, irq_flags); - devfreq_suspend_device(hba->devfreq); + __ufshcd_suspend_clkscaling(hba); } static void ufshcd_clk_scaling_resume_work(struct work_struct *work) @@ -1600,6 +1600,16 @@ static void ufshcd_devfreq_remove(struct ufs_hba *hba) dev_pm_opp_remove(hba->dev, clki->max_freq); } +static void __ufshcd_suspend_clkscaling(struct ufs_hba *hba) +{ + unsigned long flags; + + devfreq_suspend_device(hba->devfreq); + spin_lock_irqsave(hba->host->host_lock, flags); + hba->clk_scaling.window_start_t = 0; + spin_unlock_irqrestore(hba->host->host_lock, flags); +} + static void ufshcd_suspend_clkscaling(struct ufs_hba *hba) { unsigned long flags; @@ -1612,12 +1622,11 @@ static void ufshcd_suspend_clkscaling(struct ufs_hba *hba) if (!hba->clk_scaling.is_suspended) { suspend = true; hba->clk_scaling.is_suspended = true; - hba->clk_scaling.window_start_t = 0; } spin_unlock_irqrestore(hba->host->host_lock, flags); if (suspend) - devfreq_suspend_device(hba->devfreq); + __ufshcd_suspend_clkscaling(hba); } static void ufshcd_resume_clkscaling(struct ufs_hba *hba) From 20aa3d5198068ddc6f88e2f7501ecad5add17af5 Mon Sep 17 00:00:00 2001 From: "Borislav Petkov (AMD)" Date: Fri, 11 Jul 2025 21:23:58 +0200 Subject: [PATCH 970/971] x86/CPU/AMD: Properly check the TSA microcode In order to simplify backports, I resorted to an older version of the microcode revision checking which didn't pull in the whole struct x86_cpu_id matching machinery. My simpler method, however, forgot to add the extended CPU model to the patch revision, which lead to mismatches when determining whether TSA mitigation support is present. So add that forgotten extended model. This is a stable-only fix and the preference is to do it this way because it is a lot simpler. Also, the Fixes: tag below points to the respective stable patch. Fixes: 90293047df18 ("x86/bugs: Add a Transient Scheduler Attacks mitigation") Reported-by: Thomas Voegtle Signed-off-by: Borislav Petkov (AMD) Tested-by: Thomas Voegtle Message-ID: <04ea0a8e-edb0-c59e-ce21-5f3d5d167af3@lio96.de> Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/cpu/amd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 1180689a2390..f6690df70b43 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -547,6 +547,7 @@ static bool amd_check_tsa_microcode(void) p.ext_fam = c->x86 - 0xf; p.model = c->x86_model; + p.ext_model = c->x86_model >> 4; p.stepping = c->x86_stepping; if (cpu_has(c, X86_FEATURE_ZEN3) || From 9247f4e6573a4d05fe70c3e90dbd53da26e8c5cb Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 14 Jul 2025 15:57:41 +0200 Subject: [PATCH 971/971] Linux 6.6.98 Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9d5c08363637..0bb5c23c6406 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 6 PATCHLEVEL = 6 -SUBLEVEL = 97 +SUBLEVEL = 98 EXTRAVERSION = NAME = Pinguïn Aangedreven