From: Sasha Levin Date: Sun, 16 Jun 2024 02:01:18 +0000 (-0400) Subject: Fixes for 4.19 X-Git-Tag: v4.19.316~8 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=27966653065b5225bb946cf928cbb2910f9b8b4a;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 4.19 Signed-off-by: Sasha Levin --- diff --git a/queue-4.19/af_unix-annotate-data-race-of-net-unx.sysctl_max_dgr.patch b/queue-4.19/af_unix-annotate-data-race-of-net-unx.sysctl_max_dgr.patch new file mode 100644 index 00000000000..e2a09830a2c --- /dev/null +++ b/queue-4.19/af_unix-annotate-data-race-of-net-unx.sysctl_max_dgr.patch @@ -0,0 +1,38 @@ +From 8fe87f4a029792135fb0e644e2f4333ee82e32bf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 09:52:37 -0700 +Subject: af_unix: Annotate data-race of net->unx.sysctl_max_dgram_qlen. + +From: Kuniyuki Iwashima + +[ Upstream commit bd9f2d05731f6a112d0c7391a0d537bfc588dbe6 ] + +net->unx.sysctl_max_dgram_qlen is exposed as a sysctl knob and can be +changed concurrently. + +Let's use READ_ONCE() in unix_create1(). + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/af_unix.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index c01955ccf6b39..4a4b6d2544534 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -812,7 +812,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern) + + sk->sk_allocation = GFP_KERNEL_ACCOUNT; + sk->sk_write_space = unix_write_space; +- sk->sk_max_ack_backlog = net->unx.sysctl_max_dgram_qlen; ++ sk->sk_max_ack_backlog = READ_ONCE(net->unx.sysctl_max_dgram_qlen); + sk->sk_destruct = unix_sock_destructor; + u = unix_sk(sk); + u->inflight = 0; +-- +2.43.0 + diff --git a/queue-4.19/af_unix-annotate-data-race-of-sk-sk_shutdown-in-sk_d.patch b/queue-4.19/af_unix-annotate-data-race-of-sk-sk_shutdown-in-sk_d.patch new file mode 100644 index 00000000000..00351e7752d --- /dev/null +++ b/queue-4.19/af_unix-annotate-data-race-of-sk-sk_shutdown-in-sk_d.patch @@ -0,0 +1,37 @@ +From 2d8cea9fa4394553e642959946a585d33dfb4fe7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 09:52:41 -0700 +Subject: af_unix: Annotate data-race of sk->sk_shutdown in sk_diag_fill(). + +From: Kuniyuki Iwashima + +[ Upstream commit efaf24e30ec39ebbea9112227485805a48b0ceb1 ] + +While dumping sockets via UNIX_DIAG, we do not hold unix_state_lock(). + +Let's use READ_ONCE() to read sk->sk_shutdown. + +Fixes: e4e541a84863 ("sock-diag: Report shutdown for inet and unix sockets (v2)") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/diag.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/unix/diag.c b/net/unix/diag.c +index 3ff6a623445eb..9376d4d4263f0 100644 +--- a/net/unix/diag.c ++++ b/net/unix/diag.c +@@ -153,7 +153,7 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r + sock_diag_put_meminfo(sk, skb, UNIX_DIAG_MEMINFO)) + goto out_nlmsg_trim; + +- if (nla_put_u8(skb, UNIX_DIAG_SHUTDOWN, sk->sk_shutdown)) ++ if (nla_put_u8(skb, UNIX_DIAG_SHUTDOWN, READ_ONCE(sk->sk_shutdown))) + goto out_nlmsg_trim; + + nlmsg_end(skb, nlh); +-- +2.43.0 + diff --git a/queue-4.19/af_unix-annotate-data-race-of-sk-sk_state-in-unix_in.patch b/queue-4.19/af_unix-annotate-data-race-of-sk-sk_state-in-unix_in.patch new file mode 100644 index 00000000000..a4e6950a2f9 --- /dev/null +++ b/queue-4.19/af_unix-annotate-data-race-of-sk-sk_state-in-unix_in.patch @@ -0,0 +1,50 @@ +From bfdda1bea793aca6819f8054b0cd90e522a03890 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 09:52:29 -0700 +Subject: af_unix: Annotate data-race of sk->sk_state in unix_inq_len(). + +From: Kuniyuki Iwashima + +[ Upstream commit 3a0f38eb285c8c2eead4b3230c7ac2983707599d ] + +ioctl(SIOCINQ) calls unix_inq_len() that checks sk->sk_state first +and returns -EINVAL if it's TCP_LISTEN. + +Then, for SOCK_STREAM sockets, unix_inq_len() returns the number of +bytes in recvq. + +However, unix_inq_len() does not hold unix_state_lock(), and the +concurrent listen() might change the state after checking sk->sk_state. + +If the race occurs, 0 is returned for the listener, instead of -EINVAL, +because the length of skb with embryo is 0. + +We could hold unix_state_lock() in unix_inq_len(), but it's overkill +given the result is true for pre-listen() TCP_CLOSE state. + +So, let's use READ_ONCE() for sk->sk_state in unix_inq_len(). + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/af_unix.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 02100e62bf608..d363a268f272e 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -2584,7 +2584,7 @@ long unix_inq_len(struct sock *sk) + struct sk_buff *skb; + long amount = 0; + +- if (sk->sk_state == TCP_LISTEN) ++ if (READ_ONCE(sk->sk_state) == TCP_LISTEN) + return -EINVAL; + + spin_lock(&sk->sk_receive_queue.lock); +-- +2.43.0 + diff --git a/queue-4.19/af_unix-annotate-data-races-around-sk-sk_state-in-se.patch b/queue-4.19/af_unix-annotate-data-races-around-sk-sk_state-in-se.patch new file mode 100644 index 00000000000..46ef04a9a75 --- /dev/null +++ b/queue-4.19/af_unix-annotate-data-races-around-sk-sk_state-in-se.patch @@ -0,0 +1,72 @@ +From b7a2b87c044c2c6e416348bb66a7d4260a9add79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 09:52:33 -0700 +Subject: af_unix: Annotate data-races around sk->sk_state in sendmsg() and + recvmsg(). + +From: Kuniyuki Iwashima + +[ Upstream commit 8a34d4e8d9742a24f74998f45a6a98edd923319b ] + +The following functions read sk->sk_state locklessly and proceed only if +the state is TCP_ESTABLISHED. + + * unix_stream_sendmsg + * unix_stream_read_generic + * unix_seqpacket_sendmsg + * unix_seqpacket_recvmsg + +Let's use READ_ONCE() there. + +Fixes: a05d2ad1c1f3 ("af_unix: Only allow recv on connected seqpacket sockets.") +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/af_unix.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 5266908c65ec4..c01955ccf6b39 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -1886,7 +1886,7 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg, + goto out_err; + + if (msg->msg_namelen) { +- err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP; ++ err = READ_ONCE(sk->sk_state) == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP; + goto out_err; + } else { + err = -ENOTCONN; +@@ -2088,7 +2088,7 @@ static int unix_seqpacket_sendmsg(struct socket *sock, struct msghdr *msg, + if (err) + return err; + +- if (sk->sk_state != TCP_ESTABLISHED) ++ if (READ_ONCE(sk->sk_state) != TCP_ESTABLISHED) + return -ENOTCONN; + + if (msg->msg_namelen) +@@ -2102,7 +2102,7 @@ static int unix_seqpacket_recvmsg(struct socket *sock, struct msghdr *msg, + { + struct sock *sk = sock->sk; + +- if (sk->sk_state != TCP_ESTABLISHED) ++ if (READ_ONCE(sk->sk_state) != TCP_ESTABLISHED) + return -ENOTCONN; + + return unix_dgram_recvmsg(sock, msg, size, flags); +@@ -2298,7 +2298,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state, + size_t size = state->size; + unsigned int last_len; + +- if (unlikely(sk->sk_state != TCP_ESTABLISHED)) { ++ if (unlikely(READ_ONCE(sk->sk_state) != TCP_ESTABLISHED)) { + err = -EINVAL; + goto out; + } +-- +2.43.0 + diff --git a/queue-4.19/af_unix-annotate-data-races-around-sk-sk_state-in-un.patch b/queue-4.19/af_unix-annotate-data-races-around-sk-sk_state-in-un.patch new file mode 100644 index 00000000000..8f57cc165f3 --- /dev/null +++ b/queue-4.19/af_unix-annotate-data-races-around-sk-sk_state-in-un.patch @@ -0,0 +1,128 @@ +From 56741a5b6bb248b277296aadac85c4c3ef7545fb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 09:52:30 -0700 +Subject: af_unix: Annotate data-races around sk->sk_state in + unix_write_space() and poll(). + +From: Kuniyuki Iwashima + +[ Upstream commit eb0718fb3e97ad0d6f4529b810103451c90adf94 ] + +unix_poll() and unix_dgram_poll() read sk->sk_state locklessly and +calls unix_writable() which also reads sk->sk_state without holding +unix_state_lock(). + +Let's use READ_ONCE() in unix_poll() and unix_dgram_poll() and pass +it to unix_writable(). + +While at it, we remove TCP_SYN_SENT check in unix_dgram_poll() as +that state does not exist for AF_UNIX socket since the code was added. + +Fixes: 1586a5877db9 ("af_unix: do not report POLLOUT on listeners") +Fixes: 3c73419c09a5 ("af_unix: fix 'poll for write'/ connected DGRAM sockets") +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/af_unix.c | 25 ++++++++++++------------- + 1 file changed, 12 insertions(+), 13 deletions(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index d363a268f272e..5266908c65ec4 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -454,9 +454,9 @@ static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other) + return 0; + } + +-static int unix_writable(const struct sock *sk) ++static int unix_writable(const struct sock *sk, unsigned char state) + { +- return sk->sk_state != TCP_LISTEN && ++ return state != TCP_LISTEN && + (refcount_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf; + } + +@@ -465,7 +465,7 @@ static void unix_write_space(struct sock *sk) + struct socket_wq *wq; + + rcu_read_lock(); +- if (unix_writable(sk)) { ++ if (unix_writable(sk, READ_ONCE(sk->sk_state))) { + wq = rcu_dereference(sk->sk_wq); + if (skwq_has_sleeper(wq)) + wake_up_interruptible_sync_poll(&wq->wait, +@@ -2683,12 +2683,14 @@ static int unix_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned lon + static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wait) + { + struct sock *sk = sock->sk; ++ unsigned char state; + __poll_t mask; + u8 shutdown; + + sock_poll_wait(file, sock, wait); + mask = 0; + shutdown = READ_ONCE(sk->sk_shutdown); ++ state = READ_ONCE(sk->sk_state); + + /* exceptional events? */ + if (sk->sk_err) +@@ -2704,14 +2706,14 @@ static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wa + + /* Connection-based need to check for termination and startup */ + if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) && +- sk->sk_state == TCP_CLOSE) ++ state == TCP_CLOSE) + mask |= EPOLLHUP; + + /* + * we set writable also when the other side has shut down the + * connection. This prevents stuck sockets. + */ +- if (unix_writable(sk)) ++ if (unix_writable(sk, state)) + mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND; + + return mask; +@@ -2722,12 +2724,14 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock, + { + struct sock *sk = sock->sk, *other; + unsigned int writable; ++ unsigned char state; + __poll_t mask; + u8 shutdown; + + sock_poll_wait(file, sock, wait); + mask = 0; + shutdown = READ_ONCE(sk->sk_shutdown); ++ state = READ_ONCE(sk->sk_state); + + /* exceptional events? */ + if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue)) +@@ -2744,19 +2748,14 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock, + mask |= EPOLLIN | EPOLLRDNORM; + + /* Connection-based need to check for termination and startup */ +- if (sk->sk_type == SOCK_SEQPACKET) { +- if (sk->sk_state == TCP_CLOSE) +- mask |= EPOLLHUP; +- /* connection hasn't started yet? */ +- if (sk->sk_state == TCP_SYN_SENT) +- return mask; +- } ++ if (sk->sk_type == SOCK_SEQPACKET && state == TCP_CLOSE) ++ mask |= EPOLLHUP; + + /* No write status requested, avoid expensive OUT tests. */ + if (!(poll_requested_events(wait) & (EPOLLWRBAND|EPOLLWRNORM|EPOLLOUT))) + return mask; + +- writable = unix_writable(sk); ++ writable = unix_writable(sk, state); + if (writable) { + unix_state_lock(sk); + +-- +2.43.0 + diff --git a/queue-4.19/af_unix-annotate-data-races-around-sk-sk_state-in-un.patch-3084 b/queue-4.19/af_unix-annotate-data-races-around-sk-sk_state-in-un.patch-3084 new file mode 100644 index 00000000000..7fd2956354c --- /dev/null +++ b/queue-4.19/af_unix-annotate-data-races-around-sk-sk_state-in-un.patch-3084 @@ -0,0 +1,71 @@ +From 8b80a7233bda7652714e303e70f74216bd3b3c24 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 09:52:35 -0700 +Subject: af_unix: Annotate data-races around sk->sk_state in UNIX_DIAG. + +From: Kuniyuki Iwashima + +[ Upstream commit 0aa3be7b3e1f8f997312cc4705f8165e02806f8f ] + +While dumping AF_UNIX sockets via UNIX_DIAG, sk->sk_state is read +locklessly. + +Let's use READ_ONCE() there. + +Note that the result could be inconsistent if the socket is dumped +during the state change. This is common for other SOCK_DIAG and +similar interfaces. + +Fixes: c9da99e6475f ("unix_diag: Fixup RQLEN extension report") +Fixes: 2aac7a2cb0d9 ("unix_diag: Pending connections IDs NLA") +Fixes: 45a96b9be6ec ("unix_diag: Dumping all sockets core") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/diag.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/net/unix/diag.c b/net/unix/diag.c +index d6ceac688defc..f27b4e55da0e8 100644 +--- a/net/unix/diag.c ++++ b/net/unix/diag.c +@@ -61,7 +61,7 @@ static int sk_diag_dump_icons(struct sock *sk, struct sk_buff *nlskb) + u32 *buf; + int i; + +- if (sk->sk_state == TCP_LISTEN) { ++ if (READ_ONCE(sk->sk_state) == TCP_LISTEN) { + spin_lock(&sk->sk_receive_queue.lock); + + attr = nla_reserve(nlskb, UNIX_DIAG_ICONS, +@@ -99,7 +99,7 @@ static int sk_diag_show_rqlen(struct sock *sk, struct sk_buff *nlskb) + { + struct unix_diag_rqlen rql; + +- if (sk->sk_state == TCP_LISTEN) { ++ if (READ_ONCE(sk->sk_state) == TCP_LISTEN) { + rql.udiag_rqueue = sk->sk_receive_queue.qlen; + rql.udiag_wqueue = sk->sk_max_ack_backlog; + } else { +@@ -124,7 +124,7 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r + rep = nlmsg_data(nlh); + rep->udiag_family = AF_UNIX; + rep->udiag_type = sk->sk_type; +- rep->udiag_state = sk->sk_state; ++ rep->udiag_state = READ_ONCE(sk->sk_state); + rep->pad = 0; + rep->udiag_ino = sk_ino; + sock_diag_save_cookie(sk, rep->udiag_cookie); +@@ -202,7 +202,7 @@ static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) + continue; + if (num < s_num) + goto next; +- if (!(req->udiag_states & (1 << sk->sk_state))) ++ if (!(req->udiag_states & (1 << READ_ONCE(sk->sk_state)))) + goto next; + if (sk_diag_dump(sk, skb, req, + NETLINK_CB(cb->skb).portid, +-- +2.43.0 + diff --git a/queue-4.19/af_unix-use-skb_queue_len_lockless-in-sk_diag_show_r.patch b/queue-4.19/af_unix-use-skb_queue_len_lockless-in-sk_diag_show_r.patch new file mode 100644 index 00000000000..b4f002212ef --- /dev/null +++ b/queue-4.19/af_unix-use-skb_queue_len_lockless-in-sk_diag_show_r.patch @@ -0,0 +1,41 @@ +From 736204bb6d8a351ae0973b5a875755c17a8824b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 09:52:40 -0700 +Subject: af_unix: Use skb_queue_len_lockless() in sk_diag_show_rqlen(). + +From: Kuniyuki Iwashima + +[ Upstream commit 5d915e584d8408211d4567c22685aae8820bfc55 ] + +We can dump the socket queue length via UNIX_DIAG by specifying +UDIAG_SHOW_RQLEN. + +If sk->sk_state is TCP_LISTEN, we return the recv queue length, +but here we do not hold recvq lock. + +Let's use skb_queue_len_lockless() in sk_diag_show_rqlen(). + +Fixes: c9da99e6475f ("unix_diag: Fixup RQLEN extension report") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/diag.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/unix/diag.c b/net/unix/diag.c +index f27b4e55da0e8..3ff6a623445eb 100644 +--- a/net/unix/diag.c ++++ b/net/unix/diag.c +@@ -100,7 +100,7 @@ static int sk_diag_show_rqlen(struct sock *sk, struct sk_buff *nlskb) + struct unix_diag_rqlen rql; + + if (READ_ONCE(sk->sk_state) == TCP_LISTEN) { +- rql.udiag_rqueue = sk->sk_receive_queue.qlen; ++ rql.udiag_rqueue = skb_queue_len_lockless(&sk->sk_receive_queue); + rql.udiag_wqueue = sk->sk_max_ack_backlog; + } else { + rql.udiag_rqueue = (u32) unix_inq_len(sk); +-- +2.43.0 + diff --git a/queue-4.19/af_unix-use-unix_recvq_full_lockless-in-unix_stream_.patch b/queue-4.19/af_unix-use-unix_recvq_full_lockless-in-unix_stream_.patch new file mode 100644 index 00000000000..4e3d77be7d8 --- /dev/null +++ b/queue-4.19/af_unix-use-unix_recvq_full_lockless-in-unix_stream_.patch @@ -0,0 +1,72 @@ +From 0ff72815485a9af6ed834b65d22ceb3aff62534b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 09:52:38 -0700 +Subject: af_unix: Use unix_recvq_full_lockless() in unix_stream_connect(). + +From: Kuniyuki Iwashima + +[ Upstream commit 45d872f0e65593176d880ec148f41ad7c02e40a7 ] + +Once sk->sk_state is changed to TCP_LISTEN, it never changes. + +unix_accept() takes advantage of this characteristics; it does not +hold the listener's unix_state_lock() and only acquires recvq lock +to pop one skb. + +It means unix_state_lock() does not prevent the queue length from +changing in unix_stream_connect(). + +Thus, we need to use unix_recvq_full_lockless() to avoid data-race. + +Now we remove unix_recvq_full() as no one uses it. + +Note that we can remove READ_ONCE() for sk->sk_max_ack_backlog in +unix_recvq_full_lockless() because of the following reasons: + + (1) For SOCK_DGRAM, it is a written-once field in unix_create1() + + (2) For SOCK_STREAM and SOCK_SEQPACKET, it is changed under the + listener's unix_state_lock() in unix_listen(), and we hold + the lock in unix_stream_connect() + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/af_unix.c | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 4a4b6d2544534..dfcafbb8cd0e0 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -194,15 +194,9 @@ static inline int unix_may_send(struct sock *sk, struct sock *osk) + return unix_peer(osk) == NULL || unix_our_peer(sk, osk); + } + +-static inline int unix_recvq_full(const struct sock *sk) +-{ +- return skb_queue_len(&sk->sk_receive_queue) > sk->sk_max_ack_backlog; +-} +- + static inline int unix_recvq_full_lockless(const struct sock *sk) + { +- return skb_queue_len_lockless(&sk->sk_receive_queue) > +- READ_ONCE(sk->sk_max_ack_backlog); ++ return skb_queue_len_lockless(&sk->sk_receive_queue) > sk->sk_max_ack_backlog; + } + + struct sock *unix_peer_get(struct sock *s) +@@ -1306,7 +1300,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, + if (other->sk_shutdown & RCV_SHUTDOWN) + goto out_unlock; + +- if (unix_recvq_full(other)) { ++ if (unix_recvq_full_lockless(other)) { + err = -EAGAIN; + if (!timeo) + goto out_unlock; +-- +2.43.0 + diff --git a/queue-4.19/drm-amd-display-handle-y-carry-over-in-vcp-x.y-calcu.patch b/queue-4.19/drm-amd-display-handle-y-carry-over-in-vcp-x.y-calcu.patch new file mode 100644 index 00000000000..7a708aa9c43 --- /dev/null +++ b/queue-4.19/drm-amd-display-handle-y-carry-over-in-vcp-x.y-calcu.patch @@ -0,0 +1,44 @@ +From 337fade8785b1ccaadc4fdac9883f27d59327b09 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Sep 2021 19:55:39 -0400 +Subject: drm/amd/display: Handle Y carry-over in VCP X.Y calculation + +From: George Shen + +[ Upstream commit 3626a6aebe62ce7067cdc460c0c644e9445386bb ] + +[Why/How] +Theoretically rare corner case where ceil(Y) results in rounding +up to an integer. If this happens, the 1 should be carried over to +the X value. + +Reviewed-by: Wenjing Liu +Acked-by: Anson Jacob +Signed-off-by: George Shen +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c +index 6f9078f3c4d39..17bcf7ce4099c 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c +@@ -620,6 +620,12 @@ void enc1_stream_encoder_set_mst_bandwidth( + x), + 26)); + ++ // If y rounds up to integer, carry it over to x. ++ if (y >> 26) { ++ x += 1; ++ y = 0; ++ } ++ + REG_SET_2(DP_MSE_RATE_CNTL, 0, + DP_MSE_RATE_X, x, + DP_MSE_RATE_Y, y); +-- +2.43.0 + diff --git a/queue-4.19/ipv6-sr-block-bh-in-seg6_output_core-and-seg6_input_.patch b/queue-4.19/ipv6-sr-block-bh-in-seg6_output_core-and-seg6_input_.patch new file mode 100644 index 00000000000..12e5616a761 --- /dev/null +++ b/queue-4.19/ipv6-sr-block-bh-in-seg6_output_core-and-seg6_input_.patch @@ -0,0 +1,95 @@ +From ef23b47ef3e6cce8ae8f8c9c9e61704257a37640 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 May 2024 13:26:34 +0000 +Subject: ipv6: sr: block BH in seg6_output_core() and seg6_input_core() + +From: Eric Dumazet + +[ Upstream commit c0b98ac1cc104f48763cdb27b1e9ac25fd81fc90 ] + +As explained in commit 1378817486d6 ("tipc: block BH +before using dst_cache"), net/core/dst_cache.c +helpers need to be called with BH disabled. + +Disabling preemption in seg6_output_core() is not good enough, +because seg6_output_core() is called from process context, +lwtunnel_output() only uses rcu_read_lock(). + +We might be interrupted by a softirq, re-enter seg6_output_core() +and corrupt dst_cache data structures. + +Fix the race by using local_bh_disable() instead of +preempt_disable(). + +Apply a similar change in seg6_input_core(). + +Fixes: fa79581ea66c ("ipv6: sr: fix several BUGs when preemption is enabled") +Fixes: 6c8702c60b88 ("ipv6: sr: add support for SRH encapsulation and injection with lwtunnels") +Signed-off-by: Eric Dumazet +Cc: David Lebrun +Acked-by: Paolo Abeni +Link: https://lore.kernel.org/r/20240531132636.2637995-4-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/seg6_iptunnel.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c +index 2e90672852c86..7dc447e08a486 100644 +--- a/net/ipv6/seg6_iptunnel.c ++++ b/net/ipv6/seg6_iptunnel.c +@@ -313,9 +313,8 @@ static int seg6_input(struct sk_buff *skb) + + slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate); + +- preempt_disable(); ++ local_bh_disable(); + dst = dst_cache_get(&slwt->cache); +- preempt_enable(); + + skb_dst_drop(skb); + +@@ -323,14 +322,13 @@ static int seg6_input(struct sk_buff *skb) + ip6_route_input(skb); + dst = skb_dst(skb); + if (!dst->error) { +- preempt_disable(); + dst_cache_set_ip6(&slwt->cache, dst, + &ipv6_hdr(skb)->saddr); +- preempt_enable(); + } + } else { + skb_dst_set(skb, dst); + } ++ local_bh_enable(); + + err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); + if (unlikely(err)) +@@ -352,9 +350,9 @@ static int seg6_output(struct net *net, struct sock *sk, struct sk_buff *skb) + + slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate); + +- preempt_disable(); ++ local_bh_disable(); + dst = dst_cache_get(&slwt->cache); +- preempt_enable(); ++ local_bh_enable(); + + if (unlikely(!dst)) { + struct ipv6hdr *hdr = ipv6_hdr(skb); +@@ -374,9 +372,9 @@ static int seg6_output(struct net *net, struct sock *sk, struct sk_buff *skb) + goto drop; + } + +- preempt_disable(); ++ local_bh_disable(); + dst_cache_set_ip6(&slwt->cache, dst, &fl6.saddr); +- preempt_enable(); ++ local_bh_enable(); + } + + skb_dst_drop(skb); +-- +2.43.0 + diff --git a/queue-4.19/media-mc-mark-the-media-devnode-as-registered-from-t.patch b/queue-4.19/media-mc-mark-the-media-devnode-as-registered-from-t.patch new file mode 100644 index 00000000000..5f8c47154bc --- /dev/null +++ b/queue-4.19/media-mc-mark-the-media-devnode-as-registered-from-t.patch @@ -0,0 +1,53 @@ +From 81639b57df6e5e30f21227a45ffec539dc9e359a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Feb 2024 09:46:19 +0100 +Subject: media: mc: mark the media devnode as registered from the, start + +From: Hans Verkuil + +[ Upstream commit 4bc60736154bc9e0e39d3b88918f5d3762ebe5e0 ] + +First the media device node was created, and if successful it was +marked as 'registered'. This leaves a small race condition where +an application can open the device node and get an error back +because the 'registered' flag was not yet set. + +Change the order: first set the 'registered' flag, then actually +register the media device node. If that fails, then clear the flag. + +Signed-off-by: Hans Verkuil +Acked-by: Sakari Ailus +Reviewed-by: Laurent Pinchart +Fixes: cf4b9211b568 ("[media] media: Media device node support") +Cc: stable@vger.kernel.org +Signed-off-by: Sakari Ailus +Signed-off-by: Sasha Levin +--- + drivers/media/media-devnode.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/media/media-devnode.c b/drivers/media/media-devnode.c +index 6b87a721dc499..b4a62b3172e3d 100644 +--- a/drivers/media/media-devnode.c ++++ b/drivers/media/media-devnode.c +@@ -253,15 +253,14 @@ int __must_check media_devnode_register(struct media_device *mdev, + devnode->cdev.owner = owner; + + /* Part 3: Add the media and char device */ ++ set_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); + ret = cdev_device_add(&devnode->cdev, &devnode->dev); + if (ret < 0) { ++ clear_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); + pr_err("%s: cdev_device_add failed\n", __func__); + goto cdev_add_error; + } + +- /* Part 4: Activate this minor. The char device can now be used. */ +- set_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); +- + return 0; + + cdev_add_error: +-- +2.43.0 + diff --git a/queue-4.19/mmc-davinci-don-t-strip-remove-function-when-driver-.patch b/queue-4.19/mmc-davinci-don-t-strip-remove-function-when-driver-.patch new file mode 100644 index 00000000000..14d7ec092ee --- /dev/null +++ b/queue-4.19/mmc-davinci-don-t-strip-remove-function-when-driver-.patch @@ -0,0 +1,59 @@ +From 13eb98409a95b2a6eb1f84bc79c623314d9ab6f3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Mar 2024 12:40:17 +0100 +Subject: mmc: davinci: Don't strip remove function when driver is builtin +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit 55c421b364482b61c4c45313a535e61ed5ae4ea3 ] + +Using __exit for the remove function results in the remove callback being +discarded with CONFIG_MMC_DAVINCI=y. When such a device gets unbound (e.g. +using sysfs or hotplug), the driver is just removed without the cleanup +being performed. This results in resource leaks. Fix it by compiling in the +remove callback unconditionally. + +This also fixes a W=1 modpost warning: + +WARNING: modpost: drivers/mmc/host/davinci_mmc: section mismatch in +reference: davinci_mmcsd_driver+0x10 (section: .data) -> +davinci_mmcsd_remove (section: .exit.text) + +Fixes: b4cff4549b7a ("DaVinci: MMC: MMC/SD controller driver for DaVinci family") +Signed-off-by: Uwe Kleine-König +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20240324114017.231936-2-u.kleine-koenig@pengutronix.de +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + drivers/mmc/host/davinci_mmc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c +index 8af5df181d764..65b511f440c82 100644 +--- a/drivers/mmc/host/davinci_mmc.c ++++ b/drivers/mmc/host/davinci_mmc.c +@@ -1361,7 +1361,7 @@ static int davinci_mmcsd_probe(struct platform_device *pdev) + return ret; + } + +-static void __exit davinci_mmcsd_remove(struct platform_device *pdev) ++static void davinci_mmcsd_remove(struct platform_device *pdev) + { + struct mmc_davinci_host *host = platform_get_drvdata(pdev); + +@@ -1415,7 +1415,7 @@ static struct platform_driver davinci_mmcsd_driver = { + .of_match_table = davinci_mmc_dt_ids, + }, + .probe = davinci_mmcsd_probe, +- .remove_new = __exit_p(davinci_mmcsd_remove), ++ .remove_new = davinci_mmcsd_remove, + .id_table = davinci_mmc_devtype, + }; + +-- +2.43.0 + diff --git a/queue-4.19/mmc-davinci_mmc-convert-to-platform-remove-callback-.patch b/queue-4.19/mmc-davinci_mmc-convert-to-platform-remove-callback-.patch new file mode 100644 index 00000000000..cb26bdf361f --- /dev/null +++ b/queue-4.19/mmc-davinci_mmc-convert-to-platform-remove-callback-.patch @@ -0,0 +1,67 @@ +From 9c9009388174387b31572799b39aff53452809aa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Jul 2023 14:59:56 +0800 +Subject: mmc: davinci_mmc: Convert to platform remove callback returning void +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Yangtao Li + +[ Upstream commit bc1711e8332da03648d8fe1950189237e66313af ] + +The .remove() callback for a platform driver returns an int which makes +many driver authors wrongly assume it's possible to do error handling by +returning an error code. However the value returned is (mostly) ignored +and this typically results in resource leaks. To improve here there is a +quest to make the remove callback return void. In the first step of this +quest all drivers are converted to .remove_new() which already returns +void. + +Trivially convert this driver from always returning zero in the remove +callback to the void returning variant. + +Cc: Uwe Kleine-König +Signed-off-by: Yangtao Li +Link: https://lore.kernel.org/r/20230727070051.17778-7-frank.li@vivo.com +Signed-off-by: Ulf Hansson +Stable-dep-of: 55c421b36448 ("mmc: davinci: Don't strip remove function when driver is builtin") +Signed-off-by: Sasha Levin +--- + drivers/mmc/host/davinci_mmc.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c +index 70d04962f53ac..8af5df181d764 100644 +--- a/drivers/mmc/host/davinci_mmc.c ++++ b/drivers/mmc/host/davinci_mmc.c +@@ -1361,7 +1361,7 @@ static int davinci_mmcsd_probe(struct platform_device *pdev) + return ret; + } + +-static int __exit davinci_mmcsd_remove(struct platform_device *pdev) ++static void __exit davinci_mmcsd_remove(struct platform_device *pdev) + { + struct mmc_davinci_host *host = platform_get_drvdata(pdev); + +@@ -1370,8 +1370,6 @@ static int __exit davinci_mmcsd_remove(struct platform_device *pdev) + davinci_release_dma_channels(host); + clk_disable_unprepare(host->clk); + mmc_free_host(host->mmc); +- +- return 0; + } + + #ifdef CONFIG_PM +@@ -1417,7 +1415,7 @@ static struct platform_driver davinci_mmcsd_driver = { + .of_match_table = davinci_mmc_dt_ids, + }, + .probe = davinci_mmcsd_probe, +- .remove = __exit_p(davinci_mmcsd_remove), ++ .remove_new = __exit_p(davinci_mmcsd_remove), + .id_table = davinci_mmc_devtype, + }; + +-- +2.43.0 + diff --git a/queue-4.19/nilfs2-fix-nilfs_empty_dir-misjudgment-and-long-loop.patch b/queue-4.19/nilfs2-fix-nilfs_empty_dir-misjudgment-and-long-loop.patch new file mode 100644 index 00000000000..9af303f7078 --- /dev/null +++ b/queue-4.19/nilfs2-fix-nilfs_empty_dir-misjudgment-and-long-loop.patch @@ -0,0 +1,51 @@ +From ed3017c4e893eb7c84fdd788e5c517f959418fef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 22:42:55 +0900 +Subject: nilfs2: fix nilfs_empty_dir() misjudgment and long loop on I/O errors + +From: Ryusuke Konishi + +[ Upstream commit 7373a51e7998b508af7136530f3a997b286ce81c ] + +The error handling in nilfs_empty_dir() when a directory folio/page read +fails is incorrect, as in the old ext2 implementation, and if the +folio/page cannot be read or nilfs_check_folio() fails, it will falsely +determine the directory as empty and corrupt the file system. + +In addition, since nilfs_empty_dir() does not immediately return on a +failed folio/page read, but continues to loop, this can cause a long loop +with I/O if i_size of the directory's inode is also corrupted, causing the +log writer thread to wait and hang, as reported by syzbot. + +Fix these issues by making nilfs_empty_dir() immediately return a false +value (0) if it fails to get a directory folio/page. + +Link: https://lkml.kernel.org/r/20240604134255.7165-1-konishi.ryusuke@gmail.com +Signed-off-by: Ryusuke Konishi +Reported-by: syzbot+c8166c541d3971bf6c87@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=c8166c541d3971bf6c87 +Fixes: 2ba466d74ed7 ("nilfs2: directory entry operations") +Tested-by: Ryusuke Konishi +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + fs/nilfs2/dir.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c +index 22f1f75a90c1a..552234ef22fe7 100644 +--- a/fs/nilfs2/dir.c ++++ b/fs/nilfs2/dir.c +@@ -627,7 +627,7 @@ int nilfs_empty_dir(struct inode *inode) + + kaddr = nilfs_get_page(inode, i, &page); + if (IS_ERR(kaddr)) +- continue; ++ return 0; + + de = (struct nilfs_dir_entry *)kaddr; + kaddr += nilfs_last_byte(inode, i) - NILFS_DIR_REC_LEN(1); +-- +2.43.0 + diff --git a/queue-4.19/nilfs2-remove-check-for-pageerror.patch b/queue-4.19/nilfs2-remove-check-for-pageerror.patch new file mode 100644 index 00000000000..e9089e57179 --- /dev/null +++ b/queue-4.19/nilfs2-remove-check-for-pageerror.patch @@ -0,0 +1,35 @@ +From c8c60b9de2c348b4c6e83ead7c914fb596661e46 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 May 2022 18:12:25 -0400 +Subject: nilfs2: Remove check for PageError + +From: Matthew Wilcox (Oracle) + +[ Upstream commit 79ea65563ad8aaab309d61eeb4d5019dd6cf5fa0 ] + +If read_mapping_page() encounters an error, it returns an errno, not a +page with PageError set, so this test is not needed. + +Signed-off-by: Matthew Wilcox (Oracle) +Stable-dep-of: 7373a51e7998 ("nilfs2: fix nilfs_empty_dir() misjudgment and long loop on I/O errors") +Signed-off-by: Sasha Levin +--- + fs/nilfs2/dir.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c +index eb7de9e2a384e..24cfe9db66e02 100644 +--- a/fs/nilfs2/dir.c ++++ b/fs/nilfs2/dir.c +@@ -194,7 +194,7 @@ static struct page *nilfs_get_page(struct inode *dir, unsigned long n) + if (!IS_ERR(page)) { + kmap(page); + if (unlikely(!PageChecked(page))) { +- if (PageError(page) || !nilfs_check_page(page)) ++ if (!nilfs_check_page(page)) + goto fail; + } + } +-- +2.43.0 + diff --git a/queue-4.19/nilfs2-return-the-mapped-address-from-nilfs_get_page.patch b/queue-4.19/nilfs2-return-the-mapped-address-from-nilfs_get_page.patch new file mode 100644 index 00000000000..c49926930ab --- /dev/null +++ b/queue-4.19/nilfs2-return-the-mapped-address-from-nilfs_get_page.patch @@ -0,0 +1,146 @@ +From 87c0f79fcb93bdd03081e4613d9151cc0f545647 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Nov 2023 23:30:25 +0900 +Subject: nilfs2: return the mapped address from nilfs_get_page() + +From: Matthew Wilcox (Oracle) + +[ Upstream commit 09a46acb3697e50548bb265afa1d79163659dd85 ] + +In prepartion for switching from kmap() to kmap_local(), return the kmap +address from nilfs_get_page() instead of having the caller look up +page_address(). + +[konishi.ryusuke: fixed a missing blank line after declaration] +Link: https://lkml.kernel.org/r/20231127143036.2425-7-konishi.ryusuke@gmail.com +Signed-off-by: Matthew Wilcox (Oracle) +Signed-off-by: Ryusuke Konishi +Signed-off-by: Andrew Morton +Stable-dep-of: 7373a51e7998 ("nilfs2: fix nilfs_empty_dir() misjudgment and long loop on I/O errors") +Signed-off-by: Sasha Levin +--- + fs/nilfs2/dir.c | 57 +++++++++++++++++++++++-------------------------- + 1 file changed, 27 insertions(+), 30 deletions(-) + +diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c +index 24cfe9db66e02..22f1f75a90c1a 100644 +--- a/fs/nilfs2/dir.c ++++ b/fs/nilfs2/dir.c +@@ -186,19 +186,24 @@ static bool nilfs_check_page(struct page *page) + return false; + } + +-static struct page *nilfs_get_page(struct inode *dir, unsigned long n) ++static void *nilfs_get_page(struct inode *dir, unsigned long n, ++ struct page **pagep) + { + struct address_space *mapping = dir->i_mapping; + struct page *page = read_mapping_page(mapping, n, NULL); ++ void *kaddr; + +- if (!IS_ERR(page)) { +- kmap(page); +- if (unlikely(!PageChecked(page))) { +- if (!nilfs_check_page(page)) +- goto fail; +- } ++ if (IS_ERR(page)) ++ return page; ++ ++ kaddr = kmap(page); ++ if (unlikely(!PageChecked(page))) { ++ if (!nilfs_check_page(page)) ++ goto fail; + } +- return page; ++ ++ *pagep = page; ++ return kaddr; + + fail: + nilfs_put_page(page); +@@ -275,14 +280,14 @@ static int nilfs_readdir(struct file *file, struct dir_context *ctx) + for ( ; n < npages; n++, offset = 0) { + char *kaddr, *limit; + struct nilfs_dir_entry *de; +- struct page *page = nilfs_get_page(inode, n); ++ struct page *page; + +- if (IS_ERR(page)) { ++ kaddr = nilfs_get_page(inode, n, &page); ++ if (IS_ERR(kaddr)) { + nilfs_error(sb, "bad page in #%lu", inode->i_ino); + ctx->pos += PAGE_SIZE - offset; + return -EIO; + } +- kaddr = page_address(page); + de = (struct nilfs_dir_entry *)(kaddr + offset); + limit = kaddr + nilfs_last_byte(inode, n) - + NILFS_DIR_REC_LEN(1); +@@ -345,11 +350,9 @@ nilfs_find_entry(struct inode *dir, const struct qstr *qstr, + start = 0; + n = start; + do { +- char *kaddr; ++ char *kaddr = nilfs_get_page(dir, n, &page); + +- page = nilfs_get_page(dir, n); +- if (!IS_ERR(page)) { +- kaddr = page_address(page); ++ if (!IS_ERR(kaddr)) { + de = (struct nilfs_dir_entry *)kaddr; + kaddr += nilfs_last_byte(dir, n) - reclen; + while ((char *) de <= kaddr) { +@@ -387,15 +390,11 @@ nilfs_find_entry(struct inode *dir, const struct qstr *qstr, + + struct nilfs_dir_entry *nilfs_dotdot(struct inode *dir, struct page **p) + { +- struct page *page = nilfs_get_page(dir, 0); +- struct nilfs_dir_entry *de = NULL; ++ struct nilfs_dir_entry *de = nilfs_get_page(dir, 0, p); + +- if (!IS_ERR(page)) { +- de = nilfs_next_entry( +- (struct nilfs_dir_entry *)page_address(page)); +- *p = page; +- } +- return de; ++ if (IS_ERR(de)) ++ return NULL; ++ return nilfs_next_entry(de); + } + + ino_t nilfs_inode_by_name(struct inode *dir, const struct qstr *qstr) +@@ -459,12 +458,11 @@ int nilfs_add_link(struct dentry *dentry, struct inode *inode) + for (n = 0; n <= npages; n++) { + char *dir_end; + +- page = nilfs_get_page(dir, n); +- err = PTR_ERR(page); +- if (IS_ERR(page)) ++ kaddr = nilfs_get_page(dir, n, &page); ++ err = PTR_ERR(kaddr); ++ if (IS_ERR(kaddr)) + goto out; + lock_page(page); +- kaddr = page_address(page); + dir_end = kaddr + nilfs_last_byte(dir, n); + de = (struct nilfs_dir_entry *)kaddr; + kaddr += PAGE_SIZE - reclen; +@@ -627,11 +625,10 @@ int nilfs_empty_dir(struct inode *inode) + char *kaddr; + struct nilfs_dir_entry *de; + +- page = nilfs_get_page(inode, i); +- if (IS_ERR(page)) ++ kaddr = nilfs_get_page(inode, i, &page); ++ if (IS_ERR(kaddr)) + continue; + +- kaddr = page_address(page); + de = (struct nilfs_dir_entry *)kaddr; + kaddr += nilfs_last_byte(inode, i) - NILFS_DIR_REC_LEN(1); + +-- +2.43.0 + diff --git a/queue-4.19/ptp-fix-error-message-on-failed-pin-verification.patch b/queue-4.19/ptp-fix-error-message-on-failed-pin-verification.patch new file mode 100644 index 00000000000..009abffa0f6 --- /dev/null +++ b/queue-4.19/ptp-fix-error-message-on-failed-pin-verification.patch @@ -0,0 +1,42 @@ +From 41742c98d364e6b2cef535ee6be316bc881a956e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 14:05:27 +0200 +Subject: ptp: Fix error message on failed pin verification + +From: Karol Kolacinski + +[ Upstream commit 323a359f9b077f382f4483023d096a4d316fd135 ] + +On failed verification of PTP clock pin, error message prints channel +number instead of pin index after "pin", which is incorrect. + +Fix error message by adding channel number to the message and printing +pin number instead of channel number. + +Fixes: 6092315dfdec ("ptp: introduce programmable pins.") +Signed-off-by: Karol Kolacinski +Acked-by: Richard Cochran +Link: https://lore.kernel.org/r/20240604120555.16643-1-karol.kolacinski@intel.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/ptp/ptp_chardev.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c +index 8ff2dd5c52e64..f66ce68f42379 100644 +--- a/drivers/ptp/ptp_chardev.c ++++ b/drivers/ptp/ptp_chardev.c +@@ -97,7 +97,8 @@ int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin, + } + + if (info->verify(info, pin, func, chan)) { +- pr_err("driver cannot use function %u on pin %u\n", func, chan); ++ pr_err("driver cannot use function %u and channel %u on pin %u\n", ++ func, chan, pin); + return -EOPNOTSUPP; + } + +-- +2.43.0 + diff --git a/queue-4.19/selftests-mm-compaction_test-fix-bogus-test-success-.patch b/queue-4.19/selftests-mm-compaction_test-fix-bogus-test-success-.patch new file mode 100644 index 00000000000..09b56869cb6 --- /dev/null +++ b/queue-4.19/selftests-mm-compaction_test-fix-bogus-test-success-.patch @@ -0,0 +1,109 @@ +From 448bd11b77ad8b8520508415817b5f31c21f5d61 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 May 2024 13:13:56 +0530 +Subject: selftests/mm: compaction_test: fix bogus test success on Aarch64 + +From: Dev Jain + +[ Upstream commit d4202e66a4b1fe6968f17f9f09bbc30d08f028a1 ] + +Patch series "Fixes for compaction_test", v2. + +The compaction_test memory selftest introduces fragmentation in memory +and then tries to allocate as many hugepages as possible. This series +addresses some problems. + +On Aarch64, if nr_hugepages == 0, then the test trivially succeeds since +compaction_index becomes 0, which is less than 3, due to no division by +zero exception being raised. We fix that by checking for division by +zero. + +Secondly, correctly set the number of hugepages to zero before trying +to set a large number of them. + +Now, consider a situation in which, at the start of the test, a non-zero +number of hugepages have been already set (while running the entire +selftests/mm suite, or manually by the admin). The test operates on 80% +of memory to avoid OOM-killer invocation, and because some memory is +already blocked by hugepages, it would increase the chance of OOM-killing. +Also, since mem_free used in check_compaction() is the value before we +set nr_hugepages to zero, the chance that the compaction_index will +be small is very high if the preset nr_hugepages was high, leading to a +bogus test success. + +This patch (of 3): + +Currently, if at runtime we are not able to allocate a huge page, the test +will trivially pass on Aarch64 due to no exception being raised on +division by zero while computing compaction_index. Fix that by checking +for nr_hugepages == 0. Anyways, in general, avoid a division by zero by +exiting the program beforehand. While at it, fix a typo, and handle the +case where the number of hugepages may overflow an integer. + +Link: https://lkml.kernel.org/r/20240521074358.675031-1-dev.jain@arm.com +Link: https://lkml.kernel.org/r/20240521074358.675031-2-dev.jain@arm.com +Fixes: bd67d5c15cc1 ("Test compaction of mlocked memory") +Signed-off-by: Dev Jain +Cc: Anshuman Khandual +Cc: Shuah Khan +Cc: Sri Jayaramappa +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/vm/compaction_test.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/tools/testing/selftests/vm/compaction_test.c b/tools/testing/selftests/vm/compaction_test.c +index 6be4b70a26592..b5587a751664a 100644 +--- a/tools/testing/selftests/vm/compaction_test.c ++++ b/tools/testing/selftests/vm/compaction_test.c +@@ -81,12 +81,13 @@ int prereq(void) + return -1; + } + +-int check_compaction(unsigned long mem_free, unsigned int hugepage_size) ++int check_compaction(unsigned long mem_free, unsigned long hugepage_size) + { ++ unsigned long nr_hugepages_ul; + int fd, ret = -1; + int compaction_index = 0; +- char initial_nr_hugepages[10] = {0}; +- char nr_hugepages[10] = {0}; ++ char initial_nr_hugepages[20] = {0}; ++ char nr_hugepages[20] = {0}; + + /* We want to test with 80% of available memory. Else, OOM killer comes + in to play */ +@@ -135,7 +136,12 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + + /* We should have been able to request at least 1/3 rd of the memory in + huge pages */ +- compaction_index = mem_free/(atoi(nr_hugepages) * hugepage_size); ++ nr_hugepages_ul = strtoul(nr_hugepages, NULL, 10); ++ if (!nr_hugepages_ul) { ++ ksft_print_msg("ERROR: No memory is available as huge pages\n"); ++ goto close_fd; ++ } ++ compaction_index = mem_free/(nr_hugepages_ul * hugepage_size); + + lseek(fd, 0, SEEK_SET); + +@@ -146,11 +152,11 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + goto close_fd; + } + +- ksft_print_msg("Number of huge pages allocated = %d\n", +- atoi(nr_hugepages)); ++ ksft_print_msg("Number of huge pages allocated = %lu\n", ++ nr_hugepages_ul); + + if (compaction_index > 3) { +- ksft_print_msg("ERROR: Less that 1/%d of memory is available\n" ++ ksft_print_msg("ERROR: Less than 1/%d of memory is available\n" + "as huge pages\n", compaction_index); + goto close_fd; + } +-- +2.43.0 + diff --git a/queue-4.19/selftests-mm-compaction_test-fix-incorrect-write-of-.patch b/queue-4.19/selftests-mm-compaction_test-fix-incorrect-write-of-.patch new file mode 100644 index 00000000000..1a5d07a8be5 --- /dev/null +++ b/queue-4.19/selftests-mm-compaction_test-fix-incorrect-write-of-.patch @@ -0,0 +1,43 @@ +From 504a76ee928c4e44e004e6d5104d63c183586341 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 May 2024 13:13:57 +0530 +Subject: selftests/mm: compaction_test: fix incorrect write of zero to + nr_hugepages + +From: Dev Jain + +[ Upstream commit 9ad665ef55eaad1ead1406a58a34f615a7c18b5e ] + +Currently, the test tries to set nr_hugepages to zero, but that is not +actually done because the file offset is not reset after read(). Fix that +using lseek(). + +Link: https://lkml.kernel.org/r/20240521074358.675031-3-dev.jain@arm.com +Fixes: bd67d5c15cc1 ("Test compaction of mlocked memory") +Signed-off-by: Dev Jain +Cc: +Cc: Anshuman Khandual +Cc: Shuah Khan +Cc: Sri Jayaramappa +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/vm/compaction_test.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tools/testing/selftests/vm/compaction_test.c b/tools/testing/selftests/vm/compaction_test.c +index bcec712508731..cb2db2102dd26 100644 +--- a/tools/testing/selftests/vm/compaction_test.c ++++ b/tools/testing/selftests/vm/compaction_test.c +@@ -102,6 +102,8 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + goto close_fd; + } + ++ lseek(fd, 0, SEEK_SET); ++ + /* Start with the initial condition of 0 huge pages*/ + if (write(fd, "0", sizeof(char)) != sizeof(char)) { + perror("Failed to write 0 to /proc/sys/vm/nr_hugepages\n"); +-- +2.43.0 + diff --git a/queue-4.19/selftests-mm-conform-test-to-tap-format-output.patch b/queue-4.19/selftests-mm-conform-test-to-tap-format-output.patch new file mode 100644 index 00000000000..9e32ac1c1bd --- /dev/null +++ b/queue-4.19/selftests-mm-conform-test-to-tap-format-output.patch @@ -0,0 +1,229 @@ +From d5ee1e161a78acce443a381464b56626c0b165b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 1 Jan 2024 13:36:12 +0500 +Subject: selftests/mm: conform test to TAP format output + +From: Muhammad Usama Anjum + +[ Upstream commit 9a21701edc41465de56f97914741bfb7bfc2517d ] + +Conform the layout, informational and status messages to TAP. No +functional change is intended other than the layout of output messages. + +Link: https://lkml.kernel.org/r/20240101083614.1076768-1-usama.anjum@collabora.com +Signed-off-by: Muhammad Usama Anjum +Cc: Shuah Khan +Signed-off-by: Andrew Morton +Stable-dep-of: d4202e66a4b1 ("selftests/mm: compaction_test: fix bogus test success on Aarch64") +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/vm/compaction_test.c | 91 ++++++++++---------- + 1 file changed, 44 insertions(+), 47 deletions(-) + +diff --git a/tools/testing/selftests/vm/compaction_test.c b/tools/testing/selftests/vm/compaction_test.c +index cb2db2102dd26..43f5044b23c57 100644 +--- a/tools/testing/selftests/vm/compaction_test.c ++++ b/tools/testing/selftests/vm/compaction_test.c +@@ -32,7 +32,7 @@ int read_memory_info(unsigned long *memfree, unsigned long *hugepagesize) + FILE *cmdfile = popen(cmd, "r"); + + if (!(fgets(buffer, sizeof(buffer), cmdfile))) { +- perror("Failed to read meminfo\n"); ++ ksft_print_msg("Failed to read meminfo: %s\n", strerror(errno)); + return -1; + } + +@@ -43,7 +43,7 @@ int read_memory_info(unsigned long *memfree, unsigned long *hugepagesize) + cmdfile = popen(cmd, "r"); + + if (!(fgets(buffer, sizeof(buffer), cmdfile))) { +- perror("Failed to read meminfo\n"); ++ ksft_print_msg("Failed to read meminfo: %s\n", strerror(errno)); + return -1; + } + +@@ -61,14 +61,14 @@ int prereq(void) + fd = open("/proc/sys/vm/compact_unevictable_allowed", + O_RDONLY | O_NONBLOCK); + if (fd < 0) { +- perror("Failed to open\n" +- "/proc/sys/vm/compact_unevictable_allowed\n"); ++ ksft_print_msg("Failed to open /proc/sys/vm/compact_unevictable_allowed: %s\n", ++ strerror(errno)); + return -1; + } + + if (read(fd, &allowed, sizeof(char)) != sizeof(char)) { +- perror("Failed to read from\n" +- "/proc/sys/vm/compact_unevictable_allowed\n"); ++ ksft_print_msg("Failed to read from /proc/sys/vm/compact_unevictable_allowed: %s\n", ++ strerror(errno)); + close(fd); + return -1; + } +@@ -77,12 +77,13 @@ int prereq(void) + if (allowed == '1') + return 0; + ++ ksft_print_msg("Compaction isn't allowed\n"); + return -1; + } + + int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + { +- int fd; ++ int fd, ret = -1; + int compaction_index = 0; + char initial_nr_hugepages[10] = {0}; + char nr_hugepages[10] = {0}; +@@ -93,12 +94,14 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + + fd = open("/proc/sys/vm/nr_hugepages", O_RDWR | O_NONBLOCK); + if (fd < 0) { +- perror("Failed to open /proc/sys/vm/nr_hugepages"); ++ ksft_test_result_fail("Failed to open /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + return -1; + } + + if (read(fd, initial_nr_hugepages, sizeof(initial_nr_hugepages)) <= 0) { +- perror("Failed to read from /proc/sys/vm/nr_hugepages"); ++ ksft_test_result_fail("Failed to read from /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + +@@ -106,7 +109,8 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + + /* Start with the initial condition of 0 huge pages*/ + if (write(fd, "0", sizeof(char)) != sizeof(char)) { +- perror("Failed to write 0 to /proc/sys/vm/nr_hugepages\n"); ++ ksft_test_result_fail("Failed to write 0 to /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + +@@ -115,14 +119,16 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + /* Request a large number of huge pages. The Kernel will allocate + as much as it can */ + if (write(fd, "100000", (6*sizeof(char))) != (6*sizeof(char))) { +- perror("Failed to write 100000 to /proc/sys/vm/nr_hugepages\n"); ++ ksft_test_result_fail("Failed to write 100000 to /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + + lseek(fd, 0, SEEK_SET); + + if (read(fd, nr_hugepages, sizeof(nr_hugepages)) <= 0) { +- perror("Failed to re-read from /proc/sys/vm/nr_hugepages\n"); ++ ksft_test_result_fail("Failed to re-read from /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + +@@ -130,67 +136,58 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + huge pages */ + compaction_index = mem_free/(atoi(nr_hugepages) * hugepage_size); + +- if (compaction_index > 3) { +- printf("No of huge pages allocated = %d\n", +- (atoi(nr_hugepages))); +- fprintf(stderr, "ERROR: Less that 1/%d of memory is available\n" +- "as huge pages\n", compaction_index); +- goto close_fd; +- } +- +- printf("No of huge pages allocated = %d\n", +- (atoi(nr_hugepages))); +- + lseek(fd, 0, SEEK_SET); + + if (write(fd, initial_nr_hugepages, strlen(initial_nr_hugepages)) + != strlen(initial_nr_hugepages)) { +- perror("Failed to write value to /proc/sys/vm/nr_hugepages\n"); ++ ksft_test_result_fail("Failed to write value to /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + +- close(fd); +- return 0; ++ if (compaction_index > 3) { ++ ksft_print_msg("ERROR: Less that 1/%d of memory is available\n" ++ "as huge pages\n", compaction_index); ++ ksft_test_result_fail("No of huge pages allocated = %d\n", (atoi(nr_hugepages))); ++ goto close_fd; ++ } ++ ++ ksft_test_result_pass("Memory compaction succeeded. No of huge pages allocated = %d\n", ++ (atoi(nr_hugepages))); ++ ret = 0; + + close_fd: + close(fd); +- printf("Not OK. Compaction test failed."); +- return -1; ++ return ret; + } + + + int main(int argc, char **argv) + { + struct rlimit lim; +- struct map_list *list, *entry; ++ struct map_list *list = NULL, *entry; + size_t page_size, i; + void *map = NULL; + unsigned long mem_free = 0; + unsigned long hugepage_size = 0; + unsigned long mem_fragmentable = 0; + +- if (prereq() != 0) { +- printf("Either the sysctl compact_unevictable_allowed is not\n" +- "set to 1 or couldn't read the proc file.\n" +- "Skipping the test\n"); +- return KSFT_SKIP; +- } ++ ksft_print_header(); ++ ++ if (prereq() != 0) ++ return ksft_exit_pass(); ++ ++ ksft_set_plan(1); + + lim.rlim_cur = RLIM_INFINITY; + lim.rlim_max = RLIM_INFINITY; +- if (setrlimit(RLIMIT_MEMLOCK, &lim)) { +- perror("Failed to set rlimit:\n"); +- return -1; +- } ++ if (setrlimit(RLIMIT_MEMLOCK, &lim)) ++ ksft_exit_fail_msg("Failed to set rlimit: %s\n", strerror(errno)); + + page_size = getpagesize(); + +- list = NULL; +- +- if (read_memory_info(&mem_free, &hugepage_size) != 0) { +- printf("ERROR: Cannot read meminfo\n"); +- return -1; +- } ++ if (read_memory_info(&mem_free, &hugepage_size) != 0) ++ ksft_exit_fail_msg("Failed to get meminfo\n"); + + mem_fragmentable = mem_free * 0.8 / 1024; + +@@ -226,7 +223,7 @@ int main(int argc, char **argv) + } + + if (check_compaction(mem_free, hugepage_size) == 0) +- return 0; ++ return ksft_exit_pass(); + +- return -1; ++ return ksft_exit_fail(); + } +-- +2.43.0 + diff --git a/queue-4.19/selftests-mm-log-a-consistent-test-name-for-check_co.patch b/queue-4.19/selftests-mm-log-a-consistent-test-name-for-check_co.patch new file mode 100644 index 00000000000..f64dbf68cb4 --- /dev/null +++ b/queue-4.19/selftests-mm-log-a-consistent-test-name-for-check_co.patch @@ -0,0 +1,124 @@ +From b0347c3007a19e5326f323611d0f7bdf5186e523 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Feb 2024 14:30:04 +0000 +Subject: selftests/mm: log a consistent test name for check_compaction + +From: Mark Brown + +[ Upstream commit f3b7568c49420d2dcd251032c9ca1e069ec8a6c9 ] + +Every test result report in the compaction test prints a distinct log +messae, and some of the reports print a name that varies at runtime. This +causes problems for automation since a lot of automation software uses the +printed string as the name of the test, if the name varies from run to run +and from pass to fail then the automation software can't identify that a +test changed result or that the same tests are being run. + +Refactor the logging to use a consistent name when printing the result of +the test, printing the existing messages as diagnostic information instead +so they are still available for people trying to interpret the results. + +Link: https://lkml.kernel.org/r/20240209-kselftest-mm-cleanup-v1-2-a3c0386496b5@kernel.org +Signed-off-by: Mark Brown +Cc: Muhammad Usama Anjum +Cc: Ryan Roberts +Cc: Shuah Khan +Signed-off-by: Andrew Morton +Stable-dep-of: d4202e66a4b1 ("selftests/mm: compaction_test: fix bogus test success on Aarch64") +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/vm/compaction_test.c | 35 +++++++++++--------- + 1 file changed, 19 insertions(+), 16 deletions(-) + +diff --git a/tools/testing/selftests/vm/compaction_test.c b/tools/testing/selftests/vm/compaction_test.c +index 43f5044b23c57..6be4b70a26592 100644 +--- a/tools/testing/selftests/vm/compaction_test.c ++++ b/tools/testing/selftests/vm/compaction_test.c +@@ -94,14 +94,15 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + + fd = open("/proc/sys/vm/nr_hugepages", O_RDWR | O_NONBLOCK); + if (fd < 0) { +- ksft_test_result_fail("Failed to open /proc/sys/vm/nr_hugepages: %s\n", +- strerror(errno)); +- return -1; ++ ksft_print_msg("Failed to open /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); ++ ret = -1; ++ goto out; + } + + if (read(fd, initial_nr_hugepages, sizeof(initial_nr_hugepages)) <= 0) { +- ksft_test_result_fail("Failed to read from /proc/sys/vm/nr_hugepages: %s\n", +- strerror(errno)); ++ ksft_print_msg("Failed to read from /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + +@@ -109,8 +110,8 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + + /* Start with the initial condition of 0 huge pages*/ + if (write(fd, "0", sizeof(char)) != sizeof(char)) { +- ksft_test_result_fail("Failed to write 0 to /proc/sys/vm/nr_hugepages: %s\n", +- strerror(errno)); ++ ksft_print_msg("Failed to write 0 to /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + +@@ -119,16 +120,16 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + /* Request a large number of huge pages. The Kernel will allocate + as much as it can */ + if (write(fd, "100000", (6*sizeof(char))) != (6*sizeof(char))) { +- ksft_test_result_fail("Failed to write 100000 to /proc/sys/vm/nr_hugepages: %s\n", +- strerror(errno)); ++ ksft_print_msg("Failed to write 100000 to /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + + lseek(fd, 0, SEEK_SET); + + if (read(fd, nr_hugepages, sizeof(nr_hugepages)) <= 0) { +- ksft_test_result_fail("Failed to re-read from /proc/sys/vm/nr_hugepages: %s\n", +- strerror(errno)); ++ ksft_print_msg("Failed to re-read from /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + +@@ -140,24 +141,26 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + + if (write(fd, initial_nr_hugepages, strlen(initial_nr_hugepages)) + != strlen(initial_nr_hugepages)) { +- ksft_test_result_fail("Failed to write value to /proc/sys/vm/nr_hugepages: %s\n", +- strerror(errno)); ++ ksft_print_msg("Failed to write value to /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + ++ ksft_print_msg("Number of huge pages allocated = %d\n", ++ atoi(nr_hugepages)); ++ + if (compaction_index > 3) { + ksft_print_msg("ERROR: Less that 1/%d of memory is available\n" + "as huge pages\n", compaction_index); +- ksft_test_result_fail("No of huge pages allocated = %d\n", (atoi(nr_hugepages))); + goto close_fd; + } + +- ksft_test_result_pass("Memory compaction succeeded. No of huge pages allocated = %d\n", +- (atoi(nr_hugepages))); + ret = 0; + + close_fd: + close(fd); ++ out: ++ ksft_test_result(ret == 0, "check_compaction\n"); + return ret; + } + +-- +2.43.0 + diff --git a/queue-4.19/serial-sc16is7xx-fix-bug-in-sc16is7xx_set_baud-when-.patch b/queue-4.19/serial-sc16is7xx-fix-bug-in-sc16is7xx_set_baud-when-.patch new file mode 100644 index 00000000000..dd1b693d3bc --- /dev/null +++ b/queue-4.19/serial-sc16is7xx-fix-bug-in-sc16is7xx_set_baud-when-.patch @@ -0,0 +1,96 @@ +From da914c889d0f4f1994e60225b9da5ac82758448b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Apr 2024 16:04:30 -0400 +Subject: serial: sc16is7xx: fix bug in sc16is7xx_set_baud() when using + prescaler + +From: Hugo Villeneuve + +[ Upstream commit 8492bd91aa055907c67ef04f2b56f6dadd1f44bf ] + +When using a high speed clock with a low baud rate, the 4x prescaler is +automatically selected if required. In that case, sc16is7xx_set_baud() +properly configures the chip registers, but returns an incorrect baud +rate by not taking into account the prescaler value. This incorrect baud +rate is then fed to uart_update_timeout(). + +For example, with an input clock of 80MHz, and a selected baud rate of 50, +sc16is7xx_set_baud() will return 200 instead of 50. + +Fix this by first changing the prescaler variable to hold the selected +prescaler value instead of the MCR bitfield. Then properly take into +account the selected prescaler value in the return value computation. + +Also add better documentation about the divisor value computation. + +Fixes: dfeae619d781 ("serial: sc16is7xx") +Cc: stable@vger.kernel.org +Signed-off-by: Hugo Villeneuve +Reviewed-by: Jiri Slaby +Link: https://lore.kernel.org/r/20240430200431.4102923-1-hugo@hugovil.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/tty/serial/sc16is7xx.c | 23 ++++++++++++++++++----- + 1 file changed, 18 insertions(+), 5 deletions(-) + +diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c +index a1331225cdc21..8e25e3e287535 100644 +--- a/drivers/tty/serial/sc16is7xx.c ++++ b/drivers/tty/serial/sc16is7xx.c +@@ -489,16 +489,28 @@ static bool sc16is7xx_regmap_precious(struct device *dev, unsigned int reg) + return false; + } + ++/* ++ * Configure programmable baud rate generator (divisor) according to the ++ * desired baud rate. ++ * ++ * From the datasheet, the divisor is computed according to: ++ * ++ * XTAL1 input frequency ++ * ----------------------- ++ * prescaler ++ * divisor = --------------------------- ++ * baud-rate x sampling-rate ++ */ + static int sc16is7xx_set_baud(struct uart_port *port, int baud) + { + struct sc16is7xx_port *s = dev_get_drvdata(port->dev); + u8 lcr; +- u8 prescaler = 0; ++ unsigned int prescaler = 1; + unsigned long clk = port->uartclk, div = clk / 16 / baud; + + if (div >= BIT(16)) { +- prescaler = SC16IS7XX_MCR_CLKSEL_BIT; +- div /= 4; ++ prescaler = 4; ++ div /= prescaler; + } + + /* In an amazing feat of design, the Enhanced Features Register shares +@@ -533,9 +545,10 @@ static int sc16is7xx_set_baud(struct uart_port *port, int baud) + + mutex_unlock(&s->efr_lock); + ++ /* If bit MCR_CLKSEL is set, the divide by 4 prescaler is activated. */ + sc16is7xx_port_update(port, SC16IS7XX_MCR_REG, + SC16IS7XX_MCR_CLKSEL_BIT, +- prescaler); ++ prescaler == 1 ? 0 : SC16IS7XX_MCR_CLKSEL_BIT); + + /* Open the LCR divisors for configuration */ + sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, +@@ -550,7 +563,7 @@ static int sc16is7xx_set_baud(struct uart_port *port, int baud) + /* Put LCR back to the normal mode */ + sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr); + +- return DIV_ROUND_CLOSEST(clk / 16, div); ++ return DIV_ROUND_CLOSEST((clk / prescaler) / 16, div); + } + + static void sc16is7xx_handle_rx(struct uart_port *port, unsigned int rxlen, +-- +2.43.0 + diff --git a/queue-4.19/serial-sc16is7xx-replace-hardcoded-divisor-value-wit.patch b/queue-4.19/serial-sc16is7xx-replace-hardcoded-divisor-value-wit.patch new file mode 100644 index 00000000000..7a9497bcdfd --- /dev/null +++ b/queue-4.19/serial-sc16is7xx-replace-hardcoded-divisor-value-wit.patch @@ -0,0 +1,39 @@ +From 975b7a754275a98a7cf3744976b9eaa889bc5a42 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Dec 2023 18:18:19 -0500 +Subject: serial: sc16is7xx: replace hardcoded divisor value with BIT() macro + +From: Hugo Villeneuve + +[ Upstream commit 2e57cefc4477659527f7adab1f87cdbf60ef1ae6 ] + +To better show why the limit is what it is, since we have only 16 bits for +the divisor. + +Reviewed-by: Andy Shevchenko +Suggested-by: Andy Shevchenko +Signed-off-by: Hugo Villeneuve +Link: https://lore.kernel.org/r/20231221231823.2327894-13-hugo@hugovil.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 8492bd91aa05 ("serial: sc16is7xx: fix bug in sc16is7xx_set_baud() when using prescaler") +Signed-off-by: Sasha Levin +--- + drivers/tty/serial/sc16is7xx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c +index 800cb94e4b912..a1331225cdc21 100644 +--- a/drivers/tty/serial/sc16is7xx.c ++++ b/drivers/tty/serial/sc16is7xx.c +@@ -496,7 +496,7 @@ static int sc16is7xx_set_baud(struct uart_port *port, int baud) + u8 prescaler = 0; + unsigned long clk = port->uartclk, div = clk / 16 / baud; + +- if (div > 0xffff) { ++ if (div >= BIT(16)) { + prescaler = SC16IS7XX_MCR_CLKSEL_BIT; + div /= 4; + } +-- +2.43.0 + diff --git a/queue-4.19/series b/queue-4.19/series index 4a620a77011..fa50aa68533 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -206,3 +206,33 @@ sparc-move-struct-termio-to-asm-termios.h.patch ext4-fix-mb_cache_entry-s-e_refcnt-leak-in-ext4_xattr_block_cache_find.patch s390-ap-fix-crash-in-ap-internal-function-modify_bitmap.patch nfs-fix-undefined-behavior-in-nfs_block_bits.patch +wifi-mac80211-mesh-fix-leak-of-mesh_preq_queue-objec.patch +wifi-mac80211-fix-deadlock-in-ieee80211_sta_ps_deliv.patch +wifi-iwlwifi-mvm-revert-gen2-tx-a-mpdu-size-to-64.patch +wifi-iwlwifi-mvm-don-t-read-past-the-mfuart-notifcat.patch +ipv6-sr-block-bh-in-seg6_output_core-and-seg6_input_.patch +vxlan-fix-regression-when-dropping-packets-due-to-in.patch +tcp-count-close-wait-sockets-for-tcp_mib_currestab.patch +ptp-fix-error-message-on-failed-pin-verification.patch +af_unix-annotate-data-race-of-sk-sk_state-in-unix_in.patch +af_unix-annotate-data-races-around-sk-sk_state-in-un.patch +af_unix-annotate-data-races-around-sk-sk_state-in-se.patch +af_unix-annotate-data-races-around-sk-sk_state-in-un.patch-3084 +af_unix-annotate-data-race-of-net-unx.sysctl_max_dgr.patch +af_unix-use-unix_recvq_full_lockless-in-unix_stream_.patch +af_unix-use-skb_queue_len_lockless-in-sk_diag_show_r.patch +af_unix-annotate-data-race-of-sk-sk_shutdown-in-sk_d.patch +usb-gadget-f_fs-fix-race-between-aio_cancel-and-aio-.patch +drm-amd-display-handle-y-carry-over-in-vcp-x.y-calcu.patch +serial-sc16is7xx-replace-hardcoded-divisor-value-wit.patch +serial-sc16is7xx-fix-bug-in-sc16is7xx_set_baud-when-.patch +media-mc-mark-the-media-devnode-as-registered-from-t.patch +mmc-davinci_mmc-convert-to-platform-remove-callback-.patch +mmc-davinci-don-t-strip-remove-function-when-driver-.patch +selftests-mm-compaction_test-fix-incorrect-write-of-.patch +selftests-mm-conform-test-to-tap-format-output.patch +selftests-mm-log-a-consistent-test-name-for-check_co.patch +selftests-mm-compaction_test-fix-bogus-test-success-.patch +nilfs2-remove-check-for-pageerror.patch +nilfs2-return-the-mapped-address-from-nilfs_get_page.patch +nilfs2-fix-nilfs_empty_dir-misjudgment-and-long-loop.patch diff --git a/queue-4.19/tcp-count-close-wait-sockets-for-tcp_mib_currestab.patch b/queue-4.19/tcp-count-close-wait-sockets-for-tcp_mib_currestab.patch new file mode 100644 index 00000000000..fa95576b9a1 --- /dev/null +++ b/queue-4.19/tcp-count-close-wait-sockets-for-tcp_mib_currestab.patch @@ -0,0 +1,71 @@ +From 72e8c553a8f14b3f0c1f4625339370877fdffbdc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 01:02:16 +0800 +Subject: tcp: count CLOSE-WAIT sockets for TCP_MIB_CURRESTAB + +From: Jason Xing + +[ Upstream commit a46d0ea5c94205f40ecf912d1bb7806a8a64704f ] + +According to RFC 1213, we should also take CLOSE-WAIT sockets into +consideration: + + "tcpCurrEstab OBJECT-TYPE + ... + The number of TCP connections for which the current state + is either ESTABLISHED or CLOSE- WAIT." + +After this, CurrEstab counter will display the total number of +ESTABLISHED and CLOSE-WAIT sockets. + +The logic of counting +When we increment the counter? +a) if we change the state to ESTABLISHED. +b) if we change the state from SYN-RECEIVED to CLOSE-WAIT. + +When we decrement the counter? +a) if the socket leaves ESTABLISHED and will never go into CLOSE-WAIT, +say, on the client side, changing from ESTABLISHED to FIN-WAIT-1. +b) if the socket leaves CLOSE-WAIT, say, on the server side, changing +from CLOSE-WAIT to LAST-ACK. + +Please note: there are two chances that old state of socket can be changed +to CLOSE-WAIT in tcp_fin(). One is SYN-RECV, the other is ESTABLISHED. +So we have to take care of the former case. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Jason Xing +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv4/tcp.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index e3475f833f8fe..0cbfb57de0f07 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -2242,6 +2242,10 @@ void tcp_set_state(struct sock *sk, int state) + if (oldstate != TCP_ESTABLISHED) + TCP_INC_STATS(sock_net(sk), TCP_MIB_CURRESTAB); + break; ++ case TCP_CLOSE_WAIT: ++ if (oldstate == TCP_SYN_RECV) ++ TCP_INC_STATS(sock_net(sk), TCP_MIB_CURRESTAB); ++ break; + + case TCP_CLOSE: + if (oldstate == TCP_CLOSE_WAIT || oldstate == TCP_ESTABLISHED) +@@ -2253,7 +2257,7 @@ void tcp_set_state(struct sock *sk, int state) + inet_put_port(sk); + /* fall through */ + default: +- if (oldstate == TCP_ESTABLISHED) ++ if (oldstate == TCP_ESTABLISHED || oldstate == TCP_CLOSE_WAIT) + TCP_DEC_STATS(sock_net(sk), TCP_MIB_CURRESTAB); + } + +-- +2.43.0 + diff --git a/queue-4.19/usb-gadget-f_fs-fix-race-between-aio_cancel-and-aio-.patch b/queue-4.19/usb-gadget-f_fs-fix-race-between-aio_cancel-and-aio-.patch new file mode 100644 index 00000000000..b14e89a558d --- /dev/null +++ b/queue-4.19/usb-gadget-f_fs-fix-race-between-aio_cancel-and-aio-.patch @@ -0,0 +1,86 @@ +From 7ac9d7d7c8cf94fe0f509842519a6c4a17ec7c4c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 8 Apr 2024 18:40:59 -0700 +Subject: usb: gadget: f_fs: Fix race between aio_cancel() and AIO request + complete + +From: Wesley Cheng + +[ Upstream commit 24729b307eefcd7c476065cd7351c1a018082c19 ] + +FFS based applications can utilize the aio_cancel() callback to dequeue +pending USB requests submitted to the UDC. There is a scenario where the +FFS application issues an AIO cancel call, while the UDC is handling a +soft disconnect. For a DWC3 based implementation, the callstack looks +like the following: + + DWC3 Gadget FFS Application +dwc3_gadget_soft_disconnect() ... + --> dwc3_stop_active_transfers() + --> dwc3_gadget_giveback(-ESHUTDOWN) + --> ffs_epfile_async_io_complete() ffs_aio_cancel() + --> usb_ep_free_request() --> usb_ep_dequeue() + +There is currently no locking implemented between the AIO completion +handler and AIO cancel, so the issue occurs if the completion routine is +running in parallel to an AIO cancel call coming from the FFS application. +As the completion call frees the USB request (io_data->req) the FFS +application is also referencing it for the usb_ep_dequeue() call. This can +lead to accessing a stale/hanging pointer. + +commit b566d38857fc ("usb: gadget: f_fs: use io_data->status consistently") +relocated the usb_ep_free_request() into ffs_epfile_async_io_complete(). +However, in order to properly implement locking to mitigate this issue, the +spinlock can't be added to ffs_epfile_async_io_complete(), as +usb_ep_dequeue() (if successfully dequeuing a USB request) will call the +function driver's completion handler in the same context. Hence, leading +into a deadlock. + +Fix this issue by moving the usb_ep_free_request() back to +ffs_user_copy_worker(), and ensuring that it explicitly sets io_data->req +to NULL after freeing it within the ffs->eps_lock. This resolves the race +condition above, as the ffs_aio_cancel() routine will not continue +attempting to dequeue a request that has already been freed, or the +ffs_user_copy_work() not freeing the USB request until the AIO cancel is +done referencing it. + +This fix depends on + commit b566d38857fc ("usb: gadget: f_fs: use io_data->status + consistently") + +Fixes: 2e4c7553cd6f ("usb: gadget: f_fs: add aio support") +Cc: stable # b566d38857fc ("usb: gadget: f_fs: use io_data->status consistently") +Signed-off-by: Wesley Cheng +Link: https://lore.kernel.org/r/20240409014059.6740-1-quic_wcheng@quicinc.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/gadget/function/f_fs.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c +index 7294586b08dc0..0d8dae1797a97 100644 +--- a/drivers/usb/gadget/function/f_fs.c ++++ b/drivers/usb/gadget/function/f_fs.c +@@ -761,6 +761,7 @@ static void ffs_user_copy_worker(struct work_struct *work) + int ret = io_data->req->status ? io_data->req->status : + io_data->req->actual; + bool kiocb_has_eventfd = io_data->kiocb->ki_flags & IOCB_EVENTFD; ++ unsigned long flags; + + if (io_data->read && ret > 0) { + mm_segment_t oldfs = get_fs(); +@@ -777,7 +778,10 @@ static void ffs_user_copy_worker(struct work_struct *work) + if (io_data->ffs->ffs_eventfd && !kiocb_has_eventfd) + eventfd_signal(io_data->ffs->ffs_eventfd, 1); + ++ spin_lock_irqsave(&io_data->ffs->eps_lock, flags); + usb_ep_free_request(io_data->ep, io_data->req); ++ io_data->req = NULL; ++ spin_unlock_irqrestore(&io_data->ffs->eps_lock, flags); + + if (io_data->read) + kfree(io_data->to_free); +-- +2.43.0 + diff --git a/queue-4.19/vxlan-fix-regression-when-dropping-packets-due-to-in.patch b/queue-4.19/vxlan-fix-regression-when-dropping-packets-due-to-in.patch new file mode 100644 index 00000000000..d2138664efb --- /dev/null +++ b/queue-4.19/vxlan-fix-regression-when-dropping-packets-due-to-in.patch @@ -0,0 +1,65 @@ +From 94e734d1c5a2ce265bcd7c3bd39355b2cf2b682b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Jun 2024 10:59:26 +0200 +Subject: vxlan: Fix regression when dropping packets due to invalid src + addresses + +From: Daniel Borkmann + +[ Upstream commit 1cd4bc987abb2823836cbb8f887026011ccddc8a ] + +Commit f58f45c1e5b9 ("vxlan: drop packets from invalid src-address") +has recently been added to vxlan mainly in the context of source +address snooping/learning so that when it is enabled, an entry in the +FDB is not being created for an invalid address for the corresponding +tunnel endpoint. + +Before commit f58f45c1e5b9 vxlan was similarly behaving as geneve in +that it passed through whichever macs were set in the L2 header. It +turns out that this change in behavior breaks setups, for example, +Cilium with netkit in L3 mode for Pods as well as tunnel mode has been +passing before the change in f58f45c1e5b9 for both vxlan and geneve. +After mentioned change it is only passing for geneve as in case of +vxlan packets are dropped due to vxlan_set_mac() returning false as +source and destination macs are zero which for E/W traffic via tunnel +is totally fine. + +Fix it by only opting into the is_valid_ether_addr() check in +vxlan_set_mac() when in fact source address snooping/learning is +actually enabled in vxlan. This is done by moving the check into +vxlan_snoop(). With this change, the Cilium connectivity test suite +passes again for both tunnel flavors. + +Fixes: f58f45c1e5b9 ("vxlan: drop packets from invalid src-address") +Signed-off-by: Daniel Borkmann +Cc: David Bauer +Cc: Ido Schimmel +Cc: Nikolay Aleksandrov +Cc: Martin KaFai Lau +Reviewed-by: Ido Schimmel +Reviewed-by: Nikolay Aleksandrov +Reviewed-by: David Bauer +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/vxlan.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c +index d5c8d0d54b33d..82f104ec73383 100644 +--- a/drivers/net/vxlan.c ++++ b/drivers/net/vxlan.c +@@ -1040,6 +1040,10 @@ static bool vxlan_snoop(struct net_device *dev, + struct vxlan_fdb *f; + u32 ifindex = 0; + ++ /* Ignore packets from invalid src-address */ ++ if (!is_valid_ether_addr(src_mac)) ++ return true; ++ + #if IS_ENABLED(CONFIG_IPV6) + if (src_ip->sa.sa_family == AF_INET6 && + (ipv6_addr_type(&src_ip->sin6.sin6_addr) & IPV6_ADDR_LINKLOCAL)) +-- +2.43.0 + diff --git a/queue-4.19/wifi-iwlwifi-mvm-don-t-read-past-the-mfuart-notifcat.patch b/queue-4.19/wifi-iwlwifi-mvm-don-t-read-past-the-mfuart-notifcat.patch new file mode 100644 index 00000000000..103a5e60d12 --- /dev/null +++ b/queue-4.19/wifi-iwlwifi-mvm-don-t-read-past-the-mfuart-notifcat.patch @@ -0,0 +1,55 @@ +From a1577fe604f752462f7768c936fb45b211ca7b0a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 May 2024 13:27:14 +0300 +Subject: wifi: iwlwifi: mvm: don't read past the mfuart notifcation + +From: Emmanuel Grumbach + +[ Upstream commit 4bb95f4535489ed830cf9b34b0a891e384d1aee4 ] + +In case the firmware sends a notification that claims it has more data +than it has, we will read past that was allocated for the notification. +Remove the print of the buffer, we won't see it by default. If needed, +we can see the content with tracing. + +This was reported by KFENCE. + +Fixes: bdccdb854f2f ("iwlwifi: mvm: support MFUART dump in case of MFUART assert") +Signed-off-by: Emmanuel Grumbach +Reviewed-by: Johannes Berg +Signed-off-by: Miri Korenblit +Link: https://msgid.link/20240513132416.ba82a01a559e.Ia91dd20f5e1ca1ad380b95e68aebf2794f553d9b@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +index c7e2b88cd5abb..a46c731f70780 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +@@ -195,20 +195,10 @@ void iwl_mvm_mfu_assert_dump_notif(struct iwl_mvm *mvm, + { + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_mfu_assert_dump_notif *mfu_dump_notif = (void *)pkt->data; +- __le32 *dump_data = mfu_dump_notif->data; +- int n_words = le32_to_cpu(mfu_dump_notif->data_size) / sizeof(__le32); +- int i; + + if (mfu_dump_notif->index_num == 0) + IWL_INFO(mvm, "MFUART assert id 0x%x occurred\n", + le32_to_cpu(mfu_dump_notif->assert_id)); +- +- for (i = 0; i < n_words; i++) +- IWL_DEBUG_INFO(mvm, +- "MFUART assert dump, dword %u: 0x%08x\n", +- le16_to_cpu(mfu_dump_notif->index_num) * +- n_words + i, +- le32_to_cpu(dump_data[i])); + } + + static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, +-- +2.43.0 + diff --git a/queue-4.19/wifi-iwlwifi-mvm-revert-gen2-tx-a-mpdu-size-to-64.patch b/queue-4.19/wifi-iwlwifi-mvm-revert-gen2-tx-a-mpdu-size-to-64.patch new file mode 100644 index 00000000000..54c5d50fc88 --- /dev/null +++ b/queue-4.19/wifi-iwlwifi-mvm-revert-gen2-tx-a-mpdu-size-to-64.patch @@ -0,0 +1,49 @@ +From 24a230c46c05665bafcb9918c2d53f68f202d2e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 May 2024 17:06:33 +0300 +Subject: wifi: iwlwifi: mvm: revert gen2 TX A-MPDU size to 64 + +From: Johannes Berg + +[ Upstream commit 4a7aace2899711592327463c1a29ffee44fcc66e ] + +We don't actually support >64 even for HE devices, so revert +back to 64. This fixes an issue where the session is refused +because the queue is configured differently from the actual +session later. + +Fixes: 514c30696fbc ("iwlwifi: add support for IEEE802.11ax") +Signed-off-by: Johannes Berg +Reviewed-by: Liad Kaufman +Reviewed-by: Luciano Coelho +Signed-off-by: Miri Korenblit +Link: https://msgid.link/20240510170500.52f7b4cf83aa.If47e43adddf7fe250ed7f5571fbb35d8221c7c47@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/rs.h | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h +index d0f47899f2849..f76f708ea98c9 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h +@@ -144,13 +144,8 @@ enum { + + #define LINK_QUAL_AGG_FRAME_LIMIT_DEF (63) + #define LINK_QUAL_AGG_FRAME_LIMIT_MAX (63) +-/* +- * FIXME - various places in firmware API still use u8, +- * e.g. LQ command and SCD config command. +- * This should be 256 instead. +- */ +-#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF (255) +-#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_MAX (255) ++#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF (64) ++#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_MAX (64) + #define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0) + + #define LQ_SIZE 2 /* 2 mode tables: "Active" and "Search" */ +-- +2.43.0 + diff --git a/queue-4.19/wifi-mac80211-fix-deadlock-in-ieee80211_sta_ps_deliv.patch b/queue-4.19/wifi-mac80211-fix-deadlock-in-ieee80211_sta_ps_deliv.patch new file mode 100644 index 00000000000..cf33ff12c34 --- /dev/null +++ b/queue-4.19/wifi-mac80211-fix-deadlock-in-ieee80211_sta_ps_deliv.patch @@ -0,0 +1,109 @@ +From 9cd6156c1ba520d4be9b8b70e77d53ee4c1ea48b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 May 2024 08:57:53 +0200 +Subject: wifi: mac80211: Fix deadlock in ieee80211_sta_ps_deliver_wakeup() + +From: Remi Pommarel + +[ Upstream commit 44c06bbde6443de206b30f513100b5670b23fc5e ] + +The ieee80211_sta_ps_deliver_wakeup() function takes sta->ps_lock to +synchronizes with ieee80211_tx_h_unicast_ps_buf() which is called from +softirq context. However using only spin_lock() to get sta->ps_lock in +ieee80211_sta_ps_deliver_wakeup() does not prevent softirq to execute +on this same CPU, to run ieee80211_tx_h_unicast_ps_buf() and try to +take this same lock ending in deadlock. Below is an example of rcu stall +that arises in such situation. + + rcu: INFO: rcu_sched self-detected stall on CPU + rcu: 2-....: (42413413 ticks this GP) idle=b154/1/0x4000000000000000 softirq=1763/1765 fqs=21206996 + rcu: (t=42586894 jiffies g=2057 q=362405 ncpus=4) + CPU: 2 PID: 719 Comm: wpa_supplicant Tainted: G W 6.4.0-02158-g1b062f552873 #742 + Hardware name: RPT (r1) (DT) + pstate: 00000005 (nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) + pc : queued_spin_lock_slowpath+0x58/0x2d0 + lr : invoke_tx_handlers_early+0x5b4/0x5c0 + sp : ffff00001ef64660 + x29: ffff00001ef64660 x28: ffff000009bc1070 x27: ffff000009bc0ad8 + x26: ffff000009bc0900 x25: ffff00001ef647a8 x24: 0000000000000000 + x23: ffff000009bc0900 x22: ffff000009bc0900 x21: ffff00000ac0e000 + x20: ffff00000a279e00 x19: ffff00001ef646e8 x18: 0000000000000000 + x17: ffff800016468000 x16: ffff00001ef608c0 x15: 0010533c93f64f80 + x14: 0010395c9faa3946 x13: 0000000000000000 x12: 00000000fa83b2da + x11: 000000012edeceea x10: ffff0000010fbe00 x9 : 0000000000895440 + x8 : 000000000010533c x7 : ffff00000ad8b740 x6 : ffff00000c350880 + x5 : 0000000000000007 x4 : 0000000000000001 x3 : 0000000000000000 + x2 : 0000000000000000 x1 : 0000000000000001 x0 : ffff00000ac0e0e8 + Call trace: + queued_spin_lock_slowpath+0x58/0x2d0 + ieee80211_tx+0x80/0x12c + ieee80211_tx_pending+0x110/0x278 + tasklet_action_common.constprop.0+0x10c/0x144 + tasklet_action+0x20/0x28 + _stext+0x11c/0x284 + ____do_softirq+0xc/0x14 + call_on_irq_stack+0x24/0x34 + do_softirq_own_stack+0x18/0x20 + do_softirq+0x74/0x7c + __local_bh_enable_ip+0xa0/0xa4 + _ieee80211_wake_txqs+0x3b0/0x4b8 + __ieee80211_wake_queue+0x12c/0x168 + ieee80211_add_pending_skbs+0xec/0x138 + ieee80211_sta_ps_deliver_wakeup+0x2a4/0x480 + ieee80211_mps_sta_status_update.part.0+0xd8/0x11c + ieee80211_mps_sta_status_update+0x18/0x24 + sta_apply_parameters+0x3bc/0x4c0 + ieee80211_change_station+0x1b8/0x2dc + nl80211_set_station+0x444/0x49c + genl_family_rcv_msg_doit.isra.0+0xa4/0xfc + genl_rcv_msg+0x1b0/0x244 + netlink_rcv_skb+0x38/0x10c + genl_rcv+0x34/0x48 + netlink_unicast+0x254/0x2bc + netlink_sendmsg+0x190/0x3b4 + ____sys_sendmsg+0x1e8/0x218 + ___sys_sendmsg+0x68/0x8c + __sys_sendmsg+0x44/0x84 + __arm64_sys_sendmsg+0x20/0x28 + do_el0_svc+0x6c/0xe8 + el0_svc+0x14/0x48 + el0t_64_sync_handler+0xb0/0xb4 + el0t_64_sync+0x14c/0x150 + +Using spin_lock_bh()/spin_unlock_bh() instead prevents softirq to raise +on the same CPU that is holding the lock. + +Fixes: 1d147bfa6429 ("mac80211: fix AP powersave TX vs. wakeup race") +Signed-off-by: Remi Pommarel +Link: https://msgid.link/8e36fe07d0fbc146f89196cd47a53c8a0afe84aa.1716910344.git.repk@triplefau.lt +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/sta_info.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c +index 714d0b01ea629..5dfbfeb8201b8 100644 +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -1275,7 +1275,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) + skb_queue_head_init(&pending); + + /* sync with ieee80211_tx_h_unicast_ps_buf */ +- spin_lock(&sta->ps_lock); ++ spin_lock_bh(&sta->ps_lock); + /* Send all buffered frames to the station */ + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { + int count = skb_queue_len(&pending), tmp; +@@ -1304,7 +1304,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) + */ + clear_sta_flag(sta, WLAN_STA_PSPOLL); + clear_sta_flag(sta, WLAN_STA_UAPSD); +- spin_unlock(&sta->ps_lock); ++ spin_unlock_bh(&sta->ps_lock); + + atomic_dec(&ps->num_sta_ps); + +-- +2.43.0 + diff --git a/queue-4.19/wifi-mac80211-mesh-fix-leak-of-mesh_preq_queue-objec.patch b/queue-4.19/wifi-mac80211-mesh-fix-leak-of-mesh_preq_queue-objec.patch new file mode 100644 index 00000000000..7537e0a3c4f --- /dev/null +++ b/queue-4.19/wifi-mac80211-mesh-fix-leak-of-mesh_preq_queue-objec.patch @@ -0,0 +1,100 @@ +From 9e8df5da4ffa973212c9304987f979d38d8ab24c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 May 2024 16:26:05 +0200 +Subject: wifi: mac80211: mesh: Fix leak of mesh_preq_queue objects + +From: Nicolas Escande + +[ Upstream commit b7d7f11a291830fdf69d3301075dd0fb347ced84 ] + +The hwmp code use objects of type mesh_preq_queue, added to a list in +ieee80211_if_mesh, to keep track of mpath we need to resolve. If the mpath +gets deleted, ex mesh interface is removed, the entries in that list will +never get cleaned. Fix this by flushing all corresponding items of the +preq_queue in mesh_path_flush_pending(). + +This should take care of KASAN reports like this: + +unreferenced object 0xffff00000668d800 (size 128): + comm "kworker/u8:4", pid 67, jiffies 4295419552 (age 1836.444s) + hex dump (first 32 bytes): + 00 1f 05 09 00 00 ff ff 00 d5 68 06 00 00 ff ff ..........h..... + 8e 97 ea eb 3e b8 01 00 00 00 00 00 00 00 00 00 ....>........... + backtrace: + [<000000007302a0b6>] __kmem_cache_alloc_node+0x1e0/0x35c + [<00000000049bd418>] kmalloc_trace+0x34/0x80 + [<0000000000d792bb>] mesh_queue_preq+0x44/0x2a8 + [<00000000c99c3696>] mesh_nexthop_resolve+0x198/0x19c + [<00000000926bf598>] ieee80211_xmit+0x1d0/0x1f4 + [<00000000fc8c2284>] __ieee80211_subif_start_xmit+0x30c/0x764 + [<000000005926ee38>] ieee80211_subif_start_xmit+0x9c/0x7a4 + [<000000004c86e916>] dev_hard_start_xmit+0x174/0x440 + [<0000000023495647>] __dev_queue_xmit+0xe24/0x111c + [<00000000cfe9ca78>] batadv_send_skb_packet+0x180/0x1e4 + [<000000007bacc5d5>] batadv_v_elp_periodic_work+0x2f4/0x508 + [<00000000adc3cd94>] process_one_work+0x4b8/0xa1c + [<00000000b36425d1>] worker_thread+0x9c/0x634 + [<0000000005852dd5>] kthread+0x1bc/0x1c4 + [<000000005fccd770>] ret_from_fork+0x10/0x20 +unreferenced object 0xffff000009051f00 (size 128): + comm "kworker/u8:4", pid 67, jiffies 4295419553 (age 1836.440s) + hex dump (first 32 bytes): + 90 d6 92 0d 00 00 ff ff 00 d8 68 06 00 00 ff ff ..........h..... + 36 27 92 e4 02 e0 01 00 00 58 79 06 00 00 ff ff 6'.......Xy..... + backtrace: + [<000000007302a0b6>] __kmem_cache_alloc_node+0x1e0/0x35c + [<00000000049bd418>] kmalloc_trace+0x34/0x80 + [<0000000000d792bb>] mesh_queue_preq+0x44/0x2a8 + [<00000000c99c3696>] mesh_nexthop_resolve+0x198/0x19c + [<00000000926bf598>] ieee80211_xmit+0x1d0/0x1f4 + [<00000000fc8c2284>] __ieee80211_subif_start_xmit+0x30c/0x764 + [<000000005926ee38>] ieee80211_subif_start_xmit+0x9c/0x7a4 + [<000000004c86e916>] dev_hard_start_xmit+0x174/0x440 + [<0000000023495647>] __dev_queue_xmit+0xe24/0x111c + [<00000000cfe9ca78>] batadv_send_skb_packet+0x180/0x1e4 + [<000000007bacc5d5>] batadv_v_elp_periodic_work+0x2f4/0x508 + [<00000000adc3cd94>] process_one_work+0x4b8/0xa1c + [<00000000b36425d1>] worker_thread+0x9c/0x634 + [<0000000005852dd5>] kthread+0x1bc/0x1c4 + [<000000005fccd770>] ret_from_fork+0x10/0x20 + +Fixes: 050ac52cbe1f ("mac80211: code for on-demand Hybrid Wireless Mesh Protocol") +Signed-off-by: Nicolas Escande +Link: https://msgid.link/20240528142605.1060566-1-nico.escande@gmail.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/mesh_pathtbl.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c +index 8efb2bf08bf48..040f983dea417 100644 +--- a/net/mac80211/mesh_pathtbl.c ++++ b/net/mac80211/mesh_pathtbl.c +@@ -736,10 +736,23 @@ void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata, + */ + void mesh_path_flush_pending(struct mesh_path *mpath) + { ++ struct ieee80211_sub_if_data *sdata = mpath->sdata; ++ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; ++ struct mesh_preq_queue *preq, *tmp; + struct sk_buff *skb; + + while ((skb = skb_dequeue(&mpath->frame_queue)) != NULL) + mesh_path_discard_frame(mpath->sdata, skb); ++ ++ spin_lock_bh(&ifmsh->mesh_preq_queue_lock); ++ list_for_each_entry_safe(preq, tmp, &ifmsh->preq_queue.list, list) { ++ if (ether_addr_equal(mpath->dst, preq->dst)) { ++ list_del(&preq->list); ++ kfree(preq); ++ --ifmsh->preq_queue_len; ++ } ++ } ++ spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); + } + + /** +-- +2.43.0 +