6.6.93-rc1 review
Subsystems (3)
Greg Kroah-Hartman
maintainerPATCH 410/444 af_unix: Skip GC if no cycle exists.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
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.
--- net/unix/garbage.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-)
net/unix/garbage.c +47 -1
@@ -112,6 +112,19 @@ static struct unix_vertex *unix_edge_sucreturn 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_ 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_listunix_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_structspin_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/* 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);
Greg Kroah-Hartman
maintainerPATCH 411/444 af_unix: Avoid Tarjans algorithm if unnecessary.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
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.
--- net/unix/garbage.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-)
net/unix/garbage.c +27 -1
@@ -113,6 +113,7 @@ static struct unix_vertex *unix_edge_suc }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 unireturn ; 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_ 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_structif (!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
Greg Kroah-Hartman
maintainerPATCH 412/444 af_unix: Assign a unique index to SCC.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
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.
--- include/net/af_unix.h | 2 +- net/unix/garbage.c | 29 +++++++++++++++-------------- 2 files changed, 16 insertions(+), 15 deletions(-)
include/net/af_unix.h +1 -1
@@ -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 {
net/unix/garbage.c +15 -14
@@ -312,9 +312,8 @@ static bool unix_scc_cyclic(struct list_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);
Greg Kroah-Hartman
maintainerPATCH 413/444 af_unix: Detect dead SCC.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
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.
--- net/unix/garbage.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-)
net/unix/garbage.c +43 -1
@@ -289,6 +289,39 @@ void unix_destroy_fpl(struct scm_fp_listunix_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); }
Greg Kroah-Hartman
maintainerPATCH 414/444 af_unix: Replace garbage collection algorithm.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
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.
--- include/net/af_unix.h | 8 - net/unix/af_unix.c | 12 - net/unix/garbage.c | 318 ++++++++++---------------------------------------- 3 files changed, 64 insertions(+), 274 deletions(-)
include/net/af_unix.h +0 -8
@@ -19,9 +19,6 @@ static inline struct unix_sock *unix_getextern 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 1struct socket_wq peer_wq;wait_queue_entry_t peer_wake;struct scm_stat scm_stat;
net/unix/af_unix.c +0 -12
@@ -979,12 +979,10 @@ static struct sock *unix_create1(struct 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(strstatic 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_coif (!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_costatic 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)
net/unix/garbage.c +64 -254
384 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 415/444 af_unix: Remove lock dance in unix_peek_fds().
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
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.
--- include/net/af_unix.h | 1 - net/unix/af_unix.c | 42 ------------------------------------------ net/unix/garbage.c | 2 +- 3 files changed, 1 insertion(+), 44 deletions(-)
include/net/af_unix.h +0 -1
@@ -17,7 +17,6 @@ static inline struct unix_sock *unix_get }#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);
net/unix/af_unix.c +0 -42
48 lines not on this page · raw message
net/unix/garbage.c +1 -1
@@ -183,7 +183,7 @@ static void unix_free_vertices(struct sc } } -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)
Greg Kroah-Hartman
maintainerPATCH 416/444 af_unix: Try not to hold unix_gc_lock during accept().
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
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()
--- include/net/af_unix.h | 1 + net/unix/af_unix.c | 2 +- net/unix/garbage.c | 20 ++++++++++++++++---- 3 files changed, 18 insertions(+), 5 deletions(-)
include/net/af_unix.h +1 -0
@@ -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))
net/unix/af_unix.c +1 -1
@@ -1703,12 +1703,12 @@ static int unix_accept(struct socket *so } 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);
net/unix/garbage.c +16 -4
@@ -209,6 +209,7 @@ void unix_add_edges(struct scm_fp_list *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 *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)
Greg Kroah-Hartman
maintainerPATCH 417/444 af_unix: Dont access successor in unix_del_edges() during GC.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
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) = 03. 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: <TASK> __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 </TASK> 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)
--- net/unix/garbage.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
net/unix/garbage.c +12 -5
@@ -158,11 +158,14 @@ static void unix_add_edge(struct scm_fp_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 *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_buffstatic 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 skif (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 sklist_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;
Greg Kroah-Hartman
maintainerPATCH 418/444 af_unix: Add dead flag to struct scm_fp_list.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
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().
--- include/net/scm.h | 1 + net/core/scm.c | 1 + net/unix/garbage.c | 14 ++++++++++---- 3 files changed, 12 insertions(+), 4 deletions(-)
include/net/scm.h +1 -0
@@ -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
net/core/scm.c +1 -0
@@ -91,6 +91,7 @@ static int scm_fp_copy(struct cmsghdr *c fpl->user =NULL ;#if IS_ENABLED (CONFIG_UNIX ) fpl->inflight = false; + fpl->dead = false; fpl->edges =NULL ;INIT_LIST_HEAD (&fpl->vertices);#endif
net/unix/garbage.c +10 -4
@@ -158,13 +158,11 @@ static void unix_add_edge(struct scm_fp_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 *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 sklist_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_structspin_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);
Greg Kroah-Hartman
maintainerPATCH 419/444 af_unix: Fix garbage collection of embryos carrying OOB with SCM_RIGHTS
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Luczaj <[email protected]>
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
--- net/unix/garbage.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
net/unix/garbage.c +14 -9
@@ -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/* 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);
Greg Kroah-Hartman
maintainerPATCH 420/444 af_unix: Fix uninit-value in __unix_walk_scc()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shigeru Yoshida <[email protected]>
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
--- net/unix/garbage.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
net/unix/garbage.c +5 -4
@@ -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)
Greg Kroah-Hartman
maintainerPATCH 421/444 arm64: dts: qcom: ipq9574: Add missing properties for cryptobam
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stephan Gerhold <[email protected]>
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/[email protected]/
[2]: https://lore.kernel.org/r/[email protected]/
--- arch/arm64/boot/dts/qcom/ipq9574.dtsi | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/boot/dts/qcom/ipq9574.dtsi +2 -0
@@ -231,6 +231,8 @@ interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>; #dma-cells = <1>; qcom,ee = <1>; + qcom,num-ees = <4>; + num-channels = <16>; qcom,controlled-remotely; };
Greg Kroah-Hartman
maintainerPATCH 422/444 arm64: dts: qcom: sm8350: Fix typo in pil_camera_mem node
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alok Tiwari <[email protected]>
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.
--- arch/arm64/boot/dts/qcom/sm8350.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/sm8350.dtsi +1 -1
@@ -442,7 +442,7 @@ no-map; }; - pil_camera_mem: mmeory@85200000 { + pil_camera_mem: memory@85200000 { reg = <0x0 0x85200000 0x0 0x500000>; no-map; };
Greg Kroah-Hartman
maintainerPATCH 423/444 arm64: dts: qcom: sm8450: Add missing properties for cryptobam
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stephan Gerhold <[email protected]>
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/[email protected]/
[2]: https://lore.kernel.org/r/[email protected]/
--- arch/arm64/boot/dts/qcom/sm8450.dtsi | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/boot/dts/qcom/sm8450.dtsi +2 -0
@@ -4233,6 +4233,8 @@ interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>; #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>,
Greg Kroah-Hartman
maintainerPATCH 424/444 arm64: dts: qcom: sm8550: Add missing properties for cryptobam
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stephan Gerhold <[email protected]>
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/[email protected]/
[2]: https://lore.kernel.org/r/[email protected]/
--- arch/arm64/boot/dts/qcom/sm8550.dtsi | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/boot/dts/qcom/sm8550.dtsi +2 -0
@@ -1866,6 +1866,8 @@ interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>; #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>;
Greg Kroah-Hartman
maintainerPATCH 425/444 arm64: dts: ti: k3-am68-sk: Fix regulator hierarchy
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yemike Abhilash Chandra <[email protected]>
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
--- arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts +12 -1
@@ -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>;
Greg Kroah-Hartman
maintainerPATCH 426/444 net_sched: hfsc: Address reentrant enqueue adding class to eltree twice
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pedro Tammela <[email protected]>
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
--- net/sched/sch_hfsc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
net/sched/sch_hfsc.c +8 -1
@@ -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, u32if (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 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 )
Greg Kroah-Hartman
maintainerPATCH 427/444 perf/arm-cmn: Fix REQ2/SNP2 mixup
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robin Murphy <[email protected]>
commit 11b0f576e0cbde6a12258f2af6753b17b8df342b upstream.
Somehow the encodings for REQ2/SNP2 channels in XP events got mixed up... Unmix them.
--- drivers/perf/arm-cmn.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/perf/arm-cmn.c +4 -4
@@ -684,8 +684,8 @@ static umode_t arm_cmn_event_attr_is_visif ((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_vis _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)), \
Greg Kroah-Hartman
maintainerPATCH 428/444 perf/arm-cmn: Initialise cmn->cpu earlier
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robin Murphy <[email protected]>
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.
--- drivers/perf/arm-cmn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/perf/arm-cmn.c +1 -1
@@ -2443,6 +2443,7 @@ static int arm_cmn_probe(struct platform 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 platformif (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,
Greg Kroah-Hartman
maintainerPATCH 429/444 coredump: fix error handling for replace_fd()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <[email protected]>
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.
--- fs/coredump.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
fs/coredump.c +7 -2
@@ -502,7 +502,9 @@ static int umh_pipe_setup(struct subproc {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 subproc 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)
Greg Kroah-Hartman
maintainerPATCH 430/444 coredump: hand a pidfd to the usermode coredump helper
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <[email protected]>
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.]
--- fs/coredump.c | 78 ++++++++++++++++++++++++++++++++++++++++++----- include/linux/coredump.h | 1 2 files changed, 72 insertions(+), 7 deletions(-)
fs/coredump.c +71 -7
@@ -42,6 +42,7 @@#include <linux/timekeeping.h> #include <linux/sysctl.h> #include <linux/elf.h> +#include <uapi/linux/pidfd.h> #include <linux/uaccess.h> #include <asm/mmu_context.h>
@@ -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_ncase '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 }/* -* 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* 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 }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 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 );
include/linux/coredump.h +1 -0
@@ -28,6 +28,7 @@ struct coredump_params {int vma_count;size_t vma_data_size;struct core_vma_metadata *vma_meta; +struct pid *pid; };/*
Greg Kroah-Hartman
maintainerPATCH 431/444 dmaengine: idxd: cdev: Fix uninitialized use of sva in idxd_cdev_open
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Purva Yeshi <[email protected]>
[ 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.
--- drivers/dma/idxd/cdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/dma/idxd/cdev.c +2 -2
@@ -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 @@ static int idxd_cdev_open(struct inode *inode, struct file *filp)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);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 432/444 HID: quirks: Add ADATA XPG alpha wireless mouse support
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Milton Barrera <[email protected]>
[ 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.
--- drivers/hid/hid-ids.h | 4 ++++ drivers/hid/hid-quirks.c | 2 ++ 2 files changed, 6 insertions(+)
drivers/hid/hid-ids.h +4 -0
@@ -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
drivers/hid/hid-quirks.c +2 -0
@@ -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 },
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 433/444 nfs: dont share pNFS DS connections between net namespaces
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <[email protected]>
[ 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.
--- 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(-)
fs/nfs/filelayout/filelayoutdev.c +3 -3
@@ -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;
fs/nfs/flexfilelayout/flexfilelayoutdev.c +3 -3
@@ -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;
fs/nfs/pnfs.h +3 -1
@@ -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,
fs/nfs/pnfs_nfs.c +5 -4
@@ -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 @@ nfs4_pnfs_remotestr(struct list_head *dsaddrs, gfp_t gfp_flags)* 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__,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 434/444 platform/x86: thinkpad_acpi: Support also NEC Lavie X1475JAS
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Chau <[email protected]>
[ 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
--- drivers/platform/x86/thinkpad_acpi.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/platform/x86/thinkpad_acpi.c +2 -0
@@ -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;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 435/444 um: let make clean properly clean underlying SUBARCH as well
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masahiro Yamada <[email protected]>
[ 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.
--- arch/um/Makefile | 1 + 1 file changed, 1 insertion(+)
arch/um/Makefile +1 -0
@@ -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
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 436/444 drm/amd/display: fix link_set_dpms_off multi-display MST corner case
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: George Shen <[email protected]>
[ 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.
--- drivers/gpu/drm/amd/display/dc/link/link_dpms.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/dc/link/link_dpms.c +11 -2
@@ -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); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 437/444 phy: starfive: jh7110-usb: Fix USB 2.0 host occasional detection failure
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hal Feng <[email protected]>
[ 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.
--- drivers/phy/starfive/phy-jh7110-usb.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/phy/starfive/phy-jh7110-usb.c +7 -0
@@ -16,6 +16,8 @@#include <linux/usb/of.h> #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 ; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 438/444 spi: spi-sun4i: fix early activation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alessandro Grassi <[email protected]>
[ 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.
--- drivers/spi/spi-sun4i.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/spi/spi-sun4i.c +4 -1
@@ -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 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 439/444 nvme-pci: add NVME_QUIRK_NO_DEEPEST_PS quirk for SOLIDIGM P44 Pro
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilya Guterman <[email protected]>
[ 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.
--- drivers/nvme/host/pci.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/nvme/host/pci.c +2 -0
@@ -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 */
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 440/444 NFS: Avoid flushing data while holding directory locks in nfs_rename()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ 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.
--- fs/nfs/client.c | 2 ++ fs/nfs/dir.c | 15 ++++++++++++++- include/linux/nfs_fs_sb.h | 12 +++++++++--- 3 files changed, 25 insertions(+), 4 deletions(-)
fs/nfs/client.c +2 -0
@@ -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,
fs/nfs/dir.c +14 -1
@@ -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 );
include/linux/nfs_fs_sb.h +9 -3
@@ -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 */
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 441/444 platform/x86: fujitsu-laptop: Support Lifebook S2110 hotkeys
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Valtteri Koskivuori <[email protected]>
[ 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.
--- drivers/platform/x86/fujitsu-laptop.c | 33 +++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-)
drivers/platform/x86/fujitsu-laptop.c +29 -4
@@ -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 + }, {} };
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 442/444 platform/x86: thinkpad_acpi: Ignore battery threshold change event notification
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Pearson <[email protected]>
[ 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.
--- drivers/platform/x86/thinkpad_acpi.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/platform/x86/thinkpad_acpi.c +5 -0
@@ -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 */
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 443/444 net: ethernet: ti: am65-cpsw: Lower random mac address error print to info
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nishanth Menon <[email protected]>
[ 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.
--- drivers/net/ethernet/ti/am65-cpsw-nuss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/ti/am65-cpsw-nuss.c +1 -1
@@ -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" ); } } }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 444/444 ksmbd: use list_first_entry_or_null for opinfo_get_list()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
[ 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.
--- fs/smb/server/oplock.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
fs/smb/server/oplock.c +2 -5
@@ -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))
Signature · 1 line
2.39.5
Am 02.06.2025 um 15:41 schrieb Greg Kroah-Hartman:
Quoted 4 lines
This is the start of the stable review cycle for the 6.6.93 release. There are 444 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Builds, boots and works on my 2-socket Ivy Bridge Xeon E5-2697 v2 server. No dmesg oddities or regressions found.
Beste Grüße,
Peter Schneider
Signature · 8 lines
Climb the mountain not to plant your flag, but to embrace the challenge, enjoy the air and behold the view. Climb it so you can see the world, not so the world can see you. -- David McCullough Jr. OpenPGP: 0xA3828BD796CCE11A8CADE8866E3A92C92C3FF244 Download: https://www.peters-netzplatz.de/download/pschneider1968_pub.asc https://keys.mailvelope.com/pks/lookup?op=get&[email protected] https://keys.mailvelope.com/pks/lookup?op=get&[email protected]
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.93 release. There are 444 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 04 Jun 2025 13:42:20 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.93-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Signature · 1 line
Florian
Hi Greg,
Quoted 7 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.93 release. There are 444 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 04 Jun 2025 13:42:20 +0000. Anything received after that time might be too late.
No problems seen on x86_64 and aarch64 with our testing.
Thanks,
Harshit
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.93 release. There are 444 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 04 Jun 2025 13:42:20 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.93-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.93 release. There are 444 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 04 Jun 2025 13:42:20 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.93-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
## Build
* kernel: 6.6.93-rc1
* git: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
* git commit: 58cbe685685b1c9c144356315c7c08561e004d4e
* git describe: v6.6.92-445-g58cbe685685b
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.6.y/build/v6.6.92-445-g58cbe685685b
## Test Regressions (compared to v6.6.91-118-g18952a1fc4ac)
## Metric Regressions (compared to v6.6.91-118-g18952a1fc4ac)
## Test Fixes (compared to v6.6.91-118-g18952a1fc4ac)
## Metric Fixes (compared to v6.6.91-118-g18952a1fc4ac)
## Test result summary
total: 281357, pass: 258682, fail: 5380, skip: 16800, xfail: 495
## Build Summary
* arc: 5 total, 5 passed, 0 failed
* arm: 129 total, 129 passed, 0 failed
* arm64: 44 total, 44 passed, 0 failed
* i386: 23 total, 20 passed, 3 failed
* mips: 26 total, 25 passed, 1 failed
* parisc: 4 total, 4 passed, 0 failed
* powerpc: 32 total, 31 passed, 1 failed
* riscv: 20 total, 20 passed, 0 failed
* s390: 14 total, 13 passed, 1 failed
* sh: 10 total, 10 passed, 0 failed
* sparc: 7 total, 7 passed, 0 failed
* x86_64: 37 total, 33 passed, 4 failed
## Test suites summary
* boot
* commands
* kselftest-arm64
* kselftest-breakpoints
* kselftest-capabilities
* kselftest-cgroup
* kselftest-clone3
* kselftest-core
* kselftest-cpu-hotplug
* kselftest-cpufreq
* kselftest-efivarfs
* kselftest-exec
* kselftest-fpu
* kselftest-ftrace
* kselftest-futex
* kselftest-gpio
* kselftest-intel_pstate
* kselftest-ipc
* kselftest-kcmp
* kselftest-kvm
* kselftest-livepatch
* kselftest-membarrier
* kselftest-memfd
* kselftest-mincore
* kselftest-mm
* kselftest-mqueue
* kselftest-net
* kselftest-net-mptcp
* kselftest-openat2
* kselftest-ptrace
* kselftest-rseq
* kselftest-rtc
* kselftest-seccomp
* kselftest-sigaltstack
* kselftest-size
* kselftest-tc-testing
* kselftest-timers
* kselftest-tmpfs
* kselftest-tpm2
* kselftest-user_events
* kselftest-vDSO
* kselftest-x86
* kunit
* kvm-unit-tests
* lava
* libgpiod
* libhugetlbfs
* log-parser-boot
* log-parser-build-clang
* log-parser-build-gcc
* log-parser-test
* ltp-capability
* ltp-commands
* ltp-containers
* ltp-controllers
* ltp-cpuhotplug
* ltp-crypto
* ltp-cve
* ltp-dio
* ltp-fcntl-locktests
* ltp-fs
* ltp-fs_bind
* ltp-fs_perms_simple
* ltp-hugetlb
* ltp-ipc
* ltp-math
* ltp-mm
* ltp-nptl
* ltp-pty
* ltp-sched
* ltp-smoke
* ltp-syscalls
* ltp-tracing
* modules
* perf
* rcutorture
--
Linaro LKFT
https://lkft.linaro.org
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.93 release. There are 444 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 04 Jun 2025 13:42:20 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.93-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.93 release. There are 444 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 8 lines · On Mon, 02 Jun 2025 15:41:04 +0200 Greg Kroah-Hartman…
This is the start of the stable review cycle for the 6.6.93 release. There are 444 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 04 Jun 2025 13:42:20 +0000. Anything received after that time might be too late.
Boot-tested under QEMU for Rust x86_64:
Thanks!
Cheers,
Miguel
The kernel, bpf tool, and perf tool builds fine for v6.6.93-rc1 on x86 and arm64 Azure VM.
Kernel binary size for x86 build:
text data bss dec hex filename 27322670 16732594 4640768 48696032 2e70ae0 vmlinux
Kernel binary size for arm64 build:
text data bss dec hex filename 34701581 13853966 970368 49525915 2f3b49b vmlinux
Thanks,
Hardik
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.93 release. There are 444 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 04 Jun 2025 13:42:20 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.93-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v6.6:
10 builds: 10 pass, 0 fail
28 boots: 28 pass, 0 fail
116 tests: 116 pass, 0 failLinux version: 6.6.93-rc1-g58cbe685685b
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra186-p3509-0000+p3636-0001, tegra194-p2972-0000,
tegra194-p3509-0000+p3668-0000, tegra20-ventana,
tegra210-p2371-2180, tegra210-p3450-0000,
tegra30-cardhu-a04Jon